Exemple #1
0
    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()
Exemple #3
0
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()
Exemple #4
0
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()
Exemple #5
0
    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