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)
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()
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()
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()
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:
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()
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()
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> </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> </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> </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()
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:
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> </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> </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> </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.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()
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()
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()