From b4141dda949890eaa50f0097b6fc6baeb3c489ac Mon Sep 17 00:00:00 2001 From: Michael Vogt Date: Tue, 6 Dec 2005 21:59:07 +0000 Subject: * apt.progress.InstallProgress class improved --- apt/progress.py | 53 +++++++++++++++++++++++++++++++++++++++++-- doc/examples/inst.py | 63 ++++++++++++++++++---------------------------------- 2 files changed, 73 insertions(+), 43 deletions(-) diff --git a/apt/progress.py b/apt/progress.py index 8c47ab95..b02fb33a 100644 --- a/apt/progress.py +++ b/apt/progress.py @@ -19,7 +19,7 @@ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 # USA -import sys, apt_pkg +import sys, apt_pkg, os, fcntl, string class OpProgress: """ Abstract class to implement reporting on cache opening @@ -117,7 +117,7 @@ class TextFetchProgress(FetchProgress): res = false; return res -class InstallProgress: +class DumbInstallProgress: """ Report the install progress Subclass this class to implement install progress reporting """ @@ -132,6 +132,55 @@ class InstallProgress: def updateInterface(self): pass +class InstallProgress(DumbInstallProgress): + """ A InstallProgress that is pretty useful. + It supports the attributes 'percent' 'status' and callbacks + for the dpkg errors and conffiles (not implemented yet) + """ + def __init__(self): + (read, write) = os.pipe() + self.writefd=write + self.statusfd = os.fdopen(read, "r") + fcntl.fcntl(self.statusfd.fileno(), fcntl.F_SETFL,os.O_NONBLOCK) + self.read = "" + self.percent = 0.0 + self.status = "" + def updateInterface(self): + if self.statusfd != None: + try: + self.read += os.read(self.statusfd.fileno(),1) + except OSError, (errno,errstr): + # resource temporarly unavailable is ignored + if errno != 11: + print errstr + if self.read.endswith("\n"): + # FIXME: add errorhandling + s = self.read + #print s + (status, pkg, percent, status_str) = string.split(s, ":") + #print "percent: %s %s" % (pkg, float(percent)/100.0) + self.percent = float(percent) + self.status = string.strip(status_str) + self.read = "" + def fork(self): + return os.fork() + def waitChild(self): + while True: + (pid, res) = os.waitpid(self.child_pid,os.WNOHANG) + if pid == self.child_pid: + break + self.updateInterface() + return os.WEXITSTATUS(res) + def run(self, pm): + pid = self.fork() + if pid == 0: + # child + res = pm.DoInstall(self.writefd) + sys.exit(res) + self.child_pid = pid + res = self.waitChild() + return res + class CdromProgress: """ Report the cdrom add progress Subclass this class to implement cdrom add progress reporting diff --git a/doc/examples/inst.py b/doc/examples/inst.py index fe5ec8e3..66b61c54 100644 --- a/doc/examples/inst.py +++ b/doc/examples/inst.py @@ -2,60 +2,41 @@ # example how to deal with the depcache import apt -import apt_pkg import sys, os import copy +import time -from progress import TextFetchProgress, TextInstallProgress -from apt.progress import OpTextProgress +from apt.progress import InstallProgress class TextInstallProgress(InstallProgress): def __init__(self): - InstallProgress.__init__(self) - self.status = None - def StartUpdate(self): - print "StartUpdate: %s" % self.statusfd - self.status = os.fdopen(self.statusfd, "r") - print self.status - def UpdateInterface(self): - if self.status != None: - s = self.status.readline() - if s: - print s - def FinishUpdate(self): - self.status.close() - -# init -apt_pkg.init() - -progress = OpTextProgress() -cache = apt_pkg.GetCache(progress) -print "Available packages: %s " % cache.PackageCount - -# get depcache -depcache = apt_pkg.GetDepCache(cache) -depcache.ReadPinFile() -depcache.Init(progress) - -# do something -fprogress = TextFetchProgress() + apt.progress.InstallProgress.__init__(self) + self.last = 0.0 + def updateInterface(self): + InstallProgress.updateInterface(self) + if self.last >= self.percent: + return + sys.stdout.write("\r[%s] %s\n" %(self.percent, self.status)) + sys.stdout.flush() + self.last = self.percent + +cache = apt.Cache(apt.progress.OpTextProgress()) + +fprogress = apt.progress.TextFetchProgress() iprogress = TextInstallProgress() -# can be used to set a custom fork method (like vte.Terminal.forkpty) -#iprogress.fork = os.fork - -iter = cache["base-config"] -print "\n%s"%iter +pkg = cache["base-config"] # install or remove, the importend thing is to keep us busy :) -if iter.CurrentVer == None: - depcache.MarkInstall(iter) +if pkg.isInstalled: + print "Going to delete %s" % pkg.name + pkg.markDelete() else: - depcache.MarkDelete(iter) -res = depcache.Commit(fprogress, iprogress) + print "Going to install %s" % pkg.name + pkg.markInstall() +res = cache.commit(fprogress, iprogress) print res -print "Exiting" sys.exit(0) -- cgit v1.2.3