Viewing file: Progress.py (8.63 KB) -rw-r--r-- Select action/file-type: (+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
# Copyright 2005-2007 Red Hat, Inc. # # Jeremy Katz <katzj@redhat.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; version 2 only # # 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 Library 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 os import fcntl import logging # # Python gettext: # import gettext import rpm
import gtk import gtk.glade import gtk.gdk as gdk import pango
from rhpl.translate import _, N_
from yum.constants import *
from constants import * from Errors import *
if os.access("data/yumhelpers.glade", os.R_OK): gygladefn = "data/yumhelpers.glade" else: gygladefn = "/usr/share/pirut/ui/yumhelpers.glade"
# # Python gettext: # t = gettext.translation(I18N_DOMAIN, "/usr/share/locale", fallback = True) # _ = t.lgettext
# lame main loop runner... this should probably just be where we need it def _runGtkMain(*args): while gtk.events_pending(): gtk.main_iteration()
UPDTHRESH = 0.005
class PirutProgress: def __init__(self, title, parent = None): self.xml = gtk.glade.XML(gygladefn, domain="pirut") self.dialog = self.xml.get_widget("graphicalYumProgressDialog") if parent: self.dialog.set_modal(True) self.dialog.set_transient_for(parent) self.dialog.set_position(gtk.WIN_POS_CENTER_ON_PARENT)
self.dialog.set_title(title) t = self.xml.get_widget("graphicalYumProgressTitle") t.set_markup("<span weight=\"bold\" size=\"x-large\">" + title + "</span>")
self.pbar = self.xml.get_widget("graphicalYumProgressBar") self.set_fraction(0.0)
self.label = self.xml.get_widget("graphicalYumProgressLabel") self.set_markup("") self.set_pbar_text("")
def show(self): self.dialog.show() self.dialog.window.set_cursor(gdk.Cursor(gdk.WATCH)) _runGtkMain()
def hide(self): self.dialog.hide() if self.dialog is not None and self.dialog.window is not None: self.dialog.window.set_cursor(None) _runGtkMain()
def destroy(self): if self.dialog.window is not None: self.dialog.window.set_cursor(None) self.dialog.destroy()
def set_fraction(self, fract): if fract > 1.0: fract = 1.0 if fract < 0.0: fract = 0.0 self.pbar.set_fraction(fract) _runGtkMain()
def get_fraction(self): return self.pbar.get_fraction()
def set_markup(self, txt): if len(txt) > 0: self.label.show() self.label.set_markup(txt) _runGtkMain()
def set_ellipsize(self, e): self.label.set_ellipsize(e)
def set_pbar_text(self, txt): self.pbar.set_text(txt) _runGtkMain()
def __del__(self): self.destroy()
class PirutCancellableProgress(PirutProgress): def __init__(self, title, parent = None): self.cancel = False PirutProgress.__init__(self, title, parent) self.xml.get_widget("buttonArea").show() self.xml.get_widget("cancelButton").connect("clicked", self.cancelClicked)
def cancelClicked(self, *args): self.cancel = True def _checkCancel(self): if self.cancel: self.cancel = False raise PirutCancelledError
def set_fraction(self, fract): self._checkCancel() PirutProgress.set_fraction(self, fract) def get_fraction(self): self._checkCancel() return PirutProgress.get_fraction(self) def set_markup(self, txt): self._checkCancel() PirutProgress.set_markup(self, txt) def set_pbar_text(self, txt): self._checkCancel() PirutProgress.set_pbar_text(self, txt)
class PirutProgressCallback(PirutCancellableProgress): def __init__(self, title, parent = None, num_tasks = 1): PirutCancellableProgress.__init__(self, title, parent) self.num_tasks = float(num_tasks) self.cur_task = 0 self.this_task = 1
self.length = 0
def update(self, current): if self.length: pct = (current / self.length) else: pct = 0 curval = self.pbar.get_fraction() newval = (pct * 1/self.num_tasks) * self.this_task + \ (self.cur_task / self.num_tasks) if newval > curval + UPDTHRESH: self.set_fraction(newval) def start(self, local, remote, basename, size, **kwargs): # txt = _("Retrieving %s") %(remote,) # self.set_ellipsize(pango.ELLIPSIZE_MIDDLE) # self.set_markup('<span size=\"small\"><i>%s</i></span>' %(txt,)) if size is not None: self.length = float(size)
def end(self, *args, **kwargs): # self.set_ellipsize(pango.ELLIPSIZE_END) # self.set_markup("") self.length = 0 self.next_task()
def progressbar(self, current, total, name = None): pct = float(current) / total curval = self.pbar.get_fraction() newval = (pct * 1/self.num_tasks) * self.this_task + \ (self.cur_task / self.num_tasks) if newval > curval + UPDTHRESH: self.set_fraction(newval)
def next_task(self, incr = 1, next = 1): self.cur_task += incr self.this_task = next self.set_pbar_text("") self.set_fraction(self.cur_task / self.num_tasks)
class PirutDepsolveProgress(PirutCancellableProgress): def __init__(self, ayum, title, parent = None): PirutCancellableProgress.__init__(self, title, parent) self.ayum = ayum self.incr = 0.0
# if we run pending events when we get a callback, things # seem more responsive which is good (tm) self.procReq = self.transactionPopulation = self.downloadHeader = self.start = self.unresolved = self.procConflict = _runGtkMain
def tscheck(self): num = len(self.ayum.tsInfo.getMembers()) self.incr = (1.0 / num) * ((1.0 - self.get_fraction()) / 2)
def pkgAdded(self, *args): self.set_fraction(self.get_fraction() + self.incr)
def restartLoop(self): cur = self.get_fraction() new = ((1.0 - cur) / 2) + cur self.set_fraction(new)
def end(self): self.set_fraction(1.0)
class PirutTransactionCallback(yum.rpmtrans.RPMBaseCallback, PirutProgress): def __init__(self, title, parent = None): PirutProgress.__init__(self, title, parent) yum.rpmtrans.RPMBaseCallback.__init__(self)
# FIXME: these should be better but can't due to string freeze self.action = { TS_UPDATE : _("Updating %s"), TS_ERASE: _("Cleanup %s"), TS_INSTALL: _("Updating %s"), TS_TRUEINSTALL : _("Updating %s"), TS_OBSOLETED: _("Cleanup %s"), TS_OBSOLETING: _("Updating %s"), TS_UPDATED: _("Cleanup %s"), 'repackaging': _("Cleanup %s")} self.lastpkg = None self.lastpct = -0.05 # bogus so we get an update at the beginning
self._output = {} self._readPipe = None
def setReadPipe(self, f): self._readPipe = f fcntl.fcntl(f.fileno(), fcntl.F_SETFL, fcntl.fcntl(f.fileno(), fcntl.F_GETFL) | os.O_NONBLOCK)
def _readCurrent(self): if not self._readPipe: return try: out = self._readPipe.read() if out: self._output[self.lastpkg] = out self.logger.info(out) except IOError: pass def getOutput(self): self._readCurrent() return self._output
def event(self, package, action, te_current, te_total, ts_current, ts_total): msg = self.action[action] %(package,)
if "%s" %(package,) != self.lastpkg: self._readCurrent() self.set_markup("<i>%s</i>" % msg) self.lastpkg = "%s" %(package,)
pct = (ts_current-1)/float(ts_total) + (1 / float(ts_total) * te_current/float(te_total)) if pct > self.lastpct + UPDTHRESH: self.set_fraction(pct) self.lastpct = pct
|