diff options
author | René 'Necoro' Neumann <necoro@necoro.net> | 2008-09-02 13:01:17 +0200 |
---|---|---|
committer | René 'Necoro' Neumann <necoro@necoro.net> | 2008-09-02 13:01:17 +0200 |
commit | afa1de13f0576ace6dcbb0176490fd20922950cd (patch) | |
tree | 056a5fd646f53dfa83f2fe231ec0943747b15ffc /portato/gui | |
parent | 02d96210d9102f0cdec95b4e0f595cbd8fdd1e10 (diff) | |
download | portato-afa1de13f0576ace6dcbb0176490fd20922950cd.tar.gz portato-afa1de13f0576ace6dcbb0176490fd20922950cd.tar.bz2 portato-afa1de13f0576ace6dcbb0176490fd20922950cd.zip |
Switch from tabs to 4 spaces
Diffstat (limited to 'portato/gui')
-rw-r--r-- | portato/gui/__init__.py | 18 | ||||
-rw-r--r-- | portato/gui/dialogs.py | 134 | ||||
-rw-r--r-- | portato/gui/exception_handling.py | 196 | ||||
-rw-r--r-- | portato/gui/queue.py | 1234 | ||||
-rw-r--r-- | portato/gui/session.py | 16 | ||||
-rw-r--r-- | portato/gui/updater.py | 200 | ||||
-rw-r--r-- | portato/gui/utils.py | 530 | ||||
-rw-r--r-- | portato/gui/views.py | 214 | ||||
-rw-r--r-- | portato/gui/windows/about.py | 16 | ||||
-rw-r--r-- | portato/gui/windows/basic.py | 180 | ||||
-rw-r--r-- | portato/gui/windows/mailinfo.py | 106 | ||||
-rw-r--r-- | portato/gui/windows/main.py | 3482 | ||||
-rw-r--r-- | portato/gui/windows/plugin.py | 316 | ||||
-rw-r--r-- | portato/gui/windows/preference.py | 384 | ||||
-rw-r--r-- | portato/gui/windows/search.py | 98 | ||||
-rw-r--r-- | portato/gui/windows/splash.py | 60 | ||||
-rw-r--r-- | portato/gui/windows/update.py | 188 | ||||
-rw-r--r-- | portato/gui/wrapper.py | 622 |
18 files changed, 3997 insertions, 3997 deletions
diff --git a/portato/gui/__init__.py b/portato/gui/__init__.py index 0df890c..5bbe4c8 100644 --- a/portato/gui/__init__.py +++ b/portato/gui/__init__.py @@ -16,13 +16,13 @@ from .. import get_listener from .exception_handling import register_ex_handler def run (): - from .windows.splash import SplashScreen - s = SplashScreen(_("Loading Backend")) + from .windows.splash import SplashScreen + s = SplashScreen(_("Loading Backend")) - register_ex_handler() - s.show() - - from .windows.main import MainWindow - m = MainWindow(s) - s.hide() - m.main() + register_ex_handler() + s.show() + + from .windows.main import MainWindow + m = MainWindow(s) + s.hide() + m.main() diff --git a/portato/gui/dialogs.py b/portato/gui/dialogs.py index bf7acc7..f178d2b 100644 --- a/portato/gui/dialogs.py +++ b/portato/gui/dialogs.py @@ -14,95 +14,95 @@ import gtk from ..helper import error def mail_failure_dialog(e): - dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("Mail could not be sent")) - dialog.format_secondary_text(_("The error was: %s") % e) - ret = dialog.run() - dialog.destroy() - return ret + dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("Mail could not be sent")) + dialog.format_secondary_text(_("The error was: %s") % e) + ret = dialog.run() + dialog.destroy() + return ret def queue_not_empty_dialog(): - dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION, gtk.BUTTONS_NONE, _("Do you really want to quit?")) - dialog.format_secondary_text(_("There are some packages in the emerge queue and/or an emerge process is running.")) - dialog.add_buttons(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE) - ret = dialog.run() - dialog.destroy() - return ret + dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION, gtk.BUTTONS_NONE, _("Do you really want to quit?")) + dialog.format_secondary_text(_("There are some packages in the emerge queue and/or an emerge process is running.")) + dialog.add_buttons(gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL, gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE) + ret = dialog.run() + dialog.destroy() + return ret def io_ex_dialog (io_ex): - string = io_ex.strerror - if io_ex.filename: - string = string+": "+io_ex.filename - - error(string) - dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, string) - ret = dialog.run() - dialog.destroy() - return ret + string = io_ex.strerror + if io_ex.filename: + string = string+": "+io_ex.filename + + error(string) + dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, string) + ret = dialog.run() + dialog.destroy() + return ret def blocked_dialog (blocked, blocks): - dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("%(blocked)s is blocked by %(blocks)s.") % {"blocked":blocked, "blocks" : blocks}) - dialog.format_secondary_text(_("Please unmerge the blocking package.")) - ret = dialog.run() - dialog.destroy() - return ret + dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("%(blocked)s is blocked by %(blocks)s.") % {"blocked":blocked, "blocks" : blocks}) + dialog.format_secondary_text(_("Please unmerge the blocking package.")) + ret = dialog.run() + dialog.destroy() + return ret def not_root_dialog (): - errorMB = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("You are not root.")) - ret = errorMB.run() - errorMB.destroy() - return ret + errorMB = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_ERROR, gtk.BUTTONS_OK, _("You are not root.")) + ret = errorMB.run() + errorMB.destroy() + return ret def unmask_dialog (cpv): - dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, _("%s seems to be masked.") % cpv ) - dialog.format_secondary_text(_("Do you want to unmask it and its dependencies?")) - ret = dialog.run() - dialog.destroy() - return ret + dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, _("%s seems to be masked.") % cpv ) + dialog.format_secondary_text(_("Do you want to unmask it and its dependencies?")) + ret = dialog.run() + dialog.destroy() + return ret def nothing_found_dialog (): - dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, _("Package not found!")) - ret = dialog.run() - dialog.destroy() - return ret + dialog = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, _("Package not found!")) + ret = dialog.run() + dialog.destroy() + return ret def changed_flags_dialog (what = "flags"): - check = gtk.CheckButton(_("Do not show this dialog again.")) - hintMB = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, _("Changed %s") % what) - hintMB.format_secondary_text(_("Portato will write these changes into the appropriate files.\nPlease backup them if you think it is necessairy.")) - hintMB.vbox.add(check) - hintMB.vbox.show_all() - ret = hintMB.run() - hintMB.destroy() + check = gtk.CheckButton(_("Do not show this dialog again.")) + hintMB = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, _("Changed %s") % what) + hintMB.format_secondary_text(_("Portato will write these changes into the appropriate files.\nPlease backup them if you think it is necessairy.")) + hintMB.vbox.add(check) + hintMB.vbox.show_all() + ret = hintMB.run() + hintMB.destroy() - return ret, check.get_active() + return ret, check.get_active() def remove_deps_dialog (): - infoMB = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, _("You cannot remove dependencies. :)")) - ret = infoMB.run() - infoMB.destroy() - return ret + infoMB = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_INFO, gtk.BUTTONS_OK, _("You cannot remove dependencies. :)")) + ret = infoMB.run() + infoMB.destroy() + return ret def remove_updates_dialog(): - askMB = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, _("This is the updates queue. You cannot remove single elements.\nDo you want to clear the whole queue instead?")) - ret = askMB.run() - askMB.destroy() - return ret + askMB = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, _("This is the updates queue. You cannot remove single elements.\nDo you want to clear the whole queue instead?")) + ret = askMB.run() + askMB.destroy() + return ret def remove_queue_dialog (): - askMB = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, _("Do you really want to clear the whole queue?")) - ret = askMB.run() - askMB.destroy() - return ret + askMB = gtk.MessageDialog(None, gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION, gtk.BUTTONS_YES_NO, _("Do you really want to clear the whole queue?")) + ret = askMB.run() + askMB.destroy() + return ret def file_chooser_dialog (title, parent): - fc = gtk.FileChooserDialog(title = title, parent = parent, action = gtk.FILE_CHOOSER_ACTION_SAVE, buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)) - fc.set_do_overwrite_confirmation(True) - ret = fc.run() + fc = gtk.FileChooserDialog(title = title, parent = parent, action = gtk.FILE_CHOOSER_ACTION_SAVE, buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT, gtk.STOCK_OK, gtk.RESPONSE_ACCEPT)) + fc.set_do_overwrite_confirmation(True) + ret = fc.run() - if ret == gtk.RESPONSE_ACCEPT: - ret = fc.get_filename() - else: - ret = None + if ret == gtk.RESPONSE_ACCEPT: + ret = fc.get_filename() + else: + ret = None - fc.destroy() - return ret + fc.destroy() + return ret diff --git a/portato/gui/exception_handling.py b/portato/gui/exception_handling.py index dae95ed..df555de 100644 --- a/portato/gui/exception_handling.py +++ b/portato/gui/exception_handling.py @@ -24,108 +24,108 @@ from .windows.mailinfo import MailInfoWindow from .utils import GtkThread class UncaughtExceptionDialog(gtk.MessageDialog): - """Original idea by Gustavo Carneiro - original code: http://www.daa.com.au/pipermail/pygtk/attachments/20030828/2d304204/gtkexcepthook.py.""" - - def __init__(self, type, value, tb, thread = None): - - super(UncaughtExceptionDialog,self).__init__(parent=None, flags=0, type=gtk.MESSAGE_WARNING, buttons=gtk.BUTTONS_NONE, message_format=_("A programming error has been detected during the execution of this program.")) - self.set_title(_("Bug Detected")) - self.format_secondary_text(_("It probably isn't fatal, but should be reported to the developers nonetheless.")) - - self.add_button(_("Show Details"), 1) - self.add_button(_("Send..."), 3) - self.add_button(gtk.STOCK_SAVE_AS, 2) - self.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE) - - # Details - self.textview = gtk.TextView() - self.textview.set_editable(False) - self.textview.modify_font(pango.FontDescription("Monospace")) - - self.sw = gtk.ScrolledWindow(); - self.sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) - self.sw.add(self.textview) - - self.tbFrame = gtk.Frame() - self.tbFrame.set_shadow_type(gtk.SHADOW_IN) - self.tbFrame.add(self.sw) - self.tbFrame.set_border_width(6) - - self.vbox.add(self.tbFrame) - - textbuffer = self.textview.get_buffer() - self.text = get_trace(type, value, tb) - if thread: - self.text = _("Exception in thread \"%(thread)s\":\n%(trace)s") % {"thread": thread, "trace": self.text} - textbuffer.set_text(self.text) - self.textview.set_size_request(gtk.gdk.screen_width()/2, gtk.gdk.screen_height()/3) - - self.details = self.tbFrame - self.set_position(gtk.WIN_POS_CENTER) - self.set_gravity(gtk.gdk.GRAVITY_CENTER) - - def run (self): - while True: - resp = super(UncaughtExceptionDialog, self).run() - if resp == 1: - self.details.show_all() - self.set_response_sensitive(1, False) - elif resp == 2: - debug("Want to save") - file = file_chooser_dialog(_("Save traceback..."), self) - if file: - debug("Save to %s", file) - - try: - with open(file, "w") as f: - f.writelines(self.text) - except IOError, e: - io_ex_dialog(e) - - else: - debug("Nothing to save") - elif resp == 3: - debug("Send bug per mail") - self.destroy() - MailInfoWindow(None, self.text) - return - else: - break - self.destroy() + """Original idea by Gustavo Carneiro - original code: http://www.daa.com.au/pipermail/pygtk/attachments/20030828/2d304204/gtkexcepthook.py.""" + + def __init__(self, type, value, tb, thread = None): + + super(UncaughtExceptionDialog,self).__init__(parent=None, flags=0, type=gtk.MESSAGE_WARNING, buttons=gtk.BUTTONS_NONE, message_format=_("A programming error has been detected during the execution of this program.")) + self.set_title(_("Bug Detected")) + self.format_secondary_text(_("It probably isn't fatal, but should be reported to the developers nonetheless.")) + + self.add_button(_("Show Details"), 1) + self.add_button(_("Send..."), 3) + self.add_button(gtk.STOCK_SAVE_AS, 2) + self.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_CLOSE) + + # Details + self.textview = gtk.TextView() + self.textview.set_editable(False) + self.textview.modify_font(pango.FontDescription("Monospace")) + + self.sw = gtk.ScrolledWindow(); + self.sw.set_policy(gtk.POLICY_AUTOMATIC, gtk.POLICY_AUTOMATIC) + self.sw.add(self.textview) + + self.tbFrame = gtk.Frame() + self.tbFrame.set_shadow_type(gtk.SHADOW_IN) + self.tbFrame.add(self.sw) + self.tbFrame.set_border_width(6) + + self.vbox.add(self.tbFrame) + + textbuffer = self.textview.get_buffer() + self.text = get_trace(type, value, tb) + if thread: + self.text = _("Exception in thread \"%(thread)s\":\n%(trace)s") % {"thread": thread, "trace": self.text} + textbuffer.set_text(self.text) + self.textview.set_size_request(gtk.gdk.screen_width()/2, gtk.gdk.screen_height()/3) + + self.details = self.tbFrame + self.set_position(gtk.WIN_POS_CENTER) + self.set_gravity(gtk.gdk.GRAVITY_CENTER) + + def run (self): + while True: + resp = super(UncaughtExceptionDialog, self).run() + if resp == 1: + self.details.show_all() + self.set_response_sensitive(1, False) + elif resp == 2: + debug("Want to save") + file = file_chooser_dialog(_("Save traceback..."), self) + if file: + debug("Save to %s", file) + + try: + with open(file, "w") as f: + f.writelines(self.text) + except IOError, e: + io_ex_dialog(e) + + else: + debug("Nothing to save") + elif resp == 3: + debug("Send bug per mail") + self.destroy() + MailInfoWindow(None, self.text) + return + else: + break + self.destroy() def convert (version): - """Converts a version given as int-tuple to a normal version string.""" - return ".".join(map(str, version)) + """Converts a version given as int-tuple to a normal version string.""" + return ".".join(map(str, version)) def get_version_infos(): - from ..constants import VERSION - from ..backend import system - - return "\n".join(( - "Portato version: %s" % VERSION, - "Python version: %s" % sys.version, - "Used backend: %s" % system.get_version(), - "pygtk: %s (using GTK+: %s)" % (convert(gtk.pygtk_version), convert(gtk.gtk_version)), - "pygobject: %s (using GLib: %s)" % (convert(gobject.pygobject_version), convert(gobject.glib_version)))) + from ..constants import VERSION + from ..backend import system + + return "\n".join(( + "Portato version: %s" % VERSION, + "Python version: %s" % sys.version, + "Used backend: %s" % system.get_version(), + "pygtk: %s (using GTK+: %s)" % (convert(gtk.pygtk_version), convert(gtk.gtk_version)), + "pygobject: %s (using GLib: %s)" % (convert(gobject.pygobject_version), convert(gobject.glib_version)))) def get_trace(type, value, tb): - trace = StringIO() - traceback.print_exception(type, value, tb, None, trace) - traceStr = trace.getvalue() - trace.close() - return traceStr + "\n" + get_version_infos() - + trace = StringIO() + traceback.print_exception(type, value, tb, None, trace) + traceStr = trace.getvalue() + trace.close() + return traceStr + "\n" + get_version_infos() + def register_ex_handler(): - - def handler(type, val, tb, thread = None): - def run_dialog(): - UncaughtExceptionDialog(type, val, tb, thread).run() - - if thread: - error(_("Exception in thread \"%(thread)s\":\n%(trace)s"), {"thread": thread, "trace": get_trace(type, val, tb)}) - else: - error(_("Exception:\n%s"), get_trace(type, val, tb)) - - gobject.idle_add(run_dialog) - - sys.excepthook = handler + + def handler(type, val, tb, thread = None): + def run_dialog(): + UncaughtExceptionDialog(type, val, tb, thread).run() + + if thread: + error(_("Exception in thread \"%(thread)s\":\n%(trace)s"), {"thread": thread, "trace": get_trace(type, val, tb)}) + else: + error(_("Exception:\n%s"), get_trace(type, val, tb)) + + gobject.idle_add(run_dialog) + + sys.excepthook = handler diff --git a/portato/gui/queue.py b/portato/gui/queue.py index b5fb736..5ff600f 100644 --- a/portato/gui/queue.py +++ b/portato/gui/queue.py @@ -31,620 +31,620 @@ from .updater import Updater from .wrapper import GtkConsole, GtkTree class EmergeQueue: - """This class manages the emerge queue.""" - - def __init__ (self, tree = None, console = None, db = None, title_update = None, threadClass = threading.Thread): - """Constructor. - - @param tree: Tree to append all the items to. - @type tree: GtkTree - @param console: Output is shown here. - @type console: GtkConsole - @param db: A database instance. - @type db: Database - @param title_update: A function, which will be called whenever there is a title update. - @type title_update: function(string)""" - - # the different queues - self.mergequeue = [] # for emerge - self.unmergequeue = [] # for emerge -C - self.oneshotmerge = [] # for emerge --oneshot - - # the emerge process - self.process = None - self.threadQueue = WaitingQueue(threadClass = threadClass) - self.pty = None - - # dictionaries with data about the packages in the queue - self.iters = {"install" : {}, "uninstall" : {}, "update" : {}} # iterator in the tree - self.deps = {"install" : {}, "update" : {}} # all the deps of the package - self.blocks = {"install" : OrderedDict(), "update" : OrderedDict()} - - # member vars - self.tree = tree - if self.tree and not isinstance(self.tree, GtkTree): raise TypeError, "tree passed is not a GtkTree-object" - - self.console = console - if self.console and not isinstance(self.console, GtkConsole): raise TypeError, "console passed is not a GtkConsole-object" - - self.db = db - self.title_update = title_update - self.threadClass = threadClass - - if self.console: - self.pty = pty.openpty() - self.console.set_pty(self.pty[0]) - - def _get_pkg_from_cpv (self, cpv, unmask = False): - """Gets a L{backend.Package}-object from a cpv. - - @param cpv: the cpv to get the package for - @type cpv: string (cpv) - @param unmask: if True we will look for masked packages if we cannot find unmasked ones - @type unmask: boolean - @return: created package - @rtype: backend.Package - - @raises backend.PackageNotFoundException: If no package could be found - normally it is existing but masked.""" - - # for the beginning: let us create a package object - but it is not guaranteed, that it actually exists in portage - pkg = system.new_package(cpv) - masked = not (pkg.is_masked() or pkg.is_testing(use_keywords=True)) # we are setting this to True in case we have unmasked it already, but portage does not know this - - # and now try to find it in portage - pkg = system.find_packages("="+cpv, masked = masked) - - if pkg: # gotcha - pkg = pkg[0] - - elif unmask: # no pkg returned, but we are allowed to unmask it - pkg = system.find_packages("="+cpv, masked = True) - - if not pkg: - raise backend.PackageNotFoundException(cpv) # also not found - else: - pkg = pkg[0] - - if pkg.is_testing(use_keywords = True): - pkg.set_testing(True) - if pkg.is_masked(): - pkg.set_masked() - - else: # no pkg returned - and we are not allowed to unmask - raise backend.PackageNotFoundException(cpv) - - return pkg - - def update_tree (self, it, cpv, unmask = False, oneshot = False, type = "install"): - """This updates the tree recursivly, or? Isn't it? Bjorn! - - @param it: iterator where to append - @type it: Iterator - @param cpv: The package to append. - @type cpv: string (cat/pkg-ver) - @param unmask: True if we are allowed to look for masked packages - @type unmask: boolean - @param oneshot: True if we want to emerge is oneshot - @type oneshot: boolean - @param type: the type of the updating - @type type: string - - @raises backend.BlockedException: When occured during dependency-calculation. - @raises backend.PackageNotFoundException: If no package could be found - normally it is existing but masked.""" - - if cpv in self.deps[type]: - return # in list already and therefore it's already in the tree too - - # try to find an already installed instance - update = False - downgrade = False - uVersion = None - changedUse = [] - try: - pkg = self._get_pkg_from_cpv(cpv, unmask) - if not pkg.is_installed(): - old = system.find_packages(pkg.get_slot_cp(), system.SET_INSTALLED) - if old: - old = old[0] # assume we have only one there - cmp = pkg.compare_version(old) - if cmp > 0: - update = True - elif cmp < 0: - downgrade = True - - uVersion = old.get_version() - - old_iuse = set(old.get_iuse_flags()) - new_iuse = set(pkg.get_iuse_flags()) - - for i in old_iuse.difference(new_iuse): - changedUse.append("-"+i) - - for i in new_iuse.difference(old_iuse): - changedUse.append("+"+i) - else: - old_iuse = set(pkg.get_iuse_flags(installed = True)) - new_iuse = set(pkg.get_iuse_flags(installed = False)) - - for i in old_iuse.difference(new_iuse): - changedUse.append("-"+i) - - for i in new_iuse.difference(old_iuse): - changedUse.append("+"+i) - - except backend.PackageNotFoundException, e: # package not found / package is masked -> delete current tree and re-raise the exception - if type == "update": # remove complete tree - self.remove_with_children(self.tree.first_iter(it), removeNewFlags = False) - - elif type == "install": # remove only the intentionally added package - top = self.tree.first_iter(it) - parent = self.tree.parent_iter(it) - - if parent: - while not self.tree.iter_equal(top, parent): - parent = self.tree.parent_iter(parent) - it = self.tree.parent_iter(it) - - self.remove_with_children(it, removeNewFlags = False) - - if not self.tree.iter_has_children(top): # remove completely if nothing left - self.remove(top) - raise - - # add iter - subIt = self.tree.append(it, self.tree.build_append_value(cpv, oneshot = oneshot, update = update, downgrade = downgrade, version = uVersion, useChange = changedUse)) - self.iters[type][cpv] = subIt - - # get dependencies - deps = pkg.get_dep_packages(return_blocks = True) - self.deps[type][cpv] = deps - - for d in deps: - if d[0] == "!": # block - dep = d[1:] - if not dep in self.blocks[type]: - self.blocks[type][dep] = set() - - self.blocks[type][dep].add(cpv) - else: # recursive call - self.update_tree(subIt, d, unmask, type = type) - - def append (self, cpv, type = "install", update = False, forceUpdate = False, unmask = False, oneshot = False): - """Appends a cpv either to the merge queue or to the unmerge-queue. - Also updates the tree-view. - - @param cpv: Package to add - @type cpv: string (cat/pkg-ver) - @param type: The type of this append process. Possible values are "install", "uninstall", "update". - @type type: string - @param update: Set to True if a package is going to be updated (e.g. if the use-flags changed). - @type update: boolean - @param forceUpdate: Set to True if the update should be forced. - @type forceUpdate: boolean - @param unmask: True if we are allowed to look for masked packages - @type unmask: boolean - @param oneshot: True if this package should not be added to the world-file. - @type oneshot: boolean - - @raises portato.backend.PackageNotFoundException: if trying to add a package which does not exist""" - - if type in ("install", "update"): # emerge - if update: - pkg = self._get_pkg_from_cpv(cpv, unmask) - deps = pkg.get_dep_packages(return_blocks = True) - - if not forceUpdate and cpv in self.deps[type] and deps == self.deps[type][cpv]: - return # nothing changed - return - else: - hasBeenInQueue = (cpv in self.mergequeue or cpv in self.oneshotmerge) - parentIt = self.tree.parent_iter(self.iters[type][cpv]) - - # delete it out of the tree - but NOT the changed flags - self.remove_with_children(self.iters[type][cpv], removeNewFlags = False) - - if hasBeenInQueue: # package has been in queue before - self._queue_append(cpv, oneshot) - - self.update_tree(parentIt, cpv, unmask, oneshot = oneshot, type = type) - else: # not update - if type == "install": - if self.tree: - self.update_tree(self.tree.get_emerge_it(), cpv, unmask, type = type, oneshot = oneshot) - self._queue_append(cpv, oneshot) - elif type == "update" and self.tree: - self.update_tree(self.tree.get_update_it(), cpv, unmask, type = type, oneshot = oneshot) - - # handle blocks - if self.blocks[type]: - # check whether anything blocks something in the queue - for block in self.blocks[type]: - for c in self.iters[type]: - if system.cpv_matches(c, block): - blocked = ", ".join(self.blocks[type][block]) - warning("'%s' is blocked by: %s", c, blocked) - self.remove_with_children(self.iters[type][c], False) - raise BlockedException(c, blocked) - - # - # check whether we block a version that we are going to replace nevertheless - # - - # get the blocks that block an installed package - inst = [] - for block in self.blocks[type]: - pkgs = system.find_packages(block, system.SET_INSTALLED) - if pkgs: - inst.append((pkgs, block)) - - # the slot-cp's of the packages in the queue - slots = {} - for c in self.iters[type]: - slots[system.new_package(c).get_slot_cp()] = cpv - - # check the installed blocks against the slot-cp's - for pkgs, block in inst[:]: - done = False - for pkg in pkgs: - done = False - if pkg.get_slot_cp() in slots: - debug("Block '%s' can be ignored, because the blocking package is going to be replaced with '%s'.", block, slots[pkg.get_slot_cp()]) - done = True - if done: - inst.remove((pkgs,block)) - - if inst: # there is still something left to block - for pkgs, block in inst: - blocked = ", ".join(self.blocks[type][block]) - warning("'%s' blocks the installation of: %s", pkgs[0].get_cpv(), blocked) - self.remove_with_children(self.iters[type][cpv], False) - raise BlockedException(blocked, pkgs[0].get_cpv()) - - else: # unmerge - self.unmergequeue.append(cpv) - if self.tree: # update tree - self.iters["uninstall"].update({cpv: self.tree.append(self.tree.get_unmerge_it(), self.tree.build_append_value(cpv))}) - - def _queue_append (self, cpv, oneshot = False): - """Convenience function appending a cpv either to self.mergequeue or to self.oneshotmerge. - - @param cpv: cpv to add - @type cpv: string (cpv) - @param oneshot: True if this package should not be added to the world-file. - @type oneshot: boolean""" - - if not oneshot: - if cpv not in self.mergequeue: - self.mergequeue.append(cpv) - else: - if cpv not in self.oneshotmerge: - self.oneshotmerge.append(cpv) - - def doEmerge (self, options, packages, it, *args, **kwargs): - top = None - if self.tree and it: - for v in it.itervalues(): - self.tree.set_in_progress(v) - top = self.tree.first_iter(v) - break - - self.threadQueue.put(self.__emerge, options, packages, it, top, *args, **kwargs) - - def __emerge (self, options, packages, it, top, command = None): - """Calls emerge and updates the terminal. - - @param options: options to send to emerge - @type options: string[] - @param packages: packages to emerge - @type packages: string[] - @param it: Iterators which point to these entries whose children will be removed after completion. - @type it: dict(string -> Iterator) - @param top: The top iterator - @type top: Iterator - @param command: the command to execute - default is "/usr/bin/python /usr/bin/emerge" - @type command: string[]""" - - @plugin.hook("emerge", packages = packages, command = command, console = self.console, title_update = self.title_update) - def sub_emerge(command): - if command is None: - command = system.get_merge_command() - - # open tty - if self.console: - self.console.reset() - - def pre (): - os.setsid() # new session - if self.console: - import fcntl, termios - fcntl.ioctl(self.pty[1], termios.TIOCSCTTY, 0) # set pty-slave as session tty - os.dup2(self.pty[1], 0) - os.dup2(self.pty[1], 1) - os.dup2(self.pty[1], 2) - - # get all categories that are being touched during the emerge process - cats = set(map(lambda x: x.split("/")[0], it.iterkeys())) - - # start emerge - self.process = Popen(command+options+packages, shell = False, env = system.get_environment(), preexec_fn = pre) - - # remove packages from queue - if self.tree and it and not self.tree.is_in_unmerge(top): - self.up = Updater(self, it, self.threadClass) - else: - self.up = None - - # update title - if self.console: - old_title = self.console.get_window_title() - while self.process and self.process.poll() is None: - if self.title_update : - title = self.console.get_window_title() - if title != old_title: - self.title_update(title) - old_title = title - time.sleep(0.5) - - if self.up: - self.up.stop() - if it: - self.tree.set_in_progress(top, False) - else: - self.remove(top) - elif self.tree and it: - self.remove_with_children(top) - - if self.title_update: self.title_update(None) - - if self.process is None: # someone resetted this - self.threadQueue.next() - return - else: - ret = self.process.returncode - self.process = None - self.threadQueue.next() - - @plugin.hook("after_emerge", packages = packages, retcode = ret) - def update_packages(): - if self.db: - for cat in cats: - self.db.reload(cat) - debug("Category %s refreshed", cat) - - update_packages() - - sub_emerge(command) - - def emerge (self, force = False, options = None): - """Emerges everything in the merge-queue. - - @param force: If False, '-pv' is send to emerge. Default: False. - @type force: boolean - @param options: Additional options to send to the emerge command - @type options: string[]""" - - def prepare(queue): - """Prepares the list of iterators and the list of packages.""" - list = [] - its = {} - for k in queue: - list += ["="+k] - if self.tree: - its.update({k : self.iters["install"][k]}) - - return list, its - - if self.tree: - ownit = self.iters["install"] - else: - ownit = {} - - # oneshot-queue - if self.oneshotmerge: - # prepare package-list for oneshot - list, its = prepare(self.oneshotmerge) - if not self.mergequeue :# the other one does not exist - remove completely - its = ownit - - s = system.get_oneshot_option() - if not force: s += system.get_pretend_option() - if options is not None: s += options - - self.doEmerge(s, list, its, caller = self.emerge) - - # normal queue - if self.mergequeue: - # prepare package-list - list, its = prepare(self.mergequeue) - if not self.oneshotmerge: # the other one does not exist - remove completely - its = ownit - - s = [] - if not force: s = system.get_pretend_option() - if options is not None: s += options - - self.doEmerge(s, list, its, caller = self.emerge) - - def unmerge (self, force = False, options = None): - """Unmerges everything in the umerge-queue. - - @param force: If False, '-pv' is send to emerge. Default: False. - @type force: boolean - @param options: Additional options to send to the emerge command - @type options: string[]""" - - if len(self.unmergequeue) == 0: return # nothing in queue - - list = self.unmergequeue[:] # copy the unmerge-queue - - # set options - s = system.get_unmerge_option() - if not force: s += system.get_pretend_option() - if options is not None: s += options - - if self.tree: - it = self.iters["uninstall"] - else: - it = {} - - self.doEmerge(s,list, it, caller = self.unmerge) - - def update_world(self, sets = ("world",), forc |