~ubuntu-branches/ubuntu/raring/software-center/raring-proposed

« back to all changes in this revision

Viewing changes to softwarecenter/distro/ubuntu.py

  • Committer: Package Import Robot
  • Author(s): Michael Vogt
  • Date: 2012-10-11 15:33:05 UTC
  • mfrom: (195.1.18 quantal)
  • Revision ID: package-import@ubuntu.com-20121011153305-fm5ln7if3rpzts4n
Tags: 5.4.1.1
* lp:~mvo/software-center/reinstall-previous-purchase-token-fix:
  - fix reinstall previous purchases that have a system-wide
    license key LP: #1065481
* lp:~mvo/software-center/lp1060106:
  - Add missing gettext init for utils/update-software-center-agent
    (LP: #1060106)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# Copyright (C) 2009 Canonical
 
2
#
 
3
# Authors:
 
4
#  Michael Vogt
 
5
#
 
6
# This program is free software; you can redistribute it and/or modify it under
 
7
# the terms of the GNU General Public License as published by the Free Software
 
8
# Foundation; version 3.
 
9
#
 
10
# This program is distributed in the hope that it will be useful, but WITHOUT
 
11
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 
12
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 
13
# details.
 
14
#
 
15
# You should have received a copy of the GNU General Public License along with
 
16
# this program; if not, write to the Free Software Foundation, Inc.,
 
17
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
18
 
 
19
import datetime
 
20
import locale
 
21
import logging
 
22
import os
 
23
import re
 
24
 
 
25
from apt.utils import (get_release_filename_for_pkg,
 
26
                       get_release_date_from_release_file,
 
27
                       get_maintenance_end_date)
 
28
from gettext import gettext as _
 
29
from softwarecenter.distro.debian import Debian
 
30
from softwarecenter.enums import BUY_SOMETHING_HOST
 
31
from softwarecenter.utils import utf8
 
32
 
 
33
LOG = logging.getLogger(__name__)
 
34
 
 
35
 
 
36
class Ubuntu(Debian):
 
37
 
 
38
    # see __init__.py description
 
39
    DISTROSERIES = ["precise",
 
40
                    "oneiric",
 
41
                    "natty",
 
42
                   ]
 
43
 
 
44
    # metapackages
 
45
    IMPORTANT_METAPACKAGES = ("ubuntu-desktop", "kubuntu-desktop")
 
46
 
 
47
    # screenshot handling
 
48
    SCREENSHOT_THUMB_URL = ("http://screenshots.ubuntu.com/"
 
49
        "thumbnail-with-version/%(pkgname)s/%(version)s")
 
50
    SCREENSHOT_LARGE_URL = ("http://screenshots.ubuntu.com/"
 
51
        "screenshot-with-version/%(pkgname)s/%(version)s")
 
52
 
 
53
    # the json description of the available screenshots
 
54
    SCREENSHOT_JSON_URL = "http://screenshots.ubuntu.com/json/package/%s"
 
55
 
 
56
    # purchase subscription
 
57
    PURCHASE_APP_URL = (BUY_SOMETHING_HOST + "/subscriptions/%s/ubuntu/%s/"
 
58
        "+new/?%s")
 
59
 
 
60
    # reviews
 
61
    REVIEWS_SERVER = (os.environ.get("SOFTWARE_CENTER_REVIEWS_HOST") or
 
62
        "http://reviews.ubuntu.com/reviews/api/1.0")
 
63
    REVIEWS_URL = (REVIEWS_SERVER + "/reviews/filter/%(language)s/%(origin)s/"
 
64
        "%(distroseries)s/%(version)s/%(pkgname)s%(appname)s/")
 
65
 
 
66
    #REVIEW_STATS_URL = (REVIEWS_SERVER + "/reviews/api/1.0/%(language)s/"
 
67
    #    "%(origin)s/%(distroseries)s/review-stats/")
 
68
    # FIXME: does that make sense?!?
 
69
    REVIEW_STATS_URL = REVIEWS_SERVER + "/review-stats"
 
70
 
 
71
    # Starting point for Ubuntu app developers
 
72
    DEVELOPER_URL = "http://developer.ubuntu.com/"
 
73
 
 
74
    def get_app_name(self):
 
75
        return _("Ubuntu Software Center")
 
76
 
 
77
    def get_app_description(self):
 
78
        return _("Lets you choose from thousands of applications available "
 
79
            "for Ubuntu.")
 
80
 
 
81
    def get_distro_channel_name(self):
 
82
        """ The name in the Release file """
 
83
        return "Ubuntu"
 
84
 
 
85
    def get_distro_channel_description(self):
 
86
        """ The description of the main distro channel """
 
87
        return _("Provided by Ubuntu")
 
88
 
 
89
    def get_removal_warning_text(self, cache, pkg, appname, depends):
 
90
        primary = _("To remove %s, these items must be removed "
 
91
                    "as well:") % utf8(appname)
 
92
        button_text = _("Remove All")
 
93
 
 
94
        # alter it if a meta-package is affected
 
95
        for m in depends:
 
96
            if cache[m].section == "metapackages":
 
97
                primary = _("If you uninstall %s, future updates will not "
 
98
                              "include new items in <b>%s</b> set. "
 
99
                              "Are you sure you want to continue?") % (appname,
 
100
                              cache[m].installed.summary)
 
101
                button_text = _("Remove Anyway")
 
102
                depends = []
 
103
                break
 
104
 
 
105
        # alter it if an important meta-package is affected
 
106
        for m in self.IMPORTANT_METAPACKAGES:
 
107
            if m in depends:
 
108
                primary = _("%s is a core application in Ubuntu. "
 
109
                              "Uninstalling it may cause future upgrades "
 
110
                              "to be incomplete. Are you sure you want to "
 
111
                              "continue?") % appname
 
112
                button_text = _("Remove Anyway")
 
113
                depends = None
 
114
                break
 
115
        return (primary, button_text)
 
116
 
 
117
    def get_license_text(self, component):
 
118
        if component in ("main", "universe", "independent"):
 
119
            return _("Open source")
 
120
        elif component == "restricted":
 
121
            return _("Proprietary")
 
122
        else:
 
123
            # commercial apps provide license info via the
 
124
            # software-center-agent, but if a given commercial app does not
 
125
            # provide this for some reason, default to a license type of
 
126
            # "Unknown"
 
127
            return _("Unknown")
 
128
 
 
129
    def is_supported(self, cache, doc, pkgname):
 
130
        # the doc does not by definition contain correct data regarding the
 
131
        # section. Looking up in the cache seems just as fast/slow.
 
132
        if pkgname in cache and cache[pkgname].candidate:
 
133
            for origin in cache[pkgname].candidate.origins:
 
134
                if (origin.origin == "Ubuntu" and
 
135
                    origin.trusted and
 
136
                    (origin.component == "main" or
 
137
                     origin.component == "restricted")):
 
138
                    return True
 
139
        return False
 
140
 
 
141
    def get_supported_query(self):
 
142
        import xapian
 
143
        query1 = xapian.Query("XOL" + "Ubuntu")
 
144
        query2a = xapian.Query("XOC" + "main")
 
145
        query2b = xapian.Query("XOC" + "restricted")
 
146
        query2 = xapian.Query(xapian.Query.OP_OR, query2a, query2b)
 
147
        return xapian.Query(xapian.Query.OP_AND, query1, query2)
 
148
 
 
149
    def get_supported_filter_name(self):
 
150
        return _("Canonical-Maintained Software")
 
151
 
 
152
    def get_maintenance_status(self, cache, appname, pkgname, component,
 
153
        channelname):
 
154
        # try to figure out the support dates of the release and make
 
155
        # sure to look only for stuff in "Ubuntu" and "distro_codename"
 
156
        # (to exclude stuff in ubuntu-updates for the support time
 
157
        # calculation because the "Release" file time for that gets
 
158
        # updated regularly)
 
159
        if not hasattr(cache, '_cache') or not pkgname:
 
160
            return
 
161
        releasef = get_release_filename_for_pkg(cache._cache, pkgname,
 
162
                                                "Ubuntu",
 
163
                                                self.get_codename())
 
164
        time_t = get_release_date_from_release_file(releasef)
 
165
        # check the release date and show support information
 
166
        # based on this
 
167
        if time_t:
 
168
            release_date = datetime.datetime.fromtimestamp(time_t)
 
169
            #print "release_date: ", release_date
 
170
            now = datetime.datetime.now()
 
171
            #release_age = (now - release_date).days
 
172
            #print "release age: ", release_age
 
173
 
 
174
            # init with the default time
 
175
            support_month = 18
 
176
 
 
177
            # see if we have a "Supported" entry in the pkg record
 
178
            if (pkgname in cache and
 
179
                cache[pkgname].candidate):
 
180
                support_time = cache._cache[pkgname].candidate.record.get(
 
181
                    "Supported")
 
182
                if support_time:
 
183
                    if support_time.endswith("y"):
 
184
                        support_month = 12 * int(support_time.strip("y"))
 
185
                    elif support_time.endswith("m"):
 
186
                        support_month = int(support_time.strip("m"))
 
187
                    else:
 
188
                        LOG.warning("unsupported 'Supported' string '%s'" %
 
189
                            support_time)
 
190
 
 
191
            # mvo: we do not define the end date very precisely
 
192
            #      currently this is why it will just display a end
 
193
            #      range
 
194
            # print release_date, support_month
 
195
            (support_end_year, support_end_month) = get_maintenance_end_date(
 
196
                release_date, support_month)
 
197
            support_end_month_str = locale.nl_langinfo(
 
198
                getattr(locale, "MON_%d" % support_end_month))
 
199
             # check if the support has ended
 
200
            support_ended = (now.year >= support_end_year and
 
201
                             now.month > support_end_month)
 
202
            if component == "main":
 
203
                if support_ended:
 
204
                    return _("Canonical does no longer provide "
 
205
                             "updates for %s in Ubuntu %s. "
 
206
                             "Updates may be available in a newer version of "
 
207
                             "Ubuntu.") % (appname, self.get_distro_release())
 
208
                else:
 
209
                    return _("Canonical provides critical updates for "
 
210
                             "%(appname)s until %(support_end_month_str)s "
 
211
                             "%(support_end_year)s.") % {
 
212
                                'appname': appname,
 
213
                                'support_end_month_str': support_end_month_str,
 
214
                                'support_end_year': support_end_year}
 
215
            elif component == "restricted":
 
216
                if support_ended:
 
217
                    return _("Canonical does no longer provide "
 
218
                             "updates for %s in Ubuntu %s. "
 
219
                             "Updates may be available in a newer version of "
 
220
                             "Ubuntu.") % (appname, self.get_distro_release())
 
221
                else:
 
222
                    return _("Canonical provides critical updates supplied "
 
223
                             "by the developers of %(appname)s until "
 
224
                             "%(support_end_month_str)s "
 
225
                             "%(support_end_year)s.") % {
 
226
                                'appname': appname,
 
227
                                'support_end_month_str': support_end_month_str,
 
228
                                'support_end_year': support_end_year,
 
229
                            }
 
230
 
 
231
        # if we couldn't determine a support date, use a generic maintenance
 
232
        # string without the date
 
233
        if (channelname or
 
234
            component in ("partner", "independent", "commercial")):
 
235
            return _("Provided by the vendor.")
 
236
        elif component == "main":
 
237
            return _("Canonical provides critical updates for %s.") % appname
 
238
        elif component == "restricted":
 
239
            return _("Canonical provides critical updates supplied by the "
 
240
                     "developers of %s.") % appname
 
241
        elif component == "universe" or component == "multiverse":
 
242
            return _("Canonical does not provide updates for %s. "
 
243
                     "Some updates may be provided by the "
 
244
                     "Ubuntu community.") % appname
 
245
        #return (_("Application %s has an unknown maintenance status.") %
 
246
        #    appname)
 
247
 
 
248
    def get_downloadable_icon_url(self, full_archive_url, icon_filename):
 
249
        """
 
250
        generates the url for a downloadable icon based on the download
 
251
        uri and the icon filename itself
 
252
        """
 
253
        split_at_pool = full_archive_url.split("pool")[0]
 
254
        # support ppas and extras.ubuntu.com
 
255
        if split_at_pool.endswith("/ppa/ubuntu/"):
 
256
            # it's a ppa, generate the icon_url for a ppa
 
257
            split_at_ppa = split_at_pool.split("/ppa/")[0]
 
258
            downloadable_icon_url = []
 
259
            downloadable_icon_url.append(split_at_ppa)
 
260
            downloadable_icon_url.append("/meta/ppa/")
 
261
            downloadable_icon_url.append(icon_filename)
 
262
            return "".join(downloadable_icon_url)
 
263
        elif re.match("http://(.*)extras.ubuntu.com/", split_at_pool):
 
264
            # it's from extras.ubuntu.com, generate the icon_url for a ppa
 
265
            split_at_ubuntu = split_at_pool.split("/ubuntu/")[0]
 
266
            downloadable_icon_url = []
 
267
            downloadable_icon_url.append(split_at_ubuntu)
 
268
            downloadable_icon_url.append("/meta/")
 
269
            downloadable_icon_url.append(icon_filename)
 
270
            return "".join(downloadable_icon_url)
 
271
        else:
 
272
            #raise ValueError("we currently support downloadable icons in "
 
273
            #    "ppa's only")
 
274
            LOG.warning("downloadable icon is not supported for archive: '%s'"
 
275
                % full_archive_url)
 
276
            return ''
 
277
 
 
278
if __name__ == "__main__":
 
279
    import apt
 
280
    cache = apt.Cache()
 
281
    print cache.get_maintenance_status(cache, "synaptic app", "synaptic",
 
282
        "main", None)
 
283
    print cache.get_maintenance_status(cache, "3dchess app", "3dchess",
 
284
        "universe", None)