summaryrefslogtreecommitdiff
path: root/portato/gui
diff options
context:
space:
mode:
authorRené 'Necoro' Neumann <necoro@necoro.net>2008-09-02 13:01:17 +0200
committerRené 'Necoro' Neumann <necoro@necoro.net>2008-09-02 13:01:17 +0200
commitafa1de13f0576ace6dcbb0176490fd20922950cd (patch)
tree056a5fd646f53dfa83f2fe231ec0943747b15ffc /portato/gui
parent02d96210d9102f0cdec95b4e0f595cbd8fdd1e10 (diff)
downloadportato-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__.py18
-rw-r--r--portato/gui/dialogs.py134
-rw-r--r--portato/gui/exception_handling.py196
-rw-r--r--portato/gui/queue.py1234
-rw-r--r--portato/gui/session.py16
-rw-r--r--portato/gui/updater.py200
-rw-r--r--portato/gui/utils.py530
-rw-r--r--portato/gui/views.py214
-rw-r--r--portato/gui/windows/about.py16
-rw-r--r--portato/gui/windows/basic.py180
-rw-r--r--portato/gui/windows/mailinfo.py106
-rw-r--r--portato/gui/windows/main.py3482
-rw-r--r--portato/gui/windows/plugin.py316
-rw-r--r--portato/gui/windows/preference.py384
-rw-r--r--portato/gui/windows/search.py98
-rw-r--r--portato/gui/windows/splash.py60
-rw-r--r--portato/gui/windows/update.py188
-rw-r--r--portato/gui/wrapper.py622
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