diff options
| author | Michael Vogt <michael.vogt@ubuntu.com> | 2008-11-24 14:46:48 +0100 |
|---|---|---|
| committer | Michael Vogt <michael.vogt@ubuntu.com> | 2008-11-24 14:46:48 +0100 |
| commit | 59937b2d3b6319773ab174066222c81ecd176628 (patch) | |
| tree | 10863dc97ff1d44e9b4732896d03eb0f3257004f /apt/package.py | |
| parent | b90575e96622f14dc3d25972d0498faf0a02259e (diff) | |
| parent | d7b8902c36f77b7ae87b88cb4fdfbba7aa2ff833 (diff) | |
| download | python-apt-59937b2d3b6319773ab174066222c81ecd176628.tar.gz | |
merged from the consolidation-bracn (with some modificatins)
Diffstat (limited to 'apt/package.py')
| -rw-r--r-- | apt/package.py | 199 |
1 files changed, 193 insertions, 6 deletions
diff --git a/apt/package.py b/apt/package.py index c1c2b1e1..94242e35 100644 --- a/apt/package.py +++ b/apt/package.py @@ -19,10 +19,18 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # USA -import apt_pkg +import httplib import sys import random +import re +import socket import string +import urllib2 + +import apt_pkg + +# Set a timeout for the changelog download +socket.setdefaulttimeout(2) #from gettext import gettext as _ import gettext @@ -68,6 +76,7 @@ class Package(object): self._pkg = pkgiter self._list = sourcelist # sourcelist self._pcache = pcache # python cache in cache.py + self._changelog = "" # Cached changelog pass # helper @@ -236,7 +245,12 @@ class Package(object): summary = property(summary) def description(self, format=True): - """ Return the formated long description """ + """ + Return the formated long description according to the Debian policy + (Chapter 5.6.13). + See http://www.debian.org/doc/debian-policy/ch-controlfields.html + for more information. + """ if not self._lookupRecord(): return "" # get the translated description @@ -249,12 +263,35 @@ class Package(object): except UnicodeDecodeError,e: s = _("Invalid unicode in description for '%s' (%s). " "Please report.") % (self.name,e) - for line in string.split(s,"\n"): - tmp = string.strip(line) - if tmp == ".": + lines = string.split(s, "\n") + for i in range(len(lines)): + # Skip the first line, since its a duplication of the summary + if i == 0: continue + raw_line = lines[i] + if raw_line.strip() == ".": + # The line is just line break + if not desc.endswith("\n"): desc += "\n" + continue + elif raw_line.startswith(" "): + # The line should be displayed verbatim without word wrapping + if not desc.endswith("\n"): + line = "\n%s\n" % raw_line[2:] + else: + line = "%s\n" % raw_line[2:] + elif raw_line.startswith(" "): + # The line is part of a paragraph. + if desc.endswith("\n") or desc == "": + # Skip the leading white space + line = raw_line[1:] else: - desc += tmp + "\n" + line = raw_line + else: + line = raw_line + # Use dots for lists + line = re.sub(r"^(\s*)(\*|0|o|-) ", ur"\1\u2022 ", line, 1) + # Add current line to the description + desc += line return desc description = property(description) @@ -354,6 +391,156 @@ class Package(object): return ver.InstalledSize installedSize = property(installedSize) + def installedFiles(self): + """ + Return the list of unicode names of the files which have + been installed by this package + """ + path = "/var/lib/dpkg/info/%s.list" % self.name + try: + list = open(path) + files = list.read().decode().split("\n") + list.close() + except: + return [] + return files + installedFiles = property(installedFiles) + + def getChangelog(self, uri=None, cancel_lock=None): + """ + Download the changelog of the package and return it as unicode + string + + uri: Is the uri to the changelog file. The following named variables + will be substituted: src_section, prefix, src_pkg and src_ver + For example the Ubuntu changelog: + uri = "http://changelogs.ubuntu.com/changelogs/pool" \\ + "/%(src_section)s/%(prefix)s/%(src_pkg)s" \\ + "/%(src_pkg)s_%(src_ver)s/changelog" + cancel_lock: If this threading.Lock() is set, the download will be + canceled + """ + # Return a cached changelog if available + if self._changelog != "": + return self._changelog + + if uri == None: + if self.candidateOrigin[0].origin == "Debian": + uri = "http://packages.debian.org/changelogs/pool" \ + "/%(src_section)s/%(prefix)s/%(src_pkg)s" \ + "/%(src_pkg)s_%(src_ver)s/changelog" + elif self.candidateOrigin[0].origin == "Ubuntu": + uri = "http://changelogs.ubuntu.com/changelogs/pool" \ + "/%(src_section)s/%(prefix)s/%(src_pkg)s" \ + "/%(src_pkg)s_%(src_ver)s/changelog" + else: + return _("The list of changes is not available") + + # get the src package name + src_pkg = self.sourcePackageName + + # assume "main" section + src_section = "main" + # use the section of the candidate as a starting point + section = self._depcache.GetCandidateVer(self._pkg).Section + + # get the source version, start with the binaries version + bin_ver = self.candidateVersion + src_ver = self.candidateVersion + #print "bin: %s" % binver + try: + # try to get the source version of the pkg, this differs + # for some (e.g. libnspr4 on ubuntu) + # this feature only works if the correct deb-src are in the + # sources.list + # otherwise we fall back to the binary version number + src_records = apt_pkg.GetPkgSrcRecords() + src_rec = src_records.Lookup(src_pkg) + if src_rec: + src_ver = src_records.Version + #if apt_pkg.VersionCompare(binver, srcver) > 0: + # srcver = binver + if not src_ver: + src_ver = bin_ver + #print "srcver: %s" % src_ver + section = src_records.Section + #print "srcsect: %s" % section + else: + # fail into the error handler + raise SystemError + except SystemError, e: + src_ver = bin_ver + + l = section.split("/") + if len(l) > 1: + src_section = l[0] + + # lib is handled special + prefix = src_pkg[0] + if src_pkg.startswith("lib"): + prefix = "lib" + src_pkg[3] + + # stip epoch + l = string.split(src_ver,":") + if len(l) > 1: + src_ver = "".join(l[1:]) + + uri = uri % {"src_section" : src_section, + "prefix" : prefix, + "src_pkg" : src_pkg, + "src_ver" : src_ver} + try: + # Check if the download was canceled + if cancel_lock and cancel_lock.isSet(): return "" + changelog_file = urllib2.urlopen(uri) + # do only get the lines that are new + changelog = "" + regexp = "^%s \((.*)\)(.*)$" % (re.escape(src_pkg)) + + i=0 + while True: + # Check if the download was canceled + if cancel_lock and cancel_lock.isSet(): return "" + # Read changelog line by line + line_raw = changelog_file.readline() + if line_raw == "": + break + # The changelog is encoded in utf-8, but since there isn't any + # http header, urllib2 seems to treat it as ascii + line = line_raw.decode("utf-8") + + #print line.encode('utf-8') + match = re.match(regexp, line) + if match: + # strip epoch from installed version + # and from changelog too + installed = self.installedVersion + if installed and ":" in installed: + installed = installed.split(":",1)[1] + changelog_ver = match.group(1) + if changelog_ver and ":" in changelog_ver: + changelog_ver = changelog_ver.split(":", 1)[1] + if installed and \ + apt_pkg.VersionCompare(changelog_ver, installed) <= 0: + break + # EOF (shouldn't really happen) + changelog += line + + # Print an error if we failed to extract a changelog + if len(changelog) == 0: + changelog = _("The list of changes is not available") + self._changelog = changelog + except urllib2.HTTPError,e: + return _("The list of changes is not available yet.\n\n" + "Please use http://launchpad.net/ubuntu/+source/%s/%s/" + "+changelog\n" + "until the changes become available or try again " + "later.") % (srcpkg, srcver), + except IOError, httplib.BadStatusLine: + return _("Failed to download the list of changes. \nPlease " + "check your Internet connection.") + return self._changelog + # canidate origin class Origin: def __init__(self, pkg, VerFileIter): |
