home *** CD-ROM | disk | FTP | other *** search
- # Source Generated with Decompyle++
- # File: in.pyc (Python 2.6)
-
- '''progress reporting classes.
-
- This module provides classes for progress reporting. They can be used with
- e.g., for reporting progress on the cache opening process, the cache update
- progress, or the package install progress.
- '''
- import errno
- import fcntl
- import os
- import re
- import select
- import sys
- import apt_pkg
- __all__ = ('CdromProgress', 'DpkgInstallProgress', 'DumbInstallProgress', 'FetchProgress', 'InstallProgress', 'OpProgress', 'OpTextProgress', 'TextFetchProgress')
-
- class OpProgress(object):
- '''Abstract class to implement reporting on cache opening.
-
- Subclass this class to implement simple Operation progress reporting.
- '''
-
- def __init__(self):
- self.op = None
- self.subOp = None
-
-
- def update(self, percent):
- '''Called periodically to update the user interface.'''
- pass
-
-
- def done(self):
- '''Called once an operation has been completed.'''
- pass
-
-
-
- class OpTextProgress(OpProgress):
- '''A simple text based cache open reporting class.'''
-
- def __init__(self):
- OpProgress.__init__(self)
-
-
- def update(self, percent):
- '''Called periodically to update the user interface.'''
- sys.stdout.write('\r%s: %.2i ' % (self.subOp, percent))
- sys.stdout.flush()
-
-
- def done(self):
- '''Called once an operation has been completed.'''
- sys.stdout.write('\r%s: Done\n' % self.op)
-
-
-
- class FetchProgress(object):
- '''Report the download/fetching progress.
-
- Subclass this class to implement fetch progress reporting
- '''
- dlDone = 0
- dlQueued = 1
- dlFailed = 2
- dlHit = 3
- dlIgnored = 4
- dlStatusStr = {
- dlDone: 'Done',
- dlQueued: 'Queued',
- dlFailed: 'Failed',
- dlHit: 'Hit',
- dlIgnored: 'Ignored' }
-
- def __init__(self):
- self.eta = 0
- self.percent = 0
- self.currentBytes = 0
- self.currentItems = 0
- self.totalBytes = 0
- self.totalItems = 0
- self.currentCPS = 0
-
-
- def start(self):
- '''Called when the fetching starts.'''
- pass
-
-
- def stop(self):
- '''Called when all files have been fetched.'''
- pass
-
-
- def updateStatus(self, uri, descr, shortDescr, status):
- '''Called when the status of an item changes.
-
- This happens eg. when the downloads fails or is completed.
- '''
- pass
-
-
- def pulse(self):
- '''Called periodically to update the user interface.
-
- Return True to continue or False to cancel.
- '''
- self.percent = (self.currentBytes + self.currentItems) * 100 / 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.'''
- pass
-
-
-
- class TextFetchProgress(FetchProgress):
- ''' Ready to use progress object for terminal windows '''
-
- def __init__(self):
- FetchProgress.__init__(self)
- self.items = { }
-
-
- def updateStatus(self, uri, descr, shortDescr, status):
- '''Called when the status of an item changes.
-
- This happens eg. when the downloads fails or is completed.
- '''
- if status != self.dlQueued:
- print '\r%s %s' % (self.dlStatusStr[status], descr)
-
- self.items[uri] = status
-
-
- def pulse(self):
- '''Called periodically to update the user interface.
-
- Return True to continue or False to cancel.
- '''
- FetchProgress.pulse(self)
- if self.currentCPS > 0:
- s = '[%2.f%%] %sB/s %s' % (self.percent, apt_pkg.SizeToStr(int(self.currentCPS)), apt_pkg.TimeToStr(int(self.eta)))
- else:
- s = '%2.f%% [Working]' % self.percent
- print '\r%s' % s,
- sys.stdout.flush()
- return True
-
-
- def stop(self):
- '''Called when all files have been fetched.'''
- print '\rDone downloading '
-
-
- def mediaChange(self, medium, drive):
- '''react to media change events.'''
- print "Media change: please insert the disc labeled '%s' in the drive '%s' and press enter" % (medium, drive)
- return raw_input() not in ('c', 'C')
-
-
-
- class DumbInstallProgress(object):
- '''Report the install progress.
-
- Subclass this class to implement install progress reporting.
- '''
-
- def startUpdate(self):
- '''Start update.'''
- pass
-
-
- def run(self, pm):
- '''Start installation.'''
- return pm.DoInstall()
-
-
- def finishUpdate(self):
- '''Called when update has finished.'''
- pass
-
-
- def updateInterface(self):
- '''Called periodically to update the user interface'''
- pass
-
-
-
- class InstallProgress(DumbInstallProgress):
- """An InstallProgress that is pretty useful.
-
- It supports the attributes 'percent' 'status' and callbacks for the dpkg
- errors and conffiles and status changes.
- """
-
- def __init__(self):
- DumbInstallProgress.__init__(self)
- self.selectTimeout = 0.1
- (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
- self.status = ''
-
-
- def error(self, pkg, errormsg):
- '''Called when a error is detected during the install.'''
- pass
-
-
- def conffile(self, current, new):
- '''Called when a conffile question from dpkg is detected.'''
- pass
-
-
- def statusChange(self, pkg, percent, status):
- '''Called when the status changed.'''
- pass
-
-
- def updateInterface(self):
- '''Called periodically to update the interface.'''
- if self.statusfd is None:
- return None
-
- try:
- while not self.read.endswith('\n'):
- self.read += os.read(self.statusfd.fileno(), 1)
- continue
- self
- except OSError:
- self.statusfd is None
- (errno_, errstr) = self.statusfd is None
- if errno_ != errno.EAGAIN and errno_ != errno.EWOULDBLOCK:
- print errstr
-
- except:
- errno_ != errno.EWOULDBLOCK
-
- if not self.read.endswith('\n'):
- return None
- s = self.read
-
- try:
- (status, pkg, percent, status_str) = s.split(':', 3)
- except ValueError:
- self.read.endswith('\n')
- self.read.endswith('\n')
- self.statusfd is None
- self.read = ''
- return None
-
- if status == 'pmerror':
- self.error(pkg, status_str)
- elif status == 'pmconffile':
- match = re.match("\\s*'(.*)'\\s*'(.*)'.*", status_str)
- if match:
- self.conffile(match.group(1), match.group(2))
-
- elif status == 'pmstatus':
- if float(percent) != self.percent or status_str != self.status:
- self.statusChange(pkg, float(percent), status_str.strip())
- self.percent = float(percent)
- self.status = status_str.strip()
-
-
- self.read = ''
-
-
- def fork(self):
- '''Fork.'''
- return os.fork()
-
-
- 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:
- break
- continue
- return res
-
-
- def run(self, pm):
- '''Start installing.'''
- pid = self.fork()
- if pid == 0:
- res = pm.DoInstall(self.writefd)
- os._exit(res)
-
- self.child_pid = pid
- res = self.waitChild()
- return os.WEXITSTATUS(res)
-
-
-
- class CdromProgress(object):
- '''Report the cdrom add progress.
-
- Subclass this class to implement cdrom add progress reporting.
- '''
-
- def __init__(self):
- pass
-
-
- def update(self, text, step):
- '''Called periodically to update the user interface.'''
- pass
-
-
- def askCdromName(self):
- '''Called to ask for the name of the cdrom.'''
- pass
-
-
- def changeCdrom(self):
- '''Called to ask for the cdrom to be changed.'''
- pass
-
-
-
- class DpkgInstallProgress(InstallProgress):
- '''Progress handler for a local Debian package installation.'''
-
- def run(self, debfile):
- '''Start installing the given Debian package.'''
- self.debfile = debfile
- self.debname = os.path.basename(debfile).split('_')[0]
- pid = self.fork()
- if pid == 0:
- res = os.system('/usr/bin/dpkg --status-fd %s -i %s' % (self.writefd, self.debfile))
- os._exit(os.WEXITSTATUS(res))
-
- self.child_pid = pid
- res = self.waitChild()
- return res
-
-
- def updateInterface(self):
- '''Process status messages from dpkg.'''
- if self.statusfd is None:
- return None
- while True:
-
- try:
- self.read += os.read(self.statusfd.fileno(), 1)
- except OSError:
- self.statusfd is None
- (errno_, errstr) = self.statusfd is None
- if errno_ != 11:
- print errstr
-
- break
- except:
- self.statusfd is None
-
- if not self.read.endswith('\n'):
- continue
-
- statusl = self.read.split(':')
- if len(statusl) < 3:
- print "got garbage from dpkg: '%s'" % self.read
- self.read = ''
- break
-
- status = statusl[2].strip()
- if status == 'error':
- self.error(self.debname, status)
- elif status == 'conffile-prompt':
- match = re.match("\\s*'(.*)'\\s*'(.*)'.*", statusl[3])
- if match:
- self.conffile(match.group(1), match.group(2))
-
- else:
- self.status = status
- self.read = ''
-
-
-