diff options
| author | Michael Vogt <michael.vogt@ubuntu.com> | 2009-05-06 21:19:53 +0200 |
|---|---|---|
| committer | Michael Vogt <michael.vogt@ubuntu.com> | 2009-05-06 21:19:53 +0200 |
| commit | 2c43ad2f4440571a1fadb6830f14d7a3f1ad2020 (patch) | |
| tree | 76b78116acb768f6379d3425bace15cc7069bfe9 | |
| parent | d9096e08b64c0e917bcfcce29f498fa47a6d7db4 (diff) | |
| parent | b285f7334fc4aa735993a057c8788876620e55cb (diff) | |
| download | python-apt-2c43ad2f4440571a1fadb6830f14d7a3f1ad2020.tar.gz | |
* merged from debian, remaining changes:
- updated mirrors
- build python2.4
- use DH_PYCENTRAL=include-links
- use --install-layout=deb
- pre-build.sh: update ubuntu mirrors on bzr-buildpackage
* apt/package.py: Handle cases where no candidate is available, by returning
None in the candidate property. (Closes: #523801)
* apt/package.py: Handle cases where no candidate is available and
one of the deprecated properties (e.g. candidateVersion) is
requested. (Closes: #523801)
* setup.py, debian/rules: Support version in setup.py again by getting
the value from the variable DEBVER (defined in debian/rules), falling
back to None.
* Build-Depend on python-debian, use it to get version number from changelog
* Depend on libjs-jquery, and remove internal copy (Closes: #521532)
* apt/package.py:
- Introduce Version.{uri,uris,fetch_binary()}
* debian/control:
- Remove mdz from Uploaders (Closes: #521477), add myself.
- Update Standards-Version to 3.8.1
- Use ${binary:Version} instead of ${Source-Version}
- Fix spelling error: python -> Python
* debian/copyright: Switch to machine-interpretable copyright
* Fix documentation building
- doc/source/conf.py: Only include directories for current python version.
- debian/control: Build-Depend on python-gtk2, python-vte.
- setup.py: If pygtk can not be imported, do not build the documentation.
* Breaks: debdelta (<< 0.28~) to avoid more problems due to the internal
API changes from 0.7.9.
* apt/gtk/widgets.py:
- Handle older versions of python-gobject which do not ship glib
* apt/package.py: Introduce the Version class
- Deprecate Package.candidate*() and Package.installed*(), except for
installedFiles.
- Provide Version.get_source() (LP: #118788)
- Provide Package.versions (Closes: #513236)
* apt/progress/: New package, replaces apt.progress and apt.gtk
- apt/progress/gtk2.py: Moved here from apt/gtk/widgets.py
- apt/progress/__init__.py: Move here from apt/progress.py
* doc/source/*: Improve the documentation
- Document more attributes and functions of apt_pkg (they are all listed)
* aptsources/distro.py:
- use iso_3166.xml instead of iso_3166.tab
- fix incorrect indent
* debian/control:
- add Recommends to iso-codes (for iso_3166.xml)
* apt/package.py:
- make sure to set the defaulttimeout back to the
original value (in getChangelog(), LP: #314212)
Closes: #513315
* apt/cache.py:
- when setting a alternative rootdir, read the
config from it as well
* python/configuration.cc, python/apt_pkgmodule.cc:
- add apt_pkg.ReadConfigDir()
* python/cache.cc, tests/getcache_mem_corruption.py:
- test if progress objects have the right methods
and raise error if not (thanks to Emanuele Rocca)
closes: #497049
* apt/package.py:
- avoid uneeded interal references in the Package objects
* aptsources/sourceslist.py:
- fix bug in invalid lines detection (LP: #324614)
40 files changed, 1016 insertions, 463 deletions
@@ -1,8 +1,3 @@ -* apt.Package: - - change all candidateInstalledSize() to installSize(useCandidate=True) - same for candidateOrigin() (see downloadable for a example). - - might be better to have "Package.candidate.{downloadable,size,etc} - * aptsources: - make the distro detection in sources.list more clever by using the origin informaton to avoid adding full uris to (unofficial/internal) diff --git a/apt/__init__.py b/apt/__init__.py index e3cfacbe..ae2abbf2 100644 --- a/apt/__init__.py +++ b/apt/__init__.py @@ -1,3 +1,21 @@ +# Copyright (c) 2005-2009 Canonical +# +# Author: Michael Vogt <michael.vogt@ubuntu.com> +# +# 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; either version 2 of the +# License, or (at your option) any later version. +# +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA # import the core of apt_pkg import apt_pkg import sys diff --git a/apt/cache.py b/apt/cache.py index 01c12c94..cc425ccb 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -1,6 +1,6 @@ # cache.py - apt cache abstraction # -# Copyright (c) 2005 Canonical +# Copyright (c) 2005-2009 Canonical # # Author: Michael Vogt <michael.vogt@ubuntu.com> # @@ -20,7 +20,6 @@ # USA import os -import sys import apt_pkg from apt import Package @@ -53,9 +52,11 @@ class Cache(object): apt_pkg.Config.Set("Dir::Cache::pkgcache", "") if rootdir: if os.path.exists(rootdir+"/etc/apt/apt.conf"): - apt_pkg.ReadConfigFile(apt_pkg.Config, rootdir+"/etc/apt/apt.conf") + apt_pkg.ReadConfigFile(apt_pkg.Config, + rootdir + "/etc/apt/apt.conf") if os.path.isdir(rootdir+"/etc/apt/apt.conf.d"): - apt_pkg.ReadConfigDir(apt_pkg.Config, rootdir+"/etc/apt/apt.conf.d") + apt_pkg.ReadConfigDir(apt_pkg.Config, + rootdir + "/etc/apt/apt.conf.d") apt_pkg.Config.Set("Dir", rootdir) apt_pkg.Config.Set("Dir::State::status", rootdir + "/var/lib/dpkg/status") @@ -71,6 +72,8 @@ class Cache(object): """ Open the package cache, after that it can be used like a dictionary """ + if progress is None: + progress = apt.progress.OpProgress() self._runCallbacks("cache_pre_open") self._cache = apt_pkg.GetCache(progress) self._depcache = apt_pkg.GetDepCache(self._cache) @@ -79,9 +82,7 @@ class Cache(object): self._list.ReadMainList() self._dict = {} - # build the packages dict - if progress is not None: - progress.Op = "Building data structures" + progress.Op = "Building data structures" i=last=0 size=len(self._cache.Packages) for pkg in self._cache.Packages: @@ -90,13 +91,11 @@ class Cache(object): last=i # drop stuff with no versions (cruft) if len(pkg.VersionList) > 0: - self._dict[pkg.Name] = Package(self._cache, self._depcache, - self._records, self._list, - self, pkg) + self._dict[pkg.Name] = Package(self, pkg) i += 1 - if progress is not None: - progress.done() + + progress.done() self._runCallbacks("cache_post_open") def __getitem__(self, key): @@ -156,7 +155,7 @@ class Cache(object): """Return the packages not downloadable packages in reqreinst state.""" reqreinst = set() for pkg in self: - if (not pkg.candidateDownloadable and + if (not pkg.candidate.downloadable and (pkg._pkg.InstState == apt_pkg.InstStateReInstReq or pkg._pkg.InstState == apt_pkg.InstStateHoldReInstReq)): reqreinst.add(pkg.name) @@ -450,7 +449,7 @@ if __name__ == "__main__": print len(f) print "Testing filtered cache (no argument)" - f = FilteredCache(progress=OpTextProgress()) + f = FilteredCache(progress=apt.progress.OpTextProgress()) f.cache.connect("cache_pre_change", cache_pre_changed) f.cache.connect("cache_post_change", cache_post_changed) f.cache.upgrade() diff --git a/apt/cdrom.py b/apt/cdrom.py index 61250fc4..b52762ad 100644 --- a/apt/cdrom.py +++ b/apt/cdrom.py @@ -1,6 +1,6 @@ # cdrom.py - CDROM handling # -# Copyright (c) 2005 Canonical +# Copyright (c) 2005-2009 Canonical # Copyright (c) 2009 Julian Andres Klode <jak@debian.org> # # Author: Michael Vogt <michael.vogt@ubuntu.com> diff --git a/apt/debfile.py b/apt/debfile.py index f24f19f4..0406a250 100644 --- a/apt/debfile.py +++ b/apt/debfile.py @@ -1,24 +1,21 @@ -# Copyright (c) 2005-2007 Canonical +# Copyright (c) 2005-2009 Canonical # -# AUTHOR: -# Michael Vogt <mvo@ubuntu.com> +# Author: Michael Vogt <michael.vogt@ubuntu.com> # -# This file is part of GDebi +# 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; either version 2 of the +# License, or (at your option) any later version. # -# GDebi 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; either version 2 of the License, or (at -# your option) any later version. -# -# GDebi 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 GDebi; if not, write to the Free Software -# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +# 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 +# USA """Classes for working with locally available Debian packages.""" from gettext import gettext as _ import os @@ -108,9 +105,8 @@ class DebPackage(object): return True continue - inst = self._cache[depname] - instver = inst.installedVersion - if instver is not None and apt_pkg.CheckDep(instver, oper, ver): + inst = self._cache[depname].installed + if inst is not None and apt_pkg.CheckDep(inst.version, oper, ver): return True return False @@ -163,9 +159,9 @@ class DebPackage(object): pkg = self._cache[pkgname] if pkg.isInstalled: - pkgver = pkg.installedVersion + pkgver = pkg.installed.version elif pkg.markedInstall: - pkgver = pkg.candidateVersion + pkgver = pkg.candidate.version else: return False #print "pkg: %s" % pkgname @@ -202,7 +198,8 @@ class DebPackage(object): if self.pkgname == pkg.name: self._dbg(3, "conflict on self, ignoring") continue - if self._check_single_pkg_conflict(pkg.name, ver, oper): + if self._check_single_pkg_conflict(pkg.name, ver, + oper): self._installed_conflicts.add(pkg.name) continue if self._check_single_pkg_conflict(depname, ver, oper): @@ -257,9 +254,9 @@ class DebPackage(object): self._dbg(3, "replacesPkg() %s %s %s" % (pkgname, oper, ver)) pkg = self._cache[pkgname] if pkg.isInstalled: - pkgver = pkg.installedVersion + pkgver = pkg.installed.version elif pkg.markedInstall: - pkgver = pkg.candidateVersion + pkgver = pkg.candidate.version else: pkgver = None for or_group in self.replaces: @@ -296,10 +293,10 @@ class DebPackage(object): debver = self._sections["Version"] self._dbg(1, "debver: %s" % debver) if pkgname in self._cache: - if use_installed: - cachever = self._cache[pkgname].installedVersion + if use_installed and self._cache[pkgname].installed: + cachever = self._cache[pkgname].installed.version else: - cachever = self._cache[pkgname].candidateVersion + cachever = self._cache[pkgname].candidate.version if cachever is not None: cmp = apt_pkg.VersionCompare(cachever, debver) self._dbg(1, "CompareVersion(debver,instver): %s" % cmp) @@ -366,7 +363,8 @@ class DebPackage(object): # check depends for or_group in depends: #print "or_group: %s" % or_group - #print "or_group satified: %s" % self._is_or_group_satisfied(or_group) + #print "or_group satified: %s" % self._is_or_group_satisfied( + # or_group) if not self._is_or_group_satisfied(or_group): if not self._satisfy_or_group(or_group): return False @@ -403,7 +401,7 @@ class DebPackage(object): # check authentication, one authenticated origin is enough # libapt will skip non-authenticated origins then authenticated = False - for origin in pkg.candidateOrigin: + for origin in pkg.candidate.origins: authenticated |= origin.trusted if not authenticated: unauthenticated.append(pkg.name) diff --git a/apt/gtk/__init__.py b/apt/gtk/__init__.py deleted file mode 100644 index e69de29b..00000000 --- a/apt/gtk/__init__.py +++ /dev/null diff --git a/apt/package.py b/apt/package.py index f5262fff..ec88a456 100644 --- a/apt/package.py +++ b/apt/package.py @@ -1,6 +1,6 @@ # package.py - apt package abstraction # -# Copyright (c) 2005 Canonical +# Copyright (c) 2005-2009 Canonical # # Author: Michael Vogt <michael.vogt@ubuntu.com> # @@ -21,15 +21,19 @@ """Functionality related to packages.""" import gettext import httplib +import os import sys import re import socket +import subprocess import urllib2 +import warnings import apt_pkg +import apt.progress - -__all__ = 'BaseDependency', 'Dependency', 'Origin', 'Package', 'Record' +__all__ = ('BaseDependency', 'Dependency', 'Origin', 'Package', 'Record', + 'Version') def _(string): @@ -37,6 +41,17 @@ def _(string): return gettext.dgettext("python-apt", string) +def _file_is_same(path, size, md5): + """Return True if the file is the same.""" + if (os.path.exists(path) and os.path.getsize(path) == size and + apt_pkg.md5sum(open(path)) == md5): + return True + + +class FetchError(Exception): + """Raised when a file could not be fetched.""" + + class BaseDependency(object): """A single dependency. @@ -53,6 +68,10 @@ class BaseDependency(object): self.version = ver self.preDepend = pre + def __repr__(self): + return ('<BaseDependency: name:%r relation:%r version:%r preDepend:%r>' + % (self.name, self.relation, self.version, self.preDepend)) + class Dependency(object): """Represent an Or-group of dependencies. @@ -64,6 +83,29 @@ class Dependency(object): def __init__(self, alternatives): self.or_dependencies = alternatives + def __repr__(self): + return repr(self.or_dependencies) + + +class DeprecatedProperty(property): + """A property which gives DeprecationWarning on access. + + This is only used for providing the properties in Package, which have been + replaced by the ones in Version. + """ + + def __init__(self, fget=None, fset=None, fdel=None, doc=None): + property.__init__(self, fget, fset, fdel, doc) + self.__doc__ = ':Deprecated: ' + (doc or fget.__doc__ or '') + + def __get__(self, obj, type=None): + if obj is not None: + warnings.warn("Accessed deprecated property %s.%s, please see the " + "Version class for alternatives." % + ((obj.__class__.__name__ or type.__name__), + self.fget.func_name), DeprecationWarning, 2) + return property.__get__(self, obj, type) + class Origin(object): """The origin of a version. @@ -85,17 +127,17 @@ class Origin(object): self.site = VerFileIter.Site self.not_automatic = VerFileIter.NotAutomatic # check the trust - indexfile = pkg._list.FindIndex(VerFileIter) + indexfile = pkg._pcache._list.FindIndex(VerFileIter) if indexfile and indexfile.IsTrusted: self.trusted = True else: self.trusted = False def __repr__(self): - return ("<Origin component:'%s' archive:'%s' origin:'%s' label:'%s'" - "site:'%s' isTrusted:'%s'>") % (self.component, self.archive, - self.origin, self.label, - self.site, self.trusted) + return ("<Origin component:%r archive:%r origin:%r label:%r " + "site:%r isTrusted:%r>") % (self.component, self.archive, + self.origin, self.label, + self.site, self.trusted) class Record(object): @@ -137,6 +179,296 @@ class Record(object): return self._rec.has_key(key) +class Version(object): + """Representation of a package version. + + :since: 0.7.9 + """ + + def __init__(self, package, cand): + self.package = package + self._cand = cand + + def __eq__(self, other): + return self._cand.ID == other._cand.ID + + def __gt__(self, other): + return apt_pkg.VersionCompare(self.version, other.version) > 0 + + def __lt__(self, other): + return apt_pkg.VersionCompare(self.version, other.version) < 0 + + def __ne__(self, other): + return not self.__eq__(other) + + def __hash__(self): + return self._cand.Hash + + def __repr__(self): + return '<Version: package:%r version:%r>' % (self.package.name, + self.version) + + @property + def _records(self): + """Internal helper that moves the Records to the right position.""" + if self.package._pcache._records.Lookup(self._cand.FileList[0]): + return self.package._pcache._records + + @property + def installed_size(self): + """Return the size of the package when installed.""" + return self._cand.InstalledSize + + @property + def homepage(self): + """Return the homepage for the package.""" + return self._records.Homepage + + @property + def size(self): + """Return the size of the package.""" + return self._cand.Size + + @property + def architecture(self): + """Return the architecture of the package version.""" + return self._cand.Arch + + @property + def downloadable(self): + """Return whether the version of the package is downloadable.""" + return bool(self._cand.Downloadable) + + @property + def version(self): + """Return the version as a string.""" + return self._cand.VerStr + + @property + def summary(self): + """Return the short description (one line summary).""" + desc_iter = self._cand.TranslatedDescription + self.package._pcache._records.Lookup(desc_iter.FileList.pop(0)) + return self.package._pcache._records.ShortDesc + + @property + def raw_description(self): + """return the long description (raw).""" + return self._records.LongDesc + + @property + def section(self): + """Return the section of the package.""" + return self._cand.Section + + @property + def description(self, format=True, useDots=False): + """Return the formatted 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. + """ + self.summary # This does the lookup for us. + desc = '' + try: + dsc = unicode(self.package._pcache._records.LongDesc, "utf-8") + except UnicodeDecodeError, err: + return _("Invalid unicode in description for '%s' (%s). " + "Please report.") % (self.package.name, err) + + lines = iter(dsc.split("\n")) + # Skip the first line, since its a duplication of the summary + lines.next() + for raw_line in lines: + if raw_line.strip() == ".": + # The line is just line break + if not desc.endswith("\n"): + desc += "\n\n" + continue + if 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: + line = raw_line + else: + line = raw_line + # Add current line to the description + desc += line + return desc + + @property + def source_name(self): + """Return the name of the source package.""" + try: + return self._records.SourcePkg or self.package.name + except IndexError: + return self.package.name + + @property + def priority(self): + """Return the priority of the package, as string.""" + return self._cand.PriorityStr + + @property + def record(self): + """Return a Record() object for this version.""" + return Record(self._records.Record) + + @property + def dependencies(self): + """Return the dependencies of the package version.""" + depends_list = [] + depends = self._cand.DependsList + for t in ["PreDepends", "Depends"]: + try: + for depVerList in depends[t]: + base_deps = [] + for depOr in depVerList: + base_deps.append(BaseDependency(depOr.TargetPkg.Name, + depOr.CompType, depOr.TargetVer, + (t == "PreDepends"))) + depends_list.append(Dependency(base_deps)) + except KeyError: + pass + return depends_list + + @property + def origins(self): + """Return a list of origins for the package version.""" + origins = [] + for (verFileIter, index) in self._cand.FileList: + origins.append(Origin(self.package, verFileIter)) + return origins + + @property + def filename(self): + """Return the path to the file inside the archive.""" + return self._records.FileName + + @property + def md5(self): + """Return the md5sum of the binary.""" + return self._records.MD5Hash + + @property + def sha1(self): + """Return the sha1sum of the binary.""" + return self._records.SHA1Hash + + @property + def sha256(self): + """Return the sha1sum of the binary.""" + return self._records.SHA256Hash + + def _uris(self): + """Return an iterator over all available urls.""" + for (packagefile, index) in self._cand.FileList: + indexfile = self.package._pcache._list.FindIndex(packagefile) + if indexfile: + yield indexfile.ArchiveURI(self._records.FileName) + + @property + def uris(self): + """Return a list of all available uris for the binary.""" + return list(self._uris()) + + @property + def uri(self): + """Return a single URI for the binary.""" + return self._uris().next() + + def fetch_binary(self, destdir='', progress=None): + """Fetch the binary version of the package. + + The parameter 'destdir' specifies the directory where the package will + be fetched to. + + The parameter 'progress' may refer to an apt.progress.FetchProgress() + object. If not specified or None, apt.progress.TextFetchProgress() is + used. + """ + base = os.path.basename(self._records.FileName) + destfile = os.path.join(destdir, base) + if _file_is_same(destfile, self.size, self._records.MD5Hash): + print 'Ignoring already existing file:', destfile + return + acq = apt_pkg.GetAcquire(progress or apt.progress.TextFetchProgress()) + apt_pkg.GetPkgAcqFile(acq, self.uri, self._records.MD5Hash, self.size, + base, destFile=destfile) + acq.Run() + for item in acq.Items: + if item.Status != item.StatDone: + raise FetchError("The item %r could not be fetched: %s" % + (item.DestFile, item.ErrorText)) + return os.path.abspath(destfile) + + def fetch_source(self, destdir="", progress=None, unpack=True): + """Get the source code of a package. + + The parameter 'destdir' specifies the directory where the source will + be fetched to. + + The parameter 'progress' may refer to an apt.progress.FetchProgress() + object. If not specified or None, apt.progress.TextFetchProgress() is + used. + + The parameter 'unpack' describes whether the source should be unpacked + (True) or not (False). By default, it is unpacked. + + If 'unpack' is True, the path to the extracted directory is returned. + Otherwise, the path to the .dsc file is returned. + """ + src = apt_pkg.GetPkgSrcRecords() + acq = apt_pkg.GetAcquire(progress or apt.progress.TextFetchProgress()) + + dsc = None + src.Lookup(self.package.name) + try: + while self.version != src.Version: + src.Lookup(self.package.name) + except AttributeError: + raise ValueError("No source for %r" % self) + for md5, size, path, type in src.Files: + base = os.path.basename(path) + destfile = os.path.join(destdir, base) + if type == 'dsc': + dsc = destfile + if os.path.exists(base) and os.path.getsize(base) == size: + fobj = open(base) + try: + if apt_pkg.md5sum(fobj) == md5: + print 'Ignoring already existing file:', destfile + continue + finally: + fobj.close() + apt_pkg.GetPkgAcqFile(acq, src.Index.ArchiveURI(path), md5, size, + base, destFile=destfile) + acq.Run() + + for item in acq.Items: + if item.Status != item.StatDone: + raise FetchError("The item %r could not be fetched: %s" % + (item.DestFile, item.ErrorText)) + + if unpack: + outdir = src.Package + '-' + apt_pkg.UpstreamVersion(src.Version) + outdir = os.path.join(destdir, outdir) + subprocess.check_call(["dpkg-source", "-x", dsc, outdir]) + return os.path.abspath(outdir) + else: + return os.path.abspath(dsc) + + class Package(object): """Representation of a package in a cache. @@ -145,38 +477,31 @@ class Package(object): much more. """ - def __init__(self, cache, depcache, records, sourcelist, pcache, pkgiter): + def __init__(self, pcache, pkgiter): """ Init the Package object """ - self._cache = cache # low level cache - self._depcache = depcache - self._records = records self._pkg = pkgiter - self._list = sourcelist # sourcelist self._pcache = pcache # python cache in cache.py self._changelog = "" # Cached changelog - def _lookupRecord(self, UseCandidate=True): - """Internal helper that moves the Records to the right position. + def __repr__(self): + return '<Package: name:%r id:%r>' % (self._pkg.Name, self._pkg.ID) - Must be called before _records is accessed. - """ - if UseCandidate: - ver = self._depcache.GetCandidateVer(self._pkg) - else: - ver = self._pkg.CurrentVer - - # check if we found a version - if ver is None: - #print "No version for: %s (Candidate: %s)" % (self._pkg.Name, - # UseCandidate) - return False - - if ver.FileList is None: - print "No FileList for: %s " % self._pkg.Name() - return False - f, index = ver.FileList.pop(0) - self._records.Lookup((f, index)) - return True + @property + def candidate(self): + """Return the candidate version of the package. + + :since: 0.7.9""" + cand = self._pcache._depcache.GetCandidateVer(self._pkg) + if cand is not None: + return Version(self, cand) + + @property + def installed(self): + """Return the currently installed version of the package. + + :since: 0.7.9""" + if self._pkg.CurrentVer is not None: + return Version(self, self._pkg.CurrentVer) @property def name(self): @@ -196,142 +521,81 @@ class Package(object): This returns the same value as ID, which is unique.""" return self._pkg.ID - @property + @DeprecatedProperty def installedVersion(self): - """Return the installed version as string.""" - ver = self._pkg.CurrentVer - if ver is not None: - return ver.VerStr - else: - return None + """Return the installed version as string. - @property + Deprecated, please use installed.version instead.""" + return getattr(self.installed, 'version', None) + + @DeprecatedProperty def candidateVersion(self): """Return the candidate version as string.""" - ver = self._depcache.GetCandidateVer(self._pkg) - if ver is not None: - return ver.VerStr - else: - return None - - def _getDependencies(self, ver): - """Get the dependencies for a given version of a package.""" - depends_list = [] - depends = ver.DependsList - for t in ["PreDepends", "Depends"]: - try: - for depVerList in depends[t]: - base_deps = [] - for depOr in depVerList: - base_deps.append(BaseDependency(depOr.TargetPkg.Name, - depOr.CompType, depOr.TargetVer, - (t == "PreDepends"))) - depends_list.append(Dependency(base_deps)) - except KeyError: - pass - return depends_list + return getattr(self.candidate, "version", None) - @property + @DeprecatedProperty def candidateDependencies(self): """Return a list of candidate dependencies.""" - candver = self._depcache.GetCandidateVer(self._pkg) - if candver is None: - return [] - return self._getDependencies(candver) + return getattr(self.candidate, "dependencies", None) - @property + @DeprecatedProperty def installedDependencies(self): """Return a list of installed dependencies.""" - ver = self._pkg.CurrentVer - if ver is None: - return [] - return self._getDependencies(ver) + return getattr(self.installed, 'dependencies', []) - @property + @DeprecatedProperty def architecture(self): """Return the Architecture of the package""" - if not self._lookupRecord(): - return None - sec = apt_pkg.ParseSection(self._records.Record) - try: - return sec["Architecture"] - except KeyError: - return None - - def _downloadable(self, useCandidate=True): - """Return True if the package is downloadable.""" - if useCandidate: - ver = self._depcache.GetCandidateVer(self._pkg) - else: - ver = self._pkg.CurrentVer - if ver is None: - return False - return ver.Downloadable + return getattr(self.candidate, "architecture", None) - @property + @DeprecatedProperty def candidateDownloadable(self): """Return True if the candidate is downloadable.""" - return self._downloadable(True) + return getattr(self.candidate, "downloadable", None) - @property + @DeprecatedProperty def installedDownloadable(self): """Return True if the installed version is downloadable.""" - return self._downloadable(False) + return getattr(self.installed, 'downloadable', False) - @property + @DeprecatedProperty def sourcePackageName(self): """Return the source package name as string.""" - if not self._lookupRecord(): - if not self._lookupRecord(False): + try: + return self.candidate._records.SourcePkg or self._pkg.Name + except AttributeError: + try: + return self.installed._records.SourcePkg or self._pkg.Name + except AttributeError: return self._pkg.Name - src = self._records.SourcePkg - if src != "": - return src - else: - return self._pkg.Name - @property + @DeprecatedProperty def homepage(self): """Return the homepage field as string.""" - if not self._lookupRecord(): - return None - return self._records.Homepage + return getattr(self.candidate, "homepage", None) @property def section(self): """Return the section of the package.""" return self._pkg.Section - @property + @DeprecatedProperty def priority(self): """Return the priority (of the candidate version).""" - ver = self._depcache.GetCandidateVer(self._pkg) - if ver: - return ver.PriorityStr - else: - return None + return getattr(self.candidate, "priority", None) - @property + @DeprecatedProperty def installedPriority(self): """Return the priority (of the installed version).""" - ver = self._depcache.GetCandidateVer(self._pkg) - if ver: - return ver.PriorityStr - else: - return None + return getattr(self.installed, 'priority', None) - @property + @DeprecatedProperty def summary(self): """Return the short description (one line summary).""" - if not self._lookupRecord(): - return "" - ver = self._depcache.GetCandidateVer(self._pkg) - desc_iter = ver.TranslatedDescription - self._records.Lookup(desc_iter.FileList.pop(0)) - return self._records.ShortDesc + return getattr(self.candidate, "summary", None) - @property - def description(self, format=True, useDots=False): + @DeprecatedProperty + def description(self): """Return the formatted long description. Return the formated long description according to the Debian policy @@ -339,105 +603,54 @@ class Package(object): See http://www.debian.org/doc/debian-policy/ch-controlfields.html for more information. """ - if not format: - return self.rawDescription - if not self._lookupRecord(): - return "" - # get the translated description - ver = self._depcache.GetCandidateVer(self._pkg) - desc_iter = ver.TranslatedDescription - self._records.Lookup(desc_iter.FileList.pop(0)) - desc = "" - try: - dsc = unicode(self._records.LongDesc, "utf-8") - except UnicodeDecodeError, err: - dsc = _("Invalid unicode in description for '%s' (%s). " - "Please report.") % (self.name, err) - lines = dsc.split("\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: - line = raw_line - else: - line = raw_line - # Use dots for lists - if useDots: - line = re.sub(r"^(\s*)(\*|0|o|-) ", ur"\1\u2022 ", line, 1) - # Add current line to the description - desc += line - return desc + return getattr(self.candidate, "description", None) - @property + @DeprecatedProperty def rawDescription(self): """return the long description (raw).""" - if not self._lookupRecord(): - return "" - return self._records.LongDesc + return getattr(self.candidate, "raw_description", None) - @property + @DeprecatedProperty def candidateRecord(self): """Return the Record of the candidate version of the package.""" - if not self._lookupRecord(True): - return None - return Record(self._records.Record) + return getattr(self.candidate, "record", None) - @property + @DeprecatedProperty def installedRecord(self): """Return the Record of the candidate version of the package.""" - if not self._lookupRecord(False): - return None - return Record(self._records.Record) + return getattr(self.installed, 'record', '') # depcache states @property def markedInstall(self): """Return True if the package is marked for install.""" - return self._depcache.MarkedInstall(self._pkg) + return self._pcache._depcache.MarkedInstall(self._pkg) @property def markedUpgrade(self): """Return True if the package is marked for upgrade.""" - return self._depcache.MarkedUpgrade(self._pkg) + return self._pcache._depcache.MarkedUpgrade(self._pkg) @property def markedDelete(self): """Return True if the package is marked for delete.""" - return self._depcache.MarkedDelete(self._pkg) + return self._pcache._depcache.MarkedDelete(self._pkg) @property def markedKeep(self): """Return True if the package is marked for keep.""" - return self._depcache.MarkedKeep(self._pkg) + return self._pcache._depcache.MarkedKeep(self._pkg) @property def markedDowngrade(self): """ Package is marked for downgrade """ - return self._depcache.MarkedDowngrade(self._pkg) + return self._pcache._depcache.MarkedDowngrade(self._pkg) @property def markedReinstall(self): """Return True if the package is marked for reinstall.""" - return self._depcache.MarkedReinstall(self._pkg) + return self._pcache._depcache.MarkedReinstall(self._pkg) @property def isInstalled(self): @@ -447,7 +660,8 @@ class Package(object): @property def isUpgradable(self): """Return True if the package is upgradable.""" - return self.isInstalled and self._depcache.IsUpgradable(self._pkg) + return (self.isInstalled and + self._pcache._depcache.IsUpgradable(self._pkg)) @property def isAutoRemovable(self): @@ -457,38 +671,29 @@ class Package(object): another package, and if no packages depend on it anymore, the package is no longer required. """ - return self.isInstalled and self._depcache.IsGarbage(self._pkg) + return self.isInstalled and self._pcache._depcache.IsGarbage(self._pkg) # sizes - @property + @DeprecatedProperty def packageSize(self): """Return the size of the candidate deb package.""" - ver = self._depcache.GetCandidateVer(self._pkg) - return ver.Size + return getattr(self.candidate, "size", None) - @property + @DeprecatedProperty def installedPackageSize(self): """Return the size of the installed deb package.""" - ver = self._pkg.CurrentVer - return ver.Size + return getattr(self.installed, 'size', 0) - @property - def candidateInstalledSize(self, UseCandidate=True): + @DeprecatedProperty + def candidateInstalledSize(self): """Return the size of the candidate installed package.""" - ver = self._depcache.GetCandidateVer(self._pkg) - if ver: - return ver.Size - else: - return None + return getattr(self.candidate, "installed_size", None) - @property + @DeprecatedProperty def installedSize(self): """Return the size of the currently installed package.""" - ver = self._pkg.CurrentVer - if ver is None: - return 0 - return ver.InstalledSize + return getattr(self.installed, 'installed_size', 0) @property def installedFiles(self): @@ -528,11 +733,13 @@ class Package(object): return self._changelog if uri is None: - if self.candidateOrigin[0].origin == "Debian": + if not self.candidate: + pass + if self.candidate.origins[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": + elif self.candidate.origins[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" @@ -540,16 +747,16 @@ class Package(object): return _("The list of changes is not available") # get the src package name - src_pkg = self.sourcePackageName + src_pkg = self.candidate.source_name # assume "main" section src_section = "main" # use the section of the candidate as a starting point - section = self._depcache.GetCandidateVer(self._pkg).Section + section = self.candidate.section # get the source version, start with the binaries version - bin_ver = self.candidateVersion - src_ver = self.candidateVersion + bin_ver = self.candidate.version + src_ver = self.candidate.version #print "bin: %s" % binver try: # FIXME: This try-statement is too long ... @@ -595,7 +802,7 @@ class Package(object): "src_ver": src_ver} timeout = socket.getdefaulttimeout() - + # FIXME: when python2.4 vanishes from the archive, # merge this into a single try..finally block (pep 341) try: @@ -610,7 +817,6 @@ class Package(object): # do only get the lines that are new changelog = "" regexp = "^%s \((.*)\)(.*)$" % (re.escape(src_pkg)) - while True: # Check if the download was canceled if cancel_lock and cancel_lock.isSet(): @@ -619,8 +825,8 @@ class Package(object): 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 + # 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') @@ -634,8 +840,8 @@ class Package(object): 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): + if (installed and apt_pkg.VersionCompare(changelog_ver, + installed) <= 0): break # EOF (shouldn't really happen) changelog += line @@ -647,8 +853,8 @@ class Package(object): except urllib2.HTTPError: return _("The list of changes is not available yet.\n\n" - "Please use http://launchpad.net/ubuntu/+source/%s/%s/" - "+changelog\n" + "Please use http://launchpad.net/ubuntu/+source/%s/" + "%s/+changelog\n" "until the changes become available or try again " "later.") % (src_pkg, src_ver) except (IOError, httplib.BadStatusLine): @@ -658,23 +864,25 @@ class Package(object): socket.setdefaulttimeout(timeout) return self._changelog - @property + @DeprecatedProperty def candidateOrigin(self): - """Return the Origin() of the candidate version.""" - ver = self._depcache.GetCandidateVer(self._pkg) - if not ver: - return None - origins = [] - for (verFileIter, index) in ver.FileList: - origins.append(Origin(self, verFileIter)) - return origins + """Return a list of Origin() objects for the candidate version.""" + return getattr(self.candidate, "origins", None) + + @property + def versions(self): + """Return a list of versions. + + :since: 0.7.9 + """ + return [Version(self, ver) for ver in self._pkg.VersionList] # depcache actions def markKeep(self): """Mark a package for keep.""" self._pcache.cachePreChange() - self._depcache.MarkKeep(self._pkg) + self._pcache._depcache.MarkKeep(self._pkg) self._pcache.cachePostChange() def markDelete(self, autoFix=True, purge=False): @@ -687,10 +895,10 @@ class Package(object): well. The default is to keep the configuration. """ self._pcache.cachePreChange() - self._depcache.MarkDelete(self._pkg, purge) + self._pcache._depcache.MarkDelete(self._pkg, purge) # try to fix broken stuffsta - if autoFix and self._depcache.BrokenCount > 0: - Fix = apt_pkg.GetPkgProblemResolver(self._depcache) + if autoFix and self._pcache._depcache.BrokenCount > 0: + Fix = apt_pkg.GetPkgProblemResolver(self._pcache._depcache) Fix.Clear(self._pkg) Fix.Protect(self._pkg) Fix.Remove(self._pkg) @@ -713,10 +921,10 @@ class Package(object): it. """ self._pcache.cachePreChange() - self._depcache.MarkInstall(self._pkg, autoInst, fromUser) + self._pcache._depcache.MarkInstall(self._pkg, autoInst, fromUser) # try to fix broken stuff - if autoFix and self._depcache.BrokenCount > 0: - fixer = apt_pkg.GetPkgProblemResolver(self._depcache) + if autoFix and self._pcache._depcache.BrokenCount > 0: + fixer = apt_pkg.GetPkgProblemResolver(self._pcache._depcache) fixer.Clear(self._pkg) fixer.Protect(self._pkg) fixer.Resolve(True) @@ -740,7 +948,7 @@ class Package(object): The parameter `iprogress` refers to an InstallProgress() object, as found in apt.progress. """ - self._depcache.Commit(fprogress, iprogress) + self._pcache._depcache.Commit(fprogress, iprogress) def _test(): @@ -749,40 +957,33 @@ def _test(): import random import apt apt_pkg.init() - cache = apt_pkg.GetCache() - depcache = apt_pkg.GetDepCache(cache) - records = apt_pkg.GetPkgRecords(cache) - sourcelist = apt_pkg.GetPkgSourceList() - - pkgiter = cache["apt-utils"] - pkg = Package(cache, depcache, records, sourcelist, None, pkgiter) + progress = apt.progress.OpTextProgress() + cache = apt.Cache(progress) + pkg = cache["apt-utils"] print "Name: %s " % pkg.name print "ID: %s " % pkg.id - print "Priority (Candidate): %s " % pkg.priority - print "Priority (Installed): %s " % pkg.installedPriority - print "Installed: %s " % pkg.installedVersion - print "Candidate: %s " % pkg.candidateVersion - print "CandidateDownloadable: %s" % pkg.candidateDownloadable - print "CandidateOrigins: %s" % pkg.candidateOrigin - print "SourcePkg: %s " % pkg.sourcePackageName + print "Priority (Candidate): %s " % pkg.candidate.priority + print "Priority (Installed): %s " % pkg.installed.priority + print "Installed: %s " % pkg.installed.version + print "Candidate: %s " % pkg.candidate.version + print "CandidateDownloadable: %s" % pkg.candidate.downloadable + print "CandidateOrigins: %s" % pkg.candidate.origins + print "SourcePkg: %s " % pkg.candidate.source_name print "Section: %s " % pkg.section - print "Summary: %s" % pkg.summary - print "Description (formated) :\n%s" % pkg.description - print "Description (unformated):\n%s" % pkg.rawDescription - print "InstalledSize: %s " % pkg.installedSize - print "PackageSize: %s " % pkg.packageSize - print "Dependencies: %s" % pkg.installedDependencies - for dep in pkg.candidateDependencies: + print "Summary: %s" % pkg.candidate.summary + print "Description (formated) :\n%s" % pkg.candidate.description + print "Description (unformated):\n%s" % pkg.candidate.raw_description + print "InstalledSize: %s " % pkg.candidate.installed_size + print "PackageSize: %s " % pkg.candidate.size + print "Dependencies: %s" % pkg.installed.dependencies + for dep in pkg.candidate.dependencies: print ",".join("%s (%s) (%s) (%s)" % (o.name, o.version, o.relation, o.preDepend) for o in dep.or_dependencies) - print "arch: %s" % pkg.architecture - print "homepage: %s" % pkg.homepage - print "rec: ", pkg.candidateRecord + print "arch: %s" % pkg.candidate.architecture + print "homepage: %s" % pkg.candidate.homepage + print "rec: ", pkg.candidate.record - # now test install/remove - progress = apt.progress.OpTextProgress() - cache = apt.Cache(progress) print cache["2vcard"].getChangelog() for i in True, False: print "Running install on random upgradable pkgs with AutoFix: %s " % i diff --git a/apt/progress.py b/apt/progress/__init__.py index 51eb2426..769942ce 100644 --- a/apt/progress.py +++ b/apt/progress/__init__.py @@ -1,6 +1,6 @@ -# Progress.py - progress reporting classes +# progress.py - progress reporting classes # -# Copyright (c) 2005 Canonical +# Copyright (c) 2005-2009 Canonical # # Author: Michael Vogt <michael.vogt@ubuntu.com> # diff --git a/apt/gtk/widgets.py b/apt/progress/gtk2.py index 34cc2759..f872e34f 100644 --- a/apt/gtk/widgets.py +++ b/apt/progress/gtk2.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -# Copyright (c) 2004-2005 Canonical +# Copyright (c) 2004-2009 Canonical # # Authors: Michael Vogt <michael.vogt@ubuntu.com> # Sebastian Heinlein <glatzor@ubuntu.com> @@ -29,7 +29,10 @@ import time import pygtk pygtk.require('2.0') import gtk -import glib +try: + import glib +except ImportError: + import gobject as glib import gobject import pango import vte diff --git a/aptsources/distinfo.py b/aptsources/distinfo.py index 59fa7e02..ce44e48b 100644 --- a/aptsources/distinfo.py +++ b/aptsources/distinfo.py @@ -1,12 +1,10 @@ -#!/usr/bin/env python -# # distinfo.py - provide meta information for distro repositories # -# Copyright (c) 2005 Gustavo Noronha Silva -# 2006-2007 Sebastian Heinlein +# Copyright (c) 2005 Gustavo Noronha Silva <kov@debian.org> +# Copyright (c) 2006-2007 Sebastian Heinlein <glatzor@ubuntu.com> # -# Author: Gustavo Noronha Silva <kov@debian.org> -# Sebastian Heinlein <glatzor@ubuntu.com> +# Authors: Gustavo Noronha Silva <kov@debian.org> +# Sebastian Heinlein <glatzor@ubuntu.com> # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as diff --git a/aptsources/distro.py b/aptsources/distro.py index 36ab0ff8..bbb8ba50 100644 --- a/aptsources/distro.py +++ b/aptsources/distro.py @@ -1,7 +1,7 @@ # distro.py - Provide a distro abstraction of the sources.list # -# Copyright (c) 2004-2007 Canonical Ltd. -# 2006-2007 Sebastian Heinlein +# Copyright (c) 2004-2009 Canonical Ltd. +# Copyright (c) 2006-2007 Sebastian Heinlein # # Authors: Sebastian Heinlein <glatzor@ubuntu.com> # Michael Vogt <mvo@debian.org> @@ -103,22 +103,22 @@ class Distribution: self.is_codename(source.template.name)): #print "yeah! found a distro repo: %s" % source.line # cdroms need do be handled differently - if (source.uri.startswith("cdrom:") and + if (source.uri.startswith("cdrom:") and source.disabled == False): self.cdrom_sources.append(source) cdrom_comps.extend(source.comps) - elif (source.uri.startswith("cdrom:") and + elif (source.uri.startswith("cdrom:") and source.disabled == True): self.cdrom_sources.append(source) - elif (source.type == self.binary_type and + elif (source.type == self.binary_type and source.disabled == False): self.main_sources.append(source) comps.extend(source.comps) media.append(source.uri) - elif (source.type == self.binary_type and + elif (source.type == self.binary_type and source.disabled == True): self.disabled_sources.append(source) - elif (source.type == self.source_type + elif (source.type == self.source_type and source.disabled == False): self.source_code_sources.append(source) elif (source.type == self.source_type and @@ -126,10 +126,10 @@ class Distribution: self.disabled_sources.append(source) if (source.invalid == False and source.template in self.source_template.children): - if (source.disabled == False + if (source.disabled == False and source.type == self.binary_type): self.child_sources.append(source) - elif (source.disabled == False + elif (source.disabled == False and source.type == self.source_type): self.source_code_sources.append(source) else: @@ -167,15 +167,16 @@ class Distribution: et = ElementTree(file=fname) it = et.getiterator('iso_3166_entry') for elm in it: - if elm.attrib.has_key("common_name"): + try: descr = elm.attrib["common_name"] - else: + except KeyError: descr = elm.attrib["name"] - if elm.attrib.has_key("alpha_2_code"): + try: code = elm.attrib["alpha_2_code"] - else: + except KeyError: code = elm.attrib["alpha_3_code"] - self.countries[code.lower()] = gettext.dgettext('iso_3166',descr) + self.countries[code.lower()] = gettext.dgettext('iso_3166', + descr) # try to guess the nearest mirror from the locale self.country = None @@ -219,14 +220,14 @@ class Distribution: # Store all available servers: # Name, URI, active mirrors = [] - if (len(self.used_servers) < 1 or - (len(self.used_servers) == 1 and + 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]) if self.nearest_server: mirrors.append([self._get_mirror_name(self.nearest_server), self.nearest_server, False]) - elif (len(self.used_servers) == 1 and not + 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 @@ -384,7 +385,7 @@ class Distribution: change_server_of_source(source, uri, seen_binary) for source in self.child_sources: # Do not change the forces server of a child source - if (source.template.base_uri is None or + if (source.template.base_uri is None or source.template.base_uri != source.uri): change_server_of_source(source, uri, seen_binary) for source in self.source_code_sources: diff --git a/aptsources/sourceslist.py b/aptsources/sourceslist.py index cb36d9df..1dfd870f 100644 --- a/aptsources/sourceslist.py +++ b/aptsources/sourceslist.py @@ -1,12 +1,12 @@ # aptsource.py - Provide an abstraction of the sources.list # -# Copyright (c) 2004-2007 Canonical Ltd. -# 2004 Michiel Sikkes -# 2006-2007 Sebastian Heinlein +# Copyright (c) 2004-2009 Canonical Ltd. +# Copyright (c) 2004 Michiel Sikkes +# Copyright (c) 2006-2007 Sebastian Heinlein # -# Author: Michiel Sikkes <michiel@eyesopened.nl> -# Michael Vogt <mvo@debian.org> -# Sebastian Heinlein <glatzor@ubuntu.com> +# Authors: Michiel Sikkes <michiel@eyesopened.nl> +# Michael Vogt <mvo@debian.org> +# Sebastian Heinlein <glatzor@ubuntu.com> # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as @@ -219,7 +219,7 @@ class NullMatcher(object): return True -class SourcesList: +class SourcesList(object): """ represents the full sources.list + sources.list.d file """ def __init__(self, @@ -236,9 +236,8 @@ class SourcesList: """ update the list of known entries """ self.list = [] # read sources.list - dir = apt_pkg.Config.FindDir("Dir::Etc") - file = apt_pkg.Config.Find("Dir::Etc::sourcelist") - self.load(dir+file) + file = apt_pkg.Config.FindFile("Dir::Etc::sourcelist") + self.load(file) # read sources.list.d partsdir = apt_pkg.Config.FindDir("Dir::Etc::sourceparts") for file in glob.glob("%s/*.list" % partsdir): @@ -312,11 +311,10 @@ class SourcesList: def restoreBackup(self, backup_ext): " restore sources.list files based on the backup extension " - dir = apt_pkg.Config.FindDir("Dir::Etc") - file = apt_pkg.Config.Find("Dir::Etc::sourcelist") - if os.path.exists(dir+file+backup_ext) and \ - os.path.exists(dir+file): - shutil.copy(dir+file+backup_ext, dir+file) + file = apt_pkg.Config.FindFile("Dir::Etc::sourcelist") + if os.path.exists(file+backup_ext) and \ + os.path.exists(file): + shutil.copy(file+backup_ext, file) # now sources.list.d partsdir = apt_pkg.Config.FindDir("Dir::Etc::sourceparts") for file in glob.glob("%s/*.list" % partsdir): @@ -353,8 +351,7 @@ class SourcesList: files = {} # write an empty default config file if there aren't any sources if len(self.list) == 0: - path = "%s%s" % (apt_pkg.Config.FindDir("Dir::Etc"), - apt_pkg.Config.Find("Dir::Etc::sourcelist")) + path = apt_pkg.Config.FindFile("Dir::Etc::sourcelist") header = ( "## See sources.list(5) for more information, especialy\n" "# Remember that you can only use http, ftp or file URIs\n" diff --git a/debian/changelog b/debian/changelog index a0fc52b8..94b5f37e 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,95 @@ +python-apt (0.7.10.3ubuntu1) karmic; urgency=low + + * merged from debian, remaining changes: + - updated mirrors + - build python2.4 + - use DH_PYCENTRAL=include-links + - use --install-layout=deb + - pre-build.sh: update ubuntu mirrors on bzr-buildpackage + + -- Michael Vogt <mvo@debian.org> Tue, 05 May 2009 12:03:27 +0200 + +python-apt (0.7.10.3) unstable; urgency=low + + * apt/package.py: Handle cases where no candidate is available, by returning + None in the candidate property. (Closes: #523801) + + -- Julian Andres Klode <jak@debian.org> Sun, 12 Apr 2009 19:50:26 +0200 + +python-apt (0.7.10.2) unstable; urgency=low + + * apt/package.py: Handle cases where no candidate is available and + one of the deprecated properties (e.g. candidateVersion) is + requested. (Closes: #523801) + * setup.py, debian/rules: Support version in setup.py again by getting + the value from the variable DEBVER (defined in debian/rules), falling + back to None. + + -- Julian Andres Klode <jak@debian.org> Sun, 12 Apr 2009 19:00:07 +0200 + +python-apt (0.7.10) unstable; urgency=low + + * Build-Depend on python-debian, use it to get version number from changelog + * Depend on libjs-jquery, and remove internal copy (Closes: #521532) + * apt/package.py: + - Introduce Version.{uri,uris,fetch_binary()} + * debian/control: + - Remove mdz from Uploaders (Closes: #521477), add myself. + - Update Standards-Version to 3.8.1 + - Use ${binary:Version} instead of ${Source-Version} + - Fix spelling error: python -> Python + * debian/copyright: Switch to machine-interpretable copyright + * Fix documentation building + - doc/source/conf.py: Only include directories for current python version. + - debian/control: Build-Depend on python-gtk2, python-vte. + - setup.py: If pygtk can not be imported, do not build the documentation. + * Breaks: debdelta (<< 0.28~) to avoid more problems due to the internal + API changes from 0.7.9. + + -- Julian Andres Klode <jak@debian.org> Wed, 01 Apr 2009 15:24:29 +0200 + +python-apt (0.7.9) unstable; urgency=low + + [ Julian Andres Klode ] + * apt/gtk/widgets.py: + - Handle older versions of python-gobject which do not ship glib + * apt/package.py: Introduce the Version class + - Deprecate Package.candidate*() and Package.installed*(), except for + installedFiles. + - Provide Version.get_source() (LP: #118788) + - Provide Package.versions (Closes: #513236) + * apt/progress/: New package, replaces apt.progress and apt.gtk + - apt/progress/gtk2.py: Moved here from apt/gtk/widgets.py + - apt/progress/__init__.py: Move here from apt/progress.py + * doc/source/*: Improve the documentation + - Document more attributes and functions of apt_pkg (they are all listed) + + [ Michael Vogt ] + * aptsources/distro.py: + - use iso_3166.xml instead of iso_3166.tab + - fix incorrect indent + * debian/control: + - add Recommends to iso-codes (for iso_3166.xml) + * apt/package.py: + - make sure to set the defaulttimeout back to the + original value (in getChangelog(), LP: #314212) + Closes: #513315 + * apt/cache.py: + - when setting a alternative rootdir, read the + config from it as well + * python/configuration.cc, python/apt_pkgmodule.cc: + - add apt_pkg.ReadConfigDir() + * python/cache.cc, tests/getcache_mem_corruption.py: + - test if progress objects have the right methods + and raise error if not (thanks to Emanuele Rocca) + closes: #497049 + * apt/package.py: + - avoid uneeded interal references in the Package objects + * aptsources/sourceslist.py: + - fix bug in invalid lines detection (LP: #324614) + + -- Michael Vogt <mvo@debian.org> Thu, 19 Mar 2009 13:39:21 +0100 + python-apt (0.7.9~exp2ubuntu11) karmic; urgency=low [ Matthias Klose ] diff --git a/debian/control b/debian/control index abae4b5b..57a95cd4 100644 --- a/debian/control +++ b/debian/control @@ -3,18 +3,32 @@ Section: python Priority: optional Maintainer: Ubuntu Core Developers <ubuntu-devel-discuss@lists.ubuntu.com> XSBC-Original-Maintainer: APT Development Team <deity@lists.debian.org> -Uploaders: Matt Zimmerman <mdz@debian.org>, Michael Vogt <mvo@debian.org> -Standards-Version: 3.7.2.2 -XS-Python-Version: 2.4, all -Build-Depends: debhelper (>= 5.0.37.1), libapt-pkg-dev (>= 0.7.20), apt-utils, python-all-dev, python-distutils-extra (>= 1.9.0), cdbs, python-central (>= 0.6.11), python-all-dbg, python-sphinx (>= 0.5), python2.4-dev, python2.4-dbg -XS-Original-Vcs-Bzr: http://bzr.debian.org/apt/python-apt/debian-sid -Vcs-Bzr: http://code.launchpad.net/~ubuntu-core-dev/python-apt/ubuntu +Uploaders: Michael Vogt <mvo@debian.org>, Julian Andres Klode <jak@debian.org> +Standards-Version: 3.8.1 +XS-Python-Version: all +Build-Depends: apt-utils, + cdbs, + debhelper (>= 5.0.37.1), + libapt-pkg-dev (>= 0.7.10), + python-all-dbg, + python-all-dev, + python2.4-dev, + python2.4-dbg, + python-central (>= 0.5), + python-debian, + python-distutils-extra (>= 1.9.0), + python-gtk2, + python-sphinx (>= 0.5), + python-vte +Vcs-Bzr: http://bzr.debian.org/apt/python-apt/debian-sid +Vcs-Browser: http://bzr.debian.org/loggerhead/apt/python-apt/debian-sid/changes Package: python-apt Architecture: any -Depends: ${python:Depends}, ${shlibs:Depends}, ${misc:Depends}, lsb-release +Depends: ${python:Depends}, ${shlibs:Depends}, ${misc:Depends}, lsb-release, + libjs-jquery Recommends: iso-codes -Priority: optional +Breaks: debdelta (<< 0.28~) Provides: ${python:Provides} Suggests: python-apt-dbg, python-gtk2, python-vte XB-Python-Version: ${python:Versions} @@ -34,10 +48,12 @@ Description: Python interface to libapt-pkg Package: python-apt-dbg Priority: extra Architecture: any -Depends: python-dbg, python-apt (= ${Source-Version}), ${shlibs:Depends} +Section: debug +Depends: python-dbg, python-apt (= ${binary:Version}), ${shlibs:Depends}, + ${misc:Depends} Description: Python interface to libapt-pkg (debug extension) The apt_pkg Python interface will provide full access to the internal libapt-pkg structures allowing Python programs to easily perform a variety of functions. . - This package contains the extension built for the python debug interpreter. + This package contains the extension built for the Python debug interpreter. diff --git a/debian/copyright b/debian/copyright index f8463185..8599328a 100644 --- a/debian/copyright +++ b/debian/copyright @@ -1,7 +1,53 @@ -APT is free software; you can redistribute them and/or modify them under -the terms of the GNU General Public License as published by the Free Software -Foundation; either version 2 of the License, or (at your option) any later -version. +Format-Specification: http://wiki.debian.org/Proposals/CopyrightFormat?action=recall&rev=443 -On Debian systems, a copy of the GNU General Public License can be -found in /usr/share/common-licenses/GPL. +Files: * +Copyright: © 2004-2009 Canonical Ltd. +License: GPL-2+ + +Files: aptsources/*.py +Copyright: © 2004-2009 Canonical Ltd. +Copyright: © 2005 Gustavo Noronha Silva +Copyright: © 2006-2007 Sebastian Heinlein +License: GPL-2+ + +Files: doc/source/* +Copyright: © 2009 Julian Andres Klode <jak@debian.org> +License: GPL-2+ + +Files: utils/get_*.py +Copyright: © 2006 Free Software Foundation Europe +License: GPL-2+ + +Files: po/* +Copyright: © 2006 Canonical Ltd, and Rosetta Contributors 2006 +License: GPL-2+ + +Files: po/de.po +Copyright: © 2005 Michiel Sikkes <michiel@eyesopened.nl> +License: GPL-2+ + +Files: po/en_CA.po +Copyright: © 2005 Adam Weinberger and the GNOME Foundation +License: GPL-2+ + +Files: po/fi.po +Copyright: © 2005-2006 Timo Jyrinki +License: GPL-2+ + +Files: po/fr.po +Copyright: © 2007 Hugues NAULET <hnaulet@gmail.com> +License: GPL-2+ + +Files: po/hu.po, po/lt.po, po/pt.po, po/ro.po, po/rw.po, po/sv.po, po/uk.po, + po/zh_HK.po +Copyright: © 2005-2006 Free Software Foundation +License: GPL-2+ + +License: GPL-2+ + APT is free software; you can redistribute them and/or modify them under + the terms of the GNU General Public License as published by the Free Software + Foundation; either version 2 of the License, or (at your option) any later + version. + . + On Debian systems, a copy of the GNU General Public License can be + found in /usr/share/common-licenses/GPL-2. diff --git a/debian/rules b/debian/rules index a96e17ff..e9917843 100755 --- a/debian/rules +++ b/debian/rules @@ -15,6 +15,7 @@ PKG=python-apt DEBVER=$(shell dpkg-parsechangelog |sed -n -e '/^Version:/s/^Version: //p') DEB_COMPRESS_EXCLUDE:=.html .js _static/* _sources/* _sources/*/* .inv DEB_BUILD_PROG:=debuild --preserve-envvar PATH --preserve-envvar CCACHE_DIR -us -uc $(DEB_BUILD_PROG_OPTS) +export DEBVER build/python-apt-dbg:: set -e; \ @@ -22,9 +23,6 @@ build/python-apt-dbg:: python$$i-dbg ./setup.py build; \ done -build/python-apt:: - pydoc -w - install/python-apt-dbg:: for i in $(cdbs_python_build_versions); do \ python$$i-dbg ./setup.py install --root $(CURDIR)/debian/python-apt-dbg --install-layout=deb; \ @@ -33,6 +31,9 @@ install/python-apt-dbg:: ! -type d ! -name '*_d.so' | xargs rm -f find debian/python-apt-dbg -depth -empty -exec rmdir {} \; +binary-predeb/python-apt:: + ln -sf ../../../../javascript/jquery/jquery.js debian/python-apt/usr/share/doc/python-apt/html/_static/jquery.js + binary-predeb/python-apt-dbg:: rm -rf debian/python-apt-dbg/usr/share/doc/python-apt-dbg ln -s python-apt debian/python-apt-dbg/usr/share/doc/python-apt-dbg diff --git a/doc/examples/acquire.py b/doc/examples/acquire.py index 58372961..41a38588 100644 --- a/doc/examples/acquire.py +++ b/doc/examples/acquire.py @@ -1,8 +1,7 @@ +#!/usr/bin/python import apt import apt_pkg import os -import sys -import tempfile def get_file(fetcher, uri, destFile): diff --git a/doc/examples/action.py b/doc/examples/action.py index 9b9d7dd3..8ee86eb7 100644 --- a/doc/examples/action.py +++ b/doc/examples/action.py @@ -3,7 +3,6 @@ import apt_pkg import sys -import copy from apt.progress import OpTextProgress from progress import TextFetchProgress diff --git a/doc/examples/build-deps.py b/doc/examples/build-deps.py index aeb5667c..b5ac88a2 100755 --- a/doc/examples/build-deps.py +++ b/doc/examples/build-deps.py @@ -32,7 +32,7 @@ if len(sys.argv) < 2: print "need a package name as argument" sys.exit(1) try: - base = cache[sys.argv[1]] + pkg = base = cache[sys.argv[1]] except KeyError: print "No package %s found" % sys.argv[1] sys.exit(1) diff --git a/doc/examples/cdrom.py b/doc/examples/cdrom.py index 743220a6..408bd720 100644 --- a/doc/examples/cdrom.py +++ b/doc/examples/cdrom.py @@ -3,10 +3,8 @@ import apt_pkg import sys -import os -import copy -from progress import CdromProgress +from progress import TextCdromProgress # init @@ -15,7 +13,7 @@ apt_pkg.init() cdrom = apt_pkg.GetCdrom() print cdrom -progress = CdromProgress() +progress = TextCdromProgress() (res, ident) = cdrom.Ident(progress) print "ident result is: %s (%s) " % (res, ident) diff --git a/doc/examples/configisc.py b/doc/examples/configisc.py index de8ec6be..8da1ad0a 100755 --- a/doc/examples/configisc.py +++ b/doc/examples/configisc.py @@ -10,7 +10,6 @@ import apt_pkg import sys -import posixpath ConfigFile = apt_pkg.ParseCommandLine(apt_pkg.Config, [], sys.argv) diff --git a/doc/examples/depcache.py b/doc/examples/depcache.py index 790cc9d6..de038fe8 100644 --- a/doc/examples/depcache.py +++ b/doc/examples/depcache.py @@ -1,10 +1,7 @@ #!/usr/bin/python # example how to deal with the depcache -import apt import apt_pkg -import sys -import copy from progress import TextProgress diff --git a/doc/examples/desc.py b/doc/examples/desc.py index f47517cf..2febf348 100644 --- a/doc/examples/desc.py +++ b/doc/examples/desc.py @@ -1,3 +1,4 @@ +#!/usr/bin/python import apt_pkg diff --git a/doc/examples/gui-inst.py b/doc/examples/gui-inst.py index 8138d922..68f06fc0 100755 --- a/doc/examples/gui-inst.py +++ b/doc/examples/gui-inst.py @@ -5,13 +5,13 @@ import pygtk pygtk.require('2.0') import gtk -import apt.gtk.widgets +import apt.progress.gtk2 if __name__ == "__main__": win = gtk.Window() - progress = apt.gtk.widgets.GtkAptProgress() + progress = apt.progress.gtk2.GtkAptProgress() win.set_title("GtkAptProgress Demo") win.add(progress) progress.show() diff --git a/doc/examples/indexfile.py b/doc/examples/indexfile.py index 22d0b635..2f1f27f8 100644 --- a/doc/examples/indexfile.py +++ b/doc/examples/indexfile.py @@ -1,3 +1,4 @@ +#!/usr/bin/python import apt_pkg diff --git a/doc/examples/inst.py b/doc/examples/inst.py index a3a50356..5a7fc993 100644 --- a/doc/examples/inst.py +++ b/doc/examples/inst.py @@ -3,9 +3,6 @@ import apt import sys -import os -import copy -import time from apt.progress import InstallProgress diff --git a/doc/examples/metaindex.py b/doc/examples/metaindex.py index f00a7e01..816a3fd7 100644 --- a/doc/examples/metaindex.py +++ b/doc/examples/metaindex.py @@ -1,3 +1,4 @@ +#!/usr/bin/python import apt_pkg diff --git a/doc/examples/progress.py b/doc/examples/progress.py index 83847598..2231001f 100644 --- a/doc/examples/progress.py +++ b/doc/examples/progress.py @@ -1,3 +1,5 @@ +#!/usr/bin/python + import sys import time @@ -38,7 +40,7 @@ class TextFetchProgress(apt.FetchProgress): def pulse(self): print "Pulse: CPS: %s/s; Bytes: %s/%s; Item: %s/%s" % ( - apt.SizeToStr(self.currentCPS), SizeToStr(self.currentBytes), + apt.SizeToStr(self.currentCPS), apt.SizeToStr(self.currentBytes), apt.SizeToStr(self.totalBytes), self.currentItems, self.totalItems) return True @@ -79,12 +81,12 @@ class TextCdromProgress(apt.CdromProgress): def update(self, text, step): # check if we actually have some text to display if text != "": - print "Update: %s %s" % (string.strip(text), step) + print "Update: %s %s" % (text.strip(), step) def askCdromName(self): print "Please enter cd-name: ", cd_name = sys.stdin.readline() - return (True, string.strip(cd_name)) + return (True, cd_name.strip()) def changeCdrom(self): print "Please insert cdrom and press <ENTER>" diff --git a/doc/examples/records.py b/doc/examples/records.py index a0fc8dc4..681eac0c 100755 --- a/doc/examples/records.py +++ b/doc/examples/records.py @@ -5,9 +5,9 @@ import apt cache = apt.Cache() for pkg in cache: - if not pkg.candidateRecord: + if not pkg.candidate.record: continue - if "Task" in pkg.candidateRecord: + if "Task" in pkg.candidate.record: print "Pkg %s is part of '%s'" % ( - pkg.name, pkg.candidateRecord["Task"].split()) + pkg.name, pkg.candidate.record["Task"].split()) #print pkg.candidateRecord diff --git a/doc/examples/update.py b/doc/examples/update.py index 364fa1c9..5929c9f8 100755 --- a/doc/examples/update.py +++ b/doc/examples/update.py @@ -1,3 +1,4 @@ +#!/usr/bin/python import apt import apt_pkg import os.path diff --git a/doc/source/apt/package.rst b/doc/source/apt/package.rst index 1bd032ab..bb74915e 100644 --- a/doc/source/apt/package.rst +++ b/doc/source/apt/package.rst @@ -10,6 +10,16 @@ The Package class .. autoclass:: Package :members: + .. note:: + + Several methods have been deprecated in version 0.7.9 of python-apt, + please see the :class:`Version` class for the new alternatives. + +The Version class +----------------- +.. autoclass:: Version + :members: + Dependency Information ---------------------- @@ -88,14 +98,14 @@ Examples cache = apt.Cache() pkg = cache['python-apt'] # Access the Package object for python-apt - print 'python-apt is trusted:', pkg.candidateOrigin.trusted + print 'python-apt is trusted:', pkg.candidate.origins[0].trusted # Mark python-apt for install pkg.markInstall() print 'python-apt is marked for install:', pkg.markedInstall - print 'python-apt is', pkg.summary #Python interface to libapt-pkg + print 'python-apt is (summary):', pkg.candidate.summary # Now, really install it cache.commit() diff --git a/doc/source/apt/gtk.widgets.rst b/doc/source/apt/progress.gtk2.rst index 9fa84ead..a83ab111 100644 --- a/doc/source/apt/gtk.widgets.rst +++ b/doc/source/apt/progress.gtk2.rst @@ -1,6 +1,6 @@ -:mod:`apt.gtk.widgets` --- GTK widgets -====================================== -.. automodule:: apt.gtk.widgets +:mod:`apt.progress.gtk2` --- GTK widgets +======================================== +.. automodule:: apt.progress.gtk2 GObject progress classes diff --git a/doc/source/apt_pkg/index.rst b/doc/source/apt_pkg/index.rst index 1c5866a9..6e7b772e 100644 --- a/doc/source/apt_pkg/index.rst +++ b/doc/source/apt_pkg/index.rst @@ -34,7 +34,7 @@ Object initialization ---------------------- .. function:: GetCache([progress]) - Return a :class:`pkgCache` object. The optional parameter ``progress`` + Return a :class:`pkgCache` object. The optional parameter *progress* specifies an instance of :class:`apt.progress.OpProgress()` which will display the open progress. @@ -44,25 +44,54 @@ Object initialization .. method:: Cdrom.Ident(progress) - Identify the cdrom. The parameter ``progress`` refers to an + Identify the cdrom. The parameter *progress* refers to an :class:`apt.progress.CdromProgress()` object. .. method:: Cdrom.Add(progress) - Add the cdrom to the sources.list file. The parameter ``progress`` + Add the cdrom to the sources.list file. The parameter *progress* refers to an :class:`apt.progress.CdromProgress()` object. - .. function:: GetDepCache(cache) - Return a :class:`pkgDepCache` object. The parameter ``cache`` specifies an + Return a :class:`pkgDepCache` object. The parameter *cache* specifies an instance of :class:`pkgCache` (see :func:`GetCache()`). .. function:: GetPkgSourceList() - Return a :class:`pkgSourceList` object. + Return a :class:`PkgSourceList` object. + +.. function:: GetPackageManager(depcache) + + Return a new :class:`PkgManager` object. The parameter *depcache* specifies + a :class:`pkgDepCache` object as returned by :func:`GetDepCache`. + +.. function:: GetPkgActionGroup(depcache) + + Return a new :class:`ActionGroup` object. The parameter *depcache* + specifies a :class:`pkgDepCache` object as returned by :func:`GetDepCache`. + +.. function:: GetPkgProblemResolver(depcache) + + Return a new :class:`ProblemResolver` object. The parameter *depcache* + specifies a :class:`pkgDepCache` object as returned by :func:`GetDepCache`. + +.. function:: GetPkgRecords(cache) + + Return a new :class:`PkgRecords` object. + + The parameter *cache* refers to an :class:`pkgCache` object, as returned + by :func:`GetCache`. + +.. function:: GetPkgSrcRecords() + + Return a new :class:`PkgSrcRecords` object. + +.. function:: newConfiguration() + + Return a new :class:`Configuration` object. The Acquire interface @@ -70,7 +99,7 @@ The Acquire interface .. function:: GetAcquire([progress]) Return an :class:`Acquire` object. This is a class which allows you - to fetch files, or archive contents. The parameter ``progress`` refers to + to fetch files, or archive contents. The parameter *progress* refers to an :class:`apt.progress.FetchProgress()` object. Acquire items have multiple methods: @@ -99,26 +128,29 @@ The Acquire interface .. function:: GetPkgAcqFile(aquire, uri[, md5, size, descr, shortDescr, destDir, destFile]) - The parameter ``acquire`` refers to an :class:`Acquire()` object as returned + Create a new :class:`PkgAcqFile()` object and register it with *acquire*, + so it will be fetched. + + The parameter *acquire* refers to an :class:`Acquire()` object as returned by :func:`GetAcquire`. The file will be added to the Acquire queue automatically. - The parameter ``uri`` refers to the location of the file, any protocol + The parameter *uri* refers to the location of the file, any protocol of apt is supported. - The parameter ``md5`` refers to the md5sum of the file. This can be used + The parameter *md5* refers to the md5sum of the file. This can be used for checking the file. - The parameter ``size`` can be used to specify the size of the package, + The parameter *size* can be used to specify the size of the package, which can then be used to calculate the progress and validate the download. - The parameter ``descr`` is a descripition of the download. It may be - used to describe the item in the progress class. ``shortDescr`` is the + The parameter *descr* is a descripition of the download. It may be + used to describe the item in the progress class. *shortDescr* is the short form of it. - You can use ``destDir`` to manipulate the directory where the file will - be saved in. Together with ``destFile`` you can specify the complete target - path. + You can use *destDir* to manipulate the directory where the file will + be saved in. Instead of *destDir*, you can also specify the full path to + the file using the parameter *destFile*. You can not combine both. @@ -130,19 +162,19 @@ of the ones provides in Python's :mod:`hashlib` module. .. function:: md5sum(object) - Return the md5sum of the object. ``object`` may either be a string, in + Return the md5sum of the object. *object* may either be a string, in which case the md5sum of the string is returned, or a :class:`file()` object, in which case the md5sum of its contents is returned. .. function:: sha1sum(object) - Return the sha1sum of the object. ``object`` may either be a string, in + Return the sha1sum of the object. *object* may either be a string, in which case the sha1sum of the string is returned, or a :class:`file()` object, in which case the sha1sum of its contents is returned. .. function:: sha256sum(object) - Return the sha256sum of the object. ``object`` may either be a string, in + Return the sha256sum of the object. *object* may either be a string, in which case the sha256sum of the string is returned, or a :class:`file()` object, in which case the sha256sum of its contents is returned. @@ -151,19 +183,15 @@ Other functions .. note:: - This documentation is created automatically and should be rewritten. + This documentation is (in parts) created automatically, and still needs to + be improved. .. autofunction:: Base64Encode .. autofunction:: CheckDep .. autofunction:: CheckDomainList .. autofunction:: DeQuoteString .. autofunction:: GetLock -.. autofunction:: GetPackageManager -.. autofunction:: GetPkgActionGroup -.. autofunction:: GetPkgProblemResolver -.. autofunction:: GetPkgRecords -.. autofunction:: GetPkgSrcRecords -.. autofunction:: newConfiguration + .. autofunction:: ParseCommandLine .. autofunction:: ParseDepends .. autofunction:: ParseSection @@ -173,16 +201,108 @@ Other functions .. autofunction:: PkgSystemUnLock .. autofunction:: QuoteString .. autofunction:: ReadConfigFile +.. autofunction:: ReadConfigDir() .. autofunction:: ReadConfigFileISC .. autofunction:: RewriteSection -.. autofunction:: SizeToStr -.. autofunction:: StringToBool -.. autofunction:: StrToTime -.. autofunction:: TimeRFC1123 -.. autofunction:: TimeToStr -.. autofunction:: UpstreamVersion -.. autofunction:: URItoFileName -.. autofunction:: VersionCompare + +.. function:: SizeToStr(size) + + Return a string presenting the human-readable version of the integer + *size*. When calculating the units (k,M,G,etc.) the size is divided by the + factor 1000. + + Example:: + + >>> apt_pkg.SizeToStr(10000) + '10.0k' + +.. function:: StringToBool(input) + + Parse the string *input* and return one of **-1**, **0**, **1**. + + .. table:: Return values + + ===== ============================================= + Value Meaning + ===== ============================================= + -1 The string *input* is not recognized. + 0 The string *input* evaluates to **False**. + +1 The string *input* evaluates to **True**. + ===== ============================================= + + Example:: + + >>> apt_pkg.StringToBool("yes") + 1 + >>> apt_pkg.StringToBool("no") + 0 + >>> apt_pkg.StringToBool("not-recognized") + -1 + +.. function:: StrToTime(rfc_time) + + Convert the :rfc:`1123` conforming string *rfc_time* to the unix time, and + return the integer. This is the opposite of :func:`TimeRFC1123`. + + Example:: + + >> apt_pkg.StrToTime('Thu, 01 Jan 1970 00:00:00 GMT') + 0 + +.. function:: TimeRFC1123(seconds) + + Format the unix time specified by the integer *seconds*, according to the + requirements of :rfc:`1123`. + + Example:: + + >>> apt_pkg.TimeRFC1123(0) + 'Thu, 01 Jan 1970 00:00:00 GMT' + + +.. function:: TimeToStr(seconds) + + Format a given duration in a human-readable manner. The parameter *seconds* + refers to a number of seconds, given as an integer. The return value is a + string with a unit like 's' for seconds. + + Example:: + + >>> apt_pkg.TimeToStr(3601) + '1h0min1s' + + + +.. function:: UpstreamVersion(version) + + Return the string *version*, eliminating everything following the last + '-'. Thus, this should be equivalent to ``version.rsplit('-', 1)[0]``. + +.. function:: URItoFileName(uri) + + Take a string *uri* as parameter and return a filename which can be used to + store the file, based on the URI. + + Example:: + + >>> apt_pkg.URItoFileName('http://debian.org/index.html') + 'debian.org_index.html' + + +.. function:: VersionCompare(a, b) + + Compare two versions, *a* and *b*, and return an integer value which has + the same characteristic as the built-in :func:`cmp` function. + + .. table:: Return values + + ===== ============================================= + Value Meaning + ===== ============================================= + > 0 The version *a* is greater than version *b*. + = 0 Both versions are equal. + < 0 The version *a* is less than version *b*. + ===== ============================================= Data @@ -256,6 +376,18 @@ Select states Build information ^^^^^^^^^^^^^^^^^ .. data:: Date + + The date on which this extension has been compiled. + .. data:: LibVersion + + The version of the apt_pkg library. This is **not** the version of apt, + nor the version of python-apt. + .. data:: Time + + The time this extension has been built. + .. data:: Version + + The version of apt (not of python-apt). diff --git a/doc/source/conf.py b/doc/source/conf.py index 8f71e3e3..40154a6f 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -23,9 +23,13 @@ import sys # absolute, like shown here. sys.path.insert(0, os.path.abspath('..')) sys.path.insert(0, os.path.abspath('../..')) + +# Find the path to the built apt_pkg and apt_inst extensions if os.path.exists("../../build"): + version = '.'.join(str(x) for x in sys.version_info[:2]) for dirname in os.listdir('../../build'): - sys.path.insert(0, os.path.abspath('../../build/' + dirname)) + if version in dirname: + sys.path.insert(0, os.path.abspath('../../build/' + dirname)) # General configuration # --------------------- @@ -56,10 +60,13 @@ copyright = u'2009, Julian Andres Klode <jak@debian.org>' # |version| and |release|, also used in various other places throughout the # built documents. # +from debian_bundle.changelog import Changelog + +changes = Changelog(open('../../debian/changelog')) # The short X.Y version. -version = '0.7' +version = '.'.join(changes.full_version.split('.')[:2]) # The full version, including alpha/beta/rc tags. -release = '0.7.9~exp2' +release = changes.full_version # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/doc/source/examples/apt-gtk.py b/doc/source/examples/apt-gtk.py index c3bb09d5..835ea4ee 100644 --- a/doc/source/examples/apt-gtk.py +++ b/doc/source/examples/apt-gtk.py @@ -4,14 +4,14 @@ import pygtk pygtk.require("2.0") import gtk -import apt.gtk.widgets +import apt.progress.gtk2 def main(): """Main function.""" win = gtk.Window() win.connect("destroy", gtk.main_quit) - progress = apt.gtk.widgets.GtkAptProgress() + progress = apt.progress.gtk2.GtkAptProgress() win.set_title("GtkAptProgress Demo") win.add(progress) progress.show() diff --git a/po/POTFILES.in b/po/POTFILES.in index 0cf708e1..767fa3ca 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -2,4 +2,6 @@ [type: gettext/rfc822deb] data/templates/Ubuntu.info.in [type: gettext/rfc822deb] data/templates/Debian.info.in aptsources/distro.py -apt/gtk/widgets.py
\ No newline at end of file +apt/progress/gtk2.py +apt/package.py +apt/debfile.py diff --git a/python/cache.cc b/python/cache.cc index 1c59bece..0c59f561 100644 --- a/python/cache.cc +++ b/python/cache.cc @@ -936,14 +936,26 @@ PyObject *TmpGetCache(PyObject *Self,PyObject *Args) pkgCacheFile *Cache = new pkgCacheFile(); if(pyCallbackInst != 0) { + // sanity check for the progress object, see #497049 + if (PyObject_HasAttrString(pyCallbackInst, "done") != true) { + PyErr_SetString(PyExc_ValueError, + "OpProgress object must implement done()"); + return 0; + } + if (PyObject_HasAttrString(pyCallbackInst, "update") != true) { + PyErr_SetString(PyExc_ValueError, + "OpProgress object must implement update()"); + return 0; + } PyOpProgress progress; progress.setCallbackInst(pyCallbackInst); if (Cache->Open(progress,false) == false) - return HandleErrors(); - } else { + return HandleErrors(); + } + else { OpTextProgress Prog; if (Cache->Open(Prog,false) == false) - return HandleErrors(); + return HandleErrors(); } CppOwnedPyObject<pkgCacheFile*> *CacheFileObj = @@ -1,14 +1,14 @@ #! /usr/bin/env python # $Id: setup.py,v 1.2 2002/01/08 07:13:21 jgg Exp $ - -from distutils.core import setup, Extension -from distutils.sysconfig import parse_makefile -from DistUtilsExtra.command import build_extra, build_i18n import glob import os import shutil import sys +from distutils.core import setup, Extension +from distutils.sysconfig import parse_makefile +from DistUtilsExtra.command import build_extra, build_i18n + # The apt_pkg module files = map(lambda source: "python/"+source, @@ -46,12 +46,12 @@ if len(sys.argv) > 1 and sys.argv[1] == "clean" and '-a' in sys.argv: print "Not removing", dirname, "because it does not exist" setup(name="python-apt", - version="0.7.9", description="Python bindings for APT", + version=os.environ.get('DEBVER'), author="APT Development Team", author_email="deity@lists.debian.org", ext_modules=[apt_pkg, apt_inst], - packages=['apt', 'apt.gtk', 'aptsources'], + packages=['apt', 'apt.progress', 'aptsources'], data_files = [('share/python-apt/templates', glob.glob('build/data/templates/*.info')), ('share/python-apt/templates', @@ -64,6 +64,12 @@ setup(name="python-apt", if (len(sys.argv) > 1 and sys.argv[1] == "build" and sys.version_info[0] >= 2 and sys.version_info[1] >= 5): import sphinx + try: + import pygtk + except ImportError: + print >> sys.stderr, ('W: Not building documentation because python-' + 'gtk2 is not available at the moment.') + sys.exit(0) sphinx.main(["sphinx", "-b", "html", "-d", "build/doc/doctrees", os.path.abspath("doc/source"), "build/doc/html"]) sphinx.main(["sphinx", "-b", "text", "-d", "build/doc/doctrees", diff --git a/tests/getcache_mem_corruption.py b/tests/getcache_mem_corruption.py new file mode 100644 index 00000000..42e9af00 --- /dev/null +++ b/tests/getcache_mem_corruption.py @@ -0,0 +1,24 @@ +#!/usr/bin/python +import apt +import apt_pkg +import re + +import unittest + +class TestGetCache(unittest.TestCase): + + def setUp(self): + apt_pkg.InitConfig() + apt_pkg.InitSystem() + + def testWrongInvocation(self): + # wrongly invoke GetCache() rather than GetDepCache() + apt_cache = apt_pkg.GetCache() + self.assertRaises(ValueError, apt_pkg.GetCache, apt_cache) + + def testProperInvocation(self): + apt_cache = apt_pkg.GetCache(apt.progress.OpTextProgress()) + apt_depcache = apt_pkg.GetDepCache(apt_cache) + +if __name__ == "__main__": + unittest.main() diff --git a/utils/get_ubuntu_mirrors.py b/utils/get_ubuntu_mirrors.py index 6248ece4..ddd1e369 100755 --- a/utils/get_ubuntu_mirrors.py +++ b/utils/get_ubuntu_mirrors.py @@ -35,7 +35,7 @@ mirrors = [] # path to the local mirror list list_path = "../data/templates/Ubuntu.mirrors" -req = urllib2.Request("https://wiki.ubuntu.com/Mirrors?action=raw") +req = urllib2.Request("https://wiki.ubuntu.com/Archive?action=raw") try: print "Downloading mirrors list from the Ubuntu wiki..." |
