예제 #1
0
class UpdateManagerPref(object):
    def __init__(self):
        # Check if script is running
        self.scriptName = basename(__file__)
        self.umglobal = UmGlobal()

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    # Close the gui
    def on_windowPref_destroy(self, widget):
        Gtk.main_quit()
예제 #2
0
class LightDMManager:
    def __init__(self):
        self.scriptDir = os.path.dirname(os.path.realpath(__file__))

        # Load window and widgets
        self.builder = Gtk.Builder()
        self.builder.add_from_file(
            join(self.scriptDir,
                 '../../share/lightdm-manager/lightdm-manager.glade'))
        # Main window objects
        go = self.builder.get_object
        self.window = go('ldmWindow')
        self.swUsers = go('swUsers')
        self.tvUsers = go('tvUsers')
        self.btnSave = go('btnSave')
        self.imgBackground = go('imgBackground')
        self.btnUsers = go('btnUsers')
        self.btnAppearance = go('btnAppearance')
        self.chkHideUsers = go('chkHideUsers')
        self.ebFace = go('ebFace')
        self.imgFace = go('imgFace')
        self.nbLightDM = go('nbLightDM')
        self.cmbThemes = go('cmbThemes')

        # Read from config file
        self.cfg = Config('lightdm-manager.conf')
        self.lightdmConf = self.cfg.getValue('CONFIG', 'lightdmConf')
        self.desktopbaseDir = self.cfg.getValue('CONFIG', 'desktopbaseDir')
        gktGreeterConf = self.cfg.getValue('CONFIG', 'gtkGreeterConf')
        kdeGreeterConf = self.cfg.getValue('CONFIG', 'kdeGreeterConf')
        if exists(gktGreeterConf):
            self.greeterConf = gktGreeterConf
        else:
            self.greeterConf = kdeGreeterConf

        # Translations
        title = _("LightDM Manager")
        self.window.set_title(title)
        self.btnUsers.set_label("_{}".format(_("Users")))
        self.btnAppearance.set_label("_{}".format(_("Appearance")))
        go('lblBackground').set_label(_("Background"))
        go('lblTheme').set_label(_("Theme"))
        go('lblLightDmMenu').set_label(_("Menu"))
        self.chkHideUsers.set_label(_("Hide users"))
        go('lblUsersFace').set_label(_("User icon"))
        go('lblUsersAutologin').set_label(_("Auto-login"))

        # Get current background image
        self.cfgGreeter = Config(self.greeterConf)
        try:
            self.curBgPath = self.cfgGreeter.getValue('greeter', 'background')
            self.curTheme = self.cfgGreeter.getValue('greeter', 'theme-name')
        except:
            self.curBgPath = None
            self.curTheme = None

        # Get current auto-login user
        self.cfgLightdm = Config(self.lightdmConf)
        try:
            self.curAutoUser = self.cfgLightdm.getValue(
                'SeatDefaults', 'autologin-user').strip()
            self.curHideUsers = False
            ghu = self.cfgLightdm.getValue('SeatDefaults',
                                           'greeter-hide-users').strip()
            if 'true' in ghu:
                self.curHideUsers = True
        except:
            self.curAutoUser = None
            self.curHideUsers = False

        # Init
        self.usr = User()
        self.newbgImg = self.curBgPath
        self.newAutoUser = self.curAutoUser
        self.newTheme = self.curTheme
        self.themes = []
        self.selectedMenuItem = None
        self.debug = False
        self.logPath = ''
        self.prevPath = None
        self.tempFace = "/tmp/face"
        self.newFaces = []
        self.loggedUser = functions.getUserLoginName()
        self.curUser = self.loggedUser
        self.selectImg = join(self.scriptDir,
                              '../../share/lightdm-manager/select.png')

        # Handle arguments
        try:
            opts, args = getopt.getopt(sys.argv[1:], 'dl:', ['debug', 'log='])
        except getopt.GetoptError:
            print(("Arguments cannot be parsed: %s" % str(sys.argv[1:])))
            sys.exit(1)

        for opt, arg in opts:
            if opt in ('-d', '--debug'):
                self.debug = True
            elif opt in ('-l', '--log'):
                self.logPath = arg

        # Initialize logging
        if self.debug:
            if not self.logPath:
                self.logPath = 'lightdm-manager.log'
        self.log = Logger(self.logPath, 'debug', True, None, self.window)

        # Backup config files because ConfigParser does not preserve commented lines
        if not exists("%s.org" % self.greeterConf):
            copy(self.greeterConf, "%s.org" % self.greeterConf)
            self.log.write(
                "%(conf1)s copied to %(conf2)s.org" % {
                    "conf1": self.greeterConf,
                    "conf2": self.greeterConf
                }, 'LightDMManager.main', 'debug')
        if not exists("%s.org" % self.lightdmConf):
            copy(self.lightdmConf, "%s.org" % self.lightdmConf)
            self.log.write(
                "%(conf1)s copied to %(conf2)s.org" % {
                    "conf1": self.lightdmConf,
                    "conf2": self.lightdmConf
                }, 'LightDMManager.main', 'debug')

        # Initiate the treeview handler and connect the custom toggle event with usersCheckBoxToggled
        self.tvHandler = TreeViewHandler(self.tvUsers, self.log)
        self.tvHandler.connect('checkbox-toggled', self.usersCheckBoxToggled)

        # Get users
        self.users = self.usr.getUsers()
        self.fillUsers()
        self.tvHandler.selectValue(self.curUser, 1)
        self.setBackground(self.curBgPath)
        self.cmbHandlerThemes = ComboBoxHandler(self.cmbThemes)
        self.listThemes()
        self.chkHideUsers.set_active(self.curHideUsers)

        # Show users menu
        self.on_btnUsers_clicked(None)
        self.on_tvUsers_cursor_changed(None)

        self.version = functions.getPackageVersion('lightdm-manager')

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

    # ===============================================
    # Menu section functions
    # ===============================================

    def on_btnUsers_clicked(self, widget, event=None):
        if self.selectedMenuItem != menuItems[0]:
            self.selectedMenuItem = menuItems[0]
            self.nbLightDM.set_current_page(0)

    def on_btnAppearance_clicked(self, widget, event=None):
        if self.selectedMenuItem != menuItems[1]:
            self.selectedMenuItem = menuItems[1]
            self.nbLightDM.set_current_page(1)

    # ===============================================
    # Functions
    # ===============================================

    def on_ebFace_enter_notify_event(self, widget, event):
        self.window.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.HAND2))

    def on_ebFace_leave_notify_event(self, widget, event):
        self.window.get_window().set_cursor(None)

    def on_ebFace_button_release_event(self, widget, event):
        home = self.usr.getUserHomeDir(self.curUser)
        primaryGroup = self.usr.getUserPrimaryGroupName(self.curUser)
        imagePath = SelectImageDialog(_('Select user image'), home,
                                      self.window).show()
        if imagePath is not None:
            tempUserImg = "%(tempFace)s.%(curUser)s" % {
                "tempFace": self.tempFace,
                "curUser": self.curUser
            }
            self.newFaces.append(
                [tempUserImg,
                 join(home, ".face"), self.curUser, primaryGroup])
            print((">>> self.newFaces = %s" % self.newFaces))
            ih = ImageHandler(imagePath)
            ih.makeFaceImage(tempUserImg)
            if exists(tempUserImg):
                self.imgFace.set_from_pixbuf(ih.pixbuf)
            else:
                # This should never happen
                self.imgFace.set_from_file(self.selectImg)

    def on_tvUsers_cursor_changed(self, widget):
        self.curUser = self.tvHandler.getSelectedValue(1)
        showFace = None
        if self.newFaces:
            for face in self.newFaces:
                if face[2] == self.curUser and exists(face[0]):
                    showFace = GdkPixbuf.Pixbuf.new_from_file(face[0])
        if showFace is None:
            showFace = self.usr.getUserFacePixbuf(self.curUser)
        if showFace is None:
            # Still no user icon found: show select image
            self.imgFace.set_from_file(self.selectImg)
        else:
            self.imgFace.set_from_pixbuf(showFace)

    def on_btnSave_clicked(self, widget):
        saved = False
        saveHideUsers = False
        saveAutoUser = False
        saveFaces = False
        saveBackground = False
        saveTheme = False
        if self.chkHideUsers.get_active() != self.curHideUsers:
            saveHideUsers = True
        if self.curAutoUser != self.newAutoUser:
            saveAutoUser = True
        if self.newFaces:
            saveFaces = True
        if self.curBgPath != self.newbgImg:
            saveBackground = True
        self.newTheme = self.cmbHandlerThemes.getValue()
        if self.curTheme != self.newTheme:
            saveTheme = True

        if saveHideUsers or saveAutoUser or saveFaces or saveBackground or saveTheme:
            qd = QuestionDialog(
                _("LightDM settings"),
                _("Settings have changed\n\nDo you want to save the new settings?"
                  ), self.window)
            answer = qd.show()
            if answer:
                if saveAutoUser:
                    if self.newAutoUser is not None:
                        # Save the auto-login user
                        self.cfgLightdm.setValue('SeatDefaults',
                                                 'autologin-user',
                                                 self.newAutoUser)
                        self.cfgLightdm.setValue('SeatDefaults',
                                                 'autologin-user-timeout', '0')
                        self.curAutoUser = self.newAutoUser
                        self.log.write(
                            "New auto-login user: %(usr)s" %
                            {"usr": self.curAutoUser},
                            'LightDMManager.saveSettings', 'debug')
                    else:
                        self.cfgLightdm.removeOption('SeatDefaults',
                                                     'autologin-user')
                        self.cfgLightdm.removeOption('SeatDefaults',
                                                     'autologin-user-timeout')
                        self.curAutoUser = None
                        self.log.write("Auto-login disabled",
                                       'LightDMManager.saveSettings', 'debug')
                if saveHideUsers:
                    hideUsers = str(self.chkHideUsers.get_active()).lower()
                    self.cfgLightdm.setValue('SeatDefaults',
                                             'greeter-hide-users', hideUsers)
                    self.log.write(
                        "Hide users saved: %(users)s" % {"users": hideUsers},
                        'LightDMManager.saveSettings', 'debug')
                if saveFaces:
                    for face in self.newFaces:
                        if exists(face[0]):
                            copy(face[0], face[1])
                            if exists(face[1]):
                                os.system(
                                    "chown %(owner)s:%(group)s %(path)s" % {
                                        "owner": face[2],
                                        "group": face[3],
                                        "path": face[1]
                                    })
                    self.log.write("User icons saved",
                                   'LightDMManager.saveSettings', 'debug')
                if saveTheme:
                    self.cfgGreeter.setValue('greeter', 'theme-name',
                                             self.newTheme)
                    self.curTheme = self.newTheme
                    self.log.write(
                        "Theme saved: %(theme)s" % {"theme": self.curTheme},
                        'LightDMManager.saveSettings', 'debug')
                if saveBackground:
                    if os.path.exists(self.newbgImg):
                        self.cfgGreeter.setValue('greeter', 'background',
                                                 self.newbgImg)
                        self.curBgPath = self.newbgImg
                        self.log.write(
                            "Background saved: %(background)s" %
                            {"background": self.curBgPath},
                            'LightDMManager.saveSettings', 'debug')
                saved = True
            else:
                if os.path.exists(self.curBgPath):
                    self.setBackground(self.curBgPath)
                    self.log.write(
                        "Current background: %(background)s" %
                        {"background": self.curBgPath},
                        'LightDMManager.saveSettings', 'debug')
                else:
                    self.imgBackground.set_from_file(
                        join(self.scriptDir,
                             '../../share/lightdm-manager/select.png'))
                    self.log.write("No background set",
                                   'LightDMManager.saveSettings', 'debug')
                self.fillUsers()

        if saved:
            self.curHideUsers = self.chkHideUsers.get_active()
            self.curAutoUser = self.newAutoUser
            self.newFaces = []
            self.curBgPath = self.newbgImg
            self.curTheme = self.newTheme
            MessageDialogSafe(_("Saved"),
                              _("LightDM settings saved successfully."),
                              Gtk.MessageType.INFO, self.window).show()

    def on_ebBackground_button_release_event(self, widget, event):
        self.newbgImg = SelectImageDialog(_("Choose background image"),
                                          self.desktopbaseDir,
                                          self.window).show()
        if exists(self.newbgImg) and self.newbgImg != self.curBgPath:
            self.setBackground(self.newbgImg)
            self.log.write(
                _("New background: %(bg)s") % {"bg": self.newbgImg},
                'LightDMManager.chooseFile', 'info')

    def on_ebBackground_enter_notify_event(self, widget, event):
        self.window.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.HAND2))

    def on_ebBackground_leave_notify_event(self, widget, event):
        self.window.get_window().set_cursor(None)

    # This method is fired by the TreeView.checkbox-toggled event
    def usersCheckBoxToggled(self, obj, path, colNr, toggleValue):
        path = int(path)
        model = self.tvUsers.get_model()
        itr = model.get_iter(path)
        user = model[itr][1]

        if self.prevPath != path or toggleValue:
            # Only one toggle box can be selected (or none)
            self.tvHandler.treeviewToggleAll([0], False, 1, user)
            # Save current path
            self.prevPath = path
            # Save selected user
            self.newAutoUser = user
            self.log.write(
                _("Auto-login user selected: %(usr)s") % {"usr": user},
                'LightDMManager.usersCheckBoxToggled', 'info')
        elif self.prevPath == path and not toggleValue:
            self.newAutoUser = None

    def listThemes(self):
        themeDir = '/usr/share/themes'
        themeDirLocal = '~/.local/share/themes'
        dirs = functions.locate('gtk-*', themeDir, True) + functions.locate(
            'gtk-*', themeDirLocal, True)
        for path in dirs:
            dirList = path.split('/')
            for d in dirList:
                if 'gtk-' in d:
                    break
                themeName = d
            if themeName not in self.themes:
                self.themes.append(themeName)
        if self.themes:
            self.cmbHandlerThemes.fillComboBox(self.themes)
            if self.curTheme in self.themes:
                self.cmbHandlerThemes.selectValue(self.curTheme)

    def fillUsers(self):
        selUsr = False
        contentList = []
        i = 0
        for usr in self.users:
            if usr == self.curAutoUser:
                selUsr = True
                self.prevPath = i
            else:
                selUsr = False
            contentList.append([selUsr, usr])
            i += 1

        # Fill treeview with users
        #fillTreeview(contentList, columnTypesList, columnHideList=[-1], setCursor=0, setCursorWeight=400, firstItemIsColName=False, appendToExisting=False, appendToTop=False)
        columnTypesList = ['bool', 'str']
        self.tvHandler.fillTreeview(contentList, columnTypesList)

    def setBackground(self, path):
        # Set Background
        if path is not None:
            if exists(path):
                ih = ImageHandler(path)
                ih.resizeImage(height=200)
                self.imgBackground.set_from_pixbuf(ih.pixbuf)
            else:
                self.imgBackground.set_from_file(self.selectImg)
        else:
            self.imgBackground.set_from_file(self.selectImg)

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

    def on_ldmWindow_destroy(self, widget, data=None):
        # Close the app
        self.on_btnSave_clicked(None)
        for tmp in self.newFaces:
            os.remove(tmp[0])
        Gtk.main_quit()
class LightDMManager:

    def __init__(self):
        self.scriptDir = os.path.dirname(os.path.realpath(__file__))

        # Load window and widgets
        self.builder = Gtk.Builder()
        self.builder.add_from_file(join(self.scriptDir, '../../share/lightdm-manager/lightdm-manager.glade'))
        # Main window objects
        go = self.builder.get_object
        self.window = go('ldmWindow')
        self.swUsers = go('swUsers')
        self.tvUsers = go('tvUsers')
        self.btnSave = go('btnSave')
        self.imgBackground = go('imgBackground')
        self.btnUsers = go('btnUsers')
        self.btnAppearance = go('btnAppearance')
        self.chkHideUsers = go('chkHideUsers')
        self.ebFace = go('ebFace')
        self.imgFace = go('imgFace')
        self.nbLightDM = go('nbLightDM')
        self.cmbThemes = go('cmbThemes')

        # Read from config file
        self.cfg = Config('lightdm-manager.conf')
        self.lightdmConf = self.cfg.getValue('CONFIG', 'lightdmConf')
        self.desktopbaseDir = self.cfg.getValue('CONFIG', 'desktopbaseDir')
        gktGreeterConf = self.cfg.getValue('CONFIG', 'gtkGreeterConf')
        kdeGreeterConf = self.cfg.getValue('CONFIG', 'kdeGreeterConf')
        if exists(gktGreeterConf):
            self.greeterConf = gktGreeterConf
        else:
            self.greeterConf = kdeGreeterConf

        # Translations
        title = _("LightDM Manager")
        self.window.set_title(title)
        self.btnUsers.set_label("_{}".format(_("Users")))
        self.btnAppearance.set_label("_{}".format(_("Appearance")))
        go('lblBackground').set_label(_("Background"))
        go('lblTheme').set_label(_("Theme"))
        go('lblLightDmMenu').set_label(_("Menu"))
        self.chkHideUsers.set_label(_("Hide users"))
        go('lblUsersFace').set_label(_("User icon"))
        go('lblUsersAutologin').set_label(_("Auto-login"))

        # Get current background image
        self.cfgGreeter = Config(self.greeterConf)
        try:
            self.curBgPath = self.cfgGreeter.getValue('greeter', 'background')
            self.curTheme = self.cfgGreeter.getValue('greeter', 'theme-name')
        except:
            self.curBgPath = None
            self.curTheme = None

        # Get current auto-login user
        self.cfgLightdm = Config(self.lightdmConf)
        try:
            self.curAutoUser = self.cfgLightdm.getValue('SeatDefaults', 'autologin-user').strip()
            self.curHideUsers = False
            ghu = self.cfgLightdm.getValue('SeatDefaults', 'greeter-hide-users').strip()
            if 'true' in ghu:
                self.curHideUsers = True
        except:
            self.curAutoUser = None
            self.curHideUsers = False

        # Init
        self.usr = User()
        self.newbgImg = self.curBgPath
        self.newAutoUser = self.curAutoUser
        self.newTheme = self.curTheme
        self.themes = []
        self.selectedMenuItem = None
        self.debug = False
        self.logPath = ''
        self.prevPath = None
        self.tempFace = "/tmp/face"
        self.newFaces = []
        self.loggedUser = functions.getUserLoginName()
        self.curUser = self.loggedUser
        self.selectImg = join(self.scriptDir, '../../share/lightdm-manager/select.png')

        # Handle arguments
        try:
            opts, args = getopt.getopt(sys.argv[1:], 'dl:', ['debug', 'log='])
        except getopt.GetoptError:
            print(("Arguments cannot be parsed: %s" % str(sys.argv[1:])))
            sys.exit(1)

        for opt, arg in opts:
            if opt in ('-d', '--debug'):
                self.debug = True
            elif opt in ('-l', '--log'):
                self.logPath = arg

        # Initialize logging
        if self.debug:
            if not self.logPath:
                self.logPath = 'lightdm-manager.log'
        self.log = Logger(self.logPath, 'debug', True, None, self.window)

        # Backup config files because ConfigParser does not preserve commented lines
        if not exists("%s.org" % self.greeterConf):
            copy(self.greeterConf, "%s.org" % self.greeterConf)
            self.log.write("%(conf1)s copied to %(conf2)s.org" % { "conf1": self.greeterConf, "conf2": self.greeterConf }, 'LightDMManager.main', 'debug')
        if not exists("%s.org" % self.lightdmConf):
            copy(self.lightdmConf, "%s.org" % self.lightdmConf)
            self.log.write("%(conf1)s copied to %(conf2)s.org" % { "conf1": self.lightdmConf, "conf2": self.lightdmConf }, 'LightDMManager.main', 'debug')

        # Initiate the treeview handler and connect the custom toggle event with usersCheckBoxToggled
        self.tvHandler = TreeViewHandler(self.tvUsers, self.log)
        self.tvHandler.connect('checkbox-toggled', self.usersCheckBoxToggled)

        # Get users
        self.users = self.usr.getUsers()
        self.fillUsers()
        self.tvHandler.selectValue(self.curUser, 1)
        self.setBackground(self.curBgPath)
        self.cmbHandlerThemes = ComboBoxHandler(self.cmbThemes)
        self.listThemes()
        self.chkHideUsers.set_active(self.curHideUsers)

        # Show users menu
        self.on_btnUsers_clicked(None)
        self.on_tvUsers_cursor_changed(None)

        self.version = functions.getPackageVersion('lightdm-manager')

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

    # ===============================================
    # Menu section functions
    # ===============================================

    def on_btnUsers_clicked(self, widget, event=None):
        if self.selectedMenuItem != menuItems[0]:
            self.selectedMenuItem = menuItems[0]
            self.nbLightDM.set_current_page(0)

    def on_btnAppearance_clicked(self, widget, event=None):
        if self.selectedMenuItem != menuItems[1]:
            self.selectedMenuItem = menuItems[1]
            self.nbLightDM.set_current_page(1)

    # ===============================================
    # Functions
    # ===============================================

    def on_ebFace_enter_notify_event(self, widget, event):
        self.window.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.HAND2))

    def on_ebFace_leave_notify_event(self, widget, event):
        self.window.get_window().set_cursor(None)

    def on_ebFace_button_release_event(self, widget, event):
        home = self.usr.getUserHomeDir(self.curUser)
        primaryGroup = self.usr.getUserPrimaryGroupName(self.curUser)
        imagePath = SelectImageDialog(_('Select user image'), home, self.window).show()
        if imagePath is not None:
            tempUserImg = "%(tempFace)s.%(curUser)s" % {"tempFace": self.tempFace, "curUser": self.curUser}
            self.newFaces.append([tempUserImg, join(home, ".face"), self.curUser, primaryGroup])
            print((">>> self.newFaces = %s" % self.newFaces))
            ih = ImageHandler(imagePath)
            ih.makeFaceImage(tempUserImg)
            if exists(tempUserImg):
                self.imgFace.set_from_pixbuf(ih.pixbuf)
            else:
                # This should never happen
                self.imgFace.set_from_file(self.selectImg)

    def on_tvUsers_cursor_changed(self, widget):
        self.curUser = self.tvHandler.getSelectedValue(1)
        showFace = None
        if self.newFaces:
            for face in self.newFaces:
                if face[2] == self.curUser and exists(face[0]):
                    showFace = GdkPixbuf.Pixbuf.new_from_file(face[0])
        if showFace is None:
            showFace = self.usr.getUserFacePixbuf(self.curUser)
        if showFace is None:
            # Still no user icon found: show select image
            self.imgFace.set_from_file(self.selectImg)
        else:
            self.imgFace.set_from_pixbuf(showFace)

    def on_btnSave_clicked(self, widget):
        saved = False
        saveHideUsers = False
        saveAutoUser = False
        saveFaces = False
        saveBackground = False
        saveTheme = False
        if self.chkHideUsers.get_active() != self.curHideUsers:
            saveHideUsers = True
        if self.curAutoUser != self.newAutoUser:
            saveAutoUser = True
        if self.newFaces:
            saveFaces = True
        if self.curBgPath != self.newbgImg:
            saveBackground = True
        self.newTheme = self.cmbHandlerThemes.getValue()
        if self.curTheme != self.newTheme:
            saveTheme = True

        if saveHideUsers or saveAutoUser or saveFaces or saveBackground or saveTheme:
            qd = QuestionDialog(_("LightDM settings"), _("Settings have changed\n\nDo you want to save the new settings?"), self.window)
            answer = qd.show()
            if answer:
                if saveAutoUser:
                    if self.newAutoUser is not None:
                        # Save the auto-login user
                        self.cfgLightdm.setValue('SeatDefaults', 'autologin-user', self.newAutoUser)
                        self.cfgLightdm.setValue('SeatDefaults', 'autologin-user-timeout', '0')
                        self.curAutoUser = self.newAutoUser
                        self.log.write("New auto-login user: %(usr)s" % { "usr": self.curAutoUser }, 'LightDMManager.saveSettings', 'debug')
                    else:
                        self.cfgLightdm.removeOption('SeatDefaults', 'autologin-user')
                        self.cfgLightdm.removeOption('SeatDefaults', 'autologin-user-timeout')
                        self.curAutoUser = None
                        self.log.write("Auto-login disabled", 'LightDMManager.saveSettings', 'debug')
                if saveHideUsers:
                    hideUsers = str(self.chkHideUsers.get_active()).lower()
                    self.cfgLightdm.setValue('SeatDefaults', 'greeter-hide-users', hideUsers)
                    self.log.write("Hide users saved: %(users)s" % {"users": hideUsers}, 'LightDMManager.saveSettings', 'debug')
                if saveFaces:
                    for face in self.newFaces:
                        if exists(face[0]):
                            copy(face[0], face[1])
                            if exists(face[1]):
                                os.system("chown %(owner)s:%(group)s %(path)s" % {"owner": face[2], "group": face[3], "path": face[1]})
                    self.log.write("User icons saved", 'LightDMManager.saveSettings', 'debug')
                if saveTheme:
                    self.cfgGreeter.setValue('greeter', 'theme-name', self.newTheme)
                    self.curTheme = self.newTheme
                    self.log.write("Theme saved: %(theme)s" % { "theme": self.curTheme }, 'LightDMManager.saveSettings', 'debug')
                if saveBackground:
                    if os.path.exists(self.newbgImg):
                        self.cfgGreeter.setValue('greeter', 'background', self.newbgImg)
                        self.curBgPath = self.newbgImg
                        self.log.write("Background saved: %(background)s" % { "background": self.curBgPath }, 'LightDMManager.saveSettings', 'debug')
                saved = True
            else:
                if os.path.exists(self.curBgPath):
                    self.setBackground(self.curBgPath)
                    self.log.write("Current background: %(background)s" % { "background": self.curBgPath }, 'LightDMManager.saveSettings', 'debug')
                else:
                    self.imgBackground.set_from_file(join(self.scriptDir, '../../share/lightdm-manager/select.png'))
                    self.log.write("No background set", 'LightDMManager.saveSettings', 'debug')
                self.fillUsers()

        if saved:
            self.curHideUsers = self.chkHideUsers.get_active()
            self.curAutoUser = self.newAutoUser
            self.newFaces = []
            self.curBgPath = self.newbgImg
            self.curTheme = self.newTheme
            MessageDialogSafe(_("Saved"), _("LightDM settings saved successfully."), Gtk.MessageType.INFO, self.window).show()


    def on_ebBackground_button_release_event(self, widget, event):
        self.newbgImg = SelectImageDialog(_("Choose background image"), self.desktopbaseDir, self.window).show()
        if exists(self.newbgImg) and self.newbgImg != self.curBgPath:
            self.setBackground(self.newbgImg)
            self.log.write(_("New background: %(bg)s") % { "bg": self.newbgImg }, 'LightDMManager.chooseFile', 'info')

    def on_ebBackground_enter_notify_event(self, widget, event):
        self.window.get_window().set_cursor(Gdk.Cursor(Gdk.CursorType.HAND2))

    def on_ebBackground_leave_notify_event(self, widget, event):
        self.window.get_window().set_cursor(None)

    # This method is fired by the TreeView.checkbox-toggled event
    def usersCheckBoxToggled(self, obj, path, colNr, toggleValue):
        path = int(path)
        model = self.tvUsers.get_model()
        itr = model.get_iter(path)
        user = model[itr][1]

        if self.prevPath != path or toggleValue:
            # Only one toggle box can be selected (or none)
            self.tvHandler.treeviewToggleAll([0], False, 1, user)
            # Save current path
            self.prevPath = path
            # Save selected user
            self.newAutoUser = user
            self.log.write(_("Auto-login user selected: %(usr)s") % { "usr": user }, 'LightDMManager.usersCheckBoxToggled', 'info')
        elif self.prevPath == path and not toggleValue:
            self.newAutoUser = None

    def listThemes(self):
        themeDir = '/usr/share/themes'
        themeDirLocal = '~/.local/share/themes'
        dirs = functions.locate('gtk-*', themeDir, True) + functions.locate('gtk-*', themeDirLocal, True)
        for path in dirs:
            dirList = path.split('/')
            for d in dirList:
                if 'gtk-' in d:
                    break
                themeName = d
            if themeName not in self.themes:
                self.themes.append(themeName)
        if self.themes:
            self.cmbHandlerThemes.fillComboBox(self.themes)
            if self.curTheme in self.themes:
                self.cmbHandlerThemes.selectValue(self.curTheme)

    def fillUsers(self):
        selUsr = False
        contentList = []
        i = 0
        for usr in self.users:
            if usr == self.curAutoUser:
                selUsr = True
                self.prevPath = i
            else:
                selUsr = False
            contentList.append([selUsr, usr])
            i += 1

        # Fill treeview with users
        #fillTreeview(contentList, columnTypesList, columnHideList=[-1], setCursor=0, setCursorWeight=400, firstItemIsColName=False, appendToExisting=False, appendToTop=False)
        columnTypesList = ['bool', 'str']
        self.tvHandler.fillTreeview(contentList, columnTypesList)

    def setBackground(self, path):
        # Set Background
        if path is not None:
            if exists(path):
                ih = ImageHandler(path)
                ih.resizeImage(height=200)
                self.imgBackground.set_from_pixbuf(ih.pixbuf)
            else:
                self.imgBackground.set_from_file(self.selectImg)
        else:
            self.imgBackground.set_from_file(self.selectImg)

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

    def on_ldmWindow_destroy(self, widget, data=None):
        # Close the app
        self.on_btnSave_clicked(None)
        for tmp in self.newFaces:
            os.remove(tmp[0])
        Gtk.main_quit()
예제 #4
0
class UpdateManagerPref(object):

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    # Close the gui
    def on_windowPref_destroy(self, widget):
        Gtk.main_quit()
예제 #5
0
class DDM(object):

    def __init__(self, test=False):
        # Testing
        self.test = test
        # Set to true for testing Optimus
        self.test_optimus = False

        # Load window and widgets
        self.scriptName = basename(__file__)
        self.scriptDir = abspath(dirname(__file__))
        self.mediaDir = join(self.scriptDir, '../../share/ddm')
        self.builder = Gtk.Builder()
        self.builder.add_from_file(join(self.mediaDir, 'ddm.glade'))

        # Main window objects
        go = self.builder.get_object
        self.window = go("ddmWindow")
        self.tvDDM = go("tvDDM")
        self.btnSave = go("btnSave")
        self.btnHelp = go("btnHelp")
        self.btnQuit = go("btnQuit")
        self.pbDDM = go("pbDDM")
        self.chkBackports = go("chkBackports")

        self.window.set_title(_("Device Driver Manager"))
        self.btnSave.set_label(_("Install"))
        self.btnHelp.set_label(_("Help"))
        self.btnQuit.set_label(_("Quit"))
        self.chkBackports.set_label(_("Use Backports"))

        # Initiate variables
        self.queue = Queue(-1)
        self.threads = {}
        self.hardware = []
        self.loadedDrivers = []
        self.notSupported = []
        self.paeBooted = False
        self.htmlDir = join(self.mediaDir, "html")
        self.helpFile = join(self.get_language_dir(), "help.html")
        log = getoutput("cat /usr/bin/ddm | grep 'LOG=' | cut -d'=' -f 2")
        self.logFile = log[0]
        self.log = Logger(self.logFile, addLogTime=False, maxSizeKB=5120)
        self.tvDDMHandler = TreeViewHandler(self.tvDDM)
        self.tvDDMHandler.connect('checkbox-toggled', self.tv_checkbox_toggled)

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

        # Fill treeview
        self.fill_treeview_ddm()

        # Check backports
        if len(self.hardware) < 2 or not has_backports():
            self.chkBackports.hide()

        self.get_loaded_graphical_driver()
        self.get_loaded_wireless_driver()

    # ===============================================
    # Language specific functions
    # ===============================================

    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.htmlDir, lang)
        if not isdir(path):
            base_lang = lang.split('_')[0].lower()
            path = join(self.htmlDir, base_lang)
            if not isdir(path):
                path = join(self.htmlDir, "{}_{}".format(base_lang, base_lang.upper()))
                if not isdir(path):
                    path = join(self.htmlDir, 'en')
        return path

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

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

    def on_btnSave_clicked(self, widget):
        # Save selected hardware
        arguments = []

        model = self.tvDDM.get_model()
        itr = model.get_iter_first()
        while itr is not None:
            action = 'no change'
            selected = model.get_value(itr, 0)
            device = model.get_value(itr, 2)
            manufacturerId = ''

            # Check currently selected state with initial state
            # This decides whether we should install or purge the drivers
            for hw in self.hardware:
                self.log.write("Device = {} in {}".format(device, hw[2]), 'on_btnSave_clicked')
                if device in hw[2]:
                    manufacturerId = hw[4]
                    if hw[0] and not selected:
                        action = 'purge'
                    elif not hw[0] and selected:
                        action = 'install'
                    break

            self.log.write("{}: {} ({})".format(action, device, manufacturerId), 'on_btnSave_clicked')

            # Install/purge selected driver
            option = ""
            if action == 'install':
                option = "-i"
            elif action == 'purge':
                option = "-p"

            if option:
                driver = ''
                # Run the manufacturer specific bash script
                if manufacturerId == '1002':
                    driver = 'ati'
                elif manufacturerId == '10de':
                    driver = 'nvidia '
                elif manufacturerId == '14e4':
                    driver = 'broadcom '
                elif 'pae' in manufacturerId:
                    driver = 'pae '
                if driver:
                    arguments.append("{} {}".format(option, driver))

            # Get the next in line
            itr = model.iter_next(itr)

        # Execute the command
        if arguments:
            if '-i' in arguments and not hasInternetConnection():
                title = _("No internet connection")
                msg = _("You need an internet connection to install the additional software.\n"
                        "Please, connect to the internet and try again.")
                WarningDialog(title, msg)
            else:
                # Warn for use of Backports
                if self.chkBackports.get_active():
                    answer = QuestionDialog(self.chkBackports.get_label(),
                            _("You have selected to install drivers from the backports repository whenever they are available.\n\n"
                              "Although you can run more up to date software using the backports repository,\n"
                              "you introduce a greater risk of breakage doing so.\n\n"
                              "Are you sure you want to continue?"))
                    if not answer:
                        self.chkBackports.set_active(False)
                        return True
                    arguments.append("-b")

                # Testing
                if self.test:
                    arguments.append("-t")

                command = "ddm {}".format(" ".join(arguments))
                self.log.write("Command to execute: {}".format(command), 'on_btnSave_clicked')
                self.exec_command(command)

    def on_btnQuit_clicked(self, widget):
        self.on_ddmWindow_destroy(widget)

    def on_btnHelp_clicked(self, widget):
        # Open the help file as the real user (not root)
        shell_exec("%s/open-as-user \"%s\"" % (self.scriptDir, self.helpFile))

    def get_supported_hardware(self):
        # Fill self.hardware
        self.hardware = []

        # First row are column names
        self.hardware.append([_("Install"), '', _("Device"), 'driver', 'manid', 'deviceid'])

        # Get hardware information
        self.get_ati()
        self.get_nvidia()
        self.get_broadcom()
        self.get_pae()

    # This method is fired by the TreeView.checkbox-toggled event
    def tv_checkbox_toggled(self, obj, path, colNr, toggleValue):
        path = int(path)
        model = self.tvDDM.get_model()
        itr = model.get_iter(path)
        description = model[itr][2].lower()

        if 'pae' in description and not toggleValue and self.paeBooted:
            title = _("Remove kernel")
            msg = _("You cannot remove a booted kernel.\nPlease, boot another kernel and try again.")
            self.log.write(msg, 'tv_checkbox_toggled')
            WarningDialog(title, msg)
            model[itr][0] = True

    def fill_treeview_ddm(self):
        # Fill a list with supported hardware
        self.get_supported_hardware()

        # columns: checkbox, image (logo), device, driver
        columnTypes = ['bool', 'GdkPixbuf.Pixbuf', 'str']

        # Keep some info from the user
        showHw = []
        for hw in self.hardware:
            showHw.append([hw[0], hw[1], hw[2]])

        # Fill treeview
        self.tvDDMHandler.fillTreeview(contentList=showHw, columnTypesList=columnTypes, firstItemIsColName=True, fontSize=12000)

        # Show message if nothing is found or hardware is not supported
        title = _("Hardware scan")
        if self.notSupported:
            if len(self.hardware) < 2:
                self.set_buttons_state(False)
            msg = _("There are no available drivers for your hardware:")
            msg = "{}\n\n{}".format(msg, '\n'.join(self.notSupported))
            self.log.write(msg, 'fill_treeview_ddm')
            WarningDialog(title, msg)
        elif len(self.hardware) < 2:
            self.set_buttons_state(False)
            msg = _("DDM did not find any supported hardware.")
            self.log.write(msg, 'fill_treeview_ddm')
            MessageDialog(title, msg)

    def exec_command(self, command):
        try:
            # Run the command in a separate thread
            self.set_buttons_state(False)
            name = 'cmd'
            t = ExecuteThreadedCommands([command], self.queue)
            self.threads[name] = t
            t.daemon = True
            t.start()
            self.queue.join()
            GObject.timeout_add(250, self.check_thread, name)

        except Exception as detail:
            ErrorDialog(self.btnSave.get_label(), detail)

    def set_buttons_state(self, enable):
        if not enable:
            # Disable buttons
            self.btnSave.set_sensitive(False)
        else:
            # Enable buttons and reset progress bar
            self.btnSave.set_sensitive(True)
            self.pbDDM.set_fraction(0)

    def check_thread(self, name):
        if self.threads[name].is_alive():
            self.pbDDM.pulse()
            if not self.queue.empty():
                ret = self.queue.get()
                self.log.write("Queue returns: {}".format(ret), 'check_thread')
                self.queue.task_done()
                self.show_message(ret)
            return True

        # Thread is done
        self.log.write(">> Thread is done", 'check_thread')
        if not self.queue.empty():
            ret = self.queue.get()
            self.queue.task_done()
            self.show_message(ret)
        del self.threads[name]

        self.set_buttons_state(True)

        return False

    # Close the gui
    def on_ddmWindow_destroy(self, widget):
        # Close the app
        Gtk.main_quit()

    # ===============================================
    # Hardware functions
    # ===============================================

    def get_ati(self):
        # Debian Wiki: https://wiki.debian.org/ATIProprietary
        # Supported devices 14.9 (Jessie): http://support.amd.com/en-us/kb-articles/Pages/AMDCatalyst14-9LINReleaseNotes.aspx

        manufacturerId = '1002'
        startSeries = 5000
        deviceArray = self.get_lspci_info(manufacturerId, 'VGA')

        if self.test:
            #deviceArray = [['Advanced Micro Devices [AMD] nee ATI Manhattan [Mobility Radeon HD 5400 Series]', manufacturerId, '68e0']]
            #deviceArray = [['Advanced Micro Devices, Inc. [AMD/ATI] RV710 [Radeon HD 4350/4550]', manufacturerId, '68e0']]
            #deviceArray = [['Advanced Micro Devices [AMD/ATI] RS880 [Radeon HD 4290]', manufacturerId, '68e0']]
            #deviceArray = [['Advanced Micro Devices, Inc. [AMD/ATI] Tonga PRO [Radeon R9 285]', manufacturerId, '6939']]
            deviceArray = [['Advanced Micro Devices, Inc. [AMD/ATI] Bonaire [FirePro W5100]', manufacturerId, '6649']]

        if deviceArray:
            self.log.write("Device(s): {}".format(deviceArray), 'get_ati')
            # Check if fglrx is loaded
            # If it is: checkbox is selected
            loadedDrv = self.get_loaded_graphical_driver()
            self.log.write("Loaded graphical driver: {}".format(loadedDrv), 'get_ati')

            # Get the manufacturer's logo
            logo = join(self.mediaDir, 'images/ati.png')

            # Fill the hardware array
            for device in deviceArray:
                self.log.write("ATI device found: {}".format(device[0]), 'get_ati')
                # Check for supported cards
                matchObj = re.search('radeon\s+[0-9a-z ]+|fire[a-z]+\s+[0-9a-z -]+', device[0], flags=re.IGNORECASE)
                if matchObj:
                    if " hd " in matchObj.group(0).lower():
                        # Check if ATI series is above 5000
                        matchObjSeries = re.search('[0-9]{4}', matchObj.group(0))
                        if matchObjSeries:
                            series = int(matchObjSeries.group(0))
                            # Don't show older ATI Radeon HD cards
                            if series < startSeries:
                                break
                    elif 'fire' in matchObj.group(0).lower():
                        title = _("ATI FirePro/Gl card found")
                        msg = _("Installing the proprietary driver for an ATI FirePro/Gl card may render your system unbootable.\n\n"
                                "Proceed at your own risk.")
                        self.log.write(msg, 'get_ati')
                        WarningDialog(title, msg)

                    self.log.write("ATI series: {}".format(matchObj.group(0)), 'get_ati')

                    # Check if the available driver is already loaded
                    selected = False
                    driver = 'fglrx'
                    if loadedDrv == driver:
                        selected = True

                    # Fill self.hardware
                    #shortDevice = self.shorten_long_string(device[0], 100)
                    self.hardware.append([selected, logo, device[0], driver, device[1], device[2]])
                else:
                    self.notSupported.append(device[0])

    def get_nvidia(self):
        manufacturerId = '10de'
        deviceArray = self.get_lspci_info(manufacturerId, 'VGA')

        if self.test:
            deviceArray = [['NVIDIA Corporation GT218 [GeForce G210M]', manufacturerId, '0a74']]
            if self.test_optimus:
                deviceArray = [['Intel Corporation Haswell-ULT Integrated Graphics Controller', '8086', '0a16'], \
                                ['NVIDIA Corporation GK107M [GeForce GT 750M]', manufacturerId, '0fe4']]

        if deviceArray:
            optimus = False
            devices = []

            self.log.write("Device(s): {}".format(deviceArray), 'get_nvidia')

            # Check if nvidia is loaded
            # If it is: checkbox is selected
            loadedDrv = self.get_loaded_graphical_driver()
            self.log.write("Loaded graphical driver: {}".format(loadedDrv), 'get_nvidia')

            # Get the manufacturer's logo
            logo = join(self.mediaDir, 'images/nvidia.png')

            # Fill the hardware array
            for device in deviceArray:
                if device[1] == '8086':
                    optimus = True
                else:
                    devices.append(device)

            for device in devices:
                self.log.write("Nvidia device found: {}".format(device[0]), 'get_nvidia')
                optimusString = ""
                if optimus:
                    optimusString = "(Optimus) "

                # Check if the available driver is already loaded
                selected = False
                if optimus:
                    if loadedDrv == 'nvidia' or loadedDrv == 'intel':
                        bbversion = getPackageVersion("bumblebee-nvidia")
                        self.log.write("bumblebee-nvidia version: {}".format(bbversion), 'get_nvidia')
                        if bbversion != '':
                            selected = True
                elif loadedDrv == 'nvidia':
                    selected = True

                driver = ""
                if optimus:
                    driver = "bumblebee-nvidia"
                else:
                    if self.test:
                        driver = 'nvidia-driver'
                    else:
                        nvidiaDetect = getoutput("nvidia-detect | grep nvidia- | tr -d ' '")
                        if nvidiaDetect:
                            driver = nvidiaDetect[0]

                self.log.write("Nvidia driver to use: {}".format(driver), 'get_nvidia')

                # Fill self.hardware
                if driver != "":
                    #shortDevice = "{0}{1}".format(optimusString, self.shorten_long_string(device[0], 100))
                    self.hardware.append([selected, logo, "{0}{1}".format(optimusString, device[0]), driver, device[1], device[2]])

    def get_broadcom_ids(self, driver_name):
        driver_name = driver_name.upper()
        ids = getoutput("cat /usr/bin/ddm | grep '{}=' | cut -d'=' -f 2".format(driver_name))
        if len(ids) > 0:
            return ids[0].split('|')
        return []

    def get_broadcom(self):
        ## Hardware list (device ids)
        ## http://linuxwireless.org/en/users/Drivers/b43
        deviceIds = {}
        deviceIds['b43'] = self.get_broadcom_ids('b43')
        deviceIds['b43legacy'] = self.get_broadcom_ids('b43legacy')
        deviceIds['wldebian'] = self.get_broadcom_ids('wldebian')
        deviceIds['brcmdebian'] = self.get_broadcom_ids('brcmdebian')
        deviceIds['unknown'] = self.get_broadcom_ids('unknown')

        self.log.write("Broadcom deviceIds = {}".format(deviceIds))

        manufacturerId = '14e4'

        deviceArray = self.get_lspci_info(manufacturerId)

        if self.test:
            deviceArray = [['Broadcom Corporation BCM43142 802.11a/b/g', manufacturerId, '4365']]

        if deviceArray:
            self.log.write("Device(s): {}".format(deviceArray), 'get_broadcom')
            # Check if broadcom is loaded
            # If it is: checkbox is selected
            loadedDrv = self.get_loaded_wireless_driver()
            self.log.write("Loaded wireless driver: {}".format(loadedDrv), 'get_broadcom')

            # Get the manufacturer's logo
            logo = join(self.mediaDir, 'images/broadcom.png')

            # Fill the hardware array
            for device in deviceArray:
                self.log.write("Broadcom device found: {}".format(device[0]), 'get_broadcom')
                driver = ''
                for key, did in list(deviceIds.items()):
                    #print(("{}:{} in {}:{}".format(device[0], device[2], key, did)))
                    if device[2] in did:
                        driver = key
                        break

                if driver != '':
                    if driver == 'unknown':
                        self.notSupported.append(device[0])
                        self.log.write("Broadcom device not supported: {}".format(device[0]), 'get_broadcom')
                    else:
                        self.log.write("Broadcom driver to use: {}".format(driver), 'get_broadcom')
                        # Check if the available driver is already loaded
                        selected = False
                        if loadedDrv == driver:
                            selected = True

                        # Fill self.hardware
                        #shortDevice = self.shorten_long_string(device[0], 100)
                        self.hardware.append([selected, logo, device[0], driver, device[1], device[2]])

    def get_pae(self):
        machine = getoutput('uname -m')[0]
        release = getoutput('uname -r')[0]

        if self.test:
            machine = 'i686'
            release = '3.16.0-4-586'

        self.log.write("PAE check: machine={} / release={}".format(machine, release), 'get_pae')

        if machine == 'i686':
            # Check if PAE is installed and running
            selected = False
            if 'pae' in release:
                self.paeBooted = True
                selected = True
            else:
                if getPackageVersion('linux-image-686-pae') != '':
                    selected = True

            # Get the logo
            logo = join(self.mediaDir, 'images/pae.png')

            # Fill self.hardware
            paeDescription = _("PAE capable system")
            self.hardware.append([selected, logo, paeDescription, '', 'pae', ''])

    def get_lspci_info(self, manufacturerId, filterString=''):
        deviceArray = []
        output = []

        # Check for Optimus
        if manufacturerId == '10de':
            output = getoutput("lspci -vnn | grep '\[030[02]\]'")

            if self.test_optimus:
                output = ['00:02.0 VGA compatible controller [0300]: Intel Corporation Haswell-ULT Integrated Graphics Controller [8086:0a16] (rev 09) (prog-if 00 [VGA controller])', \
                          '01:00.0 3D controller [0302]: NVIDIA Corporation GK107M [GeForce GT 750M] [10de:0fe4] (rev a1)']

        # Optimus will return 2 devices
        # If there are less than 2 devices, do regular check
        if len(output) < 2:
            if filterString != '':
                filterString = " | grep {}".format(filterString)
            output = getoutput("lspci -nn -d {}:{}".format(manufacturerId, filterString))

        if output:
            self.log.write("lspci output = {}".format(output), 'get_lspci_info')

        for line in output:
            matchObj = re.search(':\W(.*)\W\[(.+):(.+)\]', line)
            if matchObj:
                deviceArray.append([matchObj.group(1), matchObj.group(2), matchObj.group(3)])
        return deviceArray

    def shorten_long_string(self, longString, charLen, breakOnWord=True):
        tmpArr = []
        if breakOnWord:
            stringArr = longString.split(' ')
            nrChrs = 0
            for s in stringArr:
                nrChrs += len(s) + 1
                if nrChrs < charLen:
                    tmpArr.append(s)
                else:
                    break
        else:
            if len(longString) > charLen:
                tmpArr.append("{}...".format(longString[0:charLen]))
            else:
                tmpArr.append(longString)
        return ' '.join(tmpArr)

    # Return graphics module used by X.org
    # TODO: is lsmod an alternative?
    def get_loaded_graphical_driver(self):
        # sort on the most recent X.org log
        module = ''
        log = ''
        logDir = '/var/log/'
        logPath = None
        logs = glob(os.path.join(logDir, 'Xorg.*.log*'))
        logs.sort()

        for logPath in logs:
            # Search for "depth" in each line and check the used module
            # Sometimes these logs are saved as binary: open as read-only binary
            # When opening as ascii, read() will throw error: "UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80"
            with open(logPath, 'rb') as f:
                # replace utf-8 binary read errors (with ?)
                log = f.read().decode(encoding='utf-8', errors='replace')
                #print((log))

            matchObj = re.search('([a-zA-Z]*)\(\d+\):\s+depth.*framebuffer', log, flags=re.IGNORECASE)
            if matchObj:
                module = matchObj.group(1).lower()
                self.log.write("Log module={}".format(module))
                break

        return module

    # Return used wireless driver
    def get_loaded_wireless_driver(self):
        driver = ''
        logDir = '/var/log/'
        for logPath in glob(os.path.join(logDir, 'syslog*')):
            if driver == '' and not 'gz' in logPath:
                # Open the log file
                lines = []
                with open(logPath, 'rb') as f:
                    log = f.read().decode(encoding='utf-8', errors='replace')
                    lines = list(log.splitlines())

                for line in reversed(lines):
                    # First check for Network Manager entry
                    # Search for wlan0 in each line and get the listed driver
                    matchObj = re.search('\(wlan\d\):.*driver:\s*\'([a-zA-Z0-9\-]*)', line, flags=re.IGNORECASE)
                    if matchObj:
                        driver = matchObj.group(1)
                        self.log.write("Network Manager driver={}".format(driver))
                        break
                    else:
                        # Wicd
                        # Search for ieee in each line and get the listed driver
                        matchObj = re.search('ieee.*implement', line, flags=re.IGNORECASE)
                        if matchObj:
                            driver = matchObj.group(0)
                            self.log.write("Wicd driver={}".format(driver))
                            break

        return driver

    def show_message(self, cmdOutput):
        try:
            self.log.write("Command output: {}".format(cmdOutput), 'show_message')
            ret = int(cmdOutput)
            if ret > 1 and ret != 255:
                if ret == 1:
                    ErrorDialog(self.btnSave.get_label(), _("Run as root."))
                elif ret == 2:
                    ErrorDialog(self.btnSave.get_label(), _("Wrong arguments passed to ddm."))
                elif ret == 3:
                    ErrorDialog(self.btnSave.get_label(), _("There are no driver available."))
                elif ret == 4:
                    ErrorDialog(self.btnSave.get_label(), _("The driver cannot be found in repository."))
                elif ret == 5:
                    ErrorDialog(self.btnSave.get_label(), _("Download error.\nCheck your internet connection."))
                elif ret == 6:
                    ErrorDialog(self.btnSave.get_label(), _("DDM cannot purge the driver."))
                elif ret == 7:
                    ErrorDialog(self.btnSave.get_label(), _("This card is not supported."))
                else:
                    msg = _("There was an error during the installation.\n"
                    "Please, run 'sudo apt-get -f install' in a terminal.\n"
                    "Visit our forum for support: http://forums.solydxk.com")
                    ErrorDialog(self.btnSave.get_label(), msg)
            else:
                msg = _("The software has been successfully installed.")
                msg_restart = _("You will need to restart your system.")
                MessageDialog(self.btnSave.get_label(), "{}\n\n{}".format(msg, msg_restart))
        except:
            ErrorDialog(self.btnSave.get_label(), cmdOutput)
예제 #6
0
class DDM(object):
    def __init__(self, test=False):
        # Testing
        self.test = test
        # Set to true for testing Optimus
        self.test_optimus = False

        # Load window and widgets
        self.scriptName = basename(__file__)
        self.scriptDir = abspath(dirname(__file__))
        self.mediaDir = join(self.scriptDir, '../../share/ddm')
        self.builder = Gtk.Builder()
        self.builder.add_from_file(join(self.mediaDir, 'ddm.glade'))

        # Main window objects
        go = self.builder.get_object
        self.window = go("ddmWindow")
        self.tvDDM = go("tvDDM")
        self.btnSave = go("btnSave")
        self.btnHelp = go("btnHelp")
        self.btnQuit = go("btnQuit")
        self.pbDDM = go("pbDDM")
        self.chkBackports = go("chkBackports")

        self.window.set_title(_("Device Driver Manager"))
        self.btnSave.set_label(_("Install"))
        self.btnHelp.set_label(_("Help"))
        self.btnQuit.set_label(_("Quit"))
        self.chkBackports.set_label(_("Use Backports"))

        # Initiate variables
        self.queue = Queue(-1)
        self.threads = {}
        self.hardware = []
        self.loadedDrivers = []
        self.notSupported = []
        self.paeBooted = False
        self.htmlDir = join(self.mediaDir, "html")
        self.helpFile = join(self.get_language_dir(), "help.html")
        log = getoutput("cat /usr/bin/ddm | grep 'LOG=' | cut -d'=' -f 2")
        self.logFile = log[0]
        self.log = Logger(self.logFile, addLogTime=False, maxSizeKB=5120)
        self.tvDDMHandler = TreeViewHandler(self.tvDDM)
        self.tvDDMHandler.connect('checkbox-toggled', self.tv_checkbox_toggled)

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

        # Fill treeview
        self.fill_treeview_ddm()

        # Check backports
        if len(self.hardware) < 2 or not has_backports():
            self.chkBackports.hide()

        self.get_loaded_graphical_driver()
        self.get_loaded_wireless_driver()

    # ===============================================
    # Language specific functions
    # ===============================================

    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.htmlDir, lang)
        if not isdir(path):
            base_lang = lang.split('_')[0].lower()
            path = join(self.htmlDir, base_lang)
            if not isdir(path):
                path = join(self.htmlDir,
                            "{}_{}".format(base_lang, base_lang.upper()))
                if not isdir(path):
                    path = join(self.htmlDir, 'en')
        return path

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

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

    def on_btnSave_clicked(self, widget):
        # Save selected hardware
        arguments = []

        model = self.tvDDM.get_model()
        itr = model.get_iter_first()
        while itr is not None:
            action = 'no change'
            selected = model.get_value(itr, 0)
            device = model.get_value(itr, 2)
            manufacturerId = ''

            # Check currently selected state with initial state
            # This decides whether we should install or purge the drivers
            for hw in self.hardware:
                self.log.write("Device = {} in {}".format(device, hw[2]),
                               'on_btnSave_clicked')
                if device in hw[2]:
                    manufacturerId = hw[4]
                    if hw[0] and not selected:
                        action = 'purge'
                    elif not hw[0] and selected:
                        action = 'install'
                    break

            self.log.write(
                "{}: {} ({})".format(action, device, manufacturerId),
                'on_btnSave_clicked')

            # Install/purge selected driver
            option = ""
            if action == 'install':
                option = "-i"
            elif action == 'purge':
                option = "-p"

            if option:
                driver = ''
                # Run the manufacturer specific bash script
                if manufacturerId == '1002':
                    driver = 'ati'
                elif manufacturerId == '10de':
                    driver = 'nvidia '
                elif manufacturerId == '14e4':
                    driver = 'broadcom '
                elif 'pae' in manufacturerId:
                    driver = 'pae '
                if driver:
                    arguments.append("{} {}".format(option, driver))

            # Get the next in line
            itr = model.iter_next(itr)

        # Execute the command
        if arguments:
            if '-i' in arguments and not hasInternetConnection():
                title = _("No internet connection")
                msg = _(
                    "You need an internet connection to install the additional software.\n"
                    "Please, connect to the internet and try again.")
                WarningDialog(title, msg)
            else:
                # Warn for use of Backports
                if self.chkBackports.get_active():
                    answer = QuestionDialog(
                        self.chkBackports.get_label(),
                        _("You have selected to install drivers from the backports repository whenever they are available.\n\n"
                          "Although you can run more up to date software using the backports repository,\n"
                          "you introduce a greater risk of breakage doing so.\n\n"
                          "Are you sure you want to continue?"))
                    if not answer:
                        self.chkBackports.set_active(False)
                        return True
                    arguments.append("-b")

                # Testing
                if self.test:
                    arguments.append("-t")

                command = "ddm {}".format(" ".join(arguments))
                self.log.write("Command to execute: {}".format(command),
                               'on_btnSave_clicked')
                self.exec_command(command)

    def on_btnQuit_clicked(self, widget):
        self.on_ddmWindow_destroy(widget)

    def on_btnHelp_clicked(self, widget):
        # Open the help file as the real user (not root)
        shell_exec("%s/open-as-user \"%s\"" % (self.scriptDir, self.helpFile))

    def get_supported_hardware(self):
        # Fill self.hardware
        self.hardware = []

        # First row are column names
        self.hardware.append(
            [_("Install"), '',
             _("Device"), 'driver', 'manid', 'deviceid'])

        # Get hardware information
        self.get_ati()
        self.get_nvidia()
        self.get_broadcom()
        self.get_pae()

    # This method is fired by the TreeView.checkbox-toggled event
    def tv_checkbox_toggled(self, obj, path, colNr, toggleValue):
        path = int(path)
        model = self.tvDDM.get_model()
        itr = model.get_iter(path)
        description = model[itr][2].lower()

        if 'pae' in description and not toggleValue and self.paeBooted:
            title = _("Remove kernel")
            msg = _(
                "You cannot remove a booted kernel.\nPlease, boot another kernel and try again."
            )
            self.log.write(msg, 'tv_checkbox_toggled')
            WarningDialog(title, msg)
            model[itr][0] = True

    def fill_treeview_ddm(self):
        # Fill a list with supported hardware
        self.get_supported_hardware()

        # columns: checkbox, image (logo), device, driver
        columnTypes = ['bool', 'GdkPixbuf.Pixbuf', 'str']

        # Keep some info from the user
        showHw = []
        for hw in self.hardware:
            showHw.append([hw[0], hw[1], hw[2]])

        # Fill treeview
        self.tvDDMHandler.fillTreeview(contentList=showHw,
                                       columnTypesList=columnTypes,
                                       firstItemIsColName=True,
                                       fontSize=12000)

        # Show message if nothing is found or hardware is not supported
        title = _("Hardware scan")
        if self.notSupported:
            if len(self.hardware) < 2:
                self.set_buttons_state(False)
            msg = _("There are no available drivers for your hardware:")
            msg = "{}\n\n{}".format(msg, '\n'.join(self.notSupported))
            self.log.write(msg, 'fill_treeview_ddm')
            WarningDialog(title, msg)
        elif len(self.hardware) < 2:
            self.set_buttons_state(False)
            msg = _("DDM did not find any supported hardware.")
            self.log.write(msg, 'fill_treeview_ddm')
            MessageDialog(title, msg)

    def exec_command(self, command):
        try:
            # Run the command in a separate thread
            self.set_buttons_state(False)
            name = 'cmd'
            t = ExecuteThreadedCommands([command], self.queue)
            self.threads[name] = t
            t.daemon = True
            t.start()
            self.queue.join()
            GObject.timeout_add(250, self.check_thread, name)

        except Exception as detail:
            ErrorDialog(self.btnSave.get_label(), detail)

    def set_buttons_state(self, enable):
        if not enable:
            # Disable buttons
            self.btnSave.set_sensitive(False)
        else:
            # Enable buttons and reset progress bar
            self.btnSave.set_sensitive(True)
            self.pbDDM.set_fraction(0)

    def check_thread(self, name):
        if self.threads[name].is_alive():
            self.pbDDM.pulse()
            if not self.queue.empty():
                ret = self.queue.get()
                self.log.write("Queue returns: {}".format(ret), 'check_thread')
                self.queue.task_done()
                self.show_message(ret)
            return True

        # Thread is done
        self.log.write(">> Thread is done", 'check_thread')
        if not self.queue.empty():
            ret = self.queue.get()
            self.queue.task_done()
            self.show_message(ret)
        del self.threads[name]

        self.set_buttons_state(True)

        return False

    # Close the gui
    def on_ddmWindow_destroy(self, widget):
        # Close the app
        Gtk.main_quit()

    # ===============================================
    # Hardware functions
    # ===============================================

    def get_ati(self):
        # Debian Wiki: https://wiki.debian.org/ATIProprietary
        # Supported devices 14.9 (Jessie): http://support.amd.com/en-us/kb-articles/Pages/AMDCatalyst14-9LINReleaseNotes.aspx

        manufacturerId = '1002'
        startSeries = 5000
        deviceArray = self.get_lspci_info(manufacturerId, 'VGA')

        if self.test:
            #deviceArray = [['Advanced Micro Devices [AMD] nee ATI Manhattan [Mobility Radeon HD 5400 Series]', manufacturerId, '68e0']]
            #deviceArray = [['Advanced Micro Devices, Inc. [AMD/ATI] RV710 [Radeon HD 4350/4550]', manufacturerId, '68e0']]
            #deviceArray = [['Advanced Micro Devices [AMD/ATI] RS880 [Radeon HD 4290]', manufacturerId, '68e0']]
            #deviceArray = [['Advanced Micro Devices, Inc. [AMD/ATI] Tonga PRO [Radeon R9 285]', manufacturerId, '6939']]
            deviceArray = [[
                'Advanced Micro Devices, Inc. [AMD/ATI] Bonaire [FirePro W5100]',
                manufacturerId, '6649'
            ]]

        if deviceArray:
            self.log.write("Device(s): {}".format(deviceArray), 'get_ati')
            # Check if fglrx is loaded
            # If it is: checkbox is selected
            loadedDrv = self.get_loaded_graphical_driver()
            self.log.write("Loaded graphical driver: {}".format(loadedDrv),
                           'get_ati')

            # Get the manufacturer's logo
            logo = join(self.mediaDir, 'images/ati.png')

            # Fill the hardware array
            for device in deviceArray:
                self.log.write("ATI device found: {}".format(device[0]),
                               'get_ati')
                # Check for supported cards
                matchObj = re.search(
                    'radeon\s+[0-9a-z ]+|fire[a-z]+\s+[0-9a-z -]+',
                    device[0],
                    flags=re.IGNORECASE)
                if matchObj:
                    if " hd " in matchObj.group(0).lower():
                        # Check if ATI series is above 5000
                        matchObjSeries = re.search('[0-9]{4}',
                                                   matchObj.group(0))
                        if matchObjSeries:
                            series = int(matchObjSeries.group(0))
                            # Don't show older ATI Radeon HD cards
                            if series < startSeries:
                                break
                    elif 'fire' in matchObj.group(0).lower():
                        title = _("ATI FirePro/Gl card found")
                        msg = _(
                            "Installing the proprietary driver for an ATI FirePro/Gl card may render your system unbootable.\n\n"
                            "Proceed at your own risk.")
                        self.log.write(msg, 'get_ati')
                        WarningDialog(title, msg)

                    self.log.write("ATI series: {}".format(matchObj.group(0)),
                                   'get_ati')

                    # Check if the available driver is already loaded
                    selected = False
                    driver = 'fglrx'
                    if loadedDrv == driver:
                        selected = True

                    # Fill self.hardware
                    #shortDevice = self.shorten_long_string(device[0], 100)
                    self.hardware.append([
                        selected, logo, device[0], driver, device[1], device[2]
                    ])
                else:
                    self.notSupported.append(device[0])

    def get_nvidia(self):
        manufacturerId = '10de'
        deviceArray = self.get_lspci_info(manufacturerId, 'VGA')

        if self.test:
            deviceArray = [[
                'NVIDIA Corporation GT218 [GeForce G210M]', manufacturerId,
                '0a74'
            ]]
            if self.test_optimus:
                deviceArray = [['Intel Corporation Haswell-ULT Integrated Graphics Controller', '8086', '0a16'], \
                                ['NVIDIA Corporation GK107M [GeForce GT 750M]', manufacturerId, '0fe4']]

        if deviceArray:
            optimus = False
            devices = []

            self.log.write("Device(s): {}".format(deviceArray), 'get_nvidia')

            # Check if nvidia is loaded
            # If it is: checkbox is selected
            loadedDrv = self.get_loaded_graphical_driver()
            self.log.write("Loaded graphical driver: {}".format(loadedDrv),
                           'get_nvidia')

            # Get the manufacturer's logo
            logo = join(self.mediaDir, 'images/nvidia.png')

            # Fill the hardware array
            for device in deviceArray:
                if device[1] == '8086':
                    optimus = True
                else:
                    devices.append(device)

            for device in devices:
                self.log.write("Nvidia device found: {}".format(device[0]),
                               'get_nvidia')
                optimusString = ""
                if optimus:
                    optimusString = "(Optimus) "

                # Check if the available driver is already loaded
                selected = False
                if optimus:
                    if loadedDrv == 'nvidia' or loadedDrv == 'intel':
                        bbversion = getPackageVersion("bumblebee-nvidia")
                        self.log.write(
                            "bumblebee-nvidia version: {}".format(bbversion),
                            'get_nvidia')
                        if bbversion != '':
                            selected = True
                elif loadedDrv == 'nvidia':
                    selected = True

                driver = ""
                if optimus:
                    driver = "bumblebee-nvidia"
                else:
                    if self.test:
                        driver = 'nvidia-driver'
                    else:
                        nvidiaDetect = getoutput(
                            "nvidia-detect | grep nvidia- | tr -d ' '")
                        if nvidiaDetect:
                            driver = nvidiaDetect[0]

                self.log.write("Nvidia driver to use: {}".format(driver),
                               'get_nvidia')

                # Fill self.hardware
                if driver != "":
                    #shortDevice = "{0}{1}".format(optimusString, self.shorten_long_string(device[0], 100))
                    self.hardware.append([
                        selected, logo,
                        "{0}{1}".format(optimusString, device[0]), driver,
                        device[1], device[2]
                    ])

    def get_broadcom_ids(self, driver_name):
        driver_name = driver_name.upper()
        ids = getoutput(
            "cat /usr/bin/ddm | grep '{}=' | cut -d'=' -f 2".format(
                driver_name))
        if len(ids) > 0:
            return ids[0].split('|')
        return []

    def get_broadcom(self):
        ## Hardware list (device ids)
        ## http://linuxwireless.org/en/users/Drivers/b43
        deviceIds = {}
        deviceIds['b43'] = self.get_broadcom_ids('b43')
        deviceIds['b43legacy'] = self.get_broadcom_ids('b43legacy')
        deviceIds['wldebian'] = self.get_broadcom_ids('wldebian')
        deviceIds['brcmdebian'] = self.get_broadcom_ids('brcmdebian')
        deviceIds['unknown'] = self.get_broadcom_ids('unknown')

        self.log.write("Broadcom deviceIds = {}".format(deviceIds))

        manufacturerId = '14e4'

        deviceArray = self.get_lspci_info(manufacturerId)

        if self.test:
            deviceArray = [[
                'Broadcom Corporation BCM43142 802.11a/b/g', manufacturerId,
                '4365'
            ]]

        if deviceArray:
            self.log.write("Device(s): {}".format(deviceArray), 'get_broadcom')
            # Check if broadcom is loaded
            # If it is: checkbox is selected
            loadedDrv = self.get_loaded_wireless_driver()
            self.log.write("Loaded wireless driver: {}".format(loadedDrv),
                           'get_broadcom')

            # Get the manufacturer's logo
            logo = join(self.mediaDir, 'images/broadcom.png')

            # Fill the hardware array
            for device in deviceArray:
                self.log.write("Broadcom device found: {}".format(device[0]),
                               'get_broadcom')
                driver = ''
                for key, did in list(deviceIds.items()):
                    #print(("{}:{} in {}:{}".format(device[0], device[2], key, did)))
                    if device[2] in did:
                        driver = key
                        break

                if driver != '':
                    if driver == 'unknown':
                        self.notSupported.append(device[0])
                        self.log.write(
                            "Broadcom device not supported: {}".format(
                                device[0]), 'get_broadcom')
                    else:
                        self.log.write(
                            "Broadcom driver to use: {}".format(driver),
                            'get_broadcom')
                        # Check if the available driver is already loaded
                        selected = False
                        if loadedDrv == driver:
                            selected = True

                        # Fill self.hardware
                        #shortDevice = self.shorten_long_string(device[0], 100)
                        self.hardware.append([
                            selected, logo, device[0], driver, device[1],
                            device[2]
                        ])

    def get_pae(self):
        machine = getoutput('uname -m')[0]
        release = getoutput('uname -r')[0]

        if self.test:
            machine = 'i686'
            release = '3.16.0-4-586'

        self.log.write(
            "PAE check: machine={} / release={}".format(machine, release),
            'get_pae')

        if machine == 'i686':
            # Check if PAE is installed and running
            selected = False
            if 'pae' in release:
                self.paeBooted = True
                selected = True
            else:
                if getPackageVersion('linux-image-686-pae') != '':
                    selected = True

            # Get the logo
            logo = join(self.mediaDir, 'images/pae.png')

            # Fill self.hardware
            paeDescription = _("PAE capable system")
            self.hardware.append(
                [selected, logo, paeDescription, '', 'pae', ''])

    def get_lspci_info(self, manufacturerId, filterString=''):
        deviceArray = []
        output = []

        # Check for Optimus
        if manufacturerId == '10de':
            output = getoutput("lspci -vnn | grep '\[030[02]\]'")

            if self.test_optimus:
                output = ['00:02.0 VGA compatible controller [0300]: Intel Corporation Haswell-ULT Integrated Graphics Controller [8086:0a16] (rev 09) (prog-if 00 [VGA controller])', \
                          '01:00.0 3D controller [0302]: NVIDIA Corporation GK107M [GeForce GT 750M] [10de:0fe4] (rev a1)']

        # Optimus will return 2 devices
        # If there are less than 2 devices, do regular check
        if len(output) < 2:
            if filterString != '':
                filterString = " | grep {}".format(filterString)
            output = getoutput("lspci -nn -d {}:{}".format(
                manufacturerId, filterString))

        if output:
            self.log.write("lspci output = {}".format(output),
                           'get_lspci_info')

        for line in output:
            matchObj = re.search(':\W(.*)\W\[(.+):(.+)\]', line)
            if matchObj:
                deviceArray.append(
                    [matchObj.group(1),
                     matchObj.group(2),
                     matchObj.group(3)])
        return deviceArray

    def shorten_long_string(self, longString, charLen, breakOnWord=True):
        tmpArr = []
        if breakOnWord:
            stringArr = longString.split(' ')
            nrChrs = 0
            for s in stringArr:
                nrChrs += len(s) + 1
                if nrChrs < charLen:
                    tmpArr.append(s)
                else:
                    break
        else:
            if len(longString) > charLen:
                tmpArr.append("{}...".format(longString[0:charLen]))
            else:
                tmpArr.append(longString)
        return ' '.join(tmpArr)

    # Return graphics module used by X.org
    # TODO: is lsmod an alternative?
    def get_loaded_graphical_driver(self):
        # sort on the most recent X.org log
        module = ''
        log = ''
        logDir = '/var/log/'
        logPath = None
        logs = glob(os.path.join(logDir, 'Xorg.*.log*'))
        logs.sort()

        for logPath in logs:
            # Search for "depth" in each line and check the used module
            # Sometimes these logs are saved as binary: open as read-only binary
            # When opening as ascii, read() will throw error: "UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80"
            with open(logPath, 'rb') as f:
                # replace utf-8 binary read errors (with ?)
                log = f.read().decode(encoding='utf-8', errors='replace')
                #print((log))

            matchObj = re.search('([a-zA-Z]*)\(\d+\):\s+depth.*framebuffer',
                                 log,
                                 flags=re.IGNORECASE)
            if matchObj:
                module = matchObj.group(1).lower()
                self.log.write("Log module={}".format(module))
                break

        return module

    # Return used wireless driver
    def get_loaded_wireless_driver(self):
        driver = ''
        logDir = '/var/log/'
        for logPath in glob(os.path.join(logDir, 'syslog*')):
            if driver == '' and not 'gz' in logPath:
                # Open the log file
                lines = []
                with open(logPath, 'rb') as f:
                    log = f.read().decode(encoding='utf-8', errors='replace')
                    lines = list(log.splitlines())

                for line in reversed(lines):
                    # First check for Network Manager entry
                    # Search for wlan0 in each line and get the listed driver
                    matchObj = re.search(
                        '\(wlan\d\):.*driver:\s*\'([a-zA-Z0-9\-]*)',
                        line,
                        flags=re.IGNORECASE)
                    if matchObj:
                        driver = matchObj.group(1)
                        self.log.write(
                            "Network Manager driver={}".format(driver))
                        break
                    else:
                        # Wicd
                        # Search for ieee in each line and get the listed driver
                        matchObj = re.search('ieee.*implement',
                                             line,
                                             flags=re.IGNORECASE)
                        if matchObj:
                            driver = matchObj.group(0)
                            self.log.write("Wicd driver={}".format(driver))
                            break

        return driver

    def show_message(self, cmdOutput):
        try:
            self.log.write("Command output: {}".format(cmdOutput),
                           'show_message')
            ret = int(cmdOutput)
            if ret > 1 and ret != 255:
                if ret == 1:
                    ErrorDialog(self.btnSave.get_label(), _("Run as root."))
                elif ret == 2:
                    ErrorDialog(self.btnSave.get_label(),
                                _("Wrong arguments passed to ddm."))
                elif ret == 3:
                    ErrorDialog(self.btnSave.get_label(),
                                _("There are no driver available."))
                elif ret == 4:
                    ErrorDialog(self.btnSave.get_label(),
                                _("The driver cannot be found in repository."))
                elif ret == 5:
                    ErrorDialog(
                        self.btnSave.get_label(),
                        _("Download error.\nCheck your internet connection."))
                elif ret == 6:
                    ErrorDialog(self.btnSave.get_label(),
                                _("DDM cannot purge the driver."))
                elif ret == 7:
                    ErrorDialog(self.btnSave.get_label(),
                                _("This card is not supported."))
                else:
                    msg = _(
                        "There was an error during the installation.\n"
                        "Please, run 'sudo apt-get -f install' in a terminal.\n"
                        "Visit our forum for support: http://forums.solydxk.com"
                    )
                    ErrorDialog(self.btnSave.get_label(), msg)
            else:
                msg = _("The software has been successfully installed.")
                msg_restart = _("You will need to restart your system.")
                MessageDialog(self.btnSave.get_label(),
                              "{}\n\n{}".format(msg, msg_restart))
        except:
            ErrorDialog(self.btnSave.get_label(), cmdOutput)