Module callback
[hide private]
[frames] | no frames]

Source Code for Module callback

  1  #!/usr/bin/python -t 
  2  # This program is free software; you can redistribute it and/or modify 
  3  # it under the terms of the GNU General Public License as published by 
  4  # the Free Software Foundation; either version 2 of the License, or 
  5  # (at your option) any later version. 
  6  # 
  7  # This program is distributed in the hope that it will be useful, 
  8  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
  9  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 10  # GNU Library General Public License for more details. 
 11  # 
 12  # You should have received a copy of the GNU General Public License 
 13  # along with this program; if not, write to the Free Software 
 14  # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 
 15  # Copyright 2005 Duke University 
 16   
 17  """ 
 18  Progress display callback classes for the yum command line. 
 19  """ 
 20   
 21  import rpm 
 22  import os 
 23  import sys 
 24  import logging 
 25  from yum import _ 
 26  from yum.constants import * 
 27   
 28   
29 -class RPMInstallCallback:
30 31 """ 32 Yum command line callback class for callbacks from the RPM library. 33 """ 34
35 - def __init__(self, output=1):
36 self.output = output 37 self.callbackfilehandles = {} 38 self.total_actions = 0 39 self.total_installed = 0 40 self.installed_pkg_names = [] 41 self.total_removed = 0 42 self.mark = "#" 43 self.marks = 27 44 self.lastmsg = None 45 self.logger = logging.getLogger('yum.filelogging.RPMInstallCallback') 46 self.filelog = False 47 48 self.myprocess = { TS_UPDATE : _('Updating'), 49 TS_ERASE: _('Erasing'), 50 TS_INSTALL: _('Installing'), 51 TS_TRUEINSTALL : _('Installing'), 52 TS_OBSOLETED: _('Obsoleted'), 53 TS_OBSOLETING: _('Installing')} 54 self.mypostprocess = { TS_UPDATE: _('Updated'), 55 TS_ERASE: _('Erased'), 56 TS_INSTALL: _('Installed'), 57 TS_TRUEINSTALL: _('Installed'), 58 TS_OBSOLETED: _('Obsoleted'), 59 TS_OBSOLETING: _('Installed')} 60 61 self.tsInfo = None # this needs to be set for anything else to work
62
63 - def _dopkgtup(self, hdr):
64 tmpepoch = hdr['epoch'] 65 if tmpepoch is None: epoch = '0' 66 else: epoch = str(tmpepoch) 67 68 return (hdr['name'], hdr['arch'], epoch, hdr['version'], hdr['release'])
69
70 - def _makeHandle(self, hdr):
71 handle = '%s:%s.%s-%s-%s' % (hdr['epoch'], hdr['name'], hdr['version'], 72 hdr['release'], hdr['arch']) 73 74 return handle
75
76 - def _localprint(self, msg):
77 if self.output: 78 print msg
79
80 - def _makefmt(self, percent, progress = True):
81 l = len(str(self.total_actions)) 82 size = "%s.%s" % (l, l) 83 fmt_done = "[%" + size + "s/%" + size + "s]" 84 done = fmt_done % (self.total_installed + self.total_removed, 85 self.total_actions) 86 marks = self.marks - (2 * l) 87 width = "%s.%s" % (marks, marks) 88 fmt_bar = "%-" + width + "s" 89 if progress: 90 bar = fmt_bar % (self.mark * int(marks * (percent / 100.0)), ) 91 fmt = "\r %-10.10s: %-28.28s " + bar + " " + done 92 else: 93 bar = fmt_bar % (self.mark * marks, ) 94 fmt = " %-10.10s: %-28.28s " + bar + " " + done 95 return fmt
96
97 - def _logPkgString(self, hdr):
98 """return nice representation of the package for the log""" 99 (n,a,e,v,r) = self._dopkgtup(hdr) 100 if e == '0': 101 pkg = '%s.%s %s-%s' % (n, a, v, r) 102 else: 103 pkg = '%s.%s %s:%s-%s' % (n, a, e, v, r) 104 105 return pkg
106
107 - def callback(self, what, bytes, total, h, user):
108 if what == rpm.RPMCALLBACK_TRANS_START: 109 if bytes == 6: 110 self.total_actions = total 111 112 elif what == rpm.RPMCALLBACK_TRANS_PROGRESS: 113 pass 114 115 elif what == rpm.RPMCALLBACK_TRANS_STOP: 116 pass 117 118 elif what == rpm.RPMCALLBACK_INST_OPEN_FILE: 119 self.lastmsg = None 120 hdr = None 121 if h is not None: 122 hdr, rpmloc = h 123 handle = self._makeHandle(hdr) 124 fd = os.open(rpmloc, os.O_RDONLY) 125 self.callbackfilehandles[handle]=fd 126 self.total_installed += 1 127 self.installed_pkg_names.append(hdr['name']) 128 return fd 129 else: 130 self._localprint(_("No header - huh?")) 131 132 elif what == rpm.RPMCALLBACK_INST_CLOSE_FILE: 133 hdr = None 134 if h is not None: 135 hdr, rpmloc = h 136 handle = self._makeHandle(hdr) 137 os.close(self.callbackfilehandles[handle]) 138 fd = 0 139 140 # log stuff 141 pkgtup = self._dopkgtup(hdr) 142 143 txmbrs = self.tsInfo.getMembers(pkgtup=pkgtup) 144 for txmbr in txmbrs: 145 try: 146 process = self.myprocess[txmbr.output_state] 147 processed = self.mypostprocess[txmbr.output_state] 148 except KeyError: 149 pass 150 151 if self.filelog: 152 pkgrep = self._logPkgString(hdr) 153 msg = '%s: %s' % (processed, pkgrep) 154 self.logger.info(msg) 155 156 157 elif what == rpm.RPMCALLBACK_INST_PROGRESS: 158 if h is not None: 159 # If h is a string, we're repackaging. 160 # Why the RPMCALLBACK_REPACKAGE_PROGRESS flag isn't set, I have no idea 161 if type(h) == type(""): 162 if total == 0: 163 percent = 0 164 else: 165 percent = (bytes*100L)/total 166 if self.output and sys.stdout.isatty(): 167 fmt = self._makefmt(percent) 168 msg = fmt % (_('Repackage'), h) 169 if bytes == total: 170 msg = msg + "\n" 171 172 if msg != self.lastmsg: 173 sys.stdout.write(msg) 174 sys.stdout.flush() 175 self.lastmsg = msg 176 else: 177 hdr, rpmloc = h 178 if total == 0: 179 percent = 0 180 else: 181 percent = (bytes*100L)/total 182 pkgtup = self._dopkgtup(hdr) 183 184 txmbrs = self.tsInfo.getMembers(pkgtup=pkgtup) 185 for txmbr in txmbrs: 186 try: 187 process = self.myprocess[txmbr.output_state] 188 except KeyError, e: 189 print _("Error: invalid output state: %s for %s") % \ 190 (txmbr.output_state, hdr['name']) 191 else: 192 if self.output and (sys.stdout.isatty() or bytes == total): 193 fmt = self._makefmt(percent) 194 msg = fmt % (process, hdr['name']) 195 if msg != self.lastmsg: 196 sys.stdout.write(msg) 197 sys.stdout.flush() 198 self.lastmsg = msg 199 if bytes == total: 200 print " " 201 202 203 elif what == rpm.RPMCALLBACK_UNINST_START: 204 pass 205 206 elif what == rpm.RPMCALLBACK_UNINST_PROGRESS: 207 pass 208 209 elif what == rpm.RPMCALLBACK_UNINST_STOP: 210 self.total_removed += 1 211 if self.filelog and h not in self.installed_pkg_names: 212 logmsg = _('Erased: %s' % (h)) 213 self.logger.info(logmsg) 214 215 if self.output and sys.stdout.isatty(): 216 if h not in self.installed_pkg_names: 217 process = _("Removing") 218 else: 219 process = _("Cleanup") 220 percent = 100 221 fmt = self._makefmt(percent, False) 222 msg = fmt % (process, h) 223 sys.stdout.write(msg + "\n") 224 sys.stdout.flush() 225 226 elif what == rpm.RPMCALLBACK_REPACKAGE_START: 227 pass 228 elif what == rpm.RPMCALLBACK_REPACKAGE_STOP: 229 pass 230 elif what == rpm.RPMCALLBACK_REPACKAGE_PROGRESS: 231 pass
232