Example #1
0
    def __init__(self):
        # Check if script is running
        self.scriptDir = abspath(dirname(__file__))
        self.filesDir = join(self.scriptDir, "files")
        self.scriptName = basename(__file__)
        self.umglobal = UmGlobal()
        self.ec = ExecCmd()

        # Handle arguments
        parser = argparse.ArgumentParser(
            description='Trail Update Manager Tray')
        parser.add_argument('-r', '--reload', action="store_true", help='')
        args, extra = parser.parse_known_args()

        print((">> args = {}".format(args)))
        if args.reload:
            pids = self.umglobal.getScriptPids("updatemanagertray.py")
            if len(pids) > 1:
                print(("updatemanagertray.py already running - kill pid {}".
                       format(pids[0])))
                os.system("kill {}".format(pids[0]))

        # Build status icon menu
        self.refreshText = _("Refresh")
        self.quitText = _("Quit")
        menu = Gtk.Menu()
        menuUm = Gtk.MenuItem(_("Update Manager"))
        menuUm.connect('activate', self.open_um)
        menu.append(menuUm)
        # Separator not functioning in wheezy
        #menuSep1 = Gtk.SeparatorMenuItem()
        #menu.append(menuSep1)
        menuPref = Gtk.MenuItem(_("Preferences"))
        menuPref.connect('activate', self.open_preferences)
        menu.append(menuPref)
        menuRefresh = Gtk.MenuItem(self.refreshText)
        menuRefresh.connect('activate', self.manualRefresh)
        menu.append(menuRefresh)
        menuQuit = Gtk.MenuItem(self.quitText)
        menuQuit.connect('activate', self.quit_tray)
        menu.append(menuQuit)

        self.statusIcon = Gtk.StatusIcon()
        self.umrefresh = UmRefresh(self.statusIcon, self.umglobal)
        self.notifier = UmNotifier(self.statusIcon, self.umglobal,
                                   self.umrefresh)

        self.statusIcon.connect('activate', self.icon_activate)
        self.statusIcon.connect('popup-menu', self.popup_menu, menu)

        # Initiate first check
        self.refresh()

        # Loop the refresh function
        # For some reason you cannot start a threaded class from init
        self.timeout = int(self.umglobal.settings["hrs-check-status"] * 60 *
                           60)
        GObject.timeout_add_seconds(self.timeout, self.refresh)
    def __init__(self):
        # Check if script is running
        self.scriptDir = abspath(dirname(__file__))
        self.filesDir = join(self.scriptDir, "files")
        self.scriptName = basename(__file__)
        self.umglobal = UmGlobal()
        self.ec = ExecCmd()

        # Handle arguments
        parser = argparse.ArgumentParser(description='Trail Update Manager Tray')
        parser.add_argument('-r','--reload', action="store_true", help='')
        args, extra = parser.parse_known_args()

        print((">> args = {}".format(args)))
        if args.reload:
            pids = self.umglobal.getScriptPids("updatemanagertray.py")
            if len(pids) > 1:
                print(("updatemanagertray.py already running - kill pid {}".format(pids[0])))
                os.system("kill {}".format(pids[0]))

        # Build status icon menu
        self.refreshText = _("Refresh")
        self.quitText = _("Quit")
        menu = Gtk.Menu()
        menuUm = Gtk.MenuItem(_("Update Manager"))
        menuUm.connect('activate', self.open_um)
        menu.append(menuUm)
        # Separator not functioning in wheezy
        #menuSep1 = Gtk.SeparatorMenuItem()
        #menu.append(menuSep1)
        menuPref = Gtk.MenuItem(_("Preferences"))
        menuPref.connect('activate', self.open_preferences)
        menu.append(menuPref)
        menuRefresh = Gtk.MenuItem(self.refreshText)
        menuRefresh.connect('activate', self.manualRefresh)
        menu.append(menuRefresh)
        menuQuit = Gtk.MenuItem(self.quitText)
        menuQuit.connect('activate', self.quit_tray)
        menu.append(menuQuit)

        self.statusIcon = Gtk.StatusIcon()
        self.umrefresh = UmRefresh(self.statusIcon, self.umglobal)
        self.notifier = UmNotifier(self.statusIcon, self.umglobal, self.umrefresh)

        self.statusIcon.connect('activate', self.icon_activate)
        self.statusIcon.connect('popup-menu', self.popup_menu, menu)

        # Initiate first check
        self.refresh()

        # Loop the refresh function
        # For some reason you cannot start a threaded class from init
        self.timeout = int(self.umglobal.settings["hrs-check-status"] * 60 * 60)
        GObject.timeout_add_seconds(self.timeout, self.refresh)
Example #3
0
    def __init__(self):
        # Check if script is running
        self.scriptName = basename(__file__)
        self.umglobal = UmGlobal()

        # Handle arguments
        parser = argparse.ArgumentParser(
            description='SolydXK Update Manager Preferences')
        parser.add_argument('-r', '--reload', action="store_true", help='')
        args, extra = parser.parse_known_args()

        print(("args = {}".format(args)))
        if args.reload:
            pids = self.umglobal.getProcessPids("updatemanagerpref.py")
            if len(pids) > 1:
                print(("updatemanagerpref.py already running - kill pid {}".
                       format(pids[0])))
                os.system("kill {}".format(pids[0]))

        # Initiate logging
        self.logFile = join('/var/log', self.umglobal.settings['log'])
        self.log = Logger(self.logFile)

        # Load window and widgets
        self.builder = Gtk.Builder()
        self.builder.add_from_file(
            join(self.umglobal.shareDir, 'updatemanagerpref.glade'))

        # Preferences window objects
        go = self.builder.get_object
        self.window = go("windowPref")
        self.nbPref = go('nbPref')
        self.btnSaveMirrors = go('btnSaveMirrors')
        self.btnCheckMirrorsSpeed = go("btnCheckMirrorsSpeed")
        self.lblMirrors = go('lblMirrors')
        self.tvMirrors = go("tvMirrors")
        self.btnRemoveBlackList = go("btnRemoveBlacklist")
        self.btnAddBlackList = go("btnAddBlacklist")
        self.tvBlacklist = go("tvBlacklist")
        self.tvAvailable = go("tvAvailable")
        self.lblGeneral = go("lblGeneral")
        self.btnSaveGeneral = go("btnSaveGeneral")
        self.chkHideMaintenance = go("chkHideMaintenance")
        self.chkAutostart = go("chkAutostart")

        # GUI translations
        self.window.set_title(_("Update Manager Preferences"))
        self.btnSaveMirrors.set_label(_("Save mirrors"))
        self.btnCheckMirrorsSpeed.set_label(_("Check mirrors speed"))
        self.btnRemoveBlackList.set_label(_("Remove"))
        self.btnAddBlackList.set_label(_("Blacklist"))
        self.lblMirrors.set_label(_("Repository mirrors"))
        self.lblGeneral.set_label(_("General"))
        go("lblHideMaintenance").set_label(_("Hide maintenance"))
        go("lblBlacklist").set_label(_("Blacklisted packages"))
        go("lblMirrorsText").set_label(_("Select the fastest repository"))
        go("lblBlacklistText").set_label(_("Blacklisted packages"))
        go("lblAvailableText").set_label(_("Available packages"))
        go("lblGlobalSettings").set_label(_("Global settings"))

        # Initiate the treeview handler and connect the custom toggle event with on_tvMirrors_toggle
        self.tvMirrorsHandler = TreeViewHandler(self.tvMirrors)
        self.tvMirrorsHandler.connect('checkbox-toggled',
                                      self.on_tvMirrors_toggle)

        self.tvBlacklistHandler = TreeViewHandler(self.tvBlacklist)
        self.tvAvailableHandler = TreeViewHandler(self.tvAvailable)

        # Initialize
        self.ec = ExecCmd(loggerObject=self.log)
        self.queue = Queue()
        self.excludeMirrors = ['security', 'community']
        self.activeMirrors = self.umglobal.getMirrorData(
            excludeMirrors=self.excludeMirrors)
        self.deadMirrors = self.umglobal.getMirrorData(getDeadMirrors=True)
        self.mirrors = self.getMirrors()
        self.threads = {}
        self.blacklist = []
        self.available = []

        self.fillGeneralSettings()
        self.fillTreeViewMirrors()
        self.fillTreeViewBlackList()
        self.fillTreeViewAvailable()

        # Connect the signals and show the window
        self.builder.connect_signals(self)
        self.window.show()
Example #4
0
class UpdateManagerPref(object):
    def __init__(self):
        # Check if script is running
        self.scriptName = basename(__file__)
        self.umglobal = UmGlobal()

        # Handle arguments
        parser = argparse.ArgumentParser(
            description='SolydXK Update Manager Preferences')
        parser.add_argument('-r', '--reload', action="store_true", help='')
        args, extra = parser.parse_known_args()

        print(("args = {}".format(args)))
        if args.reload:
            pids = self.umglobal.getProcessPids("updatemanagerpref.py")
            if len(pids) > 1:
                print(("updatemanagerpref.py already running - kill pid {}".
                       format(pids[0])))
                os.system("kill {}".format(pids[0]))

        # Initiate logging
        self.logFile = join('/var/log', self.umglobal.settings['log'])
        self.log = Logger(self.logFile)

        # Load window and widgets
        self.builder = Gtk.Builder()
        self.builder.add_from_file(
            join(self.umglobal.shareDir, 'updatemanagerpref.glade'))

        # Preferences window objects
        go = self.builder.get_object
        self.window = go("windowPref")
        self.nbPref = go('nbPref')
        self.btnSaveMirrors = go('btnSaveMirrors')
        self.btnCheckMirrorsSpeed = go("btnCheckMirrorsSpeed")
        self.lblMirrors = go('lblMirrors')
        self.tvMirrors = go("tvMirrors")
        self.btnRemoveBlackList = go("btnRemoveBlacklist")
        self.btnAddBlackList = go("btnAddBlacklist")
        self.tvBlacklist = go("tvBlacklist")
        self.tvAvailable = go("tvAvailable")
        self.lblGeneral = go("lblGeneral")
        self.btnSaveGeneral = go("btnSaveGeneral")
        self.chkHideMaintenance = go("chkHideMaintenance")
        self.chkAutostart = go("chkAutostart")

        # GUI translations
        self.window.set_title(_("Update Manager Preferences"))
        self.btnSaveMirrors.set_label(_("Save mirrors"))
        self.btnCheckMirrorsSpeed.set_label(_("Check mirrors speed"))
        self.btnRemoveBlackList.set_label(_("Remove"))
        self.btnAddBlackList.set_label(_("Blacklist"))
        self.lblMirrors.set_label(_("Repository mirrors"))
        self.lblGeneral.set_label(_("General"))
        go("lblHideMaintenance").set_label(_("Hide maintenance"))
        go("lblBlacklist").set_label(_("Blacklisted packages"))
        go("lblMirrorsText").set_label(_("Select the fastest repository"))
        go("lblBlacklistText").set_label(_("Blacklisted packages"))
        go("lblAvailableText").set_label(_("Available packages"))
        go("lblGlobalSettings").set_label(_("Global settings"))

        # Initiate the treeview handler and connect the custom toggle event with on_tvMirrors_toggle
        self.tvMirrorsHandler = TreeViewHandler(self.tvMirrors)
        self.tvMirrorsHandler.connect('checkbox-toggled',
                                      self.on_tvMirrors_toggle)

        self.tvBlacklistHandler = TreeViewHandler(self.tvBlacklist)
        self.tvAvailableHandler = TreeViewHandler(self.tvAvailable)

        # Initialize
        self.ec = ExecCmd(loggerObject=self.log)
        self.queue = Queue()
        self.excludeMirrors = ['security', 'community']
        self.activeMirrors = self.umglobal.getMirrorData(
            excludeMirrors=self.excludeMirrors)
        self.deadMirrors = self.umglobal.getMirrorData(getDeadMirrors=True)
        self.mirrors = self.getMirrors()
        self.threads = {}
        self.blacklist = []
        self.available = []

        self.fillGeneralSettings()
        self.fillTreeViewMirrors()
        self.fillTreeViewBlackList()
        self.fillTreeViewAvailable()

        # Connect the signals and show the window
        self.builder.connect_signals(self)
        self.window.show()

    # ===============================================
    # Main window functions
    # ===============================================

    def on_btnSaveGeneral_clicked(self, widget):
        self.saveGeneralSettings()

    def on_btnCheckMirrorsSpeed_clicked(self, widget):
        self.checkMirrorsSpeed()

    def on_btnSaveMirrors_clicked(self, widget):
        self.saveMirrors()

    def on_btnCancel_clicked(self, widget):
        self.window.destroy()

    def on_btnRemoveBlacklist_clicked(self, widget):
        self.removeBlacklist()

    def on_btnAddBlacklist_clicked(self, widget):
        self.addBlacklist()

    # ===============================================
    # Blacklist functions
    # ===============================================

    def fillGeneralSettings(self):
        for tab in self.umglobal.settings["hide-tabs"]:
            if tab == "maintenance":
                self.chkHideMaintenance.set_active(True)
        self.chkAutostart.set_active(self.umglobal.settings["autostart"])

    def fillTreeViewBlackList(self):
        self.blacklist = []
        cmd = "env LANG=C dpkg --get-selections | grep hold$ | awk '{print $1}'"
        lst = self.ec.run(cmd, False)
        for pck in lst:
            self.blacklist.append([False, pck.strip()])
        # Fill treeview
        columnTypesList = ['bool', 'str']
        self.tvBlacklistHandler.fillTreeview(self.blacklist, columnTypesList,
                                             0, 400, False)

    def fillTreeViewAvailable(self):
        self.available = []
        cmd = "env LANG=C dpkg --get-selections | grep install$ | awk '{print $1}'"
        lst = self.ec.run(cmd, False)
        for pck in lst:
            self.available.append([False, pck.strip()])
        # Fill treeview
        columnTypesList = ['bool', 'str']
        self.tvAvailableHandler.fillTreeview(self.available, columnTypesList,
                                             0, 400, False)

    def addBlacklist(self):
        packages = self.tvAvailableHandler.getToggledValues()
        for pck in packages:
            self.log.write("Blacklist package: %s" % pck,
                           "UMPref.addBlacklist", "debug")
            cmd = "echo '%s hold' | dpkg --set-selections" % pck
            system(cmd)
        self.fillTreeViewBlackList()
        self.fillTreeViewAvailable()

    def removeBlacklist(self):
        packages = self.tvBlacklistHandler.getToggledValues()
        for pck in packages:
            self.log.write("Remove package from blacklist: %s" % pck,
                           "UMPref.removeBlacklist", "debug")
            cmd = "echo '%s install' | dpkg --set-selections" % pck
            system(cmd)
        self.fillTreeViewBlackList()
        self.fillTreeViewAvailable()

    # ===============================================
    # Mirror functions
    # ===============================================

    def fillTreeViewMirrors(self):
        # Fill mirror list
        if len(self.mirrors) > 1:
            # Fill treeview
            columnTypesList = ['bool', 'str', 'str', 'str', 'str']
            self.tvMirrorsHandler.fillTreeview(self.mirrors, columnTypesList,
                                               0, 400, True)

            # TODO - We have no mirrors: hide the tab until we do
            #self.nbPref.get_nth_page(1).set_visible(False)
        else:
            self.nbPref.get_nth_page(1).set_visible(False)

    def saveMirrors(self):
        # Safe mirror settings
        replaceRepos = []
        # Get user selected mirrors
        model = self.tvMirrors.get_model()
        itr = model.get_iter_first()
        while itr is not None:
            sel = model.get_value(itr, 0)
            if sel:
                repo = model.get_value(itr, 2)
                url = model.get_value(itr, 3)
                not_changed = ''
                # Get currently selected data
                for mirror in self.mirrors:
                    if mirror[0] and mirror[2] == repo:
                        if mirror[3] != url:
                            # Currently selected mirror
                            replaceRepos.append([mirror[3], url])
                        else:
                            not_changed = url
                        break
                if url not in replaceRepos and url not in not_changed:
                    # Append the repositoriy to the sources file
                    replaceRepos.append(['', url])
            itr = model.iter_next(itr)

        if not replaceRepos:
            # Check for dead mirrors
            model = self.tvMirrors.get_model()
            itr = model.get_iter_first()
            while itr is not None:
                sel = model.get_value(itr, 0)
                if sel:
                    repo = model.get_value(itr, 2)
                    url = model.get_value(itr, 3)
                    # Get currently selected data
                    for mirror in self.deadMirrors:
                        if mirror[1] == repo and mirror[2] != url:
                            # Currently selected mirror
                            replaceRepos.append([mirror[2], url])
                            break
                itr = model.iter_next(itr)

        if replaceRepos:
            self.btnSaveMirrors.set_sensitive(False)
            self.btnCheckMirrorsSpeed.set_sensitive(False)

            m = Mirror()
            ret = m.save(replaceRepos, self.excludeMirrors)
            if ret == '':
                self.ec.run(cmd="apt-get update",
                            outputTreeView=self.tvMirrors)
                self.umglobal.getLocalInfo()
                self.mirrors = self.getMirrors()
                self.fillTreeViewMirrors()
            else:
                self.log.write(ret, "UMPref.saveMirrors", "exception")

            self.btnSaveMirrors.set_sensitive(True)
            self.btnCheckMirrorsSpeed.set_sensitive(True)
        else:
            msg = _("There are no repositories to save.")
            MessageDialog(self.lblMirrors.get_label(), msg)

    def getMirrors(self):
        mirrors = [[
            _("Current"),
            _("Country"),
            _("Repository"),
            _("URL"),
            _("Speed")
        ]]
        for mirror in self.activeMirrors:
            if mirror:
                self.log.write("Mirror data: %s" % ' '.join(mirror),
                               "UMPref.getMirrors", "debug")
                blnCurrent = self.isUrlInSources(mirror[2])
                mirrors.append(
                    [blnCurrent, mirror[0], mirror[1], mirror[2], ''])
        return mirrors

    def isUrlInSources(self, url):
        url = "://%s" % url
        blnRet = False

        for repo in self.umglobal.repos:
            if url in repo:
                blnRet = True
                for excl in self.excludeMirrors:
                    if excl in repo:
                        blnRet = False
                        break
                break
        return blnRet

    def checkMirrorsSpeed(self):
        name = 'mirrorspeed'
        self.btnCheckMirrorsSpeed.set_sensitive(False)
        self.btnSaveMirrors.set_sensitive(False)
        t = MirrorGetSpeed(self.mirrors, self.queue, self.umglobal)
        self.threads[name] = t
        t.daemon = True
        t.start()
        self.queue.join()
        GObject.timeout_add(5, self.checkThread, name)

    def checkThread(self, name):
        if self.threads[name].is_alive():
            lst = self.queue.get()
            if lst:
                self.writeSpeed(lst[0], lst[1])
            self.queue.task_done()
            return True

        # Thread is done
        if not self.queue.empty():
            lst = self.queue.get()
            if lst:
                self.writeSpeed(lst[0], lst[1])
            self.queue.task_done()
        del self.threads[name]
        self.btnCheckMirrorsSpeed.set_sensitive(True)
        self.btnSaveMirrors.set_sensitive(True)
        return False

    def writeSpeed(self, url, speed):
        model = self.tvMirrors.get_model()
        itr = model.get_iter_first()
        while itr is not None:
            repo = model.get_value(itr, 3)
            if repo == url:
                self.log.write("Mirror speed for %s = %s" % (url, speed),
                               "UMPref.writeSpeed", "debug")
                model.set_value(itr, 4, speed)
                path = model.get_path(itr)
                self.tvMirrors.scroll_to_cell(path)
            itr = model.iter_next(itr)
        self.tvMirrors.set_model(model)
        # Repaint GUI, or the update won't show
        while Gtk.events_pending():
            Gtk.main_iteration()

    def on_tvMirrors_toggle(self, obj, path, colNr, toggleValue):
        path = int(path)
        model = self.tvMirrors.get_model()
        selectedIter = model.get_iter(path)
        selectedRepo = model.get_value(selectedIter, 2)

        rowCnt = 0
        itr = model.get_iter_first()
        while itr is not None:
            if rowCnt != path:
                repo = model.get_value(itr, 2)
                if repo == selectedRepo:
                    model[itr][0] = False
            itr = model.iter_next(itr)
            rowCnt += 1

    # ===============================================
    # General functions
    # ===============================================

    def saveGeneralSettings(self):
        lst = []
        for tab in self.umglobal.settings["hide-tabs"]:
            if tab != "maintenance":
                lst.append(tab)
        if self.chkHideMaintenance.get_active():
            lst.append("maintenance")
        if lst:
            self.umglobal.saveSettings('misc', 'hide-tabs', ",".join(lst))
        else:
            self.umglobal.saveSettings('misc', 'hide-tabs', "")

        # Automatically start updatemanager on boot
        autostart = self.chkAutostart.get_active()
        self.umglobal.settings["autostart"] = autostart
        if autostart:
            if exists(self.umglobal.autostartSourceFile) and \
               exists(self.umglobal.autostartDir):
                copy(self.umglobal.autostartSourceFile,
                     self.umglobal.autostartDir)
        elif exists(self.umglobal.autostartDestFile):
            remove(self.umglobal.autostartDestFile)

        msg = _("The new settings will take effect after UM restart.")
        MessageDialog(self.lblGeneral.get_label(), msg)

    # Close the gui
    def on_windowPref_destroy(self, widget):
        Gtk.main_quit()
Example #5
0
    def __init__(self):
        # Check if script is running
        self.scriptName = basename(__file__)
        self.umglobal = UmGlobal()
        self.ec = ExecCmd()
        self.status = AppIndicator3.IndicatorStatus

        # Load window and widgets
        self.builder = Gtk.Builder()
        self.builder.add_from_file(join(self.umglobal.shareDir, 'updatemanagerlegend.glade'))
        go = self.builder.get_object
        # Main window objects
        self.legend = go("windowLegenda")
        go("imgConnected").set_from_file(join(self.umglobal.iconsDir, self.umglobal.settings["icon-connected"]))
        go("imgDisconnected").set_from_file(join(self.umglobal.iconsDir, self.umglobal.settings["icon-disconnected"]))
        go("imgError").set_from_file(join(self.umglobal.iconsDir, self.umglobal.settings["icon-error"]))
        go("imgExecute").set_from_file(join(self.umglobal.iconsDir, self.umglobal.settings["icon-execute"]))
        go("imgUpdates").set_from_file(join(self.umglobal.iconsDir, self.umglobal.settings["icon-updates"]))
        go("imgWarning").set_from_file(join(self.umglobal.iconsDir, self.umglobal.settings["icon-warning"]))
        go("lblConnected").set_label(self.umglobal.connectedText)
        go("lblDisconnected").set_label(self.umglobal.disconnectedText)
        go("lblExecute").set_label(self.umglobal.executeText)
        self.lblError = go("lblError")
        self.lblWarning = go("lblWarning")
        self.lblUpdates = go("lblUpdates")
        self.builder.connect_signals(self)

        # Handle arguments
        parser = argparse.ArgumentParser(description='SolydXK Update Manager Tray')
        parser.add_argument('-r','--reload', action="store_true", help='')
        args, extra = parser.parse_known_args()

        #print((">> args = {}".format(args)))
        if args.reload:
            pids = self.umglobal.getProcessPids("updatemanagertray.py")
            if len(pids) > 1:
                print(("updatemanagertray.py already running - kill pid {}".format(pids[0])))
                os.system("kill {}".format(pids[0]))

        # Build status icon menu
        self.quitText = _("Quit")
        menu = Gtk.Menu()
        menuUm = Gtk.MenuItem(self.umglobal.title)
        menuUm.connect('activate', self.open_um)
        menu.append(menuUm)
        # Separator not functioning in wheezy
        menuSep1 = Gtk.SeparatorMenuItem()
        menu.append(menuSep1)
        menuQupd = Gtk.MenuItem(_("Quick Update"))
        menuQupd.connect('activate', self.quick_update)
        menu.append(menuQupd)
        menuSep2 = Gtk.SeparatorMenuItem()
        menu.append(menuSep2)
        menuPref = Gtk.MenuItem(_("Preferences"))
        menuPref.connect('activate', self.open_preferences)
        menu.append(menuPref)
        menuLegend = Gtk.MenuItem(_("Legend"))
        menuLegend.connect('activate', self.open_legend)
        menu.append(menuLegend)
        menuQuit = Gtk.MenuItem(self.quitText)
        menuQuit.connect('activate', self.quit_tray)
        menu.append(menuQuit)
        menu.show_all()

        if self.umglobal.isKf5:
            print(("> Running KDE5"))
            # Use this for KDE5
            self.indicator = AppIndicator3.Indicator.new_with_path("updatemanager",
                                                              self.umglobal.settings["icon-connected"],
                                                              AppIndicator3.IndicatorCategory.SYSTEM_SERVICES,
                                                              self.umglobal.iconsDir)
            # Title not showing in KDE4
            self.indicator.set_title("<strong>{}</strong>".format(self.umglobal.title))
            self.indicator.set_secondary_activate_target(menuUm)
            self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)
            self.indicator.set_menu(menu)
        else:
            print(("> Running KDE4"))
            # Use this for KDE4
            self.indicator = Gtk.StatusIcon()
            #self.indicator.connect('activate', self.open_um)
            self.indicator.connect('popup-menu', self.popup_menu, menu)

        self.umrefresh = UmRefresh(self.umglobal, self.indicator)
        self.notifier = UmNotifier(self.umrefresh)

        # Initiate first check
        self.refresh()
Example #6
0
class UpdateManagerTray(object):

    def __init__(self):
        # Check if script is running
        self.scriptName = basename(__file__)
        self.umglobal = UmGlobal()
        self.ec = ExecCmd()
        self.status = AppIndicator3.IndicatorStatus

        # Load window and widgets
        self.builder = Gtk.Builder()
        self.builder.add_from_file(join(self.umglobal.shareDir, 'updatemanagerlegend.glade'))
        go = self.builder.get_object
        # Main window objects
        self.legend = go("windowLegenda")
        go("imgConnected").set_from_file(join(self.umglobal.iconsDir, self.umglobal.settings["icon-connected"]))
        go("imgDisconnected").set_from_file(join(self.umglobal.iconsDir, self.umglobal.settings["icon-disconnected"]))
        go("imgError").set_from_file(join(self.umglobal.iconsDir, self.umglobal.settings["icon-error"]))
        go("imgExecute").set_from_file(join(self.umglobal.iconsDir, self.umglobal.settings["icon-execute"]))
        go("imgUpdates").set_from_file(join(self.umglobal.iconsDir, self.umglobal.settings["icon-updates"]))
        go("imgWarning").set_from_file(join(self.umglobal.iconsDir, self.umglobal.settings["icon-warning"]))
        go("lblConnected").set_label(self.umglobal.connectedText)
        go("lblDisconnected").set_label(self.umglobal.disconnectedText)
        go("lblExecute").set_label(self.umglobal.executeText)
        self.lblError = go("lblError")
        self.lblWarning = go("lblWarning")
        self.lblUpdates = go("lblUpdates")
        self.builder.connect_signals(self)

        # Handle arguments
        parser = argparse.ArgumentParser(description='SolydXK Update Manager Tray')
        parser.add_argument('-r','--reload', action="store_true", help='')
        args, extra = parser.parse_known_args()

        #print((">> args = {}".format(args)))
        if args.reload:
            pids = self.umglobal.getProcessPids("updatemanagertray.py")
            if len(pids) > 1:
                print(("updatemanagertray.py already running - kill pid {}".format(pids[0])))
                os.system("kill {}".format(pids[0]))

        # Build status icon menu
        self.quitText = _("Quit")
        menu = Gtk.Menu()
        menuUm = Gtk.MenuItem(self.umglobal.title)
        menuUm.connect('activate', self.open_um)
        menu.append(menuUm)
        # Separator not functioning in wheezy
        menuSep1 = Gtk.SeparatorMenuItem()
        menu.append(menuSep1)
        menuQupd = Gtk.MenuItem(_("Quick Update"))
        menuQupd.connect('activate', self.quick_update)
        menu.append(menuQupd)
        menuSep2 = Gtk.SeparatorMenuItem()
        menu.append(menuSep2)
        menuPref = Gtk.MenuItem(_("Preferences"))
        menuPref.connect('activate', self.open_preferences)
        menu.append(menuPref)
        menuLegend = Gtk.MenuItem(_("Legend"))
        menuLegend.connect('activate', self.open_legend)
        menu.append(menuLegend)
        menuQuit = Gtk.MenuItem(self.quitText)
        menuQuit.connect('activate', self.quit_tray)
        menu.append(menuQuit)
        menu.show_all()

        if self.umglobal.isKf5:
            print(("> Running KDE5"))
            # Use this for KDE5
            self.indicator = AppIndicator3.Indicator.new_with_path("updatemanager",
                                                              self.umglobal.settings["icon-connected"],
                                                              AppIndicator3.IndicatorCategory.SYSTEM_SERVICES,
                                                              self.umglobal.iconsDir)
            # Title not showing in KDE4
            self.indicator.set_title("<strong>{}</strong>".format(self.umglobal.title))
            self.indicator.set_secondary_activate_target(menuUm)
            self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)
            self.indicator.set_menu(menu)
        else:
            print(("> Running KDE4"))
            # Use this for KDE4
            self.indicator = Gtk.StatusIcon()
            #self.indicator.connect('activate', self.open_um)
            self.indicator.connect('popup-menu', self.popup_menu, menu)

        self.umrefresh = UmRefresh(self.umglobal, self.indicator)
        self.notifier = UmNotifier(self.umrefresh)

        # Initiate first check
        self.refresh()

    def refresh(self, widget=None):
        if not self.umglobal.isProcessRunning("updatemanager.py"):
            self.umrefresh.refresh()
        # Return True or timeout_add_seconds will only run once
        return True

    def popup_menu(self, widget, button, time, data):
        data.show_all()
        data.popup(None, None, None, None, button, time)

    def open_um(self, widget):
        if not self.umglobal.isProcessRunning("updatemanager.py"):
            # Run UM in its own thread
            pref_thread = threading.Thread(target=self.ec.run, args=("updatemanager",))
            pref_thread.setDaemon(True)
            pref_thread.start()

    def quick_update(self, widget):
        if not self.umglobal.isProcessRunning("updatemanager.py"):
            parm = ""
            if not self.umglobal.newUpd:
                # Quick update
                parm = " -q"
            # Run UM in its own thread
            pref_thread = threading.Thread(target=self.ec.run, args=("updatemanager{}".format(parm),))
            pref_thread.setDaemon(True)
            pref_thread.start()

    def open_preferences(self, widget):
        # Run preferences in its own thread
        if not self.umglobal.isProcessRunning("updatemanagerpref.py"):
            pref_thread = threading.Thread(target=self.ec.run, args=("updatemanager -p",))
            pref_thread.setDaemon(True)
            pref_thread.start()

    def quit_tray(self, widget):
        if self.umglobal.isUpgrading():
            MessageDialog(self.quitText, _("Cannot quit: upgrade in progress"))
        else:
            self.umglobal.killScriptProcess("updatemanager.py")
            self.umglobal.killScriptProcess("updatemanagerpref.py")
            self.notifier.quit()
            Gtk.main_quit()

    # Show the legend window
    def open_legend(self, widget):
        self.lblError.set_label(self.umglobal.errorText)
        self.lblUpdates.set_label(self.umglobal.updatesText)
        self.lblWarning.set_label(self.umglobal.warningText)
        self.legend.show_all()

    # Hide the legend window when mouse leaves the window
    def on_windowLegenda_leave_notify_event(self, widget, event):
        if event.detail != Gdk.NotifyType.NONLINEAR:
            return False
        self.legend.hide()
Example #7
0
import sys
sys.path.insert(1, '/usr/lib/solydxk/updatemanager')
import os
import gettext
import argparse
from time import sleep
from gi.repository import Gtk
from os.path import join, abspath, dirname, exists
from umglobal import UmGlobal
from dialogs import WarningDialog, ErrorDialog

# i18n: http://docs.python.org/2/library/gettext.html
gettext.install("updatemanager", "/usr/share/locale")
_ = gettext.gettext

umglobal = UmGlobal(False)
scriptDir = abspath(dirname(__file__))
filesDir = join(scriptDir, "files")


# Clear update history
def clearUpHistory():
    histFile = join(filesDir, "updatemanager.hist")
    resetLine = None
    if exists(histFile):
        with open(histFile, 'r') as f:
            for line in reversed(f.readlines()):
                if "upd=" in line:
                    resetLine = "upd=2000.01.01\n"
                    break
        if resetLine is not None:
Example #8
0
    def __init__(self):
        # Check if script is running
        self.scriptName = basename(__file__)
        self.umglobal = UmGlobal()
        self.ec = ExecCmd()
        self.status = AppIndicator3.IndicatorStatus

        # Load window and widgets
        self.builder = Gtk.Builder()
        self.builder.add_from_file(
            join(self.umglobal.shareDir, 'updatemanagerlegend.glade'))
        go = self.builder.get_object
        # Main window objects
        self.legend = go("windowLegenda")
        go("imgConnected").set_from_file(
            join(self.umglobal.iconsDir,
                 self.umglobal.settings["icon-connected"]))
        go("imgDisconnected").set_from_file(
            join(self.umglobal.iconsDir,
                 self.umglobal.settings["icon-disconnected"]))
        go("imgError").set_from_file(
            join(self.umglobal.iconsDir, self.umglobal.settings["icon-error"]))
        go("imgExecute").set_from_file(
            join(self.umglobal.iconsDir,
                 self.umglobal.settings["icon-execute"]))
        go("imgUpdates").set_from_file(
            join(self.umglobal.iconsDir,
                 self.umglobal.settings["icon-updates"]))
        go("imgWarning").set_from_file(
            join(self.umglobal.iconsDir,
                 self.umglobal.settings["icon-warning"]))
        go("lblConnected").set_label(self.umglobal.connectedText)
        go("lblDisconnected").set_label(self.umglobal.disconnectedText)
        go("lblExecute").set_label(self.umglobal.executeText)
        self.lblError = go("lblError")
        self.lblWarning = go("lblWarning")
        self.lblUpdates = go("lblUpdates")
        self.builder.connect_signals(self)

        # Handle arguments
        parser = argparse.ArgumentParser(
            description='SolydXK Update Manager Tray')
        parser.add_argument('-r', '--reload', action="store_true", help='')
        args, extra = parser.parse_known_args()

        #print((">> args = {}".format(args)))
        if args.reload:
            pids = self.umglobal.getProcessPids("updatemanagertray.py")
            if len(pids) > 1:
                print(("updatemanagertray.py already running - kill pid {}".
                       format(pids[0])))
                os.system("kill {}".format(pids[0]))

        # Build status icon menu
        self.quitText = _("Quit")
        menu = Gtk.Menu()
        menuUm = Gtk.MenuItem(self.umglobal.title)
        menuUm.connect('activate', self.open_um)
        menu.append(menuUm)
        # Separator not functioning in wheezy
        menuSep1 = Gtk.SeparatorMenuItem()
        menu.append(menuSep1)
        menuQupd = Gtk.MenuItem(_("Quick Update"))
        menuQupd.connect('activate', self.quick_update)
        menu.append(menuQupd)
        menuSep2 = Gtk.SeparatorMenuItem()
        menu.append(menuSep2)
        menuPref = Gtk.MenuItem(_("Preferences"))
        menuPref.connect('activate', self.open_preferences)
        menu.append(menuPref)
        menuLegend = Gtk.MenuItem(_("Legend"))
        menuLegend.connect('activate', self.open_legend)
        menu.append(menuLegend)
        menuQuit = Gtk.MenuItem(self.quitText)
        menuQuit.connect('activate', self.quit_tray)
        menu.append(menuQuit)
        menu.show_all()

        if self.umglobal.isKf5:
            print(("> Running KDE5"))
            # Use this for KDE5
            self.indicator = AppIndicator3.Indicator.new_with_path(
                "updatemanager", self.umglobal.settings["icon-connected"],
                AppIndicator3.IndicatorCategory.SYSTEM_SERVICES,
                self.umglobal.iconsDir)
            # Title not showing in KDE4
            self.indicator.set_title("<strong>{}</strong>".format(
                self.umglobal.title))
            self.indicator.set_secondary_activate_target(menuUm)
            self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)
            self.indicator.set_menu(menu)
        else:
            print(("> Running KDE4"))
            # Use this for KDE4
            self.indicator = Gtk.StatusIcon()
            #self.indicator.connect('activate', self.open_um)
            self.indicator.connect('popup-menu', self.popup_menu, menu)

        self.umrefresh = UmRefresh(self.umglobal, self.indicator)
        self.notifier = UmNotifier(self.umrefresh)

        # Initiate first check
        self.refresh()
    def __init__(self):
        # Check if script is running
        self.scriptName = basename(__file__)
        self.umglobal = UmGlobal()

        # Handle arguments
        parser = argparse.ArgumentParser(description='SolydXK Update Manager Preferences')
        parser.add_argument('-r','--reload', action="store_true", help='')
        args, extra = parser.parse_known_args()

        print(("args = {}".format(args)))
        if args.reload:
            pids = self.umglobal.getProcessPids("updatemanagerpref.py")
            if len(pids) > 1:
                print(("updatemanagerpref.py already running - kill pid {}".format(pids[0])))
                os.system("kill {}".format(pids[0]))

        # Initiate logging
        self.logFile = join('/var/log', self.umglobal.settings['log'])
        self.log = Logger(self.logFile)

        # Load window and widgets
        self.builder = Gtk.Builder()
        self.builder.add_from_file(join(self.umglobal.shareDir, 'updatemanagerpref.glade'))

        # Preferences window objects
        go = self.builder.get_object
        self.window = go("windowPref")
        self.nbPref = go('nbPref')
        self.btnSaveMirrors = go('btnSaveMirrors')
        self.btnCheckMirrorsSpeed = go("btnCheckMirrorsSpeed")
        self.lblMirrors = go('lblMirrors')
        self.tvMirrors = go("tvMirrors")
        self.btnRemoveBlackList = go("btnRemoveBlacklist")
        self.btnAddBlackList = go("btnAddBlacklist")
        self.tvBlacklist = go("tvBlacklist")
        self.tvAvailable = go("tvAvailable")
        self.lblGeneral = go("lblGeneral")
        self.btnSaveGeneral = go("btnSaveGeneral")
        self.chkHideMaintenance = go("chkHideMaintenance")
        self.chkAutostart = go("chkAutostart")

        # GUI translations
        self.window.set_title(_("Update Manager Preferences"))
        self.btnSaveMirrors.set_label(_("Save mirrors"))
        self.btnCheckMirrorsSpeed.set_label(_("Check mirrors speed"))
        self.btnRemoveBlackList.set_label(_("Remove"))
        self.btnAddBlackList.set_label(_("Blacklist"))
        self.lblMirrors.set_label(_("Repository mirrors"))
        self.lblGeneral.set_label(_("General"))
        go("lblHideMaintenance").set_label(_("Hide maintenance"))
        go("lblBlacklist").set_label(_("Blacklisted packages"))
        go("lblMirrorsText").set_label(_("Select the fastest repository"))
        go("lblBlacklistText").set_label(_("Blacklisted packages"))
        go("lblAvailableText").set_label(_("Available packages"))
        go("lblGlobalSettings").set_label(_("Global settings"))

        # Initiate the treeview handler and connect the custom toggle event with on_tvMirrors_toggle
        self.tvMirrorsHandler = TreeViewHandler(self.tvMirrors)
        self.tvMirrorsHandler.connect('checkbox-toggled', self.on_tvMirrors_toggle)

        self.tvBlacklistHandler = TreeViewHandler(self.tvBlacklist)
        self.tvAvailableHandler = TreeViewHandler(self.tvAvailable)

        # Initialize
        self.ec = ExecCmd(loggerObject=self.log)
        self.queue = Queue()
        self.excludeMirrors = ['security', 'community']
        self.activeMirrors = self.umglobal.getMirrorData(excludeMirrors=self.excludeMirrors)
        self.deadMirrors = self.umglobal.getMirrorData(getDeadMirrors=True)
        self.mirrors = self.getMirrors()
        self.threads = {}
        self.blacklist = []
        self.available = []

        self.fillGeneralSettings()
        self.fillTreeViewMirrors()
        self.fillTreeViewBlackList()
        self.fillTreeViewAvailable()

        # Connect the signals and show the window
        self.builder.connect_signals(self)
        self.window.show()
class UpdateManagerPref(object):

    def __init__(self):
        # Check if script is running
        self.scriptName = basename(__file__)
        self.umglobal = UmGlobal()

        # Handle arguments
        parser = argparse.ArgumentParser(description='SolydXK Update Manager Preferences')
        parser.add_argument('-r','--reload', action="store_true", help='')
        args, extra = parser.parse_known_args()

        print(("args = {}".format(args)))
        if args.reload:
            pids = self.umglobal.getProcessPids("updatemanagerpref.py")
            if len(pids) > 1:
                print(("updatemanagerpref.py already running - kill pid {}".format(pids[0])))
                os.system("kill {}".format(pids[0]))

        # Initiate logging
        self.logFile = join('/var/log', self.umglobal.settings['log'])
        self.log = Logger(self.logFile)

        # Load window and widgets
        self.builder = Gtk.Builder()
        self.builder.add_from_file(join(self.umglobal.shareDir, 'updatemanagerpref.glade'))

        # Preferences window objects
        go = self.builder.get_object
        self.window = go("windowPref")
        self.nbPref = go('nbPref')
        self.btnSaveMirrors = go('btnSaveMirrors')
        self.btnCheckMirrorsSpeed = go("btnCheckMirrorsSpeed")
        self.lblMirrors = go('lblMirrors')
        self.tvMirrors = go("tvMirrors")
        self.btnRemoveBlackList = go("btnRemoveBlacklist")
        self.btnAddBlackList = go("btnAddBlacklist")
        self.tvBlacklist = go("tvBlacklist")
        self.tvAvailable = go("tvAvailable")
        self.lblGeneral = go("lblGeneral")
        self.btnSaveGeneral = go("btnSaveGeneral")
        self.chkHideMaintenance = go("chkHideMaintenance")
        self.chkAutostart = go("chkAutostart")

        # GUI translations
        self.window.set_title(_("Update Manager Preferences"))
        self.btnSaveMirrors.set_label(_("Save mirrors"))
        self.btnCheckMirrorsSpeed.set_label(_("Check mirrors speed"))
        self.btnRemoveBlackList.set_label(_("Remove"))
        self.btnAddBlackList.set_label(_("Blacklist"))
        self.lblMirrors.set_label(_("Repository mirrors"))
        self.lblGeneral.set_label(_("General"))
        go("lblHideMaintenance").set_label(_("Hide maintenance"))
        go("lblBlacklist").set_label(_("Blacklisted packages"))
        go("lblMirrorsText").set_label(_("Select the fastest repository"))
        go("lblBlacklistText").set_label(_("Blacklisted packages"))
        go("lblAvailableText").set_label(_("Available packages"))
        go("lblGlobalSettings").set_label(_("Global settings"))

        # Initiate the treeview handler and connect the custom toggle event with on_tvMirrors_toggle
        self.tvMirrorsHandler = TreeViewHandler(self.tvMirrors)
        self.tvMirrorsHandler.connect('checkbox-toggled', self.on_tvMirrors_toggle)

        self.tvBlacklistHandler = TreeViewHandler(self.tvBlacklist)
        self.tvAvailableHandler = TreeViewHandler(self.tvAvailable)

        # Initialize
        self.ec = ExecCmd(loggerObject=self.log)
        self.queue = Queue()
        self.excludeMirrors = ['security', 'community']
        self.activeMirrors = self.umglobal.getMirrorData(excludeMirrors=self.excludeMirrors)
        self.deadMirrors = self.umglobal.getMirrorData(getDeadMirrors=True)
        self.mirrors = self.getMirrors()
        self.threads = {}
        self.blacklist = []
        self.available = []

        self.fillGeneralSettings()
        self.fillTreeViewMirrors()
        self.fillTreeViewBlackList()
        self.fillTreeViewAvailable()

        # Connect the signals and show the window
        self.builder.connect_signals(self)
        self.window.show()

    # ===============================================
    # Main window functions
    # ===============================================

    def on_btnSaveGeneral_clicked(self, widget):
        self.saveGeneralSettings()

    def on_btnCheckMirrorsSpeed_clicked(self, widget):
        self.checkMirrorsSpeed()

    def on_btnSaveMirrors_clicked(self, widget):
        self.saveMirrors()

    def on_btnCancel_clicked(self, widget):
        self.window.destroy()

    def on_btnRemoveBlacklist_clicked(self, widget):
        self.removeBlacklist()

    def on_btnAddBlacklist_clicked(self, widget):
        self.addBlacklist()

    # ===============================================
    # Blacklist functions
    # ===============================================

    def fillGeneralSettings(self):
        for tab in self.umglobal.settings["hide-tabs"]:
            if tab == "maintenance":
                self.chkHideMaintenance.set_active(True)
        self.chkAutostart.set_active(self.umglobal.settings["autostart"])

    def fillTreeViewBlackList(self):
        self.blacklist = []
        cmd = "env LANG=C dpkg --get-selections | grep hold$ | awk '{print $1}'"
        lst = self.ec.run(cmd, False)
        for pck in lst:
            self.blacklist.append([False, pck.strip()])
        # Fill treeview
        columnTypesList = ['bool', 'str']
        self.tvBlacklistHandler.fillTreeview(self.blacklist, columnTypesList, 0, 400, False)

    def fillTreeViewAvailable(self):
        self.available = []
        cmd = "env LANG=C dpkg --get-selections | grep install$ | awk '{print $1}'"
        lst = self.ec.run(cmd, False)
        for pck in lst:
            self.available.append([False, pck.strip()])
        # Fill treeview
        columnTypesList = ['bool', 'str']
        self.tvAvailableHandler.fillTreeview(self.available, columnTypesList, 0, 400, False)

    def addBlacklist(self):
        packages = self.tvAvailableHandler.getToggledValues()
        for pck in packages:
            self.log.write("Blacklist package: %s" % pck, "UMPref.addBlacklist", "debug")
            cmd = "echo '%s hold' | dpkg --set-selections" % pck
            system(cmd)
        self.fillTreeViewBlackList()
        self.fillTreeViewAvailable()

    def removeBlacklist(self):
        packages = self.tvBlacklistHandler.getToggledValues()
        for pck in packages:
            self.log.write("Remove package from blacklist: %s" % pck, "UMPref.removeBlacklist", "debug")
            cmd = "echo '%s install' | dpkg --set-selections" % pck
            system(cmd)
        self.fillTreeViewBlackList()
        self.fillTreeViewAvailable()

    # ===============================================
    # Mirror functions
    # ===============================================

    def fillTreeViewMirrors(self):
        # Fill mirror list
        if len(self.mirrors) > 1:
            # Fill treeview
            columnTypesList = ['bool', 'str', 'str', 'str', 'str']
            self.tvMirrorsHandler.fillTreeview(self.mirrors, columnTypesList, 0, 400, True)

            # TODO - We have no mirrors: hide the tab until we do
            #self.nbPref.get_nth_page(1).set_visible(False)
        else:
            self.nbPref.get_nth_page(1).set_visible(False)

    def saveMirrors(self):
        # Safe mirror settings
        replaceRepos = []
        # Get user selected mirrors
        model = self.tvMirrors.get_model()
        itr = model.get_iter_first()
        while itr is not None:
            sel = model.get_value(itr, 0)
            if sel:
                repo = model.get_value(itr, 2)
                url = model.get_value(itr, 3)
                not_changed = ''
                # Get currently selected data
                for mirror in self.mirrors:
                    if mirror[0] and mirror[2] == repo:
                        if mirror[3] != url:
                            # Currently selected mirror
                            replaceRepos.append([mirror[3], url])
                        else:
                            not_changed = url
                        break
                if url not in replaceRepos and url not in not_changed:
                    # Append the repositoriy to the sources file
                    replaceRepos.append(['', url])
            itr = model.iter_next(itr)

        if not replaceRepos:
            # Check for dead mirrors
            model = self.tvMirrors.get_model()
            itr = model.get_iter_first()
            while itr is not None:
                sel = model.get_value(itr, 0)
                if sel:
                    repo = model.get_value(itr, 2)
                    url = model.get_value(itr, 3)
                    # Get currently selected data
                    for mirror in self.deadMirrors:
                        if mirror[1] == repo and mirror[2] != url:
                            # Currently selected mirror
                            replaceRepos.append([mirror[2], url])
                            break
                itr = model.iter_next(itr)

        if replaceRepos:
            self.btnSaveMirrors.set_sensitive(False)
            self.btnCheckMirrorsSpeed.set_sensitive(False)

            m = Mirror()
            ret = m.save(replaceRepos, self.excludeMirrors)
            if ret == '':
                self.ec.run(cmd="apt-get update", outputTreeView=self.tvMirrors)
                self.umglobal.getLocalInfo()
                self.mirrors = self.getMirrors()
                self.fillTreeViewMirrors()
            else:
                self.log.write(ret, "UMPref.saveMirrors", "exception")

            self.btnSaveMirrors.set_sensitive(True)
            self.btnCheckMirrorsSpeed.set_sensitive(True)
        else:
            msg = _("There are no repositories to save.")
            MessageDialog(self.lblMirrors.get_label(), msg)

    def getMirrors(self):
        mirrors = [[_("Current"), _("Country"), _("Repository"), _("URL"), _("Speed")]]
        for mirror in  self.activeMirrors:
            if mirror:
                self.log.write("Mirror data: %s" % ' '.join(mirror), "UMPref.getMirrors", "debug")
                blnCurrent = self.isUrlInSources(mirror[2])
                mirrors.append([blnCurrent, mirror[0], mirror[1], mirror[2], ''])
        return mirrors

    def isUrlInSources(self, url):
        url = "://%s" % url
        blnRet = False

        for repo in self.umglobal.repos:
            if url in repo:
                blnRet = True
                for excl in self.excludeMirrors:
                    if excl in repo:
                        blnRet = False
                        break
                break
        return blnRet

    def checkMirrorsSpeed(self):
        name = 'mirrorspeed'
        self.btnCheckMirrorsSpeed.set_sensitive(False)
        self.btnSaveMirrors.set_sensitive(False)
        t = MirrorGetSpeed(self.mirrors, self.queue, self.umglobal)
        self.threads[name] = t
        t.daemon = True
        t.start()
        self.queue.join()
        GObject.timeout_add(5, self.checkThread, name)

    def checkThread(self, name):
        if self.threads[name].is_alive():
            lst = self.queue.get()
            if lst:
                self.writeSpeed(lst[0], lst[1])
            self.queue.task_done()
            return True

        # Thread is done
        if not self.queue.empty():
            lst = self.queue.get()
            if lst:
                self.writeSpeed(lst[0], lst[1])
            self.queue.task_done()
        del self.threads[name]
        self.btnCheckMirrorsSpeed.set_sensitive(True)
        self.btnSaveMirrors.set_sensitive(True)
        return False

    def writeSpeed(self, url, speed):
        model = self.tvMirrors.get_model()
        itr = model.get_iter_first()
        while itr is not None:
            repo = model.get_value(itr, 3)
            if repo == url:
                self.log.write("Mirror speed for %s = %s" % (url, speed), "UMPref.writeSpeed", "debug")
                model.set_value(itr, 4, speed)
                path = model.get_path(itr)
                self.tvMirrors.scroll_to_cell(path)
            itr = model.iter_next(itr)
        self.tvMirrors.set_model(model)
        # Repaint GUI, or the update won't show
        while Gtk.events_pending():
            Gtk.main_iteration()

    def on_tvMirrors_toggle(self, obj, path, colNr, toggleValue):
        path = int(path)
        model = self.tvMirrors.get_model()
        selectedIter = model.get_iter(path)
        selectedRepo = model.get_value(selectedIter, 2)

        rowCnt = 0
        itr = model.get_iter_first()
        while itr is not None:
            if rowCnt != path:
                repo = model.get_value(itr, 2)
                if repo == selectedRepo:
                    model[itr][0] = False
            itr = model.iter_next(itr)
            rowCnt += 1

    # ===============================================
    # General functions
    # ===============================================

    def saveGeneralSettings(self):
        lst = []
        for tab in self.umglobal.settings["hide-tabs"]:
            if tab != "maintenance":
                lst.append(tab)
        if self.chkHideMaintenance.get_active():
            lst.append("maintenance")
        if lst:
            self.umglobal.saveSettings('misc', 'hide-tabs', ",".join(lst))
        else:
            self.umglobal.saveSettings('misc', 'hide-tabs', "")

        # Automatically start updatemanager on boot
        autostart = self.chkAutostart.get_active()
        self.umglobal.settings["autostart"] = autostart
        if autostart:
            if exists(self.umglobal.autostartSourceFile) and \
               exists(self.umglobal.autostartDir):
                copy(self.umglobal.autostartSourceFile, self.umglobal.autostartDir)
        elif exists(self.umglobal.autostartDestFile):
            remove(self.umglobal.autostartDestFile)

        msg = _("The new settings will take effect after UM restart.")
        MessageDialog(self.lblGeneral.get_label(), msg)

    # Close the gui
    def on_windowPref_destroy(self, widget):
        Gtk.main_quit()
Example #11
0
    def __init__(self):
        # Check if script is running
        self.scriptName = basename(__file__)
        self.umglobal = UmGlobal()
        self.user = self.umglobal.getLoginName()

        # Initiate logging
        self.logFile = join('/var/log', self.umglobal.settings['log'])
        print(("UM log = %s" % self.logFile))
        self.log = Logger(self.logFile, maxSizeKB=5120)

        # Remove scripts
        self.deleteScripts(self.umglobal.localUpdVersion)

        # Initialize
        self.ec = ExecCmd(loggerObject=self.log)
        self.apt = UmApt(self.umglobal)
        self.kernelVersion = self.umglobal.getKernelVersion()
        self.upgradables = []
        self.upgradableUM = []
        self.window = None

        # Handle arguments
        parser = argparse.ArgumentParser(description='SolydXK Update Manager')
        parser.add_argument('-q',
                            '--quick',
                            action="store_true",
                            help='Quick upgrade')
        parser.add_argument('-r', '--reload', action="store_true", help='')
        args, extra = parser.parse_known_args()

        self.quickUpdate = False
        if args.quick and not self.umglobal.newUpd:
            self.quickUpdate = True
        if args.reload:
            pids = self.umglobal.getProcessPids("updatemanager.py")
            if len(pids) > 1:
                print(("updatemanager.py already running - kill pid {}".format(
                    pids[0])))
                os.system("kill {}".format(pids[0]))

        # Set some global translations
        self.aptErrorText = _("Apt error")
        self.upgradablePackagesText = _(
            "The following packages will be upgraded:")
        self.newPackagesText = _(
            "The following NEW packages will be installed:")
        self.removedPackagesText = _("The following packages will be REMOVED:")
        self.heldbackPackagesText = _(
            "The following packages have been kept back:")
        self.downgradePackagesText = _(
            "The following packages are going to be downgraded:")

        # Cleanup first
        for fle in glob(join(self.umglobal.filesDir, '.um*')):
            remove(fle)

        # Load window and widgets
        self.builder = Gtk.Builder()
        self.builder.add_from_file(
            join(self.umglobal.shareDir, 'updatemanager.glade'))
        go = self.builder.get_object

        # Quick update
        if self.quickUpdate:
            # Refresh data
            self.refresh()
            self.umglobal.collectData()
            self.apt.createPackagesInfoList()
            self.apt.createPackageLists()
            self.fillTreeView()

            # Run upgrade
            nid = self.run_upgrade()

            if nid != "":
                self.on_command_done(None, 0, nid)

            sys.exit(2)

        # Make sure the files directory is set correctly
        self.checkFilesDir()

        # Main window objects
        self.window = go("windowMain")
        #self.window.set_icon_from_file(join(self.umglobal.iconsDir, self.umglobal.settings["icon-connected"]))
        self.tvPck = go("tvPck")
        self.swTerminal = go("swTerminal")
        self.statusbar = go("statusbar")
        self.btnInstall = go("btnInstall")
        self.btnRefresh = go("btnRefresh")
        self.btnPackages = go("btnPackages")
        self.btnOutput = go("btnOutput")
        self.btnInfo = go("btnInfo")
        self.btnPreferences = go("btnPreferences")
        self.nbMain = go("nbMain")
        self.swInfo = go("swInfo")
        self.btnMaintenance = go("btnMaintenance")
        self.lblMaintenance = go("lblMaintenance")
        self.tvMaintenance = go("tvMaintenance")
        self.btnMaintenanceExecute = go("btnMaintenanceExecute")
        self.chkMaintenanceSelectAll = go("chkMaintenanceSelectAll")
        self.radUnneeded = go("radUnneeded")
        self.radCleanCache = go("radCleanCache")
        self.radDowngradable = go("radDowngradable")
        self.radNotavailable = go("radNotavailable")
        self.radOldKernel = go("radOldKernel")
        self.lblMaintenanceHelp = go("lblMaintenanceHelp")

        # Translations
        self.window.set_title(_("SolydXK Update Manager"))
        self.btnInstall.set_label(_("Install"))
        self.btnRefresh.set_label(_("Refresh"))
        self.btnOutput.set_label(_("Output"))
        self.btnInfo.set_label(_("Information"))
        self.btnPreferences.set_label(_("Preferences"))
        self.btnMaintenance.set_label(_("Maintenance"))
        self.btnPackages.set_label(_("Packages"))
        self.uptodateText = self.umglobal.connectedText
        self.lblMaintenance.set_label(self.btnMaintenance.get_label())
        self.btnMaintenanceExecute.set_label(_("Execute"))
        self.chkMaintenanceSelectAll.set_label(_("Select all"))
        self.radCleanCache.set_label(_("Clean up the apt cache"))
        self.radUnneeded.set_label(_("Remove unneeded packages"))
        self.radNotavailable.set_label(
            _("Remove packages not available\nin the repositories"))
        self.radOldKernel.set_label(_("Remove old kernels"))
        self.radDowngradable.set_label(
            _("Downgrade packages with\nonly lower versions available"))
        self.lblMaintenanceHelp.set_label(
            _("Make sure you create\n"
              "a system image before you\n"
              "continue (e.g. Clonezilla)."))

        # VTE Terminal
        self.terminal = VirtualTerminal(userInputAllowed=self.umglobal.
                                        settings["allow-terminal-user-input"])
        self.swTerminal.add(self.terminal)
        self.terminal.set_vexpand(True)
        self.terminal.set_hexpand(True)
        self.terminal.connect('command-done', self.on_command_done)
        self.terminal.connect('line-added', self.on_line_added)
        palletList = [
            '#4A4A4A', '#BD1919', '#118011', '#CE6800', '#1919BC', '#8D138D',
            '#139494', '#A7A7A7'
        ]
        self.terminal.setTerminalColors("#000000", "#FFFFFF", palletList)
        self.swTerminal.modify_bg(Gtk.StateType.NORMAL,
                                  Gdk.color_parse("#FFFFFF"))

        # Disable all buttons
        self.btnInfo.set_sensitive(False)
        self.btnPreferences.set_sensitive(False)
        self.btnOutput.set_sensitive(False)
        self.btnRefresh.set_sensitive(False)
        self.btnInstall.set_sensitive(False)
        self.btnPackages.set_sensitive(False)
        self.btnMaintenance.set_sensitive(False)

        # Hide tabs if needed
        for tab in self.umglobal.settings["hide-tabs"]:
            if tab == "packages":
                self.nbMain.get_nth_page(0).set_visible(False)
                self.btnPackages.set_visible(False)
            elif tab == "output":
                self.nbMain.get_nth_page(1).set_visible(False)
                self.btnOutput.set_visible(False)
            elif tab == "info":
                self.nbMain.get_nth_page(2).set_visible(False)
                self.btnInfo.set_visible(False)
            elif tab == "maintenance":
                self.nbMain.get_nth_page(3).set_visible(False)
                self.btnMaintenance.set_visible(False)

        # Connect the signals and show the window
        self.builder.connect_signals(self)
        self.window.show()

        # Force the window to show
        while Gtk.events_pending():
            Gtk.main_iteration()

        # Just show something that we're busy
        msg = _("Gathering information...")
        self.terminal.executeCommand('echo "%s"' % msg, 'init')
        self.showOutput()

        # Treeview handlers
        self.tvHandler = TreeViewHandler(self.tvPck)
        self.tvMaintenanceHandler = TreeViewHandler(self.tvMaintenance)

        # Version information
        ver = _("Version")
        pckVer = self.apt.getPackageVersion('updatemanager')
        versionInfo = "%(ver)s: %(pckVer)s" % {"ver": ver, "pckVer": pckVer}
        if self.umglobal.localUpdVersion != "2000.01.01":
            versionInfo = "%(ver)s: %(pckVer)s" % {
                "ver": ver,
                "pckVer": pckVer
            }
        self.pushMessage(versionInfo)

        # Log basic information
        self.log.write("==============================================",
                       "UM.init", "debug")
        self.log.write("UM version = %s" % versionInfo, "UM.init", "debug")
        self.log.write("==============================================",
                       "UM.init", "debug")
        mirrorsList = join(self.umglobal.filesDir,
                           basename(self.umglobal.settings["mirrors-list"]))
        if exists(mirrorsList):
            self.log.write("Mirrors list", "UM.init", "debug")
            with open(mirrorsList, 'r') as f:
                for line in f.readlines():
                    self.log.write(line, "UM.init", "debug")
            self.log.write("==============================================",
                           "UM.init", "debug")

        # Refresh apt cache
        self.refresh()

        # Initialize maintenance screen
        self.fillTreeViewMaintenance()
Example #12
0
class UpdateManager(object):
    def __init__(self):
        # Check if script is running
        self.scriptName = basename(__file__)
        self.umglobal = UmGlobal()
        self.user = self.umglobal.getLoginName()

        # Initiate logging
        self.logFile = join('/var/log', self.umglobal.settings['log'])
        print(("UM log = %s" % self.logFile))
        self.log = Logger(self.logFile, maxSizeKB=5120)

        # Remove scripts
        self.deleteScripts(self.umglobal.localUpdVersion)

        # Initialize
        self.ec = ExecCmd(loggerObject=self.log)
        self.apt = UmApt(self.umglobal)
        self.kernelVersion = self.umglobal.getKernelVersion()
        self.upgradables = []
        self.upgradableUM = []
        self.window = None

        # Handle arguments
        parser = argparse.ArgumentParser(description='SolydXK Update Manager')
        parser.add_argument('-q',
                            '--quick',
                            action="store_true",
                            help='Quick upgrade')
        parser.add_argument('-r', '--reload', action="store_true", help='')
        args, extra = parser.parse_known_args()

        self.quickUpdate = False
        if args.quick and not self.umglobal.newUpd:
            self.quickUpdate = True
        if args.reload:
            pids = self.umglobal.getProcessPids("updatemanager.py")
            if len(pids) > 1:
                print(("updatemanager.py already running - kill pid {}".format(
                    pids[0])))
                os.system("kill {}".format(pids[0]))

        # Set some global translations
        self.aptErrorText = _("Apt error")
        self.upgradablePackagesText = _(
            "The following packages will be upgraded:")
        self.newPackagesText = _(
            "The following NEW packages will be installed:")
        self.removedPackagesText = _("The following packages will be REMOVED:")
        self.heldbackPackagesText = _(
            "The following packages have been kept back:")
        self.downgradePackagesText = _(
            "The following packages are going to be downgraded:")

        # Cleanup first
        for fle in glob(join(self.umglobal.filesDir, '.um*')):
            remove(fle)

        # Load window and widgets
        self.builder = Gtk.Builder()
        self.builder.add_from_file(
            join(self.umglobal.shareDir, 'updatemanager.glade'))
        go = self.builder.get_object

        # Quick update
        if self.quickUpdate:
            # Refresh data
            self.refresh()
            self.umglobal.collectData()
            self.apt.createPackagesInfoList()
            self.apt.createPackageLists()
            self.fillTreeView()

            # Run upgrade
            nid = self.run_upgrade()

            if nid != "":
                self.on_command_done(None, 0, nid)

            sys.exit(2)

        # Make sure the files directory is set correctly
        self.checkFilesDir()

        # Main window objects
        self.window = go("windowMain")
        #self.window.set_icon_from_file(join(self.umglobal.iconsDir, self.umglobal.settings["icon-connected"]))
        self.tvPck = go("tvPck")
        self.swTerminal = go("swTerminal")
        self.statusbar = go("statusbar")
        self.btnInstall = go("btnInstall")
        self.btnRefresh = go("btnRefresh")
        self.btnPackages = go("btnPackages")
        self.btnOutput = go("btnOutput")
        self.btnInfo = go("btnInfo")
        self.btnPreferences = go("btnPreferences")
        self.nbMain = go("nbMain")
        self.swInfo = go("swInfo")
        self.btnMaintenance = go("btnMaintenance")
        self.lblMaintenance = go("lblMaintenance")
        self.tvMaintenance = go("tvMaintenance")
        self.btnMaintenanceExecute = go("btnMaintenanceExecute")
        self.chkMaintenanceSelectAll = go("chkMaintenanceSelectAll")
        self.radUnneeded = go("radUnneeded")
        self.radCleanCache = go("radCleanCache")
        self.radDowngradable = go("radDowngradable")
        self.radNotavailable = go("radNotavailable")
        self.radOldKernel = go("radOldKernel")
        self.lblMaintenanceHelp = go("lblMaintenanceHelp")

        # Translations
        self.window.set_title(_("SolydXK Update Manager"))
        self.btnInstall.set_label(_("Install"))
        self.btnRefresh.set_label(_("Refresh"))
        self.btnOutput.set_label(_("Output"))
        self.btnInfo.set_label(_("Information"))
        self.btnPreferences.set_label(_("Preferences"))
        self.btnMaintenance.set_label(_("Maintenance"))
        self.btnPackages.set_label(_("Packages"))
        self.uptodateText = self.umglobal.connectedText
        self.lblMaintenance.set_label(self.btnMaintenance.get_label())
        self.btnMaintenanceExecute.set_label(_("Execute"))
        self.chkMaintenanceSelectAll.set_label(_("Select all"))
        self.radCleanCache.set_label(_("Clean up the apt cache"))
        self.radUnneeded.set_label(_("Remove unneeded packages"))
        self.radNotavailable.set_label(
            _("Remove packages not available\nin the repositories"))
        self.radOldKernel.set_label(_("Remove old kernels"))
        self.radDowngradable.set_label(
            _("Downgrade packages with\nonly lower versions available"))
        self.lblMaintenanceHelp.set_label(
            _("Make sure you create\n"
              "a system image before you\n"
              "continue (e.g. Clonezilla)."))

        # VTE Terminal
        self.terminal = VirtualTerminal(userInputAllowed=self.umglobal.
                                        settings["allow-terminal-user-input"])
        self.swTerminal.add(self.terminal)
        self.terminal.set_vexpand(True)
        self.terminal.set_hexpand(True)
        self.terminal.connect('command-done', self.on_command_done)
        self.terminal.connect('line-added', self.on_line_added)
        palletList = [
            '#4A4A4A', '#BD1919', '#118011', '#CE6800', '#1919BC', '#8D138D',
            '#139494', '#A7A7A7'
        ]
        self.terminal.setTerminalColors("#000000", "#FFFFFF", palletList)
        self.swTerminal.modify_bg(Gtk.StateType.NORMAL,
                                  Gdk.color_parse("#FFFFFF"))

        # Disable all buttons
        self.btnInfo.set_sensitive(False)
        self.btnPreferences.set_sensitive(False)
        self.btnOutput.set_sensitive(False)
        self.btnRefresh.set_sensitive(False)
        self.btnInstall.set_sensitive(False)
        self.btnPackages.set_sensitive(False)
        self.btnMaintenance.set_sensitive(False)

        # Hide tabs if needed
        for tab in self.umglobal.settings["hide-tabs"]:
            if tab == "packages":
                self.nbMain.get_nth_page(0).set_visible(False)
                self.btnPackages.set_visible(False)
            elif tab == "output":
                self.nbMain.get_nth_page(1).set_visible(False)
                self.btnOutput.set_visible(False)
            elif tab == "info":
                self.nbMain.get_nth_page(2).set_visible(False)
                self.btnInfo.set_visible(False)
            elif tab == "maintenance":
                self.nbMain.get_nth_page(3).set_visible(False)
                self.btnMaintenance.set_visible(False)

        # Connect the signals and show the window
        self.builder.connect_signals(self)
        self.window.show()

        # Force the window to show
        while Gtk.events_pending():
            Gtk.main_iteration()

        # Just show something that we're busy
        msg = _("Gathering information...")
        self.terminal.executeCommand('echo "%s"' % msg, 'init')
        self.showOutput()

        # Treeview handlers
        self.tvHandler = TreeViewHandler(self.tvPck)
        self.tvMaintenanceHandler = TreeViewHandler(self.tvMaintenance)

        # Version information
        ver = _("Version")
        pckVer = self.apt.getPackageVersion('updatemanager')
        versionInfo = "%(ver)s: %(pckVer)s" % {"ver": ver, "pckVer": pckVer}
        if self.umglobal.localUpdVersion != "2000.01.01":
            versionInfo = "%(ver)s: %(pckVer)s" % {
                "ver": ver,
                "pckVer": pckVer
            }
        self.pushMessage(versionInfo)

        # Log basic information
        self.log.write("==============================================",
                       "UM.init", "debug")
        self.log.write("UM version = %s" % versionInfo, "UM.init", "debug")
        self.log.write("==============================================",
                       "UM.init", "debug")
        mirrorsList = join(self.umglobal.filesDir,
                           basename(self.umglobal.settings["mirrors-list"]))
        if exists(mirrorsList):
            self.log.write("Mirrors list", "UM.init", "debug")
            with open(mirrorsList, 'r') as f:
                for line in f.readlines():
                    self.log.write(line, "UM.init", "debug")
            self.log.write("==============================================",
                           "UM.init", "debug")

        # Refresh apt cache
        self.refresh()

        # Initialize maintenance screen
        self.fillTreeViewMaintenance()

    # ===============================================
    # Main window functions
    # ===============================================

    def on_btnInstall_clicked(self, widget):
        self.run_upgrade()

    def run_upgrade(self):
        nid = ""
        aptHasErrors = self.apt.aptHasErrors()
        if aptHasErrors is not None:
            MessageDialog(self.aptErrorText, aptHasErrors)
        elif self.upgradables:

            if self.apt.upgradablePackages:
                self.log.write(
                    "=================== upgradable pacages ====================",
                    "UM.run_upgrade", "debug")
                self.log.write(
                    self.createLogString(self.apt.upgradablePackages),
                    "UM.run_upgrade", "debug")
            if self.apt.removedPackages:
                self.log.write(
                    "==================== removed packages =====================",
                    "UM.run_upgrade", "debug")
                self.log.write(self.createLogString(self.apt.removedPackages),
                               "UM.run_upgrade", "debug")
            if self.apt.newPackages:
                self.log.write(
                    "======================= new packages =======================",
                    "UM.run_upgrade", "debug")
                self.log.write(self.createLogString(self.apt.newPackages),
                               "UM.run_upgrade", "debug")
            if self.apt.heldbackPackages:
                self.log.write(
                    "=================== kept back packages =====================",
                    "UM.run_upgrade", "debug")
                self.log.write(self.createLogString(self.apt.heldbackPackages),
                               "UM.run_upgrade", "debug")

            if not self.quickUpdate:
                self.showOutput()
            contMsg = _("Continue installation?")
            if self.upgradableUM:
                cmd = "%s install updatemanager" % self.umglobal.settings[
                    'apt-get-string']
                cmd += "; %s install %s" % (
                    self.umglobal.settings['apt-get-string'], " ".join(
                        self.apt.getPackageDependencies('updatemanager')))
                nid = 'uminstallum'
                self.prepForCommand(nid)
                if self.quickUpdate:
                    self.ec.run(cmd)
                else:
                    self.terminal.executeCommand(cmd, nid)
                self.log.write("Execute command: %s (%s)" % (cmd, nid),
                               "UM.on_btnInstall_clicked", "debug")
            else:
                msg = self.getDistUpgradeInfo()
                answer = True
                if msg != "":
                    answer = self.showConfirmationDlg(contMsg, msg)
                if answer:
                    cmd = "%s dist-upgrade" % self.umglobal.settings[
                        'apt-get-string']
                    #if self.umglobal.newUpd:
                    pre = join(
                        self.umglobal.filesDir,
                        self.umglobal.settings['pre-upd'].replace(
                            "[VERSION]", self.umglobal.serverUpdVersion))
                    post = join(
                        self.umglobal.filesDir,
                        self.umglobal.settings['post-upd'].replace(
                            "[VERSION]", self.umglobal.serverUpdVersion))
                    if exists(pre):
                        cmd = "/bin/bash %(pre)s; %(cmd)s" % {
                            "pre": pre,
                            "cmd": cmd
                        }
                    if exists(post):
                        cmd = "%(cmd)s; /bin/bash %(post)s" % {
                            "cmd": cmd,
                            "post": post
                        }
                    nid = 'umupd'
                    self.prepForCommand(nid)
                    if self.quickUpdate:
                        self.ec.run(cmd)
                    else:
                        self.terminal.executeCommand(cmd, nid)
                    self.log.write("Execute command: %s (%s)" % (cmd, nid),
                                   "UM.on_btnInstall_clicked", "debug")

        else:
            if not self.quickUpdate:
                MessageDialog(self.btnInstall.get_label(), self.uptodateText)

        return nid

    def on_btnRefresh_clicked(self, widget):
        self.refresh()

    def on_btnPackages_clicked(self, widget):
        self.showPackages()

    def on_btnOutput_clicked(self, widget):
        self.showOutput()

    def on_btnInfo_clicked(self, widget):
        self.showInfo()

    def on_btnPreferences_clicked(self, widget):
        # Run preferences in its own thread
        pref_thread = threading.Thread(target=self.openPreferences)
        pref_thread.setDaemon(True)
        pref_thread.start()

    def openPreferences(self):
        os.system("updatemanager -p")

    def on_btnMaintenance_clicked(self, widget):
        self.showMaintenance()

    def on_radCleanCache_toggled(self, widget):
        if widget.get_active():
            self.fillTreeViewMaintenance()

    def on_radUnneeded_toggled(self, widget):
        if widget.get_active():
            message = "%s\n\n%s" % (
                _("You might need to run this several times."),
                self.lblMaintenanceHelp.get_label().replace("\n", " "))
            WarningDialog(self.btnMaintenance.get_label(), message)
            self.fillTreeViewMaintenance()

    def on_radNotavailable_toggled(self, widget):
        if widget.get_active():
            message = "%s\n\n%s" % (
                _("Removing not available packages may break your system!"),
                self.lblMaintenanceHelp.get_label().replace("\n", " "))
            WarningDialog(self.btnMaintenance.get_label(), message)
            self.fillTreeViewMaintenance()

    def on_radOldKernel_toggled(self, widget):
        if widget.get_active():
            message = "%s\n\n%s" % (
                _("Once removed you will not be able to boot these kernels!"),
                self.lblMaintenanceHelp.get_label().replace("\n", " "))
            WarningDialog(self.btnMaintenance.get_label(), message)
            self.fillTreeViewMaintenance()

    def on_radDowngradable_toggled(self, widget):
        if widget.get_active():
            message = "%s\n\n%s" % (
                _("Downgrading packages may break your system!"),
                self.lblMaintenanceHelp.get_label().replace("\n", " "))
            WarningDialog(self.btnMaintenance.get_label(), message)
            self.fillTreeViewMaintenance()

    def on_btnMaintenanceExecute_clicked(self, widget):
        self.executeMaintenance()

    def on_chkMaintenanceSelectAll_toggled(self, widget):
        self.tvMaintenanceHandler.treeviewToggleAll(
            toggleColNrList=[0], toggleValue=widget.get_active())

    # ===============================================
    # Maintenance functions
    # ===============================================

    def enableMaintenance(self, enable=True):
        self.btnMaintenanceExecute.set_sensitive(enable)
        self.radUnneeded.set_sensitive(enable)
        self.radCleanCache.set_sensitive(enable)
        self.radDowngradable.set_sensitive(enable)
        self.radOldKernel.set_sensitive(enable)
        self.radNotavailable.set_sensitive(enable)
        self.chkMaintenanceSelectAll.set_sensitive(enable)
        if enable:
            self.chkMaintenanceSelectAll.set_active(False)

    def fillTreeViewMaintenance(self):
        blnCleanCache = self.radCleanCache.get_active()
        blnUnneeded = self.radUnneeded.get_active()
        blnDowngradable = self.radDowngradable.get_active()
        blnNotavailable = self.radNotavailable.get_active()
        blnOldKernels = self.radOldKernel.get_active()

        self.enableMaintenance(False)

        columnTypesList = ['bool', 'str', 'str', 'str']
        packages = [["", _("Package"), _("Installed"), _("Available")]]
        # Clear the treeview first
        self.tvMaintenanceHandler.fillTreeview(packages, columnTypesList, 0,
                                               400, True)

        msg = ""
        if blnCleanCache:
            msg = _("Hit the Execute button to clean the cache.")
            columnTypesList = ['str']
            packages.append([msg])
        elif blnUnneeded:
            msg = self.radUnneeded.get_label()
            self.apt.createPackageLists("apt-get autoremove")
            for pck in self.apt.removedPackages:
                packages.append([False, pck[0], pck[1], pck[2]])
            self.apt.createPackageLists()
            # Add orphaned files
            self.apt.fillOrphanedPackages()
            for pck in self.apt.orphanedPackages:
                packages.append([False, pck[0], pck[1], pck[2]])
        elif blnNotavailable:
            msg = self.radNotavailable.get_label()
            self.apt.fillNotAvailablePackages()
            for pck in self.apt.notavailablePackages:
                if pck[0][0:6] != "linux-":
                    packages.append([False, pck[0], pck[1], ""])
        elif blnOldKernels:
            msg = self.radOldKernel.get_label()
            self.apt.fillKernelPackages()
            for pck in self.apt.kernelPackages:
                if "headers-486" not in pck[0] \
                    and "headers-586" not in pck[0] \
                    and "headers-686" not in pck[0] \
                    and "headers-amd64" not in pck[0] \
                    and "image-486" not in pck[0] \
                    and "image-586" not in pck[0] \
                    and "image-686" not in pck[0] \
                    and "image-amd64" not in pck[0]:

                    checkVersion = self.kernelVersion
                    if "kbuild" in pck[0]:
                        indMinus = self.kernelVersion.index("-")
                        indZero = self.kernelVersion.index("0")
                        if indZero > 0 and indZero < indMinus:
                            ind = indZero - 1
                        else:
                            ind = indMinus
                        if ind > 0:
                            checkVersion = self.kernelVersion[0:ind]
                    if checkVersion not in pck[0]:
                        packages.append([False, pck[0], pck[1], ""])
        elif blnDowngradable:
            msg = self.radDowngradable.get_label()
            self.apt.fillDowngradablePackages()
            for pck in self.apt.downgradablePackages:
                packages.append([False, pck[0], pck[1], pck[2]])

        if len(packages) > 1:
            self.tvMaintenanceHandler.fillTreeview(packages, columnTypesList,
                                                   0, 400, True)
        else:
            if not blnCleanCache:
                msg = _("\"%s\"\n did not return any results.") % msg
                MessageDialog(self.btnMaintenance.get_label(), msg)

        self.enableMaintenance(True)

    def executeMaintenance(self):
        blnCleanCache = self.radCleanCache.get_active()
        blnDowngradable = self.radDowngradable.get_active()
        blnNotNeeded = self.radUnneeded.get_active()
        downgradeString = ""
        deleteString = ""
        updateGrub = False
        cmd = ""

        self.enableMaintenance(False)

        if blnCleanCache:
            safe = False
            msg = _(
                "Do you want to completely clean the apt cache?\n\n"
                "When No, only unavailable installation packages are removed.")
            answer = QuestionDialog(self.radCleanCache.get_label(), msg)
            if answer:
                safe = True
            self.apt.cleanCache(safe)
            msg = _("Apt cache has been cleaned.")
            MessageDialog(self.radCleanCache.get_label(), msg)
        else:
            # Get user selected packages
            model = self.tvMaintenance.get_model()
            itr = model.get_iter_first()
            while itr is not None:
                sel = model.get_value(itr, 0)
                if sel:
                    pck = model.get_value(itr, 1)
                    avVer = model.get_value(itr, 3)
                    if blnDowngradable:
                        downgradeString += " %(pck)s=%(avVer)s" % {
                            "pck": pck,
                            "avVer": avVer
                        }
                    else:
                        deleteString += " %s" % pck
                        if "linux-image" in pck:
                            updateGrub = True
                itr = model.iter_next(itr)

            if downgradeString != "":
                cmd = "%s install %s" % (
                    self.umglobal.settings['apt-get-string'], downgradeString)
            elif deleteString != "":
                cmd = "%s purge %s" % (
                    self.umglobal.settings['apt-get-string'], deleteString)

        if cmd != "":
            self.apt.createPackageLists(cmd)
            msg = self.getDistUpgradeInfo()
            answer = True
            if msg != "":
                contMsg = _("Execute maintenance changes?")
                answer = self.showConfirmationDlg(contMsg, msg)
            if answer:
                if updateGrub:
                    cmd += "; update-grub"
                if blnNotNeeded:
                    cmd += "; %s purge $(COLUMNS=132 dpkg -l | grep ^rc | awk '{ print $2 }')" % self.umglobal.settings[
                        'apt-get-string']
                self.showOutput()
                nid = 'ummaintenance'
                self.prepForCommand(nid)
                self.terminal.executeCommand(cmd, nid)
                self.log.write("Execute command: %s (%s)" % (cmd, nid),
                               "UM.executeMaintenance", "debug")

        self.enableMaintenance(True)

    # ===============================================
    # General functions
    # ===============================================

    def prepForCommand(self, nid):
        os.system("touch %s" % self.umglobal.umfiles[nid])
        if not self.quickUpdate:
            self.btnRefresh.set_sensitive(False)
            self.btnInstall.set_sensitive(False)
            self.btnMaintenance.set_sensitive(False)

    def on_line_added(self, terminal, line):
        if line.strip()[0:2].upper() == "E:":
            self.log.write(line, "UM.on_line_added", "error")
        else:
            self.log.write(line, "UM.on_line_added", "info")

    def on_command_done(self, terminal, pid, nid):
        if nid != "init":
            self.log.write("Command finished (pid=%s, nid=%s)" % (pid, nid),
                           "UM.on_command_done", "info")
            if nid == "uminstallum":
                # Reload UM
                self.log.write(
                    "Updating UM: kill process of updatemanagerpref.py",
                    "UM.on_command_done", "debug")
                self.umglobal.killScriptProcess("updatemanagerpref.py")
                # Reload tray as user
                self.log.write(
                    "Updating UM: kill process of updatemanagertray.py",
                    "UM.on_command_done", "debug")
                self.umglobal.killScriptProcess("updatemanagertray.py")
                cmd = "sudo -u {} updatemanager -t -r".format(self.user)
                os.system(cmd)
                self.log.write(
                    "UM updated: reload tray as user {}".format(self.user),
                    "UM.on_command_done", "debug")
                # Reload UM window
                cmd = join(self.umglobal.scriptDir, "updatemanager.py")
                if self.quickUpdate:
                    cmd = join(self.umglobal.scriptDir, "updatemanager.py -q")
                self.umglobal.reloadWindow(cmd, self.user)
                self.log.write(
                    "UM updated: reload {0} as user {1}".format(
                        cmd, self.user), "UM.on_command_done", "debug")
            elif nid == "umrefresh":
                # Build installed packages info list
                self.apt.createPackagesInfoList()
                # Run post update when needed
                self.postUpdate()
            elif nid == "ummaintenance":
                self.enableMaintenance(True)
                self.fillTreeViewMaintenance()
                self.btnInstall.set_sensitive(True)
                self.btnRefresh.set_sensitive(True)
                self.btnPackages.set_sensitive(True)
                self.btnMaintenance.set_sensitive(True)
                self.showMaintenance()
            elif nid == 'umupd':
                # Save update version in hist file
                self.umglobal.saveHistVersion("upd",
                                              self.umglobal.serverUpdVersion)
                self.log.write(
                    "Save history upd=%s" % self.umglobal.serverUpdVersion,
                    "UM.on_command_done", "debug")
                self.deleteScripts()

            # Refresh data after install or update
            self.umglobal.collectData()
            self.apt.createPackageLists()
            self.fillTreeView()

            # Enable the buttons and load the info page
            self.log.write(
                "Re-initiate window after terminal command: %s" %
                str(not self.quickUpdate), "UM.on_command_done", "debug")
            if not self.quickUpdate:
                self.btnInstall.set_sensitive(True)
                self.btnRefresh.set_sensitive(True)
                self.btnPackages.set_sensitive(True)
                self.btnMaintenance.set_sensitive(True)
                self.btnInfo.set_sensitive(True)
                self.loadInfo()

                if self.umglobal.newUpd:
                    self.showInfo()
                else:
                    # This throws a lock file error in Plasma5
                    #aptHasErrors = self.apt.aptHasErrors()
                    #if aptHasErrors is not None:
                    #MessageDialog(self.aptErrorText, aptHasErrors)
                    #el
                    if self.upgradables:
                        self.showPackages()
                    else:
                        self.showInfo()
                        MessageDialog(self.btnInfo.get_label(),
                                      self.uptodateText)
                self.log.write("Re-initiate window complete",
                               "UM.on_command_done", "debug")

            # Cleanup name file(s)
            for fle in glob(join(self.umglobal.filesDir, '.um*')):
                remove(fle)

    def createLogString(self, packagesList):
        lst = []
        for data in packagesList:
            lst.append(data[0])
        return ' '.join(lst)

    def refresh(self):
        # Refresh server info
        print((self.umglobal.hasInternet))
        self.umglobal.getServerInfo()
        print((self.umglobal.hasInternet))

        # Check of programs locking apt
        prog = self.apt.getAptCacheLockedProgram(
            self.umglobal.settings["apt-packages"])
        if prog is not None:
            msg = _("Another program is locking the apt cache\n\n"
                    "Please, close the program before refreshing:\n"
                    "* %s" % prog)
            MessageDialog(self.btnRefresh.get_label(), msg)
            self.log.write("%s is locking the apt cache" % prog, "UM.refresh",
                           "warning")
        elif self.umglobal.hasInternet:
            if not self.quickUpdate:
                # Update the apt cache
                self.btnPreferences.set_sensitive(True)
                self.btnOutput.set_sensitive(True)
                self.btnRefresh.set_sensitive(False)
                self.btnInstall.set_sensitive(False)
                self.btnMaintenance.set_sensitive(False)
                self.btnPackages.set_sensitive(True)
                self.showOutput()
            cmd = "dpkg --configure -a; %s -f install; apt-get update" % self.umglobal.settings[
                'apt-get-string']
            nid = 'umrefresh'
            self.prepForCommand(nid)
            if self.quickUpdate:
                self.ec.run(cmd)
            else:
                self.terminal.executeCommand(cmd, nid)
            self.apt.initAptShowVersions()
            self.log.write("Execute command: %s (%s)" % (cmd, nid),
                           "UM.refresh", "debug")
        else:
            if not self.quickUpdate:
                # No internet connection
                self.btnInstall.set_sensitive(True)
                self.btnRefresh.set_sensitive(True)
                self.btnPackages.set_sensitive(True)
                self.btnMaintenance.set_sensitive(True)
                self.btnInfo.set_sensitive(True)
                self.btnOutput.set_sensitive(True)
                self.btnPreferences.set_sensitive(True)
                self.loadInfo()
                self.showInfo()

    def postUpdate(self):
        # Check for changed version information
        if self.umglobal.newUpd and self.umglobal.serverUpdVersion is not None:
            self.getScripts([
                self.umglobal.settings['pre-upd'].replace(
                    "[VERSION]", self.umglobal.serverUpdVersion),
                self.umglobal.settings['post-upd'].replace(
                    "[VERSION]", self.umglobal.serverUpdVersion)
            ])

    def fillTreeView(self):
        # First check if this application is upgradable
        self.upgradableUM = self.getUpgradablePackages(
            packageNames=["updatemanager"])
        if self.upgradableUM:
            self.upgradables = self.upgradableUM
        else:
            # Get a list of packages that can be upgraded
            self.upgradableUM = []
            self.upgradables = self.getUpgradablePackages()
            #if not self.upgradables:
            ## Check for black listed packages
            #cmd = "dpkg --get-selections | grep hold$ | awk '{print $1}'"
            #lst = self.ec.run(cmd, False)
            #for pck in lst:
            #self.upgradables.append([pck.strip(), _("blacklisted"), ""])

        if not self.quickUpdate:
            contentList = [[
                _("Package"),
                _("Current version"),
                _("New version")
            ]] + self.upgradables
            self.tvHandler.fillTreeview(contentList=contentList,
                                        columnTypesList=['str', 'str', 'str'],
                                        firstItemIsColName=True)

    def getUpgradablePackages(self, packageNames=[]):
        upckList = []
        if packageNames:
            upckList = []
            for packageName in packageNames:
                for upck in self.apt.upgradablePackages:
                    if upck[0] == packageName:
                        upckList.append(upck)
                        break
        else:
            upckList = self.apt.upgradablePackages
        return upckList

    def getDistUpgradeInfo(self, upgradablesOnly=False):
        info = ""
        if upgradablesOnly:
            if self.apt.upgradablePackages:
                info = "<strong>%s</strong><br>" % self.apt.upgradablePackagesText
                for pck in self.apt.upgradablePackages:
                    info += "%s " % pck[0]
        else:
            if self.apt.removedPackages:
                info = "<strong>%s</strong><br>" % self.removedPackagesText
                for pck in self.apt.removedPackages:
                    info += "%s " % pck[0]
            if self.apt.newPackages:
                if info != "":
                    info += "<p>&nbsp;</p>"
                info += "<strong>%s</strong><br>" % self.newPackagesText
                for pck in self.apt.newPackages:
                    info += "%s " % pck[0]
            if self.apt.heldbackPackages:
                if info != "":
                    info += "<p>&nbsp;</p>"
                info += "<strong>%s</strong><br>" % self.heldbackPackagesText
                for pck in self.apt.heldbackPackages:
                    info += "%s " % pck[0]
            if self.apt.downgradablePackages:
                if info != "":
                    info += "<p>&nbsp;</p>"
                info += "<strong>%s</strong><br>" % self.downgradePackagesText
                for pck in self.apt.downgradablePackages:
                    info += "%s " % pck[0]
        return info

    def showPackages(self):
        self.nbMain.set_current_page(0)

    def showOutput(self):
        self.nbMain.set_current_page(1)
        self.terminal.grab_focus()

    def showInfo(self):
        self.nbMain.set_current_page(2)

    def showMaintenance(self):
        self.nbMain.set_current_page(3)

    def showConfirmationDlg(self, title, message):
        head = "<html><head><style>body { font-family: Arial, Helvetica, Verdana, Sans-serif; font-size: 12px; color: #555555; background: #ffffff; }</style></head><body>"
        end = "</body></html>"
        html = "%s%s%s" % (head, message, end)
        sw = Gtk.ScrolledWindow()
        sw.add(SimpleBrowser(html))
        return CustomQuestionDialog(title, sw, 550, 300, self.window).show()

    # Get pre-install script and post-install script from the server
    def getScripts(self, files):
        for fle in files:
            flePath = join(self.umglobal.filesDir, fle)
            if not exists(flePath):
                # Get the new scripts if they exist
                url = "%s/%s/%s" % (self.umglobal.settings['solydxk'],
                                    self.umglobal.settings["umfilesdir"], fle)
                try:
                    txt = urlopen(url).read().decode('utf-8')
                    if txt != '':
                        # Save to a file and make executable
                        self.log.write("Save script = %s" % flePath,
                                       "UM.getScripts", "debug")
                        with open(flePath, 'w') as f:
                            f.write(txt)
                        chmod(flePath, 0o755)
                except:
                    pass

    def loadInfo(self):
        languageDir = self.get_language_dir()
        url = join("file://%s" % languageDir,
                   self.umglobal.settings['up-to-date'])
        self.btnInfo.set_icon_name("help-about")
        if self.upgradables:
            url = join("file://%s" % languageDir,
                       self.umglobal.settings['updates'])
            if self.umglobal.newUpd:
                url = "%s/%s/%s" % (self.umglobal.settings['solydxk'],
                                    self.umglobal.settings["umfilesdir"],
                                    self.umglobal.settings['upd-info'])
        elif self.umglobal.serverUpdVersion is None:
            url = join("file://%s" % languageDir,
                       self.umglobal.settings['not-found'])

        self.log.write("Load info url: %s" % url, "UM.loadInfo", "debug")

        children = self.swInfo.get_children()
        if children:
            children[0].openUrl(url)
        else:
            self.swInfo.add(SimpleBrowser(url))

    def get_language_dir(self):
        # First test if full locale directory exists, e.g. html/pt_BR,
        # otherwise perhaps at least the language is there, e.g. html/pt
        # and if that doesn't work, try html/pt_PT
        lang = self.get_current_language()
        path = join(self.umglobal.htmlDir, lang)
        if not isdir(path):
            base_lang = lang.split('_')[0].lower()
            path = join(self.umglobal.htmlDir, base_lang)
            if not isdir(path):
                path = join(self.umglobal.htmlDir,
                            "{}_{}".format(base_lang, base_lang.upper()))
                if not isdir(path):
                    path = join(self.umglobal.htmlDir, 'en')
        return path

    def get_current_language(self):
        lang = os.environ.get('LANG', 'US').split('.')[0]
        if lang == '':
            lang = 'en'
        return lang

    def pushMessage(self, message):
        if message is not None:
            context = self.statusbar.get_context_id('message')
            self.statusbar.push(context, message)

    def checkFilesDir(self):
        if not exists(self.umglobal.filesDir):
            makedirs(self.umglobal.filesDir)
        oldFiles = glob(join(self.umglobal.scriptDir, 'pre-*')) + \
                   glob(join(self.umglobal.scriptDir, 'post-*')) + \
                   [join(self.umglobal.scriptDir, 'updatemanager.hist')] + \
                   [join(self.umglobal.scriptDir, 'mirrors.list')]
        for fle in oldFiles:
            if exists(fle):
                fleName = basename(fle)
                if not exists(join(self.umglobal.filesDir, fleName)):
                    move(fle, self.umglobal.filesDir)
                else:
                    remove(fle)
        chmod(self.umglobal.filesDir, 0o777)

    def deleteScripts(self, UpdVersion=None):
        UpdVersion = "*"
        if UpdVersion is not None:
            UpdVersion = "*%s" % UpdVersion

        oldFiles = glob(join(
            self.umglobal.filesDir, "pre-%s" % UpdVersion)) + glob(
                join(self.umglobal.filesDir, "post-%s" % UpdVersion))
        for fle in oldFiles:
            remove(fle)
            self.log.write("Cleanup file: %s" % fle, "UM.deleteScripts",
                           "debug")

    # Close the gui
    def on_windowMain_destroy(self, widget):
        # Close the app
        Gtk.main_quit()
class UpdateManagerTray(object):

    def __init__(self):
        # Check if script is running
        self.scriptDir = abspath(dirname(__file__))
        self.filesDir = join(self.scriptDir, "files")
        self.scriptName = basename(__file__)
        self.umglobal = UmGlobal()
        self.ec = ExecCmd()

        # Handle arguments
        parser = argparse.ArgumentParser(description='Trail Update Manager Tray')
        parser.add_argument('-r','--reload', action="store_true", help='')
        args, extra = parser.parse_known_args()

        print((">> args = {}".format(args)))
        if args.reload:
            pids = self.umglobal.getScriptPids("updatemanagertray.py")
            if len(pids) > 1:
                print(("updatemanagertray.py already running - kill pid {}".format(pids[0])))
                os.system("kill {}".format(pids[0]))

        # Build status icon menu
        self.refreshText = _("Refresh")
        self.quitText = _("Quit")
        menu = Gtk.Menu()
        menuUm = Gtk.MenuItem(_("Update Manager"))
        menuUm.connect('activate', self.open_um)
        menu.append(menuUm)
        # Separator not functioning in wheezy
        #menuSep1 = Gtk.SeparatorMenuItem()
        #menu.append(menuSep1)
        menuPref = Gtk.MenuItem(_("Preferences"))
        menuPref.connect('activate', self.open_preferences)
        menu.append(menuPref)
        menuRefresh = Gtk.MenuItem(self.refreshText)
        menuRefresh.connect('activate', self.manualRefresh)
        menu.append(menuRefresh)
        menuQuit = Gtk.MenuItem(self.quitText)
        menuQuit.connect('activate', self.quit_tray)
        menu.append(menuQuit)

        self.statusIcon = Gtk.StatusIcon()
        self.umrefresh = UmRefresh(self.statusIcon, self.umglobal)
        self.notifier = UmNotifier(self.statusIcon, self.umglobal, self.umrefresh)

        self.statusIcon.connect('activate', self.icon_activate)
        self.statusIcon.connect('popup-menu', self.popup_menu, menu)

        # Initiate first check
        self.refresh()

        # Loop the refresh function
        # For some reason you cannot start a threaded class from init
        self.timeout = int(self.umglobal.settings["hrs-check-status"] * 60 * 60)
        GObject.timeout_add_seconds(self.timeout, self.refresh)

    def refresh(self, widget=None):
        self.umrefresh.refresh()
        # Return True or timeout_add_seconds will only run once
        return True

    def manualRefresh(self, widget=None):
        self.umrefresh.refresh()

    def popup_menu(self, widget, button, time, data):
        data.show_all()
        data.popup(None, None, None, None, button, time)

    def open_um(self, widget):
        if not self.umglobal.isSrciptRunning("updatemanager.py"):
            # Run UM in its own thread
            pref_thread = threading.Thread(target=self.ec.run, args=("updatemanager",))
            pref_thread.setDaemon(True)
            pref_thread.start()

    def icon_activate(self, widget):
        if not self.umglobal.isSrciptRunning("updatemanager.py"):
            parm = ""
            if not self.umglobal.newUpd:
                # Quick update
                parm = " -q"
            # Run UM in its own thread
            pref_thread = threading.Thread(target=self.ec.run, args=("updatemanager{}".format(parm),))
            pref_thread.setDaemon(True)
            pref_thread.start()

    def open_preferences(self, widget):
        # Run preferences in its own thread
        if not self.umglobal.isSrciptRunning("updatemanagerpref.py"):
            pref_thread = threading.Thread(target=self.ec.run, args=("updatemanager -p",))
            pref_thread.setDaemon(True)
            pref_thread.start()

    def showInfoDlg(self, title, message):
        MessageDialog(title, message)

    def quit_tray(self, widget):
        if self.umglobal.isUpgrading():
            self.showInfoDlg(self.quitText, _("Cannot quit: upgrade in progress"))
        else:
            self.umglobal.killScriptProcess("updatemanager.py")
            self.umglobal.killScriptProcess("updatemanagerpref.py")
            self.notifier.quit()
            Gtk.main_quit()
Example #14
0
import sys
sys.path.insert(1, '/usr/lib/solydxk/updatemanager')
import os
import gettext
import argparse
from gi.repository import Gtk
from os.path import join, abspath, dirname, exists
from umglobal import UmGlobal
from dialogs import WarningDialog, ErrorDialog

# i18n: http://docs.python.org/2/library/gettext.html
gettext.install("updatemanager", "/usr/share/locale")
_ = gettext.gettext

umglobal = UmGlobal(False)
scriptDir = abspath(dirname(__file__))
filesDir = join(scriptDir, "files")


# Clear update history
def clearUpHistory():
    histFile = join(filesDir, "updatemanager.hist")
    resetLine = None
    if exists(histFile):
        with open(histFile, 'r') as f:
            for line in reversed(f.readlines()):
                if "upd=" in line:
                    resetLine = "upd=2000.01.01\n"
                    break
        if resetLine is not None:
Example #15
0
class UpdateManager(object):

    def __init__(self):
        # Check if script is running
        self.scriptName = basename(__file__)
        self.umglobal = UmGlobal()
        self.user = self.umglobal.getLoginName()

        # Initiate logging
        self.logFile = join('/var/log', self.umglobal.settings['log'])
        print(("UM log = %s" % self.logFile))
        self.log = Logger(self.logFile, maxSizeKB=5120)

        # Remove scripts
        self.deleteScripts(self.umglobal.localUpdVersion)

        # Initialize
        self.ec = ExecCmd(loggerObject=self.log)
        self.apt = UmApt(self.umglobal)
        self.kernelVersion = self.umglobal.getKernelVersion()
        self.upgradables = []
        self.upgradableUM = []
        self.window = None

        # Handle arguments
        parser = argparse.ArgumentParser(description='SolydXK Update Manager')
        parser.add_argument('-q','--quick', action="store_true", help='Quick upgrade')
        parser.add_argument('-r','--reload', action="store_true", help='')
        args, extra = parser.parse_known_args()

        self.quickUpdate = False
        if args.quick and not self.umglobal.newUpd:
            self.quickUpdate = True
        if args.reload:
            pids = self.umglobal.getProcessPids("updatemanager.py")
            if len(pids) > 1:
                print(("updatemanager.py already running - kill pid {}".format(pids[0])))
                os.system("kill {}".format(pids[0]))

        # Set some global translations
        self.aptErrorText = _("Apt error")
        self.upgradablePackagesText = _("The following packages will be upgraded:")
        self.newPackagesText = _("The following NEW packages will be installed:")
        self.removedPackagesText = _("The following packages will be REMOVED:")
        self.heldbackPackagesText = _("The following packages have been kept back:")
        self.downgradePackagesText = _("The following packages are going to be downgraded:")

        # Cleanup first
        for fle in glob(join(self.umglobal.filesDir, '.um*')):
            remove(fle)

        # Load window and widgets
        self.builder = Gtk.Builder()
        self.builder.add_from_file(join(self.umglobal.shareDir, 'updatemanager.glade'))
        go = self.builder.get_object

        # Quick update
        if self.quickUpdate:
            # Refresh data
            self.refresh()
            self.umglobal.collectData()
            self.apt.createPackagesInfoList()
            self.apt.createPackageLists()
            self.fillTreeView()

            # Run upgrade
            nid = self.run_upgrade()

            if nid != "":
                self.on_command_done(None, 0, nid)

            sys.exit(2)

        # Make sure the files directory is set correctly
        self.checkFilesDir()

        # Main window objects
        self.window = go("windowMain")
        #self.window.set_icon_from_file(join(self.umglobal.iconsDir, self.umglobal.settings["icon-connected"]))
        self.tvPck = go("tvPck")
        self.swTerminal = go("swTerminal")
        self.statusbar = go("statusbar")
        self.btnInstall = go("btnInstall")
        self.btnRefresh = go("btnRefresh")
        self.btnPackages = go("btnPackages")
        self.btnOutput = go("btnOutput")
        self.btnInfo = go("btnInfo")
        self.btnPreferences = go("btnPreferences")
        self.nbMain = go("nbMain")
        self.swInfo = go("swInfo")
        self.btnMaintenance = go("btnMaintenance")
        self.lblMaintenance = go("lblMaintenance")
        self.tvMaintenance = go("tvMaintenance")
        self.btnMaintenanceExecute = go("btnMaintenanceExecute")
        self.chkMaintenanceSelectAll = go("chkMaintenanceSelectAll")
        self.radUnneeded = go("radUnneeded")
        self.radCleanCache = go("radCleanCache")
        self.radDowngradable = go("radDowngradable")
        self.radNotavailable = go("radNotavailable")
        self.radOldKernel = go("radOldKernel")
        self.lblMaintenanceHelp = go("lblMaintenanceHelp")

        # Translations
        self.window.set_title(_("SolydXK Update Manager"))
        self.btnInstall.set_label(_("Install"))
        self.btnRefresh.set_label(_("Refresh"))
        self.btnOutput.set_label(_("Output"))
        self.btnInfo.set_label(_("Information"))
        self.btnPreferences.set_label(_("Preferences"))
        self.btnMaintenance.set_label(_("Maintenance"))
        self.btnPackages.set_label(_("Packages"))
        self.uptodateText = self.umglobal.connectedText
        self.lblMaintenance.set_label(self.btnMaintenance.get_label())
        self.btnMaintenanceExecute.set_label(_("Execute"))
        self.chkMaintenanceSelectAll.set_label(_("Select all"))
        self.radCleanCache.set_label(_("Clean up the apt cache"))
        self.radUnneeded.set_label(_("Remove unneeded packages"))
        self.radNotavailable.set_label(_("Remove packages not available\nin the repositories"))
        self.radOldKernel.set_label(_("Remove old kernels"))
        self.radDowngradable.set_label(_("Downgrade packages with\nonly lower versions available"))
        self.lblMaintenanceHelp.set_label(_("Make sure you create\n"
                                             "a system image before you\n"
                                             "continue (e.g. Clonezilla)."))

        # VTE Terminal
        self.terminal = VirtualTerminal(userInputAllowed=self.umglobal.settings["allow-terminal-user-input"])
        self.swTerminal.add(self.terminal)
        self.terminal.set_vexpand(True)
        self.terminal.set_hexpand(True)
        self.terminal.connect('command-done', self.on_command_done)
        self.terminal.connect('line-added', self.on_line_added)
        palletList = ['#4A4A4A', '#BD1919', '#118011', '#CE6800', '#1919BC', '#8D138D', '#139494', '#A7A7A7']
        self.terminal.setTerminalColors("#000000", "#FFFFFF", palletList)
        self.swTerminal.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse("#FFFFFF"))

        # Disable all buttons
        self.btnInfo.set_sensitive(False)
        self.btnPreferences.set_sensitive(False)
        self.btnOutput.set_sensitive(False)
        self.btnRefresh.set_sensitive(False)
        self.btnInstall.set_sensitive(False)
        self.btnPackages.set_sensitive(False)
        self.btnMaintenance.set_sensitive(False)

        # Hide tabs if needed
        for tab in self.umglobal.settings["hide-tabs"]:
            if tab == "packages":
                self.nbMain.get_nth_page(0).set_visible(False)
                self.btnPackages.set_visible(False)
            elif tab == "output":
                self.nbMain.get_nth_page(1).set_visible(False)
                self.btnOutput.set_visible(False)
            elif tab == "info":
                self.nbMain.get_nth_page(2).set_visible(False)
                self.btnInfo.set_visible(False)
            elif tab == "maintenance":
                self.nbMain.get_nth_page(3).set_visible(False)
                self.btnMaintenance.set_visible(False)

        # Connect the signals and show the window
        self.builder.connect_signals(self)
        self.window.show()

        # Force the window to show
        while Gtk.events_pending():
            Gtk.main_iteration()

        # Just show something that we're busy
        msg = _("Gathering information...")
        self.terminal.executeCommand('echo "%s"' % msg, 'init')
        self.showOutput()

        # Treeview handlers
        self.tvHandler = TreeViewHandler(self.tvPck)
        self.tvMaintenanceHandler = TreeViewHandler(self.tvMaintenance)

        # Version information
        ver = _("Version")
        pckVer = self.apt.getPackageVersion('updatemanager')
        versionInfo = "%(ver)s: %(pckVer)s" % { "ver": ver, "pckVer": pckVer }
        if self.umglobal.localUpdVersion != "2000.01.01":
            versionInfo = "%(ver)s: %(pckVer)s" % { "ver": ver, "pckVer": pckVer }
        self.pushMessage(versionInfo)

        # Log basic information
        self.log.write("==============================================", "UM.init", "debug")
        self.log.write("UM version = %s" % versionInfo, "UM.init", "debug")
        self.log.write("==============================================", "UM.init", "debug")
        mirrorsList = join(self.umglobal.filesDir, basename(self.umglobal.settings["mirrors-list"]))
        if exists(mirrorsList):
            self.log.write("Mirrors list", "UM.init", "debug")
            with open(mirrorsList, 'r') as f:
                for line in f.readlines():
                    self.log.write(line, "UM.init", "debug")
            self.log.write("==============================================", "UM.init", "debug")

        # Refresh apt cache
        self.refresh()

        # Initialize maintenance screen
        self.fillTreeViewMaintenance()

    # ===============================================
    # Main window functions
    # ===============================================

    def on_btnInstall_clicked(self, widget):
        self.run_upgrade()

    def run_upgrade(self):
        nid = ""
        aptHasErrors = self.apt.aptHasErrors()
        if aptHasErrors is not None:
            MessageDialog(self.aptErrorText, aptHasErrors)
        elif self.upgradables:

            if self.apt.upgradablePackages:
                self.log.write("=================== upgradable pacages ====================", "UM.run_upgrade", "debug")
                self.log.write(self.createLogString(self.apt.upgradablePackages), "UM.run_upgrade", "debug")
            if self.apt.removedPackages:
                self.log.write("==================== removed packages =====================", "UM.run_upgrade", "debug")
                self.log.write(self.createLogString(self.apt.removedPackages), "UM.run_upgrade", "debug")
            if self.apt.newPackages:
                self.log.write("======================= new packages =======================", "UM.run_upgrade", "debug")
                self.log.write(self.createLogString(self.apt.newPackages), "UM.run_upgrade", "debug")
            if self.apt.heldbackPackages:
                self.log.write("=================== kept back packages =====================", "UM.run_upgrade", "debug")
                self.log.write(self.createLogString(self.apt.heldbackPackages), "UM.run_upgrade", "debug")

            if not self.quickUpdate:
                self.showOutput()
            contMsg = _("Continue installation?")
            if self.upgradableUM:
                cmd = "%s install updatemanager" % self.umglobal.settings['apt-get-string']
                cmd += "; %s install %s" % (self.umglobal.settings['apt-get-string'], " ".join(self.apt.getPackageDependencies('updatemanager')))
                nid = 'uminstallum'
                self.prepForCommand(nid)
                if self.quickUpdate:
                    self.ec.run(cmd)
                else:
                    self.terminal.executeCommand(cmd, nid)
                self.log.write("Execute command: %s (%s)" % (cmd, nid), "UM.on_btnInstall_clicked", "debug")
            else:
                msg = self.getDistUpgradeInfo()
                answer = True
                if msg != "":
                    answer = self.showConfirmationDlg(contMsg, msg)
                if answer:
                    cmd = "%s dist-upgrade" % self.umglobal.settings['apt-get-string']
                    #if self.umglobal.newUpd:
                    pre = join(self.umglobal.filesDir, self.umglobal.settings['pre-upd'].replace("[VERSION]", self.umglobal.serverUpdVersion))
                    post = join(self.umglobal.filesDir, self.umglobal.settings['post-upd'].replace("[VERSION]", self.umglobal.serverUpdVersion))
                    if exists(pre):
                        cmd = "/bin/bash %(pre)s; %(cmd)s" % { "pre": pre, "cmd": cmd }
                    if exists(post):
                        cmd = "%(cmd)s; /bin/bash %(post)s" % { "cmd": cmd, "post": post }
                    nid = 'umupd'
                    self.prepForCommand(nid)
                    if self.quickUpdate:
                        self.ec.run(cmd)
                    else:
                        self.terminal.executeCommand(cmd, nid)
                    self.log.write("Execute command: %s (%s)" % (cmd, nid), "UM.on_btnInstall_clicked", "debug")

        else:
            if not self.quickUpdate:
                MessageDialog(self.btnInstall.get_label(), self.uptodateText)

        return nid

    def on_btnRefresh_clicked(self, widget):
        self.refresh()

    def on_btnPackages_clicked(self, widget):
        self.showPackages()

    def on_btnOutput_clicked(self, widget):
        self.showOutput()

    def on_btnInfo_clicked(self, widget):
        self.showInfo()

    def on_btnPreferences_clicked(self, widget):
        # Run preferences in its own thread
        pref_thread = threading.Thread(target=self.openPreferences)
        pref_thread.setDaemon(True)
        pref_thread.start()

    def openPreferences(self):
        os.system("updatemanager -p")

    def on_btnMaintenance_clicked(self, widget):
        self.showMaintenance()

    def on_radCleanCache_toggled(self, widget):
        if widget.get_active():
            self.fillTreeViewMaintenance()

    def on_radUnneeded_toggled(self, widget):
        if widget.get_active():
            message = "%s\n\n%s" % (_("You might need to run this several times."), self.lblMaintenanceHelp.get_label().replace("\n", " "))
            WarningDialog(self.btnMaintenance.get_label(), message)
            self.fillTreeViewMaintenance()

    def on_radNotavailable_toggled(self, widget):
        if widget.get_active():
            message = "%s\n\n%s" % (_("Removing not available packages may break your system!"), self.lblMaintenanceHelp.get_label().replace("\n", " "))
            WarningDialog(self.btnMaintenance.get_label(), message)
            self.fillTreeViewMaintenance()

    def on_radOldKernel_toggled(self, widget):
        if widget.get_active():
            message = "%s\n\n%s" % (_("Once removed you will not be able to boot these kernels!"), self.lblMaintenanceHelp.get_label().replace("\n", " "))
            WarningDialog(self.btnMaintenance.get_label(), message)
            self.fillTreeViewMaintenance()

    def on_radDowngradable_toggled(self, widget):
        if widget.get_active():
            message = "%s\n\n%s" % (_("Downgrading packages may break your system!"), self.lblMaintenanceHelp.get_label().replace("\n", " "))
            WarningDialog(self.btnMaintenance.get_label(), message)
            self.fillTreeViewMaintenance()

    def on_btnMaintenanceExecute_clicked(self, widget):
        self.executeMaintenance()

    def on_chkMaintenanceSelectAll_toggled(self, widget):
        self.tvMaintenanceHandler.treeviewToggleAll(toggleColNrList=[0], toggleValue=widget.get_active())

    # ===============================================
    # Maintenance functions
    # ===============================================

    def enableMaintenance(self, enable=True):
        self.btnMaintenanceExecute.set_sensitive(enable)
        self.radUnneeded.set_sensitive(enable)
        self.radCleanCache.set_sensitive(enable)
        self.radDowngradable.set_sensitive(enable)
        self.radOldKernel.set_sensitive(enable)
        self.radNotavailable.set_sensitive(enable)
        self.chkMaintenanceSelectAll.set_sensitive(enable)
        if enable:
            self.chkMaintenanceSelectAll.set_active(False)

    def fillTreeViewMaintenance(self):
        blnCleanCache = self.radCleanCache.get_active()
        blnUnneeded = self.radUnneeded.get_active()
        blnDowngradable = self.radDowngradable.get_active()
        blnNotavailable = self.radNotavailable.get_active()
        blnOldKernels = self.radOldKernel.get_active()

        self.enableMaintenance(False)

        columnTypesList = ['bool', 'str', 'str', 'str']
        packages = [["", _("Package"), _("Installed"), _("Available")]]
        # Clear the treeview first
        self.tvMaintenanceHandler.fillTreeview(packages, columnTypesList, 0, 400, True)

        msg = ""
        if blnCleanCache:
            msg = _("Hit the Execute button to clean the cache.")
            columnTypesList = ['str']
            packages.append([msg])
        elif blnUnneeded:
            msg = self.radUnneeded.get_label()
            self.apt.createPackageLists("apt-get autoremove")
            for pck in self.apt.removedPackages:
                packages.append([False, pck[0], pck[1], pck[2]])
            self.apt.createPackageLists()
            # Add orphaned files
            self.apt.fillOrphanedPackages()
            for pck in self.apt.orphanedPackages:
                packages.append([False, pck[0], pck[1], pck[2]])
        elif blnNotavailable:
            msg = self.radNotavailable.get_label()
            self.apt.fillNotAvailablePackages()
            for pck in self.apt.notavailablePackages:
                if pck[0][0:6] != "linux-":
                    packages.append([False, pck[0], pck[1], ""])
        elif blnOldKernels:
            msg = self.radOldKernel.get_label()
            self.apt.fillKernelPackages()
            for pck in self.apt.kernelPackages:
                if "headers-486" not in pck[0] \
                    and "headers-586" not in pck[0] \
                    and "headers-686" not in pck[0] \
                    and "headers-amd64" not in pck[0] \
                    and "image-486" not in pck[0] \
                    and "image-586" not in pck[0] \
                    and "image-686" not in pck[0] \
                    and "image-amd64" not in pck[0]:

                    checkVersion = self.kernelVersion
                    if "kbuild" in pck[0]:
                        indMinus = self.kernelVersion.index("-")
                        indZero = self.kernelVersion.index("0")
                        if indZero > 0 and indZero < indMinus:
                            ind = indZero - 1
                        else:
                            ind = indMinus
                        if ind > 0:
                            checkVersion = self.kernelVersion[0:ind]
                    if checkVersion not in pck[0]:
                        packages.append([False, pck[0], pck[1], ""])
        elif blnDowngradable:
            msg = self.radDowngradable.get_label()
            self.apt.fillDowngradablePackages()
            for pck in self.apt.downgradablePackages:
                packages.append([False, pck[0], pck[1], pck[2]])

        if len(packages) > 1:
            self.tvMaintenanceHandler.fillTreeview(packages, columnTypesList, 0, 400, True)
        else:
            if not blnCleanCache:
                msg = _("\"%s\"\n did not return any results.") % msg
                MessageDialog(self.btnMaintenance.get_label(), msg)

        self.enableMaintenance(True)

    def executeMaintenance(self):
        blnCleanCache = self.radCleanCache.get_active()
        blnDowngradable = self.radDowngradable.get_active()
        blnNotNeeded = self.radUnneeded.get_active()
        downgradeString = ""
        deleteString = ""
        updateGrub = False
        cmd = ""

        self.enableMaintenance(False)

        if blnCleanCache:
            safe = False
            msg = _("Do you want to completely clean the apt cache?\n\n"
                    "When No, only unavailable installation packages are removed.")
            answer = QuestionDialog(self.radCleanCache.get_label(), msg)
            if answer:
                safe = True
            self.apt.cleanCache(safe)
            msg = _("Apt cache has been cleaned.")
            MessageDialog(self.radCleanCache.get_label(), msg)
        else:
            # Get user selected packages
            model = self.tvMaintenance.get_model()
            itr = model.get_iter_first()
            while itr is not None:
                sel = model.get_value(itr, 0)
                if sel:
                    pck = model.get_value(itr, 1)
                    avVer = model.get_value(itr, 3)
                    if blnDowngradable:
                        downgradeString += " %(pck)s=%(avVer)s" % {"pck": pck, "avVer": avVer}
                    else:
                        deleteString += " %s" % pck
                        if "linux-image" in pck:
                            updateGrub = True
                itr = model.iter_next(itr)

            if downgradeString != "":
                cmd = "%s install %s" % (self.umglobal.settings['apt-get-string'], downgradeString)
            elif deleteString != "":
                cmd = "%s purge %s" % (self.umglobal.settings['apt-get-string'], deleteString)

        if cmd != "":
            self.apt.createPackageLists(cmd)
            msg = self.getDistUpgradeInfo()
            answer = True
            if msg != "":
                contMsg = _("Execute maintenance changes?")
                answer = self.showConfirmationDlg(contMsg, msg)
            if answer:
                if updateGrub:
                    cmd += "; update-grub"
                if blnNotNeeded:
                    cmd += "; %s purge $(COLUMNS=132 dpkg -l | grep ^rc | awk '{ print $2 }')" % self.umglobal.settings['apt-get-string']
                self.showOutput()
                nid = 'ummaintenance'
                self.prepForCommand(nid)
                self.terminal.executeCommand(cmd, nid)
                self.log.write("Execute command: %s (%s)" % (cmd, nid), "UM.executeMaintenance", "debug")

        self.enableMaintenance(True)

    # ===============================================
    # General functions
    # ===============================================

    def prepForCommand(self, nid):
        os.system("touch %s" % self.umglobal.umfiles[nid])
        if not self.quickUpdate:
            self.btnRefresh.set_sensitive(False)
            self.btnInstall.set_sensitive(False)
            self.btnMaintenance.set_sensitive(False)

    def on_line_added(self, terminal, line):
        if line.strip()[0:2].upper() == "E:":
            self.log.write(line, "UM.on_line_added", "error")
        else:
            self.log.write(line, "UM.on_line_added", "info")

    def on_command_done(self, terminal, pid, nid):
        if nid != "init":
            self.log.write("Command finished (pid=%s, nid=%s)" % (pid, nid), "UM.on_command_done", "info")
            if nid == "uminstallum":
                # Reload UM
                self.log.write("Updating UM: kill process of updatemanagerpref.py", "UM.on_command_done", "debug")
                self.umglobal.killScriptProcess("updatemanagerpref.py")
                # Reload tray as user
                self.log.write("Updating UM: kill process of updatemanagertray.py", "UM.on_command_done", "debug")
                self.umglobal.killScriptProcess("updatemanagertray.py")
                cmd = "sudo -u {} updatemanager -t -r".format(self.user)
                os.system(cmd)
                self.log.write("UM updated: reload tray as user {}".format(self.user), "UM.on_command_done", "debug")
                # Reload UM window
                cmd = join(self.umglobal.scriptDir, "updatemanager.py")
                if self.quickUpdate:
                    cmd = join(self.umglobal.scriptDir, "updatemanager.py -q")
                self.umglobal.reloadWindow(cmd, self.user)
                self.log.write("UM updated: reload {0} as user {1}".format(cmd, self.user), "UM.on_command_done", "debug")
            elif nid == "umrefresh":
                # Build installed packages info list
                self.apt.createPackagesInfoList()
                # Run post update when needed
                self.postUpdate()
            elif nid == "ummaintenance":
                self.enableMaintenance(True)
                self.fillTreeViewMaintenance()
                self.btnInstall.set_sensitive(True)
                self.btnRefresh.set_sensitive(True)
                self.btnPackages.set_sensitive(True)
                self.btnMaintenance.set_sensitive(True)
                self.showMaintenance()
            elif nid == 'umupd':
                # Save update version in hist file
                self.umglobal.saveHistVersion("upd", self.umglobal.serverUpdVersion)
                self.log.write("Save history upd=%s" % self.umglobal.serverUpdVersion, "UM.on_command_done", "debug")
                self.deleteScripts()

            # Refresh data after install or update
            self.umglobal.collectData()
            self.apt.createPackageLists()
            self.fillTreeView()

            # Enable the buttons and load the info page
            self.log.write("Re-initiate window after terminal command: %s" % str(not self.quickUpdate), "UM.on_command_done", "debug")
            if not self.quickUpdate:
                self.btnInstall.set_sensitive(True)
                self.btnRefresh.set_sensitive(True)
                self.btnPackages.set_sensitive(True)
                self.btnMaintenance.set_sensitive(True)
                self.btnInfo.set_sensitive(True)
                self.loadInfo()

                if self.umglobal.newUpd:
                    self.showInfo()
                else:
                    # This throws a lock file error in Plasma5
                    #aptHasErrors = self.apt.aptHasErrors()
                    #if aptHasErrors is not None:
                        #MessageDialog(self.aptErrorText, aptHasErrors)
                    #el
                    if self.upgradables:
                        self.showPackages()
                    else:
                        self.showInfo()
                        MessageDialog(self.btnInfo.get_label(), self.uptodateText)
                self.log.write("Re-initiate window complete", "UM.on_command_done", "debug")

            # Cleanup name file(s)
            for fle in glob(join(self.umglobal.filesDir, '.um*')):
                remove(fle)

    def createLogString(self, packagesList):
        lst = []
        for data in packagesList:
            lst.append(data[0])
        return ' '.join(lst)

    def refresh(self):
        # Refresh server info
        print((self.umglobal.hasInternet))
        self.umglobal.getServerInfo()
        print((self.umglobal.hasInternet))

        # Check of programs locking apt
        prog = self.apt.getAptCacheLockedProgram(self.umglobal.settings["apt-packages"])
        if prog is not None:
            msg = _("Another program is locking the apt cache\n\n"
                    "Please, close the program before refreshing:\n"
                    "* %s" % prog)
            MessageDialog(self.btnRefresh.get_label(), msg)
            self.log.write("%s is locking the apt cache" % prog, "UM.refresh", "warning")
        elif self.umglobal.hasInternet:
            if not self.quickUpdate:
                # Update the apt cache
                self.btnPreferences.set_sensitive(True)
                self.btnOutput.set_sensitive(True)
                self.btnRefresh.set_sensitive(False)
                self.btnInstall.set_sensitive(False)
                self.btnMaintenance.set_sensitive(False)
                self.btnPackages.set_sensitive(True)
                self.showOutput()
            cmd = "dpkg --configure -a; %s -f install; apt-get update" % self.umglobal.settings['apt-get-string']
            nid = 'umrefresh'
            self.prepForCommand(nid)
            if self.quickUpdate:
                self.ec.run(cmd)
            else:
                self.terminal.executeCommand(cmd, nid)
            self.apt.initAptShowVersions()
            self.log.write("Execute command: %s (%s)" % (cmd, nid), "UM.refresh", "debug")
        else:
            if not self.quickUpdate:
                # No internet connection
                self.btnInstall.set_sensitive(True)
                self.btnRefresh.set_sensitive(True)
                self.btnPackages.set_sensitive(True)
                self.btnMaintenance.set_sensitive(True)
                self.btnInfo.set_sensitive(True)
                self.btnOutput.set_sensitive(True)
                self.btnPreferences.set_sensitive(True)
                self.loadInfo()
                self.showInfo()

    def postUpdate(self):
        # Check for changed version information
        if self.umglobal.newUpd and self.umglobal.serverUpdVersion is not None:
            self.getScripts([self.umglobal.settings['pre-upd'].replace("[VERSION]", self.umglobal.serverUpdVersion),
                            self.umglobal.settings['post-upd'].replace("[VERSION]", self.umglobal.serverUpdVersion)])

    def fillTreeView(self):
        # First check if this application is upgradable
        self.upgradableUM = self.getUpgradablePackages(packageNames=["updatemanager"])
        if self.upgradableUM:
            self.upgradables = self.upgradableUM
        else:
            # Get a list of packages that can be upgraded
            self.upgradableUM = []
            self.upgradables = self.getUpgradablePackages()
            #if not self.upgradables:
                ## Check for black listed packages
                #cmd = "dpkg --get-selections | grep hold$ | awk '{print $1}'"
                #lst = self.ec.run(cmd, False)
                #for pck in lst:
                    #self.upgradables.append([pck.strip(), _("blacklisted"), ""])

        if not self.quickUpdate:
            contentList = [[_("Package"), _("Current version"), _("New version")]] + self.upgradables
            self.tvHandler.fillTreeview(contentList=contentList, columnTypesList=['str', 'str', 'str'], firstItemIsColName=True)

    def getUpgradablePackages(self, packageNames=[]):
        upckList = []
        if packageNames:
            upckList = []
            for packageName in packageNames:
                for upck in self.apt.upgradablePackages:
                    if upck[0] == packageName:
                        upckList.append(upck)
                        break
        else:
            upckList = self.apt.upgradablePackages
        return upckList

    def getDistUpgradeInfo(self, upgradablesOnly=False):
        info = ""
        if upgradablesOnly:
            if self.apt.upgradablePackages:
                info = "<strong>%s</strong><br>" % self.apt.upgradablePackagesText
                for pck in self.apt.upgradablePackages:
                    info += "%s " % pck[0]
        else:
            if self.apt.removedPackages:
                info = "<strong>%s</strong><br>" % self.removedPackagesText
                for pck in self.apt.removedPackages:
                    info += "%s " % pck[0]
            if self.apt.newPackages:
                if info != "":
                    info += "<p>&nbsp;</p>"
                info += "<strong>%s</strong><br>" % self.newPackagesText
                for pck in self.apt.newPackages:
                    info += "%s " % pck[0]
            if self.apt.heldbackPackages:
                if info != "":
                    info += "<p>&nbsp;</p>"
                info += "<strong>%s</strong><br>" % self.heldbackPackagesText
                for pck in self.apt.heldbackPackages:
                    info += "%s " % pck[0]
            if self.apt.downgradablePackages:
                if info != "":
                    info += "<p>&nbsp;</p>"
                info += "<strong>%s</strong><br>" % self.downgradePackagesText
                for pck in self.apt.downgradablePackages:
                    info += "%s " % pck[0]
        return info

    def showPackages(self):
        self.nbMain.set_current_page(0)

    def showOutput(self):
        self.nbMain.set_current_page(1)
        self.terminal.grab_focus()

    def showInfo(self):
        self.nbMain.set_current_page(2)

    def showMaintenance(self):
        self.nbMain.set_current_page(3)

    def showConfirmationDlg(self, title, message):
        head = "<html><head><style>body { font-family: Arial, Helvetica, Verdana, Sans-serif; font-size: 12px; color: #555555; background: #ffffff; }</style></head><body>"
        end = "</body></html>"
        html = "%s%s%s" % (head, message, end)
        sw = Gtk.ScrolledWindow()
        sw.add(SimpleBrowser(html))
        return CustomQuestionDialog(title, sw, 550, 300, self.window).show()

    # Get pre-install script and post-install script from the server
    def getScripts(self, files):
        for fle in files:
            flePath = join(self.umglobal.filesDir, fle)
            if not exists(flePath):
                # Get the new scripts if they exist
                url = "%s/%s/%s" % (self.umglobal.settings['solydxk'], self.umglobal.settings["umfilesdir"], fle)
                try:
                    txt = urlopen(url).read().decode('utf-8')
                    if txt != '':
                        # Save to a file and make executable
                        self.log.write("Save script = %s" % flePath, "UM.getScripts", "debug")
                        with open(flePath, 'w') as f:
                            f.write(txt)
                        chmod(flePath, 0o755)
                except:
                    pass

    def loadInfo(self):
        languageDir = self.get_language_dir()
        url = join("file://%s" % languageDir, self.umglobal.settings['up-to-date'])
        self.btnInfo.set_icon_name("help-about")
        if self.upgradables:
            url = join("file://%s" % languageDir, self.umglobal.settings['updates'])
            if self.umglobal.newUpd:
                url = "%s/%s/%s" % (self.umglobal.settings['solydxk'], self.umglobal.settings["umfilesdir"], self.umglobal.settings['upd-info'])
        elif self.umglobal.serverUpdVersion is None:
            url = join("file://%s" % languageDir, self.umglobal.settings['not-found'])

        self.log.write("Load info url: %s" % url, "UM.loadInfo", "debug")

        children = self.swInfo.get_children()
        if children:
            children[0].openUrl(url)
        else:
            self.swInfo.add(SimpleBrowser(url))

    def get_language_dir(self):
        # First test if full locale directory exists, e.g. html/pt_BR,
        # otherwise perhaps at least the language is there, e.g. html/pt
        # and if that doesn't work, try html/pt_PT
        lang = self.get_current_language()
        path = join(self.umglobal.htmlDir, lang)
        if not isdir(path):
            base_lang = lang.split('_')[0].lower()
            path = join(self.umglobal.htmlDir, base_lang)
            if not isdir(path):
                path = join(self.umglobal.htmlDir, "{}_{}".format(base_lang, base_lang.upper()))
                if not isdir(path):
                    path = join(self.umglobal.htmlDir, 'en')
        return path

    def get_current_language(self):
        lang = os.environ.get('LANG', 'US').split('.')[0]
        if lang == '':
            lang = 'en'
        return lang

    def pushMessage(self, message):
        if message is not None:
            context = self.statusbar.get_context_id('message')
            self.statusbar.push(context, message)

    def checkFilesDir(self):
        if not exists(self.umglobal.filesDir):
            makedirs(self.umglobal.filesDir)
        oldFiles = glob(join(self.umglobal.scriptDir, 'pre-*')) + \
                   glob(join(self.umglobal.scriptDir, 'post-*')) + \
                   [join(self.umglobal.scriptDir, 'updatemanager.hist')] + \
                   [join(self.umglobal.scriptDir, 'mirrors.list')]
        for fle in oldFiles:
            if exists(fle):
                fleName = basename(fle)
                if not exists(join(self.umglobal.filesDir, fleName)):
                    move(fle, self.umglobal.filesDir)
                else:
                    remove(fle)
        chmod(self.umglobal.filesDir, 0o777)

    def deleteScripts(self, UpdVersion=None):
        UpdVersion = "*"
        if UpdVersion is not None:
            UpdVersion = "*%s" % UpdVersion

        oldFiles = glob(join(self.umglobal.filesDir, "pre-%s" % UpdVersion)) + glob(join(self.umglobal.filesDir, "post-%s" % UpdVersion))
        for fle in oldFiles:
            remove(fle)
            self.log.write("Cleanup file: %s" % fle, "UM.deleteScripts", "debug")

    # Close the gui
    def on_windowMain_destroy(self, widget):
        # Close the app
        Gtk.main_quit()
Example #16
0
class UpdateManagerTray(object):
    def __init__(self):
        # Check if script is running
        self.scriptName = basename(__file__)
        self.umglobal = UmGlobal()
        self.ec = ExecCmd()
        self.status = AppIndicator3.IndicatorStatus

        # Load window and widgets
        self.builder = Gtk.Builder()
        self.builder.add_from_file(
            join(self.umglobal.shareDir, 'updatemanagerlegend.glade'))
        go = self.builder.get_object
        # Main window objects
        self.legend = go("windowLegenda")
        go("imgConnected").set_from_file(
            join(self.umglobal.iconsDir,
                 self.umglobal.settings["icon-connected"]))
        go("imgDisconnected").set_from_file(
            join(self.umglobal.iconsDir,
                 self.umglobal.settings["icon-disconnected"]))
        go("imgError").set_from_file(
            join(self.umglobal.iconsDir, self.umglobal.settings["icon-error"]))
        go("imgExecute").set_from_file(
            join(self.umglobal.iconsDir,
                 self.umglobal.settings["icon-execute"]))
        go("imgUpdates").set_from_file(
            join(self.umglobal.iconsDir,
                 self.umglobal.settings["icon-updates"]))
        go("imgWarning").set_from_file(
            join(self.umglobal.iconsDir,
                 self.umglobal.settings["icon-warning"]))
        go("lblConnected").set_label(self.umglobal.connectedText)
        go("lblDisconnected").set_label(self.umglobal.disconnectedText)
        go("lblExecute").set_label(self.umglobal.executeText)
        self.lblError = go("lblError")
        self.lblWarning = go("lblWarning")
        self.lblUpdates = go("lblUpdates")
        self.builder.connect_signals(self)

        # Handle arguments
        parser = argparse.ArgumentParser(
            description='SolydXK Update Manager Tray')
        parser.add_argument('-r', '--reload', action="store_true", help='')
        args, extra = parser.parse_known_args()

        #print((">> args = {}".format(args)))
        if args.reload:
            pids = self.umglobal.getProcessPids("updatemanagertray.py")
            if len(pids) > 1:
                print(("updatemanagertray.py already running - kill pid {}".
                       format(pids[0])))
                os.system("kill {}".format(pids[0]))

        # Build status icon menu
        self.quitText = _("Quit")
        menu = Gtk.Menu()
        menuUm = Gtk.MenuItem(self.umglobal.title)
        menuUm.connect('activate', self.open_um)
        menu.append(menuUm)
        # Separator not functioning in wheezy
        menuSep1 = Gtk.SeparatorMenuItem()
        menu.append(menuSep1)
        menuQupd = Gtk.MenuItem(_("Quick Update"))
        menuQupd.connect('activate', self.quick_update)
        menu.append(menuQupd)
        menuSep2 = Gtk.SeparatorMenuItem()
        menu.append(menuSep2)
        menuPref = Gtk.MenuItem(_("Preferences"))
        menuPref.connect('activate', self.open_preferences)
        menu.append(menuPref)
        menuLegend = Gtk.MenuItem(_("Legend"))
        menuLegend.connect('activate', self.open_legend)
        menu.append(menuLegend)
        menuQuit = Gtk.MenuItem(self.quitText)
        menuQuit.connect('activate', self.quit_tray)
        menu.append(menuQuit)
        menu.show_all()

        if self.umglobal.isKf5:
            print(("> Running KDE5"))
            # Use this for KDE5
            self.indicator = AppIndicator3.Indicator.new_with_path(
                "updatemanager", self.umglobal.settings["icon-connected"],
                AppIndicator3.IndicatorCategory.SYSTEM_SERVICES,
                self.umglobal.iconsDir)
            # Title not showing in KDE4
            self.indicator.set_title("<strong>{}</strong>".format(
                self.umglobal.title))
            self.indicator.set_secondary_activate_target(menuUm)
            self.indicator.set_status(AppIndicator3.IndicatorStatus.ACTIVE)
            self.indicator.set_menu(menu)
        else:
            print(("> Running KDE4"))
            # Use this for KDE4
            self.indicator = Gtk.StatusIcon()
            #self.indicator.connect('activate', self.open_um)
            self.indicator.connect('popup-menu', self.popup_menu, menu)

        self.umrefresh = UmRefresh(self.umglobal, self.indicator)
        self.notifier = UmNotifier(self.umrefresh)

        # Initiate first check
        self.refresh()

    def refresh(self, widget=None):
        if not self.umglobal.isProcessRunning("updatemanager.py"):
            self.umrefresh.refresh()
        # Return True or timeout_add_seconds will only run once
        return True

    def popup_menu(self, widget, button, time, data):
        data.show_all()
        data.popup(None, None, None, None, button, time)

    def open_um(self, widget):
        if not self.umglobal.isProcessRunning("updatemanager.py"):
            # Run UM in its own thread
            pref_thread = threading.Thread(target=self.ec.run,
                                           args=("updatemanager", ))
            pref_thread.setDaemon(True)
            pref_thread.start()

    def quick_update(self, widget):
        if not self.umglobal.isProcessRunning("updatemanager.py"):
            parm = ""
            if not self.umglobal.newUpd:
                # Quick update
                parm = " -q"
            # Run UM in its own thread
            pref_thread = threading.Thread(
                target=self.ec.run, args=("updatemanager{}".format(parm), ))
            pref_thread.setDaemon(True)
            pref_thread.start()

    def open_preferences(self, widget):
        # Run preferences in its own thread
        if not self.umglobal.isProcessRunning("updatemanagerpref.py"):
            pref_thread = threading.Thread(target=self.ec.run,
                                           args=("updatemanager -p", ))
            pref_thread.setDaemon(True)
            pref_thread.start()

    def quit_tray(self, widget):
        if self.umglobal.isUpgrading():
            MessageDialog(self.quitText, _("Cannot quit: upgrade in progress"))
        else:
            self.umglobal.killScriptProcess("updatemanager.py")
            self.umglobal.killScriptProcess("updatemanagerpref.py")
            self.notifier.quit()
            Gtk.main_quit()

    # Show the legend window
    def open_legend(self, widget):
        self.lblError.set_label(self.umglobal.errorText)
        self.lblUpdates.set_label(self.umglobal.updatesText)
        self.lblWarning.set_label(self.umglobal.warningText)
        self.legend.show_all()

    # Hide the legend window when mouse leaves the window
    def on_windowLegenda_leave_notify_event(self, widget, event):
        if event.detail != Gdk.NotifyType.NONLINEAR:
            return False
        self.legend.hide()
Example #17
0
    def __init__(self):
        # Check if script is running
        self.scriptName = basename(__file__)
        self.umglobal = UmGlobal()
        self.user = self.umglobal.getLoginName()

        # Initiate logging
        self.logFile = join('/var/log', self.umglobal.settings['log'])
        print(("UM log = %s" % self.logFile))
        self.log = Logger(self.logFile, maxSizeKB=5120)

        # Remove scripts
        self.deleteScripts(self.umglobal.localUpdVersion)

        # Initialize
        self.ec = ExecCmd(loggerObject=self.log)
        self.apt = UmApt(self.umglobal)
        self.kernelVersion = self.umglobal.getKernelVersion()
        self.upgradables = []
        self.upgradableUM = []
        self.window = None

        # Handle arguments
        parser = argparse.ArgumentParser(description='SolydXK Update Manager')
        parser.add_argument('-q','--quick', action="store_true", help='Quick upgrade')
        parser.add_argument('-r','--reload', action="store_true", help='')
        args, extra = parser.parse_known_args()

        self.quickUpdate = False
        if args.quick and not self.umglobal.newUpd:
            self.quickUpdate = True
        if args.reload:
            pids = self.umglobal.getProcessPids("updatemanager.py")
            if len(pids) > 1:
                print(("updatemanager.py already running - kill pid {}".format(pids[0])))
                os.system("kill {}".format(pids[0]))

        # Set some global translations
        self.aptErrorText = _("Apt error")
        self.upgradablePackagesText = _("The following packages will be upgraded:")
        self.newPackagesText = _("The following NEW packages will be installed:")
        self.removedPackagesText = _("The following packages will be REMOVED:")
        self.heldbackPackagesText = _("The following packages have been kept back:")
        self.downgradePackagesText = _("The following packages are going to be downgraded:")

        # Cleanup first
        for fle in glob(join(self.umglobal.filesDir, '.um*')):
            remove(fle)

        # Load window and widgets
        self.builder = Gtk.Builder()
        self.builder.add_from_file(join(self.umglobal.shareDir, 'updatemanager.glade'))
        go = self.builder.get_object

        # Quick update
        if self.quickUpdate:
            # Refresh data
            self.refresh()
            self.umglobal.collectData()
            self.apt.createPackagesInfoList()
            self.apt.createPackageLists()
            self.fillTreeView()

            # Run upgrade
            nid = self.run_upgrade()

            if nid != "":
                self.on_command_done(None, 0, nid)

            sys.exit(2)

        # Make sure the files directory is set correctly
        self.checkFilesDir()

        # Main window objects
        self.window = go("windowMain")
        #self.window.set_icon_from_file(join(self.umglobal.iconsDir, self.umglobal.settings["icon-connected"]))
        self.tvPck = go("tvPck")
        self.swTerminal = go("swTerminal")
        self.statusbar = go("statusbar")
        self.btnInstall = go("btnInstall")
        self.btnRefresh = go("btnRefresh")
        self.btnPackages = go("btnPackages")
        self.btnOutput = go("btnOutput")
        self.btnInfo = go("btnInfo")
        self.btnPreferences = go("btnPreferences")
        self.nbMain = go("nbMain")
        self.swInfo = go("swInfo")
        self.btnMaintenance = go("btnMaintenance")
        self.lblMaintenance = go("lblMaintenance")
        self.tvMaintenance = go("tvMaintenance")
        self.btnMaintenanceExecute = go("btnMaintenanceExecute")
        self.chkMaintenanceSelectAll = go("chkMaintenanceSelectAll")
        self.radUnneeded = go("radUnneeded")
        self.radCleanCache = go("radCleanCache")
        self.radDowngradable = go("radDowngradable")
        self.radNotavailable = go("radNotavailable")
        self.radOldKernel = go("radOldKernel")
        self.lblMaintenanceHelp = go("lblMaintenanceHelp")

        # Translations
        self.window.set_title(_("SolydXK Update Manager"))
        self.btnInstall.set_label(_("Install"))
        self.btnRefresh.set_label(_("Refresh"))
        self.btnOutput.set_label(_("Output"))
        self.btnInfo.set_label(_("Information"))
        self.btnPreferences.set_label(_("Preferences"))
        self.btnMaintenance.set_label(_("Maintenance"))
        self.btnPackages.set_label(_("Packages"))
        self.uptodateText = self.umglobal.connectedText
        self.lblMaintenance.set_label(self.btnMaintenance.get_label())
        self.btnMaintenanceExecute.set_label(_("Execute"))
        self.chkMaintenanceSelectAll.set_label(_("Select all"))
        self.radCleanCache.set_label(_("Clean up the apt cache"))
        self.radUnneeded.set_label(_("Remove unneeded packages"))
        self.radNotavailable.set_label(_("Remove packages not available\nin the repositories"))
        self.radOldKernel.set_label(_("Remove old kernels"))
        self.radDowngradable.set_label(_("Downgrade packages with\nonly lower versions available"))
        self.lblMaintenanceHelp.set_label(_("Make sure you create\n"
                                             "a system image before you\n"
                                             "continue (e.g. Clonezilla)."))

        # VTE Terminal
        self.terminal = VirtualTerminal(userInputAllowed=self.umglobal.settings["allow-terminal-user-input"])
        self.swTerminal.add(self.terminal)
        self.terminal.set_vexpand(True)
        self.terminal.set_hexpand(True)
        self.terminal.connect('command-done', self.on_command_done)
        self.terminal.connect('line-added', self.on_line_added)
        palletList = ['#4A4A4A', '#BD1919', '#118011', '#CE6800', '#1919BC', '#8D138D', '#139494', '#A7A7A7']
        self.terminal.setTerminalColors("#000000", "#FFFFFF", palletList)
        self.swTerminal.modify_bg(Gtk.StateType.NORMAL, Gdk.color_parse("#FFFFFF"))

        # Disable all buttons
        self.btnInfo.set_sensitive(False)
        self.btnPreferences.set_sensitive(False)
        self.btnOutput.set_sensitive(False)
        self.btnRefresh.set_sensitive(False)
        self.btnInstall.set_sensitive(False)
        self.btnPackages.set_sensitive(False)
        self.btnMaintenance.set_sensitive(False)

        # Hide tabs if needed
        for tab in self.umglobal.settings["hide-tabs"]:
            if tab == "packages":
                self.nbMain.get_nth_page(0).set_visible(False)
                self.btnPackages.set_visible(False)
            elif tab == "output":
                self.nbMain.get_nth_page(1).set_visible(False)
                self.btnOutput.set_visible(False)
            elif tab == "info":
                self.nbMain.get_nth_page(2).set_visible(False)
                self.btnInfo.set_visible(False)
            elif tab == "maintenance":
                self.nbMain.get_nth_page(3).set_visible(False)
                self.btnMaintenance.set_visible(False)

        # Connect the signals and show the window
        self.builder.connect_signals(self)
        self.window.show()

        # Force the window to show
        while Gtk.events_pending():
            Gtk.main_iteration()

        # Just show something that we're busy
        msg = _("Gathering information...")
        self.terminal.executeCommand('echo "%s"' % msg, 'init')
        self.showOutput()

        # Treeview handlers
        self.tvHandler = TreeViewHandler(self.tvPck)
        self.tvMaintenanceHandler = TreeViewHandler(self.tvMaintenance)

        # Version information
        ver = _("Version")
        pckVer = self.apt.getPackageVersion('updatemanager')
        versionInfo = "%(ver)s: %(pckVer)s" % { "ver": ver, "pckVer": pckVer }
        if self.umglobal.localUpdVersion != "2000.01.01":
            versionInfo = "%(ver)s: %(pckVer)s" % { "ver": ver, "pckVer": pckVer }
        self.pushMessage(versionInfo)

        # Log basic information
        self.log.write("==============================================", "UM.init", "debug")
        self.log.write("UM version = %s" % versionInfo, "UM.init", "debug")
        self.log.write("==============================================", "UM.init", "debug")
        mirrorsList = join(self.umglobal.filesDir, basename(self.umglobal.settings["mirrors-list"]))
        if exists(mirrorsList):
            self.log.write("Mirrors list", "UM.init", "debug")
            with open(mirrorsList, 'r') as f:
                for line in f.readlines():
                    self.log.write(line, "UM.init", "debug")
            self.log.write("==============================================", "UM.init", "debug")

        # Refresh apt cache
        self.refresh()

        # Initialize maintenance screen
        self.fillTreeViewMaintenance()
Example #18
0
class UpdateManagerTray(object):
    def __init__(self):
        # Check if script is running
        self.scriptDir = abspath(dirname(__file__))
        self.filesDir = join(self.scriptDir, "files")
        self.scriptName = basename(__file__)
        self.umglobal = UmGlobal()
        self.ec = ExecCmd()

        # Handle arguments
        parser = argparse.ArgumentParser(
            description='Trail Update Manager Tray')
        parser.add_argument('-r', '--reload', action="store_true", help='')
        args, extra = parser.parse_known_args()

        print((">> args = {}".format(args)))
        if args.reload:
            pids = self.umglobal.getScriptPids("updatemanagertray.py")
            if len(pids) > 1:
                print(("updatemanagertray.py already running - kill pid {}".
                       format(pids[0])))
                os.system("kill {}".format(pids[0]))

        # Build status icon menu
        self.refreshText = _("Refresh")
        self.quitText = _("Quit")
        menu = Gtk.Menu()
        menuUm = Gtk.MenuItem(_("Update Manager"))
        menuUm.connect('activate', self.open_um)
        menu.append(menuUm)
        # Separator not functioning in wheezy
        #menuSep1 = Gtk.SeparatorMenuItem()
        #menu.append(menuSep1)
        menuPref = Gtk.MenuItem(_("Preferences"))
        menuPref.connect('activate', self.open_preferences)
        menu.append(menuPref)
        menuRefresh = Gtk.MenuItem(self.refreshText)
        menuRefresh.connect('activate', self.manualRefresh)
        menu.append(menuRefresh)
        menuQuit = Gtk.MenuItem(self.quitText)
        menuQuit.connect('activate', self.quit_tray)
        menu.append(menuQuit)

        self.statusIcon = Gtk.StatusIcon()
        self.umrefresh = UmRefresh(self.statusIcon, self.umglobal)
        self.notifier = UmNotifier(self.statusIcon, self.umglobal,
                                   self.umrefresh)

        self.statusIcon.connect('activate', self.icon_activate)
        self.statusIcon.connect('popup-menu', self.popup_menu, menu)

        # Initiate first check
        self.refresh()

        # Loop the refresh function
        # For some reason you cannot start a threaded class from init
        self.timeout = int(self.umglobal.settings["hrs-check-status"] * 60 *
                           60)
        GObject.timeout_add_seconds(self.timeout, self.refresh)

    def refresh(self, widget=None):
        self.umrefresh.refresh()
        # Return True or timeout_add_seconds will only run once
        return True

    def manualRefresh(self, widget=None):
        self.umrefresh.refresh()

    def popup_menu(self, widget, button, time, data):
        data.show_all()
        data.popup(None, None, None, None, button, time)

    def open_um(self, widget):
        if not self.umglobal.isSrciptRunning("updatemanager.py"):
            # Run UM in its own thread
            pref_thread = threading.Thread(target=self.ec.run,
                                           args=("updatemanager", ))
            pref_thread.setDaemon(True)
            pref_thread.start()

    def icon_activate(self, widget):
        if not self.umglobal.isSrciptRunning("updatemanager.py"):
            parm = ""
            if not self.umglobal.newUpd:
                # Quick update
                parm = " -q"
            # Run UM in its own thread
            pref_thread = threading.Thread(
                target=self.ec.run, args=("updatemanager{}".format(parm), ))
            pref_thread.setDaemon(True)
            pref_thread.start()

    def open_preferences(self, widget):
        # Run preferences in its own thread
        if not self.umglobal.isSrciptRunning("updatemanagerpref.py"):
            pref_thread = threading.Thread(target=self.ec.run,
                                           args=("updatemanager -p", ))
            pref_thread.setDaemon(True)
            pref_thread.start()

    def showInfoDlg(self, title, message):
        MessageDialog(title, message)

    def quit_tray(self, widget):
        if self.umglobal.isUpgrading():
            self.showInfoDlg(self.quitText,
                             _("Cannot quit: upgrade in progress"))
        else:
            self.umglobal.killScriptProcess("updatemanager.py")
            self.umglobal.killScriptProcess("updatemanagerpref.py")
            self.notifier.quit()
            Gtk.main_quit()