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