From 1b5b026c1013dc20b572a7fd2a690fe451248ab0 Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 5 May 2009 11:59:53 +0200 Subject: * apt/progress/__init__.py: - add update_status_full() that takes file_size/partial_size as additional callback arguments - add pulse_items() that takes a addtional "items" tuple that gives the user full access to the individual items that are fetched * python/progress.cc: - low level code for update_status_full and pulse_items() --- apt/progress/__init__.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'apt') diff --git a/apt/progress/__init__.py b/apt/progress/__init__.py index 769942ce..3be197f7 100644 --- a/apt/progress/__init__.py +++ b/apt/progress/__init__.py @@ -112,6 +112,13 @@ class FetchProgress(object): This happens eg. when the downloads fails or is completed. """ + def update_status_full(self, uri, descr, short_descr, status, file_size, + partial_size): + """Called when the status of an item changes. + + This happens eg. when the downloads fails or is completed. This + version include information on current filesize and partial size + """ def pulse(self): """Called periodically to update the user interface. @@ -125,6 +132,19 @@ class FetchProgress(object): float(self.currentCPS)) return True + def pulse_items(self, items): + """Called periodically to update the user interface. + This function includes details about the items being fetched + Return True to continue or False to cancel. + + """ + self.percent = (((self.currentBytes + self.currentItems) * 100.0) / + float(self.totalBytes + self.totalItems)) + if self.currentCPS > 0: + self.eta = ((self.totalBytes - self.currentBytes) / + float(self.currentCPS)) + return True + def mediaChange(self, medium, drive): """react to media change events.""" -- cgit v1.2.3 From 1928a8fab432b219c6286ff08b142c57c6df5e6b Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Mon, 15 Jun 2009 10:56:01 +0200 Subject: * python/progress.cc: - fix crash in RunSimpleCallback() * apt/cache.py: - when the cache is run with a alternative rootdir, create required dirs/files automatically --- apt/cache.py | 25 +++++++++++++++++++++++++ debian/changelog | 5 +++++ python/progress.cc | 5 ++++- 3 files changed, 34 insertions(+), 1 deletion(-) (limited to 'apt') diff --git a/apt/cache.py b/apt/cache.py index cc425ccb..94a77fd8 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -60,8 +60,33 @@ class Cache(object): apt_pkg.Config.Set("Dir", rootdir) apt_pkg.Config.Set("Dir::State::status", rootdir + "/var/lib/dpkg/status") + # create required dirs/files when run with special rootdir + # automatically + self._check_and_create_required_dirs(rootdir) self.open(progress) + def _check_and_create_required_dirs(self, rootdir): + """ + check if the required apt directories/files are there and if + not create them + """ + files = ["/var/lib/dpkg/status", + "/etc/apt/sources.list", + ] + dirs = ["/var/lib/dpkg", + "/etc/apt/", + "/var/cache/apt/archives/partial", + "/var/lib/apt/lists/partial", + ] + for d in dirs: + if not os.path.exists(rootdir+d): + print "creating: ",rootdir+d + os.makedirs(rootdir+d) + for f in files: + if not os.path.exists(rootdir+f): + open(rootdir+f,"w") + + def _runCallbacks(self, name): """ internal helper to run a callback """ if name in self._callbacks: diff --git a/debian/changelog b/debian/changelog index a3faab79..0f9463b2 100644 --- a/debian/changelog +++ b/debian/changelog @@ -99,8 +99,13 @@ python-apt (0.7.9) unstable; urgency=low closes: #497049 * apt/package.py: - avoid uneeded interal references in the Package objects + * python/progress.cc: + - fix crash in RunSimpleCallback() * aptsources/sourceslist.py: - fix bug in invalid lines detection (LP: #324614) + * apt/cache.py: + - when the cache is run with a alternative rootdir, create + required dirs/files automatically -- Michael Vogt Thu, 19 Mar 2009 13:39:21 +0100 diff --git a/python/progress.cc b/python/progress.cc index 14948d3c..95cece3b 100644 --- a/python/progress.cc +++ b/python/progress.cc @@ -27,9 +27,12 @@ bool PyCallbackObj::RunSimpleCallback(const char* method_name, PyObject *method = PyObject_GetAttrString(callbackInst,(char*) method_name); if(method == NULL) { - // FIXME: make this silent //std::cerr << "Can't find '" << method_name << "' method" << std::endl; Py_XDECREF(arglist); + if (res) { + Py_INCREF(Py_None); + *res = Py_None; + } return false; } PyObject *result = PyEval_CallObject(method, arglist); -- cgit v1.2.3 From 80bd612d4006a493541ca8f50b1634ee529cb533 Mon Sep 17 00:00:00 2001 From: Stephan Peijnik Date: Sat, 25 Jul 2009 10:35:21 +0200 Subject: Exception handling fixes in InstallProgress class. --- apt/progress/__init__.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'apt') diff --git a/apt/progress/__init__.py b/apt/progress/__init__.py index 3be197f7..b582ad22 100644 --- a/apt/progress/__init__.py +++ b/apt/progress/__init__.py @@ -286,11 +286,20 @@ class InstallProgress(DumbInstallProgress): def waitChild(self): """Wait for child progress to exit.""" while True: - select.select([self.statusfd], [], [], self.selectTimeout) - self.updateInterface() - (pid, res) = os.waitpid(self.child_pid, os.WNOHANG) - if pid == self.child_pid: + try: + select.select([self.statusfd], [], [], self.selectTimeout) + except select.error, (errno_, errstr): + if errno_ != errno.EINTR: + raise break + self.updateInterface() + try: + (pid, res) = os.waitpid(self.child_pid, os.WNOHANG) + if pid == self.child_pid: + break + except OSError, (errno_, errstr): + if errno_ != errno.EINTR: + raise return res def run(self, pm): -- cgit v1.2.3 From 85707b8b52eba15c2ed8328e4f55f794bd242a71 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Thu, 30 Jul 2009 14:29:15 +0200 Subject: * apt/cache.py: Call InitSystem() if rootdir is not None (LP: #320665). --- apt/cache.py | 3 +++ debian/changelog | 3 +++ 2 files changed, 6 insertions(+) (limited to 'apt') diff --git a/apt/cache.py b/apt/cache.py index 94a77fd8..efa8afb3 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -63,6 +63,9 @@ class Cache(object): # create required dirs/files when run with special rootdir # automatically self._check_and_create_required_dirs(rootdir) + # Call InitSystem so the change to Dir::State::Status is actually + # recognized (LP: #320665) + apt_pkg.InitSystem() self.open(progress) def _check_and_create_required_dirs(self, rootdir): diff --git a/debian/changelog b/debian/changelog index b12c156e..66f2c052 100644 --- a/debian/changelog +++ b/debian/changelog @@ -6,6 +6,9 @@ python-apt (0.7.11.2) unstable; urgency=low * debian/control: - Only recommend libjs-jquery (Closes: #527543) - Build-depend on libapt-pkg-dev (>= 0.7.22~) + * apt/cache.py: + - Correctly handle rootdir on second and later invocations of + open(), by calling InitSystem again. (LP: #320665). [ Stefano Zacchiroli ] * debian/python-apt.doc-base: register the documentation with the -- cgit v1.2.3 From 2b64e774ba825789caea80d9424faf1ac3be19d9 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Thu, 30 Jul 2009 14:36:35 +0200 Subject: apt/progress.py: Extract the package name from the status message (Closes: #532660) --- apt/progress/__init__.py | 5 +++-- debian/changelog | 4 ++++ 2 files changed, 7 insertions(+), 2 deletions(-) (limited to 'apt') diff --git a/apt/progress/__init__.py b/apt/progress/__init__.py index b582ad22..b9288c2c 100644 --- a/apt/progress/__init__.py +++ b/apt/progress/__init__.py @@ -344,7 +344,7 @@ class DpkgInstallProgress(InstallProgress): if pid == 0: # child res = os.system("/usr/bin/dpkg --status-fd %s -i %s" % \ - (self.writefd, self.debfile)) + (self.writefd, debfile)) os._exit(os.WEXITSTATUS(res)) self.child_pid = pid res = self.waitChild() @@ -370,10 +370,11 @@ class DpkgInstallProgress(InstallProgress): print "got garbage from dpkg: '%s'" % self.read self.read = "" break + pkg_name = statusl[1].strip() status = statusl[2].strip() #print status if status == "error": - self.error(self.debname, status) + self.error(pkg_name, status) elif status == "conffile-prompt": # we get a string like this: # 'current-conffile' 'new-conffile' useredited distedited diff --git a/debian/changelog b/debian/changelog index e95a3fe2..83422b00 100644 --- a/debian/changelog +++ b/debian/changelog @@ -15,6 +15,10 @@ python-apt (0.7.11.2) unstable; urgency=low * debian/python-apt.doc-base: register the documentation with the doc-base system (Closes: #525134) + [ Sebastian Heinlein ] + * apt/progress.py: Extract the package name from the status message + (Closes: #532660) + -- Julian Andres Klode Thu, 30 Jul 2009 14:08:30 +0200 python-apt (0.7.11.1) unstable; urgency=low -- cgit v1.2.3 From 4e66ff1d8fea8631af4656d824b7d6f94f9486c4 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Thu, 30 Jul 2009 14:39:56 +0200 Subject: apt/cache.py: Provide broken_count, delete_count, install_count, keep_count properties (Closes: #532338) --- apt/cache.py | 20 ++++++++++++++++++++ debian/changelog | 2 ++ 2 files changed, 22 insertions(+) (limited to 'apt') diff --git a/apt/cache.py b/apt/cache.py index efa8afb3..31e14561 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -332,6 +332,26 @@ class Cache(object): self._callbacks[name] = [] self._callbacks[name].append(callback) + @property + def broken_count(self): + """Return the number of packages with broken dependencies.""" + return self._depcache.broken_count + + @property + def delete_count(self): + """Return the number of packages marked for deletion.""" + return self._depcache.del_count + + @property + def install_count(self): + """Return the number of packages marked for installation.""" + return self._depcache.inst_count + + @property + def keep_count(self): + """Return the number of packages marked as keep.""" + return self._depcache.keep_count + # ----------------------------- experimental interface diff --git a/debian/changelog b/debian/changelog index 83422b00..73e9eab7 100644 --- a/debian/changelog +++ b/debian/changelog @@ -10,6 +10,8 @@ python-apt (0.7.11.2) unstable; urgency=low * apt/cache.py: - Correctly handle rootdir on second and later invocations of open(), by calling InitSystem again. (LP: #320665). + - Provide broken_count, delete_count, install_count, keep_count + properties (Closes: #532338) [ Stefano Zacchiroli ] * debian/python-apt.doc-base: register the documentation with the -- cgit v1.2.3 From 00ebd1e79986dad66829edaf8dc906a4c9d1ab6c Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Thu, 30 Jul 2009 14:47:59 +0200 Subject: apt/package.py: Allow to set the candidate of a package (Closes: #523997) + Support assignments to the 'candidate' property of Package objects. + Initial patch by Sebastian Heinlein --- apt/package.py | 16 +++++++++++++--- debian/changelog | 4 ++++ 2 files changed, 17 insertions(+), 3 deletions(-) (limited to 'apt') diff --git a/apt/package.py b/apt/package.py index ec88a456..f5bdc47d 100644 --- a/apt/package.py +++ b/apt/package.py @@ -486,15 +486,25 @@ class Package(object): def __repr__(self): return '' % (self._pkg.Name, self._pkg.ID) - @property def candidate(self): """Return the candidate version of the package. - - :since: 0.7.9""" + + This property is writeable to allow you to set the candidate version + of the package. Just assign a Version() object, and it will be set as + the candidate version. + """ cand = self._pcache._depcache.GetCandidateVer(self._pkg) if cand is not None: return Version(self, cand) + def __set_candidate(self, version): + """Set the candidate version of the package.""" + self._pcache.cachePreChange() + self._pcache._depcache.SetCandidateVer(self._pkg, version._cand) + self._pcache.cachePostChange() + + candidate = property(candidate, __set_candidate) + @property def installed(self): """Return the currently installed version of the package. diff --git a/debian/changelog b/debian/changelog index 73e9eab7..fcc7fd9b 100644 --- a/debian/changelog +++ b/debian/changelog @@ -12,6 +12,10 @@ python-apt (0.7.11.2) unstable; urgency=low open(), by calling InitSystem again. (LP: #320665). - Provide broken_count, delete_count, install_count, keep_count properties (Closes: #532338) + * apt/package.py: + - Allow to set the candidate of a package (Closes: #523997) + + Support assignments to the 'candidate' property of Package objects. + + Initial patch by Sebastian Heinlein [ Stefano Zacchiroli ] * debian/python-apt.doc-base: register the documentation with the -- cgit v1.2.3 From 82166c78d6b21754bdad32ed8a94773a874d528f Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Thu, 30 Jul 2009 15:00:44 +0200 Subject: Only create Package objects when they are requested, do not keep them in a dict. Saves 10MB for 25,000 packages on my machine. --- apt/cache.py | 42 ++++++++++++++++++++++++++---------------- debian/changelog | 2 ++ 2 files changed, 28 insertions(+), 16 deletions(-) (limited to 'apt') diff --git a/apt/cache.py b/apt/cache.py index 31e14561..c1e2428c 100644 --- a/apt/cache.py +++ b/apt/cache.py @@ -20,6 +20,7 @@ # USA import os +import weakref import apt_pkg from apt import Package @@ -47,6 +48,8 @@ class Cache(object): def __init__(self, progress=None, rootdir=None, memonly=False): self._callbacks = {} + self._weakref = weakref.WeakValueDictionary() + self._set = set() if memonly: # force apt to build its caches in memory apt_pkg.Config.Set("Dir::Cache::pkgcache", "") @@ -96,7 +99,7 @@ class Cache(object): for callback in self._callbacks[name]: callback() - def open(self, progress): + def open(self, progress=None): """ Open the package cache, after that it can be used like a dictionary """ @@ -108,7 +111,8 @@ class Cache(object): self._records = apt_pkg.GetPkgRecords(self._cache) self._list = apt_pkg.GetPkgSourceList() self._list.ReadMainList() - self._dict = {} + self._set.clear() + self._weakref.clear() progress.Op = "Building data structures" i=last=0 @@ -119,7 +123,7 @@ class Cache(object): last=i # drop stuff with no versions (cruft) if len(pkg.VersionList) > 0: - self._dict[pkg.Name] = Package(self, pkg) + self._set.add(pkg.Name) i += 1 @@ -128,30 +132,36 @@ class Cache(object): def __getitem__(self, key): """ look like a dictionary (get key) """ - return self._dict[key] + try: + return self._weakref[key] + except KeyError: + if key in self._set: + pkg = self._weakref[key] = Package(self, self._cache[key]) + return pkg + else: + raise KeyError('The cache has no package named %r' % key) def __iter__(self): - for pkgname in self._dict.keys(): - yield self._dict[pkgname] + for pkgname in self._set: + yield self[pkgname] raise StopIteration def has_key(self, key): - return (key in self._dict) + return (key in self._set) def __contains__(self, key): - return (key in self._dict) + return (key in self._set) def __len__(self): - return len(self._dict) + return len(self._set) def keys(self): - return self._dict.keys() + return list(self._set) def getChanges(self): """ Get the marked changes """ changes = [] - for name in self._dict.keys(): - p = self._dict[name] + for p in self: if p.markedUpgrade or p.markedInstall or p.markedDelete or \ p.markedDowngrade or p.markedReinstall: changes.append(p) @@ -396,7 +406,7 @@ class FilteredCache(object): return len(self._filtered) def __getitem__(self, key): - return self.cache._dict[key] + return self.cache[key] def __iter__(self): for pkgname in self._filtered: @@ -414,10 +424,10 @@ class FilteredCache(object): def _reapplyFilter(self): " internal helper to refilter " self._filtered = {} - for pkg in self.cache._dict.keys(): + for pkg in self.cache: for f in self._filters: - if f.apply(self.cache._dict[pkg]): - self._filtered[pkg] = 1 + if f.apply(pkg): + self._filtered[pkg.name] = 1 break def setFilter(self, filter): diff --git a/debian/changelog b/debian/changelog index fcc7fd9b..298c0ac6 100644 --- a/debian/changelog +++ b/debian/changelog @@ -12,6 +12,8 @@ python-apt (0.7.11.2) unstable; urgency=low open(), by calling InitSystem again. (LP: #320665). - Provide broken_count, delete_count, install_count, keep_count properties (Closes: #532338) + - Only create Package objects when they are requested, do not keep them in + a dict. Saves 10MB for 25,000 packages on my machine. * apt/package.py: - Allow to set the candidate of a package (Closes: #523997) + Support assignments to the 'candidate' property of Package objects. -- cgit v1.2.3