1
# Copyright (C) 2009 Canonical
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.
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
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
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
33
LOG = logging.getLogger(__name__)
38
# see __init__.py description
48
IMPORTANT_METAPACKAGES = (
55
SCREENSHOT_THUMB_URL = ("http://screenshots.ubuntu.com/"
56
"thumbnail-with-version/%(pkgname)s/%(version)s")
57
SCREENSHOT_LARGE_URL = ("http://screenshots.ubuntu.com/"
58
"screenshot-with-version/%(pkgname)s/%(version)s")
60
# the json description of the available screenshots
61
SCREENSHOT_JSON_URL = "http://screenshots.ubuntu.com/json/package/%s"
63
# purchase subscription
64
PURCHASE_APP_URL = (BUY_SOMETHING_HOST + "/subscriptions/%s/ubuntu/%s/"
68
REVIEWS_SERVER = (os.environ.get("SOFTWARE_CENTER_REVIEWS_HOST") or
69
"http://reviews.ubuntu.com/reviews/api/1.0")
70
REVIEWS_URL = (REVIEWS_SERVER + "/reviews/filter/%(language)s/%(origin)s/"
71
"%(distroseries)s/%(version)s/%(pkgname)s%(appname)s/")
73
#REVIEW_STATS_URL = (REVIEWS_SERVER + "/reviews/api/1.0/%(language)s/"
74
# "%(origin)s/%(distroseries)s/review-stats/")
75
# FIXME: does that make sense?!?
76
REVIEW_STATS_URL = REVIEWS_SERVER + "/review-stats"
78
# Starting point for Ubuntu app developers
79
DEVELOPER_URL = "http://developer.ubuntu.com/"
81
def get_app_name(self):
82
return _("Ubuntu Software Center")
84
def get_app_description(self):
85
return _("Lets you choose from thousands of applications available "
88
def get_distro_channel_name(self):
89
""" The name in the Release file """
92
def get_distro_channel_description(self):
93
""" The description of the main distro channel """
94
return _("Provided by Ubuntu")
96
def get_removal_warning_text(self, cache, pkg, appname, depends):
97
primary = _("To remove %s, these items must be removed "
98
"as well:") % utf8(appname)
99
button_text = _("Remove All")
101
# alter it if an important meta-package is affected
102
for m in self.IMPORTANT_METAPACKAGES:
104
primary = _("%s is a core item in Ubuntu. "
105
"Removing it may cause future upgrades "
106
"to be incomplete. Are you sure you want to "
107
"continue?") % appname
108
button_text = _("Remove Anyway")
112
# alter it if a meta-package is affected
114
if cache[m].section == "metapackages":
115
primary = _("If you uninstall %s, future updates will not "
116
"include new items in <b>%s</b> set. "
117
"Are you sure you want to continue?") % (
118
appname, cache[m].installed.summary)
119
button_text = _("Remove Anyway")
123
return (primary, button_text)
125
def get_license_text(self, component):
126
if component in ("main", "universe", "independent"):
127
return _("Open source")
128
elif component == "restricted":
129
return _("Proprietary")
131
# commercial apps provide license info via the
132
# software-center-agent, but if a given commercial app does not
133
# provide this for some reason, default to a license type of
137
def is_supported(self, cache, doc, pkgname):
138
# the doc does not by definition contain correct data regarding the
139
# section. Looking up in the cache seems just as fast/slow.
140
if pkgname in cache and cache[pkgname].candidate:
141
for origin in cache[pkgname].candidate.origins:
142
if (origin.origin == "Ubuntu" and
144
(origin.component == "main" or
145
origin.component == "restricted")):
149
def get_supported_query(self):
151
query1 = xapian.Query("XOL" + "Ubuntu")
152
query2a = xapian.Query("XOC" + "main")
153
query2b = xapian.Query("XOC" + "restricted")
154
query2 = xapian.Query(xapian.Query.OP_OR, query2a, query2b)
155
return xapian.Query(xapian.Query.OP_AND, query1, query2)
157
def get_supported_filter_name(self):
158
return _("Canonical-Maintained Software")
160
def get_maintenance_status(self, cache, appname, pkgname, component,
162
# try to figure out the support dates of the release and make
163
# sure to look only for stuff in "Ubuntu" and "distro_codename"
164
# (to exclude stuff in ubuntu-updates for the support time
165
# calculation because the "Release" file time for that gets
167
if not hasattr(cache, '_cache') or not pkgname:
169
releasef = get_release_filename_for_pkg(cache._cache, pkgname,
172
time_t = get_release_date_from_release_file(releasef)
173
# check the release date and show support information
176
release_date = datetime.datetime.fromtimestamp(time_t)
177
#print "release_date: ", release_date
178
now = datetime.datetime.now()
179
#release_age = (now - release_date).days
180
#print "release age: ", release_age
182
# init with the default time
185
# see if we have a "Supported" entry in the pkg record
186
if (pkgname in cache and
187
cache[pkgname].candidate):
188
support_time = cache._cache[pkgname].candidate.record.get(
191
if support_time.endswith("y"):
192
support_month = 12 * int(support_time.strip("y"))
193
elif support_time.endswith("m"):
194
support_month = int(support_time.strip("m"))
196
LOG.warning("unsupported 'Supported' string '%s'" %
199
# mvo: we do not define the end date very precisely
200
# currently this is why it will just display a end
202
# print release_date, support_month
203
(support_end_year, support_end_month) = get_maintenance_end_date(
204
release_date, support_month)
205
support_end_month_str = locale.nl_langinfo(
206
getattr(locale, "MON_%d" % support_end_month))
207
# check if the support has ended
208
support_ended = (now.year >= support_end_year and
209
now.month > support_end_month)
210
if component == "main":
212
return _("Canonical does no longer provide "
213
"updates for %s in Ubuntu %s. "
214
"Updates may be available in a newer version of "
215
"Ubuntu.") % (appname, self.get_distro_release())
217
d = {'appname': appname,
218
'support_end_month_str': support_end_month_str,
219
'support_end_year': support_end_year}
220
return _("Canonical provides critical updates for "
221
"%(appname)s until %(support_end_month_str)s "
222
"%(support_end_year)s.") % d
223
elif component == "restricted":
225
return _("Canonical does no longer provide "
226
"updates for %s in Ubuntu %s. "
227
"Updates may be available in a newer version of "
228
"Ubuntu.") % (appname, self.get_distro_release())
230
d = {'appname': appname,
231
'support_end_month_str': support_end_month_str,
232
'support_end_year': support_end_year,
234
return _("Canonical provides critical updates supplied "
235
"by the developers of %(appname)s until "
236
"%(support_end_month_str)s "
237
"%(support_end_year)s.") % d
239
# if we couldn't determine a support date, use a generic maintenance
240
# string without the date
242
component in ("partner", "independent", "commercial")):
243
return _("Provided by the vendor.")
244
elif component == "main":
245
return _("Canonical provides critical updates for %s.") % appname
246
elif component == "restricted":
247
return _("Canonical provides critical updates supplied by the "
248
"developers of %s.") % appname
249
elif component == "universe" or component == "multiverse":
250
return _("Canonical does not provide updates for %s. "
251
"Some updates may be provided by the "
252
"Ubuntu community.") % appname
253
#return (_("Application %s has an unknown maintenance status.") %
256
def get_downloadable_icon_url(self, full_archive_url, icon_filename):
258
generates the url for a downloadable icon based on the download
259
uri and the icon filename itself
261
split_at_pool = full_archive_url.split("pool")[0]
262
# support ppas and extras.ubuntu.com
263
if split_at_pool.endswith("/ppa/ubuntu/"):
264
# it's a ppa, generate the icon_url for a ppa
265
split_at_ppa = split_at_pool.split("/ppa/")[0]
266
downloadable_icon_url = []
267
downloadable_icon_url.append(split_at_ppa)
268
downloadable_icon_url.append("/meta/ppa/")
269
downloadable_icon_url.append(icon_filename)
270
return "".join(downloadable_icon_url)
271
elif re.match("http://(.*)extras.ubuntu.com/", split_at_pool):
272
# it's from extras.ubuntu.com, generate the icon_url for a ppa
273
split_at_ubuntu = split_at_pool.split("/ubuntu/")[0]
274
downloadable_icon_url = []
275
downloadable_icon_url.append(split_at_ubuntu)
276
downloadable_icon_url.append("/meta/")
277
downloadable_icon_url.append(icon_filename)
278
return "".join(downloadable_icon_url)
280
#raise ValueError("we currently support downloadable icons in "
282
LOG.warning("downloadable icon is not supported for archive: '%s'"
286
if __name__ == "__main__":
289
print cache.get_maintenance_status(cache, "synaptic app", "synaptic",
291
print cache.get_maintenance_status(cache, "3dchess app", "3dchess",