diff options
| author | Michael Vogt <michael.vogt@ubuntu.com> | 2007-07-02 18:12:12 +0200 |
|---|---|---|
| committer | Michael Vogt <michael.vogt@ubuntu.com> | 2007-07-02 18:12:12 +0200 |
| commit | 31d5080d3a42a410581a3c5e31551035ce510cea (patch) | |
| tree | 424984026aa2ea19e4c338da33aaf67ab7fd4a07 | |
| parent | da5b9bcdf772358322d4e05a46cf6eb843d9afaa (diff) | |
| parent | 5a05be08148871001206ae60b01ed88514189817 (diff) | |
| download | python-apt-31d5080d3a42a410581a3c5e31551035ce510cea.tar.gz | |
* python/package.py:
- added Record class that can be accessed like a dictionary
and return it in candidateRecord and installedRecord
(thanks to Alexander Sack for discussing this with me)
* doc/examples/records.py:
- added example how to use the new Records class
* python/cache.py:
- throw FetchCancelleException, FetchFailedException,
LockFailedException exceptions when something goes wrong
| -rw-r--r-- | apt/cache.py | 22 | ||||
| -rw-r--r-- | apt/package.py | 21 | ||||
| -rw-r--r-- | aptsources/distro.py | 202 | ||||
| -rw-r--r-- | debian/changelog | 14 | ||||
| -rwxr-xr-x | doc/examples/records.py | 12 |
5 files changed, 176 insertions, 95 deletions
diff --git a/apt/cache.py b/apt/cache.py index 9e682bd8..65f3c9d9 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -25,6 +25,16 @@ import apt.progress import os import sys +class FetchCancelledException(IOError): + " Exception that is thrown when the user cancels a fetch operation " + pass +class FetchFailedException(IOError): + " Exception that is thrown when fetching fails " + pass +class LockFailedException(IOError): + " Exception that is thrown when locking fails " + pass + class Cache(object): """ Dictionary-like package cache This class has all the packages that are available in it's @@ -129,9 +139,11 @@ class Cache(object): errMsg += "Failed to fetch %s %s\n" % (item.DescURI,item.ErrorText) failed = True - # we raise a exception if the download failed - if failed: - raise IOError, errMsg + # we raise a exception if the download failed or it was cancelt + if res == fetcher.ResultCancelled: + raise FetchCancelledException, errMsg + elif failed: + raise FetchFailedException, errMsg return res def _fetchArchives(self, fetcher, pm): @@ -141,7 +153,7 @@ class Cache(object): lockfile = apt_pkg.Config.FindDir("Dir::Cache::Archives") + "lock" lock = apt_pkg.GetLock(lockfile) if lock < 0: - raise IOError, "Failed to lock %s" % lockfile + raise LockFailedException, "Failed to lock %s" % lockfile try: # this may as well throw a SystemError exception @@ -157,7 +169,7 @@ class Cache(object): lockfile = apt_pkg.Config.FindDir("Dir::State::Lists") + "lock" lock = apt_pkg.GetLock(lockfile) if lock < 0: - raise IOError, "Failed to lock %s" % lockfile + raise LockFailedException, "Failed to lock %s" % lockfile try: if fetchProgress == None: diff --git a/apt/package.py b/apt/package.py index b82f1aa0..4524a47d 100644 --- a/apt/package.py +++ b/apt/package.py @@ -40,6 +40,23 @@ class Dependency(object): def __init__(self, alternatives): self.or_dependencies = alternatives +class Record(object): + """ represents a pkgRecord, can be accessed like a + dictionary and gives the original package record + if accessed as a string """ + def __init__(self, s): + self._str = s + self._rec = apt_pkg.ParseSection(s) + def __str__(self): + return self._str + def __getitem__(self, key): + k = self._rec.get(key) + if k is None: + raise KeyError + return k + def has_key(self, key): + return self._rec.has_key(key) + class Package(object): """ This class represents a package in the cache """ @@ -244,14 +261,14 @@ class Package(object): " return the full pkgrecord as string of the candidate version " if not self._lookupRecord(True): return None - return self._records.Record + return Record(self._records.Record) candidateRecord = property(candidateRecord) def installedRecord(self): " return the full pkgrecord as string of the installed version " if not self._lookupRecord(False): return None - return self._records.Record + return Record(self._records.Record) installedRecord = property(installedRecord) # depcache states diff --git a/aptsources/distro.py b/aptsources/distro.py index 9d3b4105..22c86b27 100644 --- a/aptsources/distro.py +++ b/aptsources/distro.py @@ -131,7 +131,7 @@ class Distribution: self.get_mirrors() - def get_mirrors(self): + def get_mirrors(self, mirror_template=None): """ Provide a set of mirrors where you can get the distribution from """ @@ -149,6 +149,97 @@ class Distribution: else: self.default_server = self.main_sources[0].uri + # get a list of country codes and real names + self.countries = {} + try: + f = open("/usr/share/iso-codes/iso_3166.tab", "r") + lines = f.readlines() + for line in lines: + parts = line.split("\t") + self.countries[parts[0].lower()] = parts[1].strip() + except: + print "could not open file '%s'" % file + else: + f.close() + + # try to guess the nearest mirror from the locale + self.country = None + self.country_code = None + locale = os.getenv("LANG", default="en.UK") + a = locale.find("_") + z = locale.find(".") + if z == -1: + z = len(locale) + country_code = locale[a+1:z].lower() + + if mirror_template: + self.nearest_server = mirror_template % country_code + + if self.countries.has_key(country_code): + self.country = self.countries[country_code] + self.country_code = country_code + + def _get_mirror_name(self, server): + ''' Try to get a human readable name for the main mirror of a country + Customize for different distributions ''' + country = None + i = server.find("://") + l = server.find(".archive.ubuntu.com") + if i != -1 and l != -1: + country = server[i+len("://"):l] + if self.countries.has_key(country): + # TRANSLATORS: %s is a country + return _("Server for %s") % \ + gettext.dgettext("iso_3166", + self.countries[country].rstrip()).rstrip() + else: + return("%s" % server.rstrip("/ ")) + + def get_server_list(self): + ''' Return a list of used and suggested servers ''' + def compare_mirrors(mir1, mir2): + '''Helper function that handles comaprision of mirror urls + that could contain trailing slashes''' + return re.match(mir1.strip("/ "), mir2.rstrip("/ ")) + + # Store all available servers: + # Name, URI, active + mirrors = [] + if len(self.used_servers) < 1 or \ + (len(self.used_servers) == 1 and \ + compare_mirrors(self.used_servers[0], self.main_server)): + mirrors.append([_("Main server"), self.main_server, True]) + mirrors.append([self._get_mirror_name(self.nearest_server), + self.nearest_server, False]) + elif len(self.used_servers) == 1 and not \ + compare_mirrors(self.used_servers[0], self.main_server): + mirrors.append([_("Main server"), self.main_server, False]) + # Only one server is used + server = self.used_servers[0] + + # Append the nearest server if it's not already used + if not compare_mirrors(server, self.nearest_server): + mirrors.append([self._get_mirror_name(self.nearest_server), + self.nearest_server, False]) + mirrors.append([self._get_mirror_name(server), server, True]) + + elif len(self.used_servers) > 1: + # More than one server is used. Since we don't handle this case + # in the user interface we set "custom servers" to true and + # append a list of all used servers + mirrors.append([_("Main server"), self.main_server, False]) + mirrors.append([self._get_mirror_name(self.nearest_server), + self.nearest_server, False]) + mirrors.append([_("Custom servers"), None, True]) + for server in self.used_servers: + if compare_mirrors(server, self.nearest_server) or\ + compare_mirrors(server, self.main_server): + continue + elif not [self._get_mirror_name(server), server, False] in mirrors: + mirrors.append([self._get_mirror_name(server), server, False]) + + return mirrors + def add_source(self, type=None, uri=None, dist=None, comps=None, comment=""): """ @@ -295,96 +386,31 @@ class DebianDistribution(Distribution): else: return False + def _get_mirror_name(self, server): + ''' Try to get a human readable name for the main mirror of a country + Debian specific ''' + country = None + i = server.find("://ftp.") + l = server.find(".debian.org") + if i != -1 and l != -1: + country = server[i+len("://ftp."):l] + if self.countries.has_key(country): + # TRANSLATORS: %s is a country + return _("Server for %s") % \ + gettext.dgettext("iso_3166", + self.countries[country].rstrip()).rstrip() + else: + return("%s" % server.rstrip("/ ")) + + def get_mirrors(self): + Distribution.get_mirrors(self, + mirror_template="http://ftp.%s.debian.org/debian/") + class UbuntuDistribution(Distribution): ''' Class to support specific Ubuntu features ''' def get_mirrors(self): - Distribution.get_mirrors(self) - # get a list of country codes and real names - self.countries = {} - try: - f = open("/usr/share/iso-codes/iso_3166.tab", "r") - lines = f.readlines() - for line in lines: - parts = line.split("\t") - self.countries[parts[0].lower()] = parts[1].strip() - except: - print "could not open file '%s'" % file - else: - f.close() - - # try to guess the nearest mirror from the locale - self.country = None - self.country_code = None - locale = os.getenv("LANG", default="en.UK") - a = locale.find("_") - z = locale.find(".") - if z == -1: - z = len(locale) - country_code = locale[a+1:z].lower() - self.nearest_server = "http://%s.archive.ubuntu.com/ubuntu/" % \ - country_code - if self.countries.has_key(country_code): - self.country = self.countries[country_code] - self.country_code = country_code - - def get_server_list(self): - ''' Return a list of used and suggested servers ''' - def compare_mirrors(mir1, mir2): - '''Helper function that handles comaprision of mirror urls - that could contain trailing slashes''' - return re.match(mir1.strip("/ "), mir2.rstrip("/ ")) - def get_mirror_name(server): - ''' Try to get a human readable name for the main mirror of a country''' - country = None - i = server.find("://") - l = server.find(".archive.ubuntu.com") - if i != -1 and l != -1: - country = server[i+len("://"):l] - if self.countries.has_key(country): - # TRANSLATORS: %s is a country - return _("Server for %s") % \ - gettext.dgettext("iso_3166", - self.countries[country].rstrip()).rstrip() - else: - return("%s" % server.rstrip("/ ")) - - # Store all available servers: - # Name, URI, active - mirrors = [] - if len(self.used_servers) < 1 or \ - (len(self.used_servers) == 1 and \ - compare_mirrors(self.used_servers[0], self.main_server)): - mirrors.append([_("Main server"), self.main_server, True]) - mirrors.append([get_mirror_name(self.nearest_server), - self.nearest_server, False]) - elif len(self.used_servers) == 1 and not \ - compare_mirrors(self.used_servers[0], self.main_server): - mirrors.append([_("Main server"), self.main_server, False]) - # Only one server is used - server = self.used_servers[0] - - # Append the nearest server if it's not already used - if not compare_mirrors(server, self.nearest_server): - mirrors.append([get_mirror_name(self.nearest_server), - self.nearest_server, False]) - mirrors.append([get_mirror_name(server), server, True]) - - elif len(self.used_servers) > 1: - # More than one server is used. Since we don't handle this case - # in the user interface we set "custom servers" to true and - # append a list of all used servers - mirrors.append([_("Main server"), self.main_server, False]) - mirrors.append([get_mirror_name(self.nearest_server), - self.nearest_server, False]) - mirrors.append([_("Custom servers"), None, True]) - for server in self.used_servers: - if compare_mirrors(server, self.nearest_server) or\ - compare_mirrors(server, self.main_server): - continue - elif not [get_mirror_name(server), server, False] in mirrors: - mirrors.append([get_mirror_name(server), server, False]) - - return mirrors + Distribution.get_mirrors(self, + mirror_template="http://%s.archive.ubuntu.com/ubuntu/") def get_distro(): ''' Check the currently used distribution and return the corresponding diff --git a/debian/changelog b/debian/changelog index b97ecab2..7f2dc1a8 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,17 @@ +python-apt (0.7.2ubuntu2) gutsy; urgency=low + + * python/package.py: + - added Record class that can be accessed like a dictionary + and return it in candidateRecord and installedRecord + (thanks to Alexander Sack for discussing this with me) + * doc/examples/records.py: + - added example how to use the new Records class + * python/cache.py: + - throw FetchCancelleException, FetchFailedException, + LockFailedException exceptions when something goes wrong + + -- Michael Vogt <michael.vogt@ubuntu.com> Thu, 28 Jun 2007 16:03:01 +0200 + python-apt (0.7.2ubuntu1) gutsy; urgency=low * merged from debian/unstable diff --git a/doc/examples/records.py b/doc/examples/records.py new file mode 100755 index 00000000..ef04b555 --- /dev/null +++ b/doc/examples/records.py @@ -0,0 +1,12 @@ +#!/usr/bin/env python + +import apt + +cache = apt.Cache() + +for pkg in cache: + if not pkg.candidateRecord: + continue + if pkg.candidateRecord.has_key("Task"): + print "Pkg %s is part of '%s'" % (pkg.name, pkg.candidateRecord["Task"].split()) + #print pkg.candidateRecord |
