|
Server : Apache/2.2.2 (Fedora) System : Linux App1.pathumtani.go.th 2.6.20-1.2320.fc5smp #1 SMP Tue Jun 12 19:40:16 EDT 2007 i686 User : apache ( 48) PHP Version : 5.2.9 Disable Function : NONE Directory : /proc/self/root/usr/sbin/ |
Upload File : |
#!/usr/bin/python -tt
#
# Copyright 2004-2005 Red Hat, Inc.
#
# Jeremy Katz <katzj@redhat.com>
# Paul Nasrat <pnasrat@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,sys,fcntl
import string
import signal
import subprocess
import time
import rpm
import gtk
import gtk.glade
import gtk.gdk as gdk
import gobject
import pango
import yum
import yum.plugins
import yum.Errors
from yum.logger import Logger
from yum.constants import *
import urlgrabber, urlgrabber.progress
import rpmUtils.miscutils
from yum.packages import YumInstalledPackage
from rhpl.exception import installExceptionHandler
from rhpl.translate import _, N_, textdomain
from pirut import *
from pirut.Errors import *
from pirut.GroupSelector import GroupSelector
rebootpkgs = ("kernel", "kernel-smp", "kernel-xen-hypervisor",
"kernel-xen-guest", "glibc", "hal", "dbus")
class PackageUpdater(GraphicalYumBase):
def __init__(self):
if os.path.exists("data/pup.glade"):
fn = "data/pup.glade"
else:
fn = "/usr/share/pirut/ui/pup.glade"
self.pupxml = gtk.glade.XML(fn, domain="pirut")
if os.path.exists("data/pup.png"):
imgfn = "data/pup.png"
else:
imgfn = "/usr/share/pirut/pixmaps/pup.png"
i = self.pupxml.get_widget("pupImage")
pix = gtk.gdk.pixbuf_new_from_file(imgfn)
i.set_from_pixbuf(gtk.gdk.pixbuf_new_from_file(imgfn))
self.mainwin = self.pupxml.get_widget("pupWindow")
self.mainwin.set_icon_from_file(imgfn)
self._connectSignals()
self._createUpdateStore()
self.mainwin.connect("delete_event", self._quit)
# note that nothing which takes "time" should be called here!
GraphicalYumBase.__init__(self, False)
self.setupLogging()
self.localPackages = []
self.updates = []
def _connectSignals(self):
sigs = {"on_quitButton_clicked": self._quit,
"on_pupWindow_delete": self._quit,
"on_applyButton_clicked": self._apply,
"on_refreshButton_clicked": self.doRefresh}
self.pupxml.signal_autoconnect(sigs)
def _createUpdateStore(self):
# checkbox, display string, list of
# (updateFunc, printFunc, new, old) tuples
self.store = gtk.TreeStore(gobject.TYPE_BOOLEAN,
gobject.TYPE_STRING,
gobject.TYPE_PYOBJECT,
gobject.TYPE_STRING)
tree = self.pupxml.get_widget("updateList")
tree.set_model(self.store)
column = gtk.TreeViewColumn(None, None)
column.set_clickable(True)
column.set_spacing(6)
pixr = gtk.CellRendererPixbuf()
pixr.set_property('stock-size', 1)
column.pack_start(pixr, False)
column.add_attribute(pixr, 'stock-id', 3)
cbr = gtk.CellRendererToggle()
cbr.connect ("toggled", self._toggledUpdate)
column.pack_start(cbr, False)
column.add_attribute(cbr, 'active', 0)
tree.append_column(column)
renderer = gtk.CellRendererText()
column = gtk.TreeViewColumn('Text', renderer, text=1)
column.set_clickable(False)
tree.append_column(column)
tree.columns_autosize()
self.store.set_sort_column_id(1, gtk.SORT_ASCENDING)
self.pupxml.get_widget("updateDetails").set_buffer(gtk.TextBuffer())
selection = tree.get_selection()
selection.connect("changed", self._updateSelected)
def _toggledUpdate(self, data, row):
i = self.store.get_iter((int(row),))
val = self.store.get_value(i, 0)
self.store.set_value(i, 0, not val)
def _updateSelected(self, selection):
ud = self.pupxml.get_widget("updateDetails")
ud.get_buffer().set_text("")
(model, i) = selection.get_selected()
if not i:
return
lst = model.get_value(i, 2)
strs = []
for (updfunc, strfunc, new, old) in lst:
strs.append(strfunc(new, old))
ud.get_buffer().set_text(string.join(strs, "\n"))
def _runGtkmain(self, *args):
while gtk.events_pending():
gtk.main_iteration()
def _busyCursor(self):
self.mainwin.window.set_cursor(gdk.Cursor(gdk.WATCH))
self.mainwin.set_sensitive(False)
self._runGtkmain()
def _normalCursor(self):
self.mainwin.window.set_cursor(None)
self.mainwin.set_sensitive(True)
self._runGtkmain()
def doRefresh(self, *args):
pbar = PirutProgressCallback(_("Retrieving update information"),
self.mainwin, self.log, num_tasks = 2)
pbar.show()
self._busyCursor()
try:
self.reposSetup(pbar)
except yum.Errors.LockError:
pbar.destroy()
self._normalCursor()
d = gtk.MessageDialog(self.mainwin, gtk.DIALOG_MODAL,
gtk.MESSAGE_ERROR, gtk.BUTTONS_OK,
_("Another application is running which "
"is accessing software information."))
d.show_all()
d.run()
d.destroy()
sys.exit(1)
except PirutDownloadError, e:
pbar.destroy()
self._normalCursor()
d = gtk.MessageDialog(self.mainwin, gtk.DIALOG_MODAL,
gtk.MESSAGE_ERROR, gtk.BUTTONS_OK,
_("Unable to retrieve update information"))
d.format_secondary_text(_("Unable to retrieve software "
"information. This could be caused by "
"not having a network connection "
"available."))
d.show_all()
d.run()
d.destroy()
sys.exit(1)
self.doUpdateSetup()
pbar.next_task()
self.populateUpdates()
pbar.next_task()
self._normalCursor()
pbar.destroy()
def _doUpdate(self, new, old):
self.tsInfo.addUpdate(new, old)
def _doObsolete(self, new, old):
self.tsInfo.addObsoleting(new, old)
self.tsInfo.addObsoleted(old, new)
def _printUpdate(self, new, old):
return "%s updates %s" %(new, old)
def _printObsolete(self, new, old):
return "%s obsoletes %s" %(new, old)
def populateUpdates(self):
self.store.clear()
upds = {}
reboots = {}
# handle obsoletes
if hasattr(self.conf, "getConfigOption"):
opt = self.conf.getConfigOption('obsoletes')
else:
opt = self.conf.obsoletes
if opt:
obsoletes = self.up.getObsoletesTuples(newest=1)
else:
obsoletes = []
for (obs, inst) in obsoletes:
obsoleting = self.getPackageObject(obs)
installed = YumInstalledPackage(self.rpmdb.returnHeaderByTuple(inst)[0])
srpm = obsoleting.returnSimple("sourcerpm")
if upds.has_key(srpm):
upds[srpm].append( (self._doObsolete, self._printObsolete,
obsoleting, installed) )
else:
upds[srpm] = [ (self._doObsolete, self._printObsolete,
obsoleting, installed) ]
reboots[srpm] = False
if obsoleting.returnSimple("name") in rebootpkgs:
reboots[srpm] = True
# and updates
updates = self.up.getUpdatesTuples()
for (new, old) in updates:
updating = self.getPackageObject(new)
updated = YumInstalledPackage(self.rpmdb.returnHeaderByTuple(old)[0])
srpm = updating.returnSimple("sourcerpm")
if upds.has_key(srpm):
upds[srpm].append( (self._doUpdate, self._printUpdate,
updating, updated) )
else:
upds[srpm] = [ (self._doUpdate, self._printUpdate,
updating, updated) ]
reboots[srpm] = False
if updating.returnSimple("name") in rebootpkgs:
reboots[srpm] = True
for (srpm, lst) in upds.items():
if reboots[srpm]:
pix = 'gtk-refresh'
else:
pix = None
self.store.append(None, [True,
_("Updated %s packages available")
% (rpmUtils.miscutils.splitFilename(srpm)[0],),
lst, pix])
if len(upds) == 0:
self.pupxml.get_widget("updateNotebook").set_current_page(1)
self.pupxml.get_widget("applyButton").set_sensitive(False)
def _apply(self, *args):
needReboot = False
map(lambda x: self.tsInfo.remove(x.pkgtup), self.tsInfo)
self.tsInfo.makelists()
del self.ts
self.initActionTs()
# select packages that are chosen
for row in self.store:
(on, pkgstr, lst, pix) = row
if on:
for (updfunc, strfunc, new, old) in lst:
if new.name in rebootpkgs:
needReboot = True
updfunc(new, old)
if len(self.tsInfo) <= 0:
d = gtk.MessageDialog(self.mainwin, gtk.DIALOG_MODAL,
gtk.MESSAGE_ERROR, gtk.BUTTONS_OK,
_("No packages were selected for upgrade."))
d.show_all()
d.run()
d.destroy()
return
try:
self.applyChanges(self.mainwin)
except PirutError:
return
if needReboot:
self._rebootWindow()
else:
d = gtk.MessageDialog(self.mainwin, gtk.DIALOG_MODAL,
gtk.MESSAGE_INFO, gtk.BUTTONS_OK,
_("Software update successfully completed."))
d.show_all()
d.run()
d.destroy()
# and we're done
self._quit()
def _rebootWindow(self):
def _setTimeout():
l = self.pupxml.get_widget("rebootLabel")
if self.timeleft >= 0:
l.set_text(_("Will reboot in %d seconds...") % self.timeleft)
else:
l.hide()
def _countdown():
self.timeleft -= 1
_setTimeout()
if self.timeleft == 0:
return False
return True
def _timeUp():
_reboot()
return False
def _reboot():
d.hide()
self._cleanup()
subprocess.call(["/sbin/shutdown", "-r", "now"])
sys.exit(0)
d = self.pupxml.get_widget("pupRebootDialog")
primary = self.pupxml.get_widget ("rebootPrimaryLabel")
primary.set_markup ("<span size=\"larger\" weight=\"bold\">%s</span>" % _("Reboot recommended"))
d.set_transient_for(self.mainwin)
self.timeleft = -1
_setTimeout()
d.show()
if self.timeleft >= 0:
gobject.timeout_add(1 * 1000, _countdown)
gobject.timeout_add(self.timeleft * 1000, _timeUp)
rc = d.run()
d.hide()
if rc == gtk.RESPONSE_OK:
return _reboot()
return
def run(self):
self.mainwin.show()
self._runGtkmain()
self.doRefresh()
gtk.main()
def _cleanup(self, *args):
# FIXME: should make sure we close down access to lock files and dbs
# cleanly here
try:
self.closeRpmDB()
except Exception, e:
print >> sys.stderr, "Error closing rpmdb: ", e
self.doUnlock(YUM_PID_FILE)
try:
gtk.main_quit()
except:
pass
def _quit(self, *args):
self._cleanup()
sys.exit(0)
def main():
textdomain("pirut")
gtk.glade.bindtextdomain("pirut", "/usr/share/locale")
try:
pup = PackageUpdater()
except PirutError, e:
startupError(e)
pup.run()
if __name__ == "__main__":
installExceptionHandler("Software Updater", "")
main()