Source

vasm / src / vasm / ui / tui / modules / tui_repos.py

Full commit
#!/usr/bin/env python

#    This file is part of VASM.
#
#    VASM is free software: you can redistribute it and/or modify
#    it under the terms of the GNU General Public License v3 as published by
#    the Free Software Foundation.
#
#    VASM is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#    You should have received a copy of the GNU General Public License
#    along with VASM.  If not, see <http://www.gnu.org/licenses/>.

""" tui_repos.py
    Text mode module to enable/disable software sources (repos)"""

__author__ = "Moises Henriquez"
__author_email__ = "moc.liamg@xnl.E0M"[::-1]

import urwid
import os
from vasm.ui.tui.support import dialogs
from vasm.backend import repos
from vasm.backend.utils import _
import logging

logger = logging.getLogger('vasm')

VASM_CATEGORY = "System"
VASM_LABEL = "Software Sources"

class RepoManage(dialogs.ModuleDialog):
    """ TUI module to interact with software repositories.  Will display a list of
    checkboxes to tick each repo.
    
    Unlike the gtk+2 counterpart, this module CANNOT change a repository's priority setting
    """
    def __init__(self, parent):
        self.parent = parent
        msg = _("Enable or disable software sources.  Press 'Space' or 'Enter' to toggle")
        self._changes = []
        _body = []
        self.datamodel = repos.SlaptgetRcModel()
        self.datamodel.add_observer(self.refresh_repo_list)
        _body.append(self._get_repo_list())
        
        dialogs.ModuleDialog.__init__(
            self,
            parent = self.parent,
            header = _("Software Sources"),
            desc = ["",msg],
            buttons = [("OK", self.save_changes),
                ("Cancel", self.close_module)],
            body = [])
        self.datamodel.notify()
        self.set_focus('body')

    def refresh_repo_list(self):
        """ Update the body widget to display a refreshed list """
        self.set_body(urwid.LineBox(self._get_repo_list()))
        return

    def _get_repo_list(self):
        """ get the list of repos from the datamodel. Returns a listbox filled
        with checkboxes."""
        self._changes = []
        widgets = []
        # get the list of enabled repos.  These come in a list of (url, priority) tuples
        enabled = self.datamodel.get_current_active_repos()
        for url, prio in enabled:
            self._changes.append((True, url, prio))
            cb = urwid.CheckBox(url, state=True, user_data=url,
                                on_state_change = self.repo_toggle)
            aw = urwid.AttrWrap(cb, 'button', 'button sel')
            widgets.append(aw)
        # get the disabled ones
        disabled = self.datamodel.get_current_disabled_repos()
        for url, prio in disabled:
            self._changes.append((False, url, prio))
            cb = urwid.CheckBox(url, state=False, user_data=url,
                                on_state_change = self.repo_toggle)
            aw = urwid.AttrWrap(cb, 'button', 'button sel')
            widgets.append(aw)

        # Now represent this in a listbox
        listbox = urwid.ListBox(widgets)
        return listbox
    
    def repo_toggle(self, toggle, newvalue, user_data):
        """ Update the internal list of values.  user_data contains the repo url """
        for child in self._changes:
            status, url, prio = child
            if url == user_data:
                id = self._changes.index(child)
                self._changes[id] = (newvalue, user_data, prio)
    
    def save_changes(self, widget=None):
        """ Get the list of saved changes and save it to the actual config file"""
        if self.datamodel.save_changes(self._changes):
            # This should return False when successfull, otherwise, error
            dia = dialogs.Error(
                parent = self.parent,
                message = _("There was an error saving changes to /etc/slapt-get/slapt-getrc.") + \
                "  " + _("Make sure the file exists and you are doing this as root."),
                buttons = [("OK",self.return_to_module)])
            logger.error("Failed to save changes to /etc/slapt-get/slapt-getrc")
        else:
            dia = dialogs.Info(
                parent = self.parent,
                message = _("Your changes have been saved successfully.") + "  " + \
                _("You will need to run `slapt-get -u` for changes to take effect"),
                buttons = [("OK", self.close_module)]
            )
            logger.info("/etc/slapt-get/slapt-getrc has been updated.")
        return self.pop_dialog(dia)


def __vasm_test__():
    # This module cannot run if there is no /etc/slapt-get/slapt-getrc
    if not os.path.exists("/etc/slapt-get/slapt-getrc"):
        return False
    # This module is only available to root
    return os.geteuid() == 0

def __run__(parent):
    mod = RepoManage(parent)
    parent.pop_module(mod)