Commits

Moises Henriquez  committed 5aca1ae

Implementing uninstall functions and error reporting. Merged dialog.py widgets into message.py

  • Participants
  • Parent commits aec4c7f

Comments (0)

Files changed (5)

 from utils import repository
 from utils import vl
 from view import widgets
-from view import dialog
 from view import message
 import os
 import tempfile as tmp
     """ Top-level window for the vectorlinux multimedia
     add-on"""
     def _get_menubar(self):
+        """ returns the main menu bar used in the top-level window"""
         mb = gtk.MenuBar()
         filemenu = gtk.Menu()
         filem = gtk.MenuItem('_%s'% _('File'))
         filem.set_submenu(filemenu)
-        exit = gtk.MenuItem('_%s'% _('Exit'))
-        exit.connect('activate', self.exit)
-        filemenu.append(exit)
 
+        agr = gtk.AccelGroup()
+        self.add_accel_group(agr)
+        mquit = gtk.ImageMenuItem(gtk.STOCK_QUIT, agr)
+        key, mod = gtk.accelerator_parse("Q")
+        mquit.add_accelerator('activate', agr, key,
+                mod, gtk.ACCEL_VISIBLE)
+        mquit.connect('activate', self.exit)
+        filemenu.append(mquit)
         mb.append(filem)
-
         return mb
 
     def __init__(self):
         self.set_title(_('Vectorlinux Multimedia Bonus Disc'))
         self.connect('destroy', self.exit)
         self.set_position(gtk.WIN_POS_CENTER)
+        wicon = self.render_icon(gtk.STOCK_CDROM, gtk.ICON_SIZE_MENU)
+        self.set_icon(wicon)
 
         body = gtk.VBox()
         menu = self._get_menubar()
 
         pane = gtk.HPaned()
         pane.set_position(150)
-        body.pack_start(pane, True, True, 0)
+        body.pack_start(pane, True, True, 2)
         self.body = body
 
         # Create temporary slapt-getrc
         app_display = widgets.FancyAppList()
         self.display = app_display
         scrolled.add(app_display)
-        rpane.pack_start(scrolled, True, True, 0)
-        cache = vl.PackageCache()
+        rpane.pack_start(scrolled, True, True, 2)
+        cache = vl.PackageManager().cache
 
         lpane = widgets.CategoryPanel(
                 app_pool,
         lpane.add_category(icon = 'data/icons/Other.png',
                 label = _('Bonus'), overlay = False)
         lpane.add_category(icon = 'data/icons/applications-other.png',
-                label = _('Installed Only'),
+                label = _('Show Installed'),
                 overlay = True)
         self.categoriespanel = lpane
-        vpanel = gtk.VBox()
-        vpanel.pack_start(lpane, True, True, 0)
+#        vpanel = gtk.VBox()
+#        vpanel.pack_start(lpane, True, True, 0)
 
-        pane.pack1(vpanel)
+        pane.pack1(self.categoriespanel)
         pane.pack2(rpane)
         self._catpanel = lpane
         bottombar = gtk.HBox()
         bottombar.pack_end(btInstallSelected, False, False, 2)
 
         self.statusbar = gtk.Statusbar()
-        body.pack_start(self.statusbar, False, False, 0)
+        body.pack_start(self.statusbar, False, False, 2)
 
         self.resize(600, 400)
         self._stop_monitor = False
                     len(model), _('items displayed')))
                 self.actionbtn.set_property('sensitive', False)
                 gtk.gdk.threads_leave()
-            if self.categoriespanel._get_selected() == _('Installed Only'):
+            if self.categoriespanel._get_selected() == _('Show Installed'):
                 gtk.gdk.threads_enter()
                 self.actionbtn.set_property('label', _('Uninstall Selected'))
                 self.actionbtn.set_image(rimg)
 
     def install_btn_event(self, widget):
         todo = self._do_get_selected_items()
-        if self.categoriespanel._get_selected() == _('Installed Only'):
-            #        if widget.get_label() in (_('Installed Only')):
-            #           if _('Installed') in widget.get_label():
-            dia = message.Error(parent = self,
-                    text = _('Uninstall function not yet implemented'))
+        if _('Installed') in self.categoriespanel._get_selected():
+            dia = message.UninstallDialog(parent = self, pkglist = todo,
+                    categories = self.categoriespanel,
+                    view = self.display)
         else:
-            dia = dialog.InstallWindow(
-                    parent = self,
-                    pkglist = todo,
-                    slaptconfig = self.slaptgetrc)
+           dia = message.InstallDialog(parent = self, pkglist = todo, 
+                    slaptconfig = self.slaptgetrc.name, 
+                    categories = self.categoriespanel,
+                    view = self.display)
         if dia.run():
             self.body.set_property('sensitive', False)
+            self.categoriespanel.refresh_view()
             dia.destroy()
-#        gtk.gdk.threads_enter()
+
         self.body.set_property('sensitive', True)
-        self.categoriespanel.cache = vl.PackageCache()
-        self.categoriespanel.refresh_view()
+#        self.categoriespanel.cache = vl.PackageCache()
+#        self.categoriespanel.refresh_view()
         self.selbtn.set_property('label', _('Select All'))
-#        gtk.gdk.threads_leave()
 
     def _do_get_selected_items(self):
         ret = []
 import os
 import subprocess as sp
 
-try:
-    from ..view import message
-except:
-    import sys
-    sys.path.append(os.path.join(os.getcwd(), '..'))
+#try:
+#    from ..view import message
+#except:
+#    import sys
+#    sys.path.append(os.path.join(os.getcwd(), '..'))
+#    from view import message
 
-from view import message
+#        from view import message
 
 _author__ = 'Moises Henriquez'
 __author_email__ = 'moc.liamg@xnl.E0M'[::-1]
             self.configfile = configfile
 
         if not os.path.exists(self.manager):
-           dia = message.Error(
-                   text = _('slapt-get not installed in the system')
-                   )
-           if dia.run():
-               dia.destroy()
-
+            # FIXME: Raise an exception here instead of this
+            print 'ERROR: slapt-get binary not found'
 
     def update_cache(self):
         proc = _get_popen(
             raise NotImplemented
         else:
             proc = _get_popen("removepkg %s"% package)
-            out = proc.communicate(), proc.returncode
-            return out
+            return proc.communicate(), proc.returncode
+#            out = proc.communicate(), proc.returncode
+#            return out
 
     def restore_package(self, pkgname):
         """

File view/dialog.py

-#!/usr/bin/env python
-
-#    This file is part of the vectorlinux multimedia bonus disc.
-#
-#    This file is free software: you can redistribute it and/or modify
-#    it under the terms of the GNU General Public License v2 as published by
-#    the Free Software Foundation.
-#
-#    This file 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 General Public License for more details.
-#
-#    You should have received a copy of the GNU General Public License
-#    along with this file.  If not, see <http://www.gnu.org/licenses/>.
-
-import gtk
-import time
-import threading
-import sys
-import os
-import message
-
-try:
-    sys.path.append(os.path.join(os.getcwd(),'..'))
-except:
-    pass
-
-try:
-    from utils import vl
-except:
-    pass
-
-
-__author__ = 'Moises Henriquez'
-__author_email__ = 'moc.liamg@xnl.E0M'[::-1]
-
-
-def _(str):
-    return str
-
-class InstallWindow(gtk.Dialog):
-    def __init__(self, parent = None, pkglist = [], slaptconfig = None):
-        gtk.Dialog.__init__(self, parent = parent)
-        self.pkglist = pkglist
-        self.set_title(_('Installing Packages'))
-        if parent is None:
-            self.set_position(gtk.WIN_POS_CENTER)
-
-        content = self.get_content_area()
-        action = self.get_action_area()
-
-        banner = gtk.Label(
-                _('Please wait while the following tasks complete')
-                )
-        self.banner = banner
-        blank = gtk.Label()
-        self.progress = gtk.ProgressBar()
-        self.status = gtk.Label()
-
-        for item in (banner, blank, self.status, self.progress):
-            content.pack_start(item, False, False, 4)
-
-        btnCancel = gtk.Button(stock = gtk.STOCK_CANCEL)
-        btnCancel.connect('clicked', self.exit)
-        self.btCancel = btnCancel
-
-        action.pack_start(btnCancel, False, False, 4)
-        self.stopbar = False
-        self.monitor = threading.Thread(target = self.move)
-        self.resize(400, 150)
-        self.current = ""
-        self.failed_installs = []
-
-        self.show_all()
-        self._icurrent = 0.0
-        self.packagemanager = vl.PackageManager(
-                configfile = slaptconfig.name)
-
-    def change_cancel_button(self):
-        """ Change the cancel button to read close, 
-        and also change its icon.
-        This is to be triggered when the install process
-        is finished successful or not"""
-        wid = self.btCancel
-        wid.set_use_stock(False)
-        img = gtk.Image()
-        img.set_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_BUTTON)
-        wid.set_property('label', _('Close'))
-        wid.set_image(img)
-        return
-
-    def run(self):
-        """ Append our start_process() method to the dialog's
-        .run method"""
-        self.start_process()
-#        return gtk.Dialog.run(self)
-
-    def start_process(self, widget = None):
-        """ Start installation process"""
-        self.stopbar = False
-        self.monitor.start()
-        ins = threading.Thread(target = self.installation, args=(self.pkglist,))
-        ins.start()
-
-
-    def installation(self, pkgs):
-        """ Installation method. This method is not to be called
-        directly, but rather inside a thread"""
-        # First, update the cache:
-        self._icurrent = -1.0
-        gtk.gdk.threads_enter()
-        self.status.set_property('label',
-                _('Updating Package Cache')
-                )
-        gtk.gdk.threads_leave()
-        i = self.packagemanager.update_cache()
-
-        # FIXME: ^^ Error checking ??? ^^
-       # ====== Brief error checking ======
-        if i[1] > 0:
-            # Something went wrong during cache update
-            # FIXME: Error out at this point or proceed? 
-            pass
-
-        self._icurrent = 0.0
-        for pkg in self.pkglist:
-            self.current = pkg
-            gtk.gdk.threads_enter()
-            self.status.set_property('label', 'Installing %s'% pkg)
-            gtk.gdk.threads_leave()
-            # FIXME: Instead of this wait time, call the slapt-get
-            # install method to install the package and process the
-            # output.
-            ret = self.packagemanager.install_package(pkg)
-
-            # === Brief Error Checking ========
-            if ret[1] > 0 or 'unmet dependencies' in ret[0][1]:
-                self.failed_installs.append((pkg, ret[0][1]))
-            self._icurrent += 1
-
-        # When done, stop the monitor thread
-        self.stopbar = True
-        # Change the cancel button to 'Close'
-        time.sleep(0.5)
-        if len(self.failed_installs) > 0:
-            dia = message.FailedPackagesDialog(
-                    self.failed_installs)
-            gtk.gdk.threads_enter()
-            if dia.run():
-                dia.destroy()
-            gtk.gdk.threads_leave()
-        else:
-            gtk.gdk.threads_enter()
-            self.change_cancel_button()
-            gtk.gdk.threads_leave()
-
-    def exit(self, widget=None):
-        """ Do a clean exit when closing the dialog
-        and returning to the main gui"""
-        self.stopbar = True
-        time.sleep(0.25)
-        self.destroy()
-
-    def move(self):
-        """ Move the progressbar according to the progress made"""
-        val = 0.0
-        while not self.stopbar:
-            time.sleep(0.1)
-            gtk.gdk.threads_enter()
-            self.progress.pulse()
-            gtk.gdk.threads_leave()
-
-#            gtk.gdk.threads_enter()
-#            self.progress.pulse()
-#            gtk.threads_leave()
-#            time.sleep(0.25)
-#            time.sleep(0.125)
-#            while self._icurrent == -1.0:
-                #                gtk.gdk.threads_enter()
-#                self.progress.set_text(_('Updating Cache'))
-#                self.progress.pulse()
-#                gtk.gdk.threads_leave()
-#                time.sleep(0.25)
-#                val = float(float(self._icurrent) / float(len(self.pkglist)))
-#                valstr = str(int(val) * 100)
-#                gtk.gdk.threads_enter()
-#                self.progress.pulse()
-#                self.progress.set_fraction(val)
-#                gtk.gdk.threads_leave()
-#            self.progress.set_fraction(val)
-#            gtk.gdk.threads_leave()
-#            time.sleep(0.125)
-
-        time.sleep(0.5)
-
-
-        gtk.gdk.threads_enter()
-        self.progress.set_text('%i'% (val * 100) + ' %')
-        if len(self.failed_installs) > 0:
-            self.banner.set_property('label',
-                    _('Install process complete'))
-            self.progress.set_text('')
-            self.status.set_property('label',
-                    _('WARNING: Some packages failed to install.'))
-        else:
-            self.banner.set_property('label',
-                    _('Installation complete'))
-            self.progress.set_text('100 %')
-            self.status.set_property('label',
-                    _('All packages installed successfully'))
-        time.sleep(0.125)
-        self.progress.set_fraction(1.0)
-        gtk.gdk.threads_leave()
-

File view/message.py

 import gtk
 import threading
 import time
+import os
+import sys
+try:
+    from .utils import vl
+except:
+    sys.path.append(os.path.join(os.getcwd(), '..'))
+    from utils import vl
+
+
 __author__ = 'Moises Henriquez'
 __author_email__ = 'moc.liamg@xnl.E0M'[::-1]
 
 def _(str):
     return str
 
+class UninstallDialog(gtk.Dialog):
+    """ Dialog shown when uninstalling package
+    Arguments:
+    pkglist - a list of packages to be removed.
+    parent - A gtk.Window object. Defaults to None"""
+    def __init__(self, parent = None, pkglist = [],
+            categories = None, view = None):
+        gtk.Dialog.__init__(self, parent = parent)
+        self.pkglist = pkglist
+        self.set_title(_('Uninstalling Packages'))
+        if parent is None:
+            self.set_position(gtk.WIN_POS_CENTER)
+        content = self.get_content_area()
+        action = self.get_action_area()
+        banner = gtk.Label(
+                _('Please wait while packages are being uninstalled'))
+        self.banner = banner
+        blank = gtk.Label()
+        self.progress = gtk.ProgressBar()
+        self.status = gtk.Label()
+
+        for item in (banner, blank, self.status, self.progress):
+            content.pack_start(item, False, False, 2)
+
+        btnCancel = gtk.Button(stock = gtk.STOCK_CANCEL)
+        btnCancel.connect('clicked', self.exit)
+        self.btnCancel = btnCancel
+
+        action.pack_start(btnCancel, False, False, 2)
+        self.stopbar = False
+        self.monitor = threading.Thread(target = self._pulse_bar)
+        self.resize(400, 150)
+        self.current = ""
+        self.failed = []
+
+        self._icurrent = 0.0
+        self.pkgmanager = vl.PackageManager()
+        self._catpanel = categories
+        self._view = view
+
+        self.show_all()
+
+    def exit(self, widget = None):
+        self.stopbar = True
+        self._catpanel.refresh_view()
+        return self.destroy()
+
+    def _pulse_bar(self):
+        val = 0.0
+        while not self.stopbar:
+            time.sleep(0.1)
+            gtk.gdk.threads_enter()
+            self.progress.pulse()
+            gtk.gdk.threads_leave()
+
+        # After the bar is done moving.
+
+        time.sleep(0.5)
+        self._show_postproc_labels()
+
+    def _show_postproc_labels(self):
+        if len(self.failed) > 0:
+            state = _('WARNING: Some packages failed to uninstall')
+        else:
+            state = _('The selected packages have been successfully removed')
+        gtk.gdk.threads_enter()
+        self.status.set_property('label', state)
+        self.progress.set_fraction(1.0)
+        gtk.gdk.threads_leave()
+
+    def change_cancel_button(self):
+        wid = self.btnCancel
+        wid.set_use_stock(False)
+        img = gtk.Image()
+        img.set_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_BUTTON)
+        wid.set_property('label', _('Close'))
+        wid.set_image(img)
+        return
+
+    def run(self):
+        """ Start our custom run process rather than the original"""
+        return self._do_run()
+
+    def _do_run(self):
+        """ Actual package removal process"""
+        self.stopbar = False
+        self.monitor.start()
+        removal = threading.Thread(
+                target= self._do_remove_pkgs,
+                args  = (self.pkglist,))
+        removal.start()
+
+    def _do_remove_pkgs(self, pkgs):
+        """ This is the removal function. Not to be called
+        directly, but rather to be parsed as a target to
+        a threading object"""
+        self.failed = []
+
+        # Update cache first.
+        self._icurrent = -1.0
+        gtk.gdk.threads_enter()
+        self.status.set_property('label',
+                _('Updating package cache')
+                )
+        gtk.gdk.threads_leave()
+        i = self.pkgmanager.update_cache()
+        if i[1] > 0:
+            #FIXME: cache failed to update... error out here???
+            pass
+
+        self._icurrent = 0.0
+        for pkg in pkgs:
+            self.current = pkg
+            gtk.gdk.threads_enter()
+            self.status.set_property('label','%s %s'% (
+                _('Uninstalling'), pkg))
+            gtk.gdk.threads_leave()
+
+            ret = self.pkgmanager.remove_package(pkg)
+            # ==== error check ===
+            if ret[1] > 0:
+                if len(ret[0][1].strip()) == 0:
+                    msg = ret[0][0].strip()
+                else:
+                    msg = ret[0][1].strip()
+                self.failed.append((pkg, msg))
+
+            self._icurrent += 1
+
+        # When done, stop the monitor thread
+        self.stopbar = True
+
+        # Check if any packages failed to uninstall, and
+        # present the appropriate dialog message.
+        if len(self.failed) > 0:
+            ## FIXME: Add the correct failed dialog with
+            ## list.
+            dia = FailedPackagesDialog(list_reason = self.failed)
+            dia.banner.set_property('label',
+                    _('Some packages failed to uninstall.') + ' ' +\
+                    _('See details below.'))
+
+
+#            dia = Error(
+#                    text = _('Some packages failed to uninstall.'))
+        else:
+            dia = Info(
+                    text = _('The selected packages have been uninstalled'))
+        gtk.gdk.threads_enter()
+        if dia.run():
+            dia.destroy()
+        self.change_cancel_button()
+        gtk.gdk.threads_leave()
+
+class InstallDialog(UninstallDialog):
+    """ A dialog shown while installing packages
+    Arguments:
+    parent = a gtk.Window object, defaults to None
+    pkglist = a list of packages to be installed"""
+    def __init__(self, parent = None, pkglist = [], slaptconfig = None, 
+            categories = None, view = None):
+        UninstallDialog.__init__(self, parent = parent, pkglist = pkglist,
+                categories = categories,
+                view = view)
+        self.slaptconfig = slaptconfig
+        self.pkglist = pkglist
+        self.set_title(_('Install Packages'))
+        self.banner.set_property('label',
+                _('Please wait while the following operations are completed'))
+        if slaptconfig is None:
+            self.slaptconfig = '/etc/slapt-getrc'
+        else:
+            self.slaptconfig = slaptconfig
+#        self.slaptconfig = '/etc/slapt-getrc'
+
+        self.pkgmanager = vl.PackageManager(configfile = self.slaptconfig)
+
+    def _show_postproc_labels(self):
+        if len(self.failed) > 0:
+            state = _('WARNING: Some packages failed to install')
+        else:
+            state = _('All selected packages were successfully installed')
+        gtk.gdk.threads_enter()
+        self.status.set_property('label', state)
+        self.banner.set_property('label',
+                _('All operations complete'))
+        self.progress.set_fraction(1.0)
+        self.change_cancel_button()
+        gtk.gdk.threads_leave()
+
+    def _do_run(self):
+        """ Fork off the package installation process"""
+        self.stopbar = False
+        self.monitor.start()
+        inst = threading.Thread(
+                target = self._do_install_pkgs,
+                args = (self.pkglist,))
+        inst.start()
+
+    def _do_install_pkgs(self, pkgs):
+        """ This method should be started in a thread ONLY"""
+        # Update cache first.
+        self._icurrent = -1.0
+        gtk.gdk.threads_enter()
+        self.status.set_property('label', _('Updating package cache'))
+        gtk.gdk.threads_leave()
+        i = self.pkgmanager.update_cache()
+        if i[1] > 0:
+            # FIXME: Cache failed to update... Error out or continue?
+            pass
+        self._icurrent = 0.0
+        for pkg in pkgs:
+            self.current = pkg
+            gtk.gdk.threads_enter()
+            self.status.set_property('label','%s %s'% (
+                _('Installing'), pkg))
+            gtk.gdk.threads_leave()
+
+            ret = self.pkgmanager.install_package(pkg)
+
+            # error check -----
+            # WARNING: slapt-get returns 0 even when the package did not
+            # install due to missing deps.
+            if ret[1] > 0 or 'unmet dependencies' in ret[0][1]:
+                if len(ret[0][1].strip()) == 0:
+                    msg = ret[0][0].strip()
+                else:
+                    msg = ret[0][1].strip()
+                self.failed.append((pkg, msg.strip()))
+            self._icurrent += 1
+        self.stopbar = True
+        self._show_postproc_labels()
+        if len(self.failed) > 0:
+            dia = FailedPackagesDialog(self.failed)
+            gtk.gdk.threads_enter()
+            if dia.run():
+                dia.destroy()
+            self.change_cancel_button()
+            gtk.gdk.threads_leave()
+
 class FailedPackagesDialog(gtk.Dialog):
     """Dialog used to show that some packages failed to install
     """
         banner.set_property('label',
                 _('The following packages failed to install.') + '\n\n' + \
                         _('Please report this error to the developer'))
+        self.banner = banner
         bannerc.pack_start(banner, False, False, 8)
         carea.pack_start(bannerc, False, False, 0)
         scv = gtk.ScrolledWindow()

File view/widgets.py

         self.model = gtk.ListStore(gtk.gdk.Pixbuf, str, bool)
         self.set_model(self.model)
         pb = FancyPixbuf('emblem-app-installed')
-#        pb = gtk.CellRendererPixbuf()
         col = gtk.TreeViewColumn('None', pb, pixbuf = 0, overlay=2)
         col.set_fixed_width(36)
         col.set_sizing(gtk.TREE_VIEW_COLUMN_FIXED)
 
     def refresh_view(self):
         #        sel = self.get_selection().get_selected_rows()[1][0][0]
+        self.cache = vl.PackageManager().cache
+        self.view.get_model().clear()
         self.show_category(self._get_selected())
 #        self.show_category(sel)
 
         row = column.get_selection().get_selected_rows()[1][0][0]
         sel = self.model[row][1]
         self.show_category(sel)
+        self.cache = vl.PackageManager().cache
+        self.view.cache = self.cache
         return
 
     def show_category(self, category):
         model = self.view.get_model()
         model.clear()
+       # cache = vl.PackageManager().cache
 	cache = self.cache
 
         if category == _('All'):
                             app_name = app.name,
                             app_short_description = _sdesc,
                             installed_indicator = _overlay)
-        elif category == _('Installed Only'):
+        elif category == _('Show Installed'):
             for app in self.repo:
                 _overlay = cache.is_app_installed(app.name)
                 if _overlay is True:
         self.model.append([
             gtk.gdk.pixbuf_new_from_file_at_size(
                 icon, 32, 32), label, overlay])
-        #        self.model.append([Icon, label])
         return
 
 class FancyPixbuf(gtk.CellRendererPixbuf):