def run(self, cmd, realTime=True, returnAsList=True, outputTreeView=None): tvHandler = None if outputTreeView is not None: tvHandler = TreeViewHandler(outputTreeView) tvHandler.fillTreeview([], columnTypesList=['str']) msg = "Command to execute: %(cmd)s" % {"cmd": cmd} if self.log: self.log.write(msg, 'execcmd.run', 'debug') else: print(msg) p = subprocess.Popen([cmd], shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) lstOut = [] while True: line = p.stdout.readline() if not line: break # Strip the line, also from null spaces (strip() only strips white spaces) line = line.decode('utf-8').rstrip().rstrip("\0") lstOut.append(line) if realTime: if tvHandler is not None: tvHandler.fillTreeview([line], columnTypesList=['str'], appendToExisting=True, setCursor=tvHandler.getRowCount()) if self.log: self.log.write(line, 'execcmd.run', 'info') else: print(line) try: sys.stdout.flush() except: pass while Gtk.events_pending(): Gtk.main_iteration() ret = lstOut if not returnAsList: ret = "\n".join(lstOut).strip() return ret
class DPM: def __init__(self): self.scriptDir = dirname(realpath(__file__)) # Load window and widgets self.builder = Gtk.Builder() self.builder.add_from_file(join(self.scriptDir, '../../share/debian-plymouth-manager/debian-plymouth-manager.glade')) # Main window objects go = self.builder.get_object self.window = go('dpmWindow') self.tv1 = go('tv1') self.tv2 = go('tv2') self.sw2 = go('sw2') self.statusbar = go('statusbar') self.btnPlymouth = go('btnPlymouth') self.btnThemes = go('btnThemes') self.btnGrub = go('btnGrub') self.pbDPM = go('pbDPM') self.btn1 = go('btn1') self.btn2 = go('btn2') self.lblTitle1 = go('lblTitle1') self.lblTitle2 = go('lblTitle2') # Translations title = _("Debian Plymouth Manager") self.window.set_title(title) self.btnPlymouth.set_label("_" + _("Plymouth")) self.btnThemes.set_label("_" + _("Themes")) self.btnGrub.set_label("_" + _("Grub")) self.selectedMenuItem = None self.selectedAvailableTheme = None self.selectedRemoveTheme = None self.threadPackage = None self.queue = Queue() self.noPlymouth = _('None: no plymouth splash') # Set some variables self.logFile = '/var/log/dpm.log' self.log = Logger(self.logFile, addLogTime=False, maxSizeKB=1024) self.version = utils.getPackageVersion('debian-plymouth-manager') self.plymouth = Plymouth(self.log) self.grub = Grub(self.log) self.resolutions = utils.getResolutions('800x600', '', True, False) self.currentResolution = self.plymouth.getCurrentResolution() self.selectedResolution = self.currentResolution self.currentGrubResolution = self.grub.getCurrentResolution() self.selectedGrubResolution = self.currentGrubResolution self.currentTheme = self.plymouth.getCurrentTheme() self.selectedTheme = self.currentTheme self.installedThemes = self.plymouth.getInstalledThemes() self.availableThemes = self.plymouth.getAvailableThemes() self.tv1Handler = TreeViewHandler(self.tv1, self.log) self.tv2Handler = TreeViewHandler(self.tv2, self.log) self.force = utils.get_apt_force() self.on_btnPlymouth_clicked() # Connect builder signals and show window self.builder.connect_signals(self) self.window.show_all() # TODO: Hide the tool bar for now go('tlbMain').set_visible(False) # =============================================== # Menu section functions # =============================================== def on_btnPlymouth_clicked(self, widget=None, event=None, refresh=False): if self.selectedMenuItem != menuItems[0] or refresh: self.selectedMenuItem = menuItems[0] # Clear treeviews self.tv1Handler.clearTreeView() self.tv2Handler.clearTreeView() # Set object properties self.btn1.set_label(_("Set Plymouth Theme")) self.btn2.set_label(_("Preview")) self.btn2.show() self.lblTitle2.set_visible(True) self.sw2.show() # Show Installed Themes self.lblTitle1.set_label(_("Installed Themes")) # Clone the installedThemes list listInst = list(self.installedThemes) listInst.append(self.noPlymouth) # Get current theme and set setcursor ind = -1 if self.currentTheme: try: ind = listInst.index(self.currentTheme) except: # Theme is set but removed from system ind = 0 else: ind = len(listInst) - 1 if len(listInst) > 0: self.tv1Handler.fillTreeview(listInst, ['str'], ind, 700) # Show Resolutios self.lblTitle2.set_label(_("Resolutions")) ind = -1 if self.currentResolution: try: ind = self.resolutions.index(self.currentResolution) except: ind = 0 if len(self.resolutions) > 0: self.tv2Handler.fillTreeview(self.resolutions, ['str'], ind, 700) def on_btnThemes_clicked(self, widget=None, event=None, refresh=False): if self.selectedMenuItem != menuItems[1] or refresh: self.selectedMenuItem = menuItems[1] # Clear treeviews self.tv1Handler.clearTreeView() self.tv2Handler.clearTreeView() # Set object properties self.btn1.set_label(_("Install Theme")) self.btn2.set_label(_("Remove Theme")) self.btn2.show() self.lblTitle2.set_visible(True) self.sw2.show() # Show Available Themes self.lblTitle1.set_label(_("Available Themes")) if len(self.availableThemes) > 0: self.tv1Handler.fillTreeview(self.availableThemes, ['str'], 0) # Show Installed Themes self.lblTitle2.set_label(_("Installed Themes")) if len(self.installedThemes) > 0: self.tv2Handler.fillTreeview(self.installedThemes, ['str'], 0) def on_btnGrub_clicked(self, widget=None, event=None, refresh=False): if self.selectedMenuItem != menuItems[2] or refresh: self.selectedMenuItem = menuItems[2] # Clear treeviews self.tv1Handler.clearTreeView() self.tv2Handler.clearTreeView() # Set object properties self.btn1.set_label(_("Set Grub Resolution")) self.btn2.hide() self.lblTitle2.set_visible(False) self.sw2.hide() # Show Resolutios self.lblTitle1.set_text(_("Grub Resolutions")) ind = -1 if self.currentGrubResolution: try: ind = self.resolutions.index(self.currentGrubResolution) except: ind = 0 if len(self.resolutions) > 0: self.tv1Handler.fillTreeview(self.resolutions, ['str'], ind, 700) # =============================================== # Treeview functions # =============================================== def on_tv1_cursor_changed(self, widget): if self.selectedMenuItem == menuItems[0]: # Themes Menu self.selectedTheme = self.tv1Handler.getSelectedValue() self.log.write("Themes menu - seleceted theme: %(theme)s" % { "theme": self.selectedTheme }, 'dpm.tv1Changed') elif self.selectedMenuItem == menuItems[1]: # Install Menu self.selectedAvailableTheme = self.tv1Handler.getSelectedValue() self.log.write("Install menu - seleceted available theme: %(theme)s" % { "theme": self.selectedAvailableTheme }, 'dpm.tv1Changed') elif self.selectedMenuItem == menuItems[2]: # Grub Menu self.selectedGrubResolution = self.tv1Handler.getSelectedValue() self.log.write("Grub menu - seleceted grub resolution: %(res)s" % { "res": self.selectedGrubResolution }, 'dpm.tv1Changed') def on_tv2_cursor_changed(self, widget): if self.selectedMenuItem == menuItems[0]: # Themes Menu self.selectedResolution = self.tv2Handler.getSelectedValue() self.log.write("Themes menu - seleceted resolution: %(res)s" % { "res": self.selectedResolution }, 'dpm.tv2Changed') elif self.selectedMenuItem == menuItems[1]: # Install Menu self.selectedRemoveTheme = self.tv2Handler.getSelectedValue() self.log.write("Install menu - seleceted theme to remove: %(theme)s" % { "theme": self.selectedRemoveTheme }, 'dpm.tv2Changed') # =============================================== # Button functions # =============================================== def on_btn1_clicked(self, widget): if self.selectedMenuItem == menuItems[0]: # Themes self.setTheme() elif self.selectedMenuItem == menuItems[1]: # Install self.installTheme() elif self.selectedMenuItem == menuItems[2]: # Grub self.setGrubResolution() def on_btn2_clicked(self, widget): if self.selectedMenuItem == menuItems[0]: # Themes self.preview() elif self.selectedMenuItem == menuItems[1]: # Install self.removeTheme() elif self.selectedMenuItem == menuItems[2]: # Grub pass # =============================================== # Themes section functions # =============================================== def preview(self): # Check if the selected have been saved if self.currentTheme == self.selectedTheme and self.currentResolution == self.selectedResolution: self.plymouth.previewPlymouth() else: title = _("Preview") msg = _("You must save before you can preview:\n\nTheme: %(theme)s\nResolution: %(res)s") % { "theme": self.selectedTheme, "res": self.selectedResolution } MessageDialogSafe(title, msg, Gtk.MessageType.INFO, self.window).show() def setTheme(self): self.toggleGuiElements(True) if self.selectedTheme != self.noPlymouth: if self.selectedResolution is None: self.selectedResolution = self.tv2Handler.getValue(self.tv2Handler.getRowCount() - 1) else: self.selectedTheme = None self.selectedResolution = None self.log.write(_("Save setting: %(theme)s (%(res)s)") % { "theme": self.selectedTheme, "res": self.selectedResolution }, 'dpm.setTheme', 'info') # Start saving in a separate thread t = PlymouthSave(self.log, self.selectedTheme, self.selectedResolution) t.start() GObject.timeout_add(250, self.checkSaveThread) def checkSaveThread(self): #print 'Thread count = ' + str(threading.active_count()) # As long there's a thread active, keep spinning if threading.active_count() > 1: self.pbDPM.pulse() return True # Get the new data self.pbDPM.set_fraction(0) self.currentTheme = self.plymouth.getCurrentTheme() self.currentResolution = self.plymouth.getCurrentResolution() self.installedThemes = self.plymouth.getInstalledThemes() self.availableThemes = self.plymouth.getAvailableThemes() if self.selectedMenuItem == menuItems[0]: self.on_btnPlymouth_clicked(None, None, True) # Thread is done: make button sensitive again self.toggleGuiElements(False) self.log.write(_("Done saving settings: %(theme)s (%(res)s)") % { "theme": self.currentTheme, "res": self.currentResolution }, 'dpm.checkSaveThread', 'info') title = _("Save settings") msg = _("Theme: %(theme)s\nResolution: %(res)s\n\nDone") % { "theme": self.currentTheme, "res": str(self.currentResolution) } self.log.write(msg, 'dpm.checkSaveThread') MessageDialogSafe(title, msg, Gtk.MessageType.INFO, self.window).show() return False def toggleGuiElements(self, startSave): if startSave: self.btn1.set_sensitive(False) self.btn2.set_sensitive(False) else: self.btn1.set_sensitive(True) self.btn2.set_sensitive(True) # =============================================== # Install section functions # =============================================== def installTheme(self): self.threadAction = _("install") self.threadPackage = self.plymouth.getPackageName(self.selectedAvailableTheme) if self.threadPackage: dialog = QuestionDialog(_("Install theme"), _("Continue installing theme:\n%(theme)s") % { "theme": self.threadPackage }, self.window) go = dialog.show() if (go): self.toggleGuiElements(True) self.log.write(_("Start installing theme: %(theme)s") % { "theme": self.threadPackage }, 'dpm.installTheme', 'info') # Start apt in a separate thread cmd = 'apt-get install -y %s %s' % (self.force, self.threadPackage) t = ExecuteApt(self.log, cmd, self.queue) t.daemon = True t.start() self.queue.join() #self.log.write("Check every 250 miliseconds if thread is still active", 'dpm.installTheme') GObject.timeout_add(250, self.checkAptThread) else: self.log.write(_("User cancel install theme: %(theme)s") % { "theme": self.threadPackage }, 'dpm.installTheme', 'info') else: title = _("%(act1)s%(act2)s theme") % { "act1": self.threadAction[0].capitalize(), "act2": self.threadAction[1:] } msg = _("The package cannot be installed: %(pck)s\nTry apt instead") % { "pck": self.threadPackage } self.log.write(msg, 'dpm.installTheme') MessageDialogSafe(title, msg, Gtk.MessageType.INFO, self.window).show() def removeTheme(self): self.threadAction = _("remove") self.threadPackage = self.plymouth.getRemovablePackageName(self.selectedRemoveTheme) if self.threadPackage: dialog = QuestionDialog(_("Remove theme"), _("Continue removing theme:\n%(theme)s") % { "theme": self.threadPackage }, self.window) go = dialog.show() if (go): self.toggleGuiElements(True) # Start apt in a separate thread self.log.write(_("Start removing theme: %(theme)s") % { "theme": self.threadPackage }, 'dpm.removeTheme', 'info') cmd = 'apt-get purge -y %s %s' % (self.force, self.threadPackage) t = ExecuteApt(self.log, cmd, self.queue) t.daemon = True t.start() self.queue.join() #self.log.write("Check every 250 miliseconds if thread is still active", 'dpm.removeTheme') GObject.timeout_add(250, self.checkAptThread) else: self.log.write(_("User cancel remove theme: %(theme)s") % { "theme": self.threadPackage }, 'dpm.removeTheme', 'info') else: title = _("%(act1)s%(act2)s theme") % { "act1": self.threadAction[0].capitalize(), "act2": self.threadAction[1:] } msg = _("The package cannot be removed: %(pck)s\nIt is part of a meta package.\nTry apt instead") % { "pck": self.selectedRemoveTheme } self.log.write(msg, 'dpm.removeTheme') MessageDialogSafe(title, msg, Gtk.MessageType.INFO, self.window).show() def checkAptThread(self): # As long there's a thread active, keep spinning if threading.active_count() > 1: self.pbDPM.pulse() return True # Thread is done self.pbDPM.set_fraction(0) # Get the error data from the queue aptError = self.queue.get() # Get the new data self.installedThemes = self.plymouth.getInstalledThemes() self.availableThemes = self.plymouth.getAvailableThemes() if self.selectedMenuItem == menuItems[1]: self.on_btnThemes_clicked(None, None, True) self.toggleGuiElements(False) title = _("%(act1)s%(act2)s theme") % { "act1": self.threadAction[0].capitalize(), "act2": self.threadAction[1:] } if aptError: msg = _("Could not %(action)s theme:\n%(theme)s\nTry apt instead.\n\nError message:\n%(err)s") % { "action": self.threadAction, "theme": self.threadPackage, "err": aptError } else: msg = _("%(action)s successfully of:\n%(pck)s") % { "action": self.threadAction[0].capitalize() + self.threadAction[1:], "pck": self.threadPackage } self.log.write(msg, 'dpm.checkAptThread') MessageDialogSafe(title, msg, Gtk.MessageType.INFO, self.window).show() return False # =============================================== # Grub section functions # =============================================== def setGrubResolution(self): self.toggleGuiElements(True) self.log.write(_("Save grub resolution: %(res)s") % { "res": self.selectedGrubResolution }, 'dpm.setGrubResolution', 'info') # Start saving in a separate thread t = GrubSave(self.log, self.selectedGrubResolution) t.start() GObject.timeout_add(250, self.checkGrubThread) def checkGrubThread(self): # As long there's a thread active, keep spinning if threading.active_count() > 1: self.pbDPM.pulse() return True # Thread is done self.pbDPM.set_fraction(0) self.currentGrubResolution = self.grub.getCurrentResolution() if self.selectedMenuItem == menuItems[2]: self.on_btnGrub_clicked(None, None, True) self.toggleGuiElements(False) title = _("Grub resolution") msg = _("Grub resolution saved: %(res)s") % { "res": self.selectedGrubResolution } self.log.write(msg, 'dpm.setGrubResolution', 'info') MessageDialogSafe(title, msg, Gtk.MessageType.INFO, self.window).show() return False def on_dpmWindow_destroy(self, widget, data=None): # Close the app Gtk.main_quit()
class SambaShare(object): def __init__(self): self.scriptDir = abspath(dirname(__file__)) # Load window and widgets self.builder = Gtk.Builder() self.builder.add_from_file( join(self.scriptDir, '../../share/sambashare/sambashare.glade')) go = self.builder.get_object self.window = go('sambashareWindow') self.windowAdd = go('sambashareWindowAdd') self.lblTitle = go('lblTitle') self.tvShares = go('tvShares') self.btnAdd = go('btnAdd') self.btnRemove = go('btnRemove') self.txtShareDetails = go('txtShareDetails') self.lblName = go('lblName') self.lblPath = go('lblPath') self.lblComment = go('lblComment') self.lblPublic = go('lblPublic') self.lblReadOnly = go('lblReadOnly') self.txtName = go('txtName') self.txtPath = go('txtPath') self.txtComment = go('txtComment') self.chkPublic = go('chkPublic') self.chkReadOnly = go('chkReadOnly') self.btnOk = go('btnOk') self.btnCancel = go('btnCancel') # Translations self.window.set_title(_("Samba share")) self.windowAdd.set_title(_("Create samba share")) self.lblTitle.set_text(self.window.get_title()) self.lblName.set_text(_("Name")) self.lblPath.set_text(_("Path")) self.lblComment.set_text(_("Comment")) self.lblReadOnly.set_text(_("Read only")) self.lblPublic.set_text(_("Public")) # Init self.ec = ExecCmd() self.us = UserShare() self.shareName = None self.sharePath = None self.startAddNow = False # Fill treeview with shares self.tvHandler = TreeViewHandler(self.tvShares) self.refreshShares() # Command arguments args = sys.argv[1:] for arg in args: if "/" in arg: self.sharePath = arg self.startAddNow = True else: self.shareName = arg # Connect the signals and show the window self.builder.connect_signals(self) self.window.show_all() if self.startAddNow: self.on_btnAdd_clicked(None) # =============================================== # Menu section functions # =============================================== def on_tvShares_cursor_changed(self, widget, event=None): # Show share details self.setDetailText() def on_btnAdd_clicked(self, widget): # Show add share window if self.sharePath is None: self.sharePath = os.getcwd() self.shareName = basename(self.sharePath) if self.sharePath is None: self.sharePath = "" if self.shareName is None: self.shareName = "" self.txtName.set_text(self.shareName) self.txtPath.set_text(self.sharePath) self.windowAdd.show_all() def on_btnBrowse_clicked(self, widget): directory = SelectDirectoryDialog(_('Select directory to share'), self.txtPath.get_text(), self.window).show() if directory is not None: self.sharePath = directory self.txtPath.set_text(self.sharePath) def on_btnRemove_clicked(self, widget): # TODO: remove selected share title = _("Remove share") qd = QuestionDialog( title, _("Are you sure you want to remove the following share:\n\n'%(share)s'" ) % {"share": self.shareName}, self.window) answer = qd.show() if answer: ret = self.us.removeShare(self.shareName) self.showUserFeedback(ret, title, "remove", self.window) self.refreshShares() def on_btnOk_clicked(self, widget): # Create network share, and close add share window title = _("Create share") self.shareName = self.txtName.get_text() comment = self.txtComment.get_text() public = self.chkPublic.get_active() readonly = self.chkReadOnly.get_active() ret = self.us.createShare(self.sharePath, self.shareName, comment, public, readonly) closeWin = self.showUserFeedback(ret, title, "create", self.windowAdd) if closeWin: self.windowAdd.hide() self.refreshShares() def on_txtPath_changed(self, widget): self.sharePath = self.txtPath.get_text() name = basename(self.sharePath) if name == "": name = basename(dirname(self.sharePath)) self.txtName.set_text(name) def on_txtName_changed(self, widget): name = self.txtName.get_text() if name in self.us.systemNames: name += "_" self.txtName.set_text(name) self.shareName = name def showUserFeedback(self, returnList, title, action, parent): msg = "" closeWin = False for line in returnList: msg += "%s\n" % line if msg != "": MessageDialogSafe(title, msg, Gtk.MessageType.ERROR, parent).show() else: shareExists = self.us.doesShareExist(self.shareName) if action == "removed" and shareExists: msg = _("Could not remove share: '%(share)s'") % { "share": self.shareName } elif action == "created" and not shareExists: msg = _("Could not create share: '%(share)s'") % { "share": self.shareName } else: msg = _( "Share successfully %(action)s:\n\n'%(share)s' on %(path)s" ) % { "action": action, "share": self.shareName, "path": self.sharePath } closeWin = True MessageDialogSafe(title, msg, Gtk.MessageType.INFO, parent).show() return closeWin def refreshShares(self): self.shareName = None self.sharePath = None self.shares = self.us.getShares() self.shareDetail = self.us.getShares(True, True) self.fillTreeView() self.setDetailText() print("Refresh done") def on_btnCancel_clicked(self, widget): # Close add share window without saving self.windowAdd.hide() def on_sambashareWindowAdd_delete_event(self, widget, data=None): self.windowAdd.hide() return True def fillTreeView(self): # Very dirty hack: add and remove a dummy row to the treeview when treeview is empty # GtkTreeView has a problem refreshing when there's no data present if self.tvHandler.getRowCount() == 0: self.tvHandler.fillTreeview('-', ['str']) self.tvHandler.clearTreeView() self.tvHandler.fillTreeview(self.shares, ['str']) def setDetailText(self): buf = Gtk.TextBuffer() txt = "" try: self.shareName = self.tvHandler.getSelectedValue() if self.shareName is not None: if self.shareDetail[self.shareName]: txt = "Name:\t\t%s\n" % self.shareName for line in self.shareDetail[self.shareName]: line = line.strip() if line != "" and line != "[%s]" % self.shareName: if line.startswith("path="): self.sharePath = line.replace("path=", "") txt += "Path:\t\t%s\n" % self.sharePath elif line.startswith("comment="): txt += "Comment:\t%s\n" % line.replace( "comment=", "") elif ':R' in line: txt += "Share:\t\tRead permission" elif ':F' in line: txt += "Share:\t\tRead/write permission" elif line == "guest_ok=y": txt += ", public\n" elif line == "guest_ok=n": txt += ", private\n" else: self.sharePath = None except: # Best effort pass buf.set_text(txt) self.txtShareDetails.set_buffer(buf) # Close the gui def on_sambashareWindow_destroy(self, widget): # Close the app Gtk.main_quit()
class DPM: def __init__(self): self.scriptDir = dirname(realpath(__file__)) # Load window and widgets self.builder = Gtk.Builder() self.builder.add_from_file( join( self.scriptDir, '../../share/debian-plymouth-manager/debian-plymouth-manager.glade' )) # Main window objects go = self.builder.get_object self.window = go('dpmWindow') self.tv1 = go('tv1') self.tv2 = go('tv2') self.sw2 = go('sw2') self.statusbar = go('statusbar') self.btnPlymouth = go('btnPlymouth') self.btnThemes = go('btnThemes') self.btnGrub = go('btnGrub') self.pbDPM = go('pbDPM') self.btn1 = go('btn1') self.btn2 = go('btn2') self.lblTitle1 = go('lblTitle1') self.lblTitle2 = go('lblTitle2') # Translations title = _("Debian Plymouth Manager") self.window.set_title(title) self.btnPlymouth.set_label("_" + _("Plymouth")) self.btnThemes.set_label("_" + _("Themes")) self.btnGrub.set_label("_" + _("Grub")) self.selectedMenuItem = None self.selectedAvailableTheme = None self.selectedRemoveTheme = None self.threadPackage = None self.queue = Queue() self.noPlymouth = _('None: no plymouth splash') # Set some variables self.logFile = '/var/log/dpm.log' self.log = Logger(self.logFile, addLogTime=False, maxSizeKB=1024) self.version = utils.getPackageVersion('debian-plymouth-manager') self.plymouth = Plymouth(self.log) self.grub = Grub(self.log) self.resolutions = utils.getResolutions('800x600', '', True, False) self.currentResolution = self.plymouth.getCurrentResolution() self.selectedResolution = self.currentResolution self.currentGrubResolution = self.grub.getCurrentResolution() self.selectedGrubResolution = self.currentGrubResolution self.currentTheme = self.plymouth.getCurrentTheme() self.selectedTheme = self.currentTheme self.installedThemes = self.plymouth.getInstalledThemes() self.availableThemes = self.plymouth.getAvailableThemes() self.tv1Handler = TreeViewHandler(self.tv1, self.log) self.tv2Handler = TreeViewHandler(self.tv2, self.log) self.force = utils.get_apt_force() self.on_btnPlymouth_clicked() # Connect builder signals and show window self.builder.connect_signals(self) self.window.show_all() # TODO: Hide the tool bar for now go('tlbMain').set_visible(False) # =============================================== # Menu section functions # =============================================== def on_btnPlymouth_clicked(self, widget=None, event=None, refresh=False): if self.selectedMenuItem != menuItems[0] or refresh: self.selectedMenuItem = menuItems[0] # Clear treeviews self.tv1Handler.clearTreeView() self.tv2Handler.clearTreeView() # Set object properties self.btn1.set_label(_("Set Plymouth Theme")) self.btn2.set_label(_("Preview")) self.btn2.show() self.lblTitle2.set_visible(True) self.sw2.show() # Show Installed Themes self.lblTitle1.set_label(_("Installed Themes")) # Clone the installedThemes list listInst = list(self.installedThemes) listInst.append(self.noPlymouth) # Get current theme and set setcursor ind = -1 if self.currentTheme: try: ind = listInst.index(self.currentTheme) except: # Theme is set but removed from system ind = 0 else: ind = len(listInst) - 1 if len(listInst) > 0: self.tv1Handler.fillTreeview(listInst, ['str'], ind, 700) # Show Resolutios self.lblTitle2.set_label(_("Resolutions")) ind = -1 if self.currentResolution: try: ind = self.resolutions.index(self.currentResolution) except: ind = 0 if len(self.resolutions) > 0: self.tv2Handler.fillTreeview(self.resolutions, ['str'], ind, 700) def on_btnThemes_clicked(self, widget=None, event=None, refresh=False): if self.selectedMenuItem != menuItems[1] or refresh: self.selectedMenuItem = menuItems[1] # Clear treeviews self.tv1Handler.clearTreeView() self.tv2Handler.clearTreeView() # Set object properties self.btn1.set_label(_("Install Theme")) self.btn2.set_label(_("Remove Theme")) self.btn2.show() self.lblTitle2.set_visible(True) self.sw2.show() # Show Available Themes self.lblTitle1.set_label(_("Available Themes")) if len(self.availableThemes) > 0: self.tv1Handler.fillTreeview(self.availableThemes, ['str'], 0) # Show Installed Themes self.lblTitle2.set_label(_("Installed Themes")) if len(self.installedThemes) > 0: self.tv2Handler.fillTreeview(self.installedThemes, ['str'], 0) def on_btnGrub_clicked(self, widget=None, event=None, refresh=False): if self.selectedMenuItem != menuItems[2] or refresh: self.selectedMenuItem = menuItems[2] # Clear treeviews self.tv1Handler.clearTreeView() self.tv2Handler.clearTreeView() # Set object properties self.btn1.set_label(_("Set Grub Resolution")) self.btn2.hide() self.lblTitle2.set_visible(False) self.sw2.hide() # Show Resolutios self.lblTitle1.set_text(_("Grub Resolutions")) ind = -1 if self.currentGrubResolution: try: ind = self.resolutions.index(self.currentGrubResolution) except: ind = 0 if len(self.resolutions) > 0: self.tv1Handler.fillTreeview(self.resolutions, ['str'], ind, 700) # =============================================== # Treeview functions # =============================================== def on_tv1_cursor_changed(self, widget): if self.selectedMenuItem == menuItems[0]: # Themes Menu self.selectedTheme = self.tv1Handler.getSelectedValue() self.log.write( "Themes menu - seleceted theme: %(theme)s" % {"theme": self.selectedTheme}, 'dpm.tv1Changed') elif self.selectedMenuItem == menuItems[1]: # Install Menu self.selectedAvailableTheme = self.tv1Handler.getSelectedValue() self.log.write( "Install menu - seleceted available theme: %(theme)s" % {"theme": self.selectedAvailableTheme}, 'dpm.tv1Changed') elif self.selectedMenuItem == menuItems[2]: # Grub Menu self.selectedGrubResolution = self.tv1Handler.getSelectedValue() self.log.write( "Grub menu - seleceted grub resolution: %(res)s" % {"res": self.selectedGrubResolution}, 'dpm.tv1Changed') def on_tv2_cursor_changed(self, widget): if self.selectedMenuItem == menuItems[0]: # Themes Menu self.selectedResolution = self.tv2Handler.getSelectedValue() self.log.write( "Themes menu - seleceted resolution: %(res)s" % {"res": self.selectedResolution}, 'dpm.tv2Changed') elif self.selectedMenuItem == menuItems[1]: # Install Menu self.selectedRemoveTheme = self.tv2Handler.getSelectedValue() self.log.write( "Install menu - seleceted theme to remove: %(theme)s" % {"theme": self.selectedRemoveTheme}, 'dpm.tv2Changed') # =============================================== # Button functions # =============================================== def on_btn1_clicked(self, widget): if self.selectedMenuItem == menuItems[0]: # Themes self.setTheme() elif self.selectedMenuItem == menuItems[1]: # Install self.installTheme() elif self.selectedMenuItem == menuItems[2]: # Grub self.setGrubResolution() def on_btn2_clicked(self, widget): if self.selectedMenuItem == menuItems[0]: # Themes self.preview() elif self.selectedMenuItem == menuItems[1]: # Install self.removeTheme() elif self.selectedMenuItem == menuItems[2]: # Grub pass # =============================================== # Themes section functions # =============================================== def preview(self): # Check if the selected have been saved if self.currentTheme == self.selectedTheme and self.currentResolution == self.selectedResolution: self.plymouth.previewPlymouth() else: title = _("Preview") msg = _( "You must save before you can preview:\n\nTheme: %(theme)s\nResolution: %(res)s" ) % { "theme": self.selectedTheme, "res": self.selectedResolution } MessageDialogSafe(title, msg, Gtk.MessageType.INFO, self.window).show() def setTheme(self): self.toggleGuiElements(True) if self.selectedTheme != self.noPlymouth: if self.selectedResolution is None: self.selectedResolution = self.tv2Handler.getValue( self.tv2Handler.getRowCount() - 1) else: self.selectedTheme = None self.selectedResolution = None self.log.write( _("Save setting: %(theme)s (%(res)s)") % { "theme": self.selectedTheme, "res": self.selectedResolution }, 'dpm.setTheme', 'info') # Start saving in a separate thread t = PlymouthSave(self.log, self.selectedTheme, self.selectedResolution) t.start() GObject.timeout_add(250, self.checkSaveThread) def checkSaveThread(self): #print 'Thread count = ' + str(threading.active_count()) # As long there's a thread active, keep spinning if threading.active_count() > 1: self.pbDPM.pulse() return True # Get the new data self.pbDPM.set_fraction(0) self.currentTheme = self.plymouth.getCurrentTheme() self.currentResolution = self.plymouth.getCurrentResolution() self.installedThemes = self.plymouth.getInstalledThemes() self.availableThemes = self.plymouth.getAvailableThemes() if self.selectedMenuItem == menuItems[0]: self.on_btnPlymouth_clicked(None, None, True) # Thread is done: make button sensitive again self.toggleGuiElements(False) self.log.write( _("Done saving settings: %(theme)s (%(res)s)") % { "theme": self.currentTheme, "res": self.currentResolution }, 'dpm.checkSaveThread', 'info') title = _("Save settings") msg = _("Theme: %(theme)s\nResolution: %(res)s\n\nDone") % { "theme": self.currentTheme, "res": str(self.currentResolution) } self.log.write(msg, 'dpm.checkSaveThread') MessageDialogSafe(title, msg, Gtk.MessageType.INFO, self.window).show() return False def toggleGuiElements(self, startSave): if startSave: self.btn1.set_sensitive(False) self.btn2.set_sensitive(False) else: self.btn1.set_sensitive(True) self.btn2.set_sensitive(True) # =============================================== # Install section functions # =============================================== def installTheme(self): self.threadAction = _("install") self.threadPackage = self.plymouth.getPackageName( self.selectedAvailableTheme) if self.threadPackage: dialog = QuestionDialog( _("Install theme"), _("Continue installing theme:\n%(theme)s") % {"theme": self.threadPackage}, self.window) go = dialog.show() if (go): self.toggleGuiElements(True) self.log.write( _("Start installing theme: %(theme)s") % {"theme": self.threadPackage}, 'dpm.installTheme', 'info') # Start apt in a separate thread cmd = 'apt-get install -y %s %s' % (self.force, self.threadPackage) t = ExecuteApt(self.log, cmd, self.queue) t.daemon = True t.start() self.queue.join() #self.log.write("Check every 250 miliseconds if thread is still active", 'dpm.installTheme') GObject.timeout_add(250, self.checkAptThread) else: self.log.write( _("User cancel install theme: %(theme)s") % {"theme": self.threadPackage}, 'dpm.installTheme', 'info') else: title = _("%(act1)s%(act2)s theme") % { "act1": self.threadAction[0].capitalize(), "act2": self.threadAction[1:] } msg = _("The package cannot be installed: %(pck)s\nTry apt instead" ) % { "pck": self.threadPackage } self.log.write(msg, 'dpm.installTheme') MessageDialogSafe(title, msg, Gtk.MessageType.INFO, self.window).show() def removeTheme(self): self.threadAction = _("remove") self.threadPackage = self.plymouth.getRemovablePackageName( self.selectedRemoveTheme) if self.threadPackage: dialog = QuestionDialog( _("Remove theme"), _("Continue removing theme:\n%(theme)s") % {"theme": self.threadPackage}, self.window) go = dialog.show() if (go): self.toggleGuiElements(True) # Start apt in a separate thread self.log.write( _("Start removing theme: %(theme)s") % {"theme": self.threadPackage}, 'dpm.removeTheme', 'info') cmd = 'apt-get purge -y %s %s' % (self.force, self.threadPackage) t = ExecuteApt(self.log, cmd, self.queue) t.daemon = True t.start() self.queue.join() #self.log.write("Check every 250 miliseconds if thread is still active", 'dpm.removeTheme') GObject.timeout_add(250, self.checkAptThread) else: self.log.write( _("User cancel remove theme: %(theme)s") % {"theme": self.threadPackage}, 'dpm.removeTheme', 'info') else: title = _("%(act1)s%(act2)s theme") % { "act1": self.threadAction[0].capitalize(), "act2": self.threadAction[1:] } msg = _( "The package cannot be removed: %(pck)s\nIt is part of a meta package.\nTry apt instead" ) % { "pck": self.selectedRemoveTheme } self.log.write(msg, 'dpm.removeTheme') MessageDialogSafe(title, msg, Gtk.MessageType.INFO, self.window).show() def checkAptThread(self): # As long there's a thread active, keep spinning if threading.active_count() > 1: self.pbDPM.pulse() return True # Thread is done self.pbDPM.set_fraction(0) # Get the error data from the queue aptError = self.queue.get() # Get the new data self.installedThemes = self.plymouth.getInstalledThemes() self.availableThemes = self.plymouth.getAvailableThemes() if self.selectedMenuItem == menuItems[1]: self.on_btnThemes_clicked(None, None, True) self.toggleGuiElements(False) title = _("%(act1)s%(act2)s theme") % { "act1": self.threadAction[0].capitalize(), "act2": self.threadAction[1:] } if aptError: msg = _( "Could not %(action)s theme:\n%(theme)s\nTry apt instead.\n\nError message:\n%(err)s" ) % { "action": self.threadAction, "theme": self.threadPackage, "err": aptError } else: msg = _("%(action)s successfully of:\n%(pck)s") % { "action": self.threadAction[0].capitalize() + self.threadAction[1:], "pck": self.threadPackage } self.log.write(msg, 'dpm.checkAptThread') MessageDialogSafe(title, msg, Gtk.MessageType.INFO, self.window).show() return False # =============================================== # Grub section functions # =============================================== def setGrubResolution(self): self.toggleGuiElements(True) self.log.write( _("Save grub resolution: %(res)s") % {"res": self.selectedGrubResolution}, 'dpm.setGrubResolution', 'info') # Start saving in a separate thread t = GrubSave(self.log, self.selectedGrubResolution) t.start() GObject.timeout_add(250, self.checkGrubThread) def checkGrubThread(self): # As long there's a thread active, keep spinning if threading.active_count() > 1: self.pbDPM.pulse() return True # Thread is done self.pbDPM.set_fraction(0) self.currentGrubResolution = self.grub.getCurrentResolution() if self.selectedMenuItem == menuItems[2]: self.on_btnGrub_clicked(None, None, True) self.toggleGuiElements(False) title = _("Grub resolution") msg = _("Grub resolution saved: %(res)s") % { "res": self.selectedGrubResolution } self.log.write(msg, 'dpm.setGrubResolution', 'info') MessageDialogSafe(title, msg, Gtk.MessageType.INFO, self.window).show() return False def on_dpmWindow_destroy(self, widget, data=None): # Close the app Gtk.main_quit()
def run(self, cmd, realTime=True, returnAsList=True, outputTreeView=None): tvHandler = None if outputTreeView is not None: tvHandler = TreeViewHandler(outputTreeView) tvHandler.fillTreeview([], columnTypesList=['str']) msg = "Command to execute: %(cmd)s" % { "cmd": cmd } if self.log: self.log.write(msg, 'execcmd.run', 'debug') else: print(msg) p = subprocess.Popen([cmd], shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) lstOut = [] while True: line = p.stdout.readline() if not line: break # Strip the line, also from null spaces (strip() only strips white spaces) line = line.decode('utf-8').rstrip().rstrip("\0") lstOut.append(line) if realTime: if tvHandler is not None: tvHandler.fillTreeview([line], columnTypesList=['str'], appendToExisting=True, setCursor=tvHandler.getRowCount()) if self.log: self.log.write(line, 'execcmd.run', 'info') else: print(line) try: sys.stdout.flush() except: pass while Gtk.events_pending(): Gtk.main_iteration() ret = lstOut if not returnAsList: ret = "\n".join(lstOut).strip() return ret