summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael Vogt <michael.vogt@ubuntu.com>2007-07-02 18:12:12 +0200
committerMichael Vogt <michael.vogt@ubuntu.com>2007-07-02 18:12:12 +0200
commit31d5080d3a42a410581a3c5e31551035ce510cea (patch)
tree424984026aa2ea19e4c338da33aaf67ab7fd4a07
parentda5b9bcdf772358322d4e05a46cf6eb843d9afaa (diff)
parent5a05be08148871001206ae60b01ed88514189817 (diff)
downloadpython-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.py22
-rw-r--r--apt/package.py21
-rw-r--r--aptsources/distro.py202
-rw-r--r--debian/changelog14
-rwxr-xr-xdoc/examples/records.py12
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