Logo Search packages:      
Sourcecode: falcon version File versions  Download package

questions.py

# This file is part of the Falcon repository manager
# Copyright (C) 2005-2008 Dennis Kaarsemaker
# See the file named COPYING in the root of the source tree for license details
#
# questions.py - Questions for the configuration editor

import falcon
import copy, snack, os, tempfile

class SelectionForm(object):
    def __init__(self, title, intro_text, selections, exit_text = None):
        self.title = title
        self.intro_text = intro_text
        self.selections = selections
        self.exit_text = exit_text
        self.current = None

    def run(self):
        form = snack.GridFormHelp(falcon.screen, self.title, _("See /usr/share/doc/falcon for falcon documentation"),1,3)
        t = snack.TextboxReflowed(30, self.intro_text)
        l = snack.Listbox(min(5, len(self.selections)), returnExit=True)
        for s in self.selections:
            l.append(s[0],s[1])
        if self.current:
            l.setCurrent(self.current)
        b = snack.CompactButton(self.exit_text)
        form.add(t,0,0)
        form.add(l,0,1, (0,1,0,1))
        form.add(b,0,2)

        item = form.runOnce()
        if item == 'ESC' or item == b:
            return
        self.current = l.current()
        return self.current

class QuestionForm(object):
    def __init__(self, title, questions):
        self.title = title
        self.questions = questions

    def run(self, current):
        answers = copy.deepcopy(current)
        while True:
            form = snack.GridFormHelp(falcon.screen, self.title, _("See /usr/share/doc/falcon for falcon documentation"),
                                           1, sum([x.num_newt_widgets for x in self.questions])+2)
            form.last = 0
            form.x = 0
            for q in self.questions:
                if q:
                    q.add_newt_widgets(form, answers[q.key])
            bb = snack.ButtonBar(falcon.screen, ((_('OK'),1),(_('Cancel'),2)),compact=True)
            form.add(bb, 0, form.last+1,padding=(0,1,0,0))

            ret = form.runOnce()

            if ret == 'ESC' or bb.buttonPressed(ret) == 2: # Cancel
                return None

            for q in self.questions:
                if not hasattr(q, 'button'):
                    answers[q.key] = q.get_answer()

            if isinstance(ret, snack.CompactButton) and (bb.buttonPressed(ret) != 1):
                # Pressed an edit button
                for q in self.questions:
                    if hasattr(q, 'button') and q.button == ret:
                        answers[q.key] = q.button_action(answers[q.key])
                continue

            errors = []
            for q in self.questions:
                if hasattr(q, 'button'):
                    continue
                try:
                    q.validate()
                except falcon.validators.ValidationError, e:
                    errors.append((q, e.args[0]))
            if errors:
                f = snack.GridFormHelp(falcon.screen, _("Errors"), _("See /usr/share/doc/falcon for falcon documentation"), 1, 2)
                tb = snack.TextboxReflowed(50, '\n'.join(["%s\n  %s" % (x[0].question, x[1]) for x in errors]))
                f.add(tb, 0, 0)
                bb = snack.ButtonBar(falcon.screen, ((_('OK'),1),(_('Cancel'),2)),compact=True)
                f.add(bb, 0, 1,padding=(0,1,0,0))
                f.runOnce()
                continue
            return answers

class Question(object):
    needs_external_editor = False
    num_newt_widgets = 2
    def __init__(self, question, validators=[]):
        self.question = question
        self.validators = validators
    def validate(self):
        for v in self.validators:
            v(self.get_answer())

class Entry(Question):
    def add_newt_widgets(self, form, current):
        label = snack.Label(self.question)
        self.entry = snack.Entry(30, str(current), returnExit = True)
        form.add(label, form.x, form.last + 1)
        form.add(self.entry, form.x, form.last + 2)
        form.last += 2

    def get_answer(self):
        return self.entry.value()

def quote(v):
    if '"' not in v:
        return '"%s"' % v
    if "'" not in v:
        return "'%s'" % v
    if '"""' not in v:
        return '"""%s"""' % v
    if "'''" not in v:
        return "'''%s'''" % v
    raise ValueError(_("Can't properly quote %s") % v)

def unquote(v):
    ret = []
    while v:
        v = v.strip()
        if v.startswith('"""'):
            i = v.index('"""',3)
            ret.append(v[3:i])
            v = v[i+3]
        elif v.startswith("'''"):
            i = v.index("'''",3)
            ret.append(v[3:i])
            v = v[i+3]
        elif v.startswith('"'):
            i = v.index('"',1)
            ret.append(v[1:i])
            v = v[i+1]
        elif v.startswith("'"):
            i = v.index("'",1)
            ret.append(v[1:i])
            v = v[i+1]
        else:
            raise ValueError(_("Improperly quoted string: %s"))
        v = v.strip()
        if v:
            if v[0] != ',':
                raise ValueError(_("Improperly quoted string: %s"))
            v = v[1:]
    return ret

class QuotedEntry(Entry):
    def add_newt_widgets(self, form, current):
        self.current = current
        _current = ' '.join(current)
        if '"' in current or "'" in current:
            _current = '[%s]' % ', '.join([quote(x) for x in current])
        super(QuotedEntry, self).add_newt_widgets(form, _current)
    def get_answer(self):
        value = super(QuotedEntry, self).get_answer()
        if value.startswith('[') and value.endswith(']'):
            try:
                value = unquote(value[1:-1])
            except ValueError:
                # FIXME
                return self.current
        else:
            value = value.split()
        return value

class Select(Question):
    def __init__(self, question, selections, validators=[]):
        super(Select,self).__init__(question, validators)
        self.selections = selections

    def add_newt_widgets(self, form, current):
        label = snack.Label(self.question)
        self.listbox = snack.Listbox(min(5,len(self.selections)),scroll=len(self.selections) > 5,returnExit=True) 
        for s in self.selections:
            self.listbox.append(s,s)
        if current in self.selections:
            self.listbox.setCurrent(current)
        form.add(label, form.x, form.last + 1)
        form.add(self.listbox, form.x, form.last + 2)
        form.last += 2

    def get_answer(self):
        return self.listbox.current()

class SelectMulti(Select):
    def add_newt_widgets(self, form, current):
        label = snack.Label(self.question)
        self.tree = snack.CheckboxTree(min(5,len(self.selections)), scroll=len(self.selections) > 5) 
        for s in self.selections:
            self.tree.append(s, selected=(s in current))
        form.add(label, form.x, form.last + 1)
        form.add(self.tree, form.x, form.last + 2)
        form.last += 2

    def get_answer(self):
        return self.tree.getSelection()

class ComponentTree(Question):
    def add_newt_widgets(self, form, current):
        label = snack.Label(self.question)
        self.tree = snack.CheckboxTree(5, scroll=True)
        i = 0
        for p in falcon.pockets:
            self.tree.append(p.name)
            for c in p.components:
                self.tree.addItem(c.name,(i,-1),c,c in current)
            i += 1
        form.add(label, form.x, form.last + 1)
        form.add(self.tree, form.x, form.last + 2)
        form.last += 2
    def get_answer(self):
        return self.tree.getSelection()

class Text(Question):
    needs_external_editor = True
    def __init__(self, *args, **kwargs):
        super(Text, self).__init__(*args, **kwargs)

    def add_newt_widgets(self, form, current):
        label = snack.Label(self.question)
        self.button = snack.CompactButton(_("Click to edit"))
        form.add(label, form.x, form.last + 1)
        form.add(self.button, form.x, form.last + 2)
        form.last += 2

    def button_action(self, current):
        if falcon.conf.editor:
            editor = falcon.conf.editor
        elif os.getenv('EDITOR'):
            editor = os.getenv('EDITOR')
        elif os.path.exists('/usr/bin/editor'):
            editor = '/usr/bin/editor'
        elif os.path.exists('/usr/bin/nano'):
            nano = '/usr/bin/nano'
        elif os.path.exists('/usr/bin/vi'):
            vi = '/usr/bin/vi'
        else:
            falcon.util.error(_("Can't find an editor to use"))

        editor_blurb = "# %s\n# %s\n#\n" % (self.question, _("All lines beginning with # will be ignored"))
        (fd, path) = tempfile.mkstemp()
        try:
            fd = os.fdopen(fd,'r+')
            fd.write(editor_blurb)
            fd.write(current)
            fd.flush()
            falcon.screen.suspend()
            rc = os.spawnlp(os.P_WAIT, editor, editor, path)
            falcon.screen.resume()
            if rc:
                os.unlink(path)
                falcon.util.error(_("Launching an external editor (%s) failed, returncode: %d") % (editor, code))
            fd.seek(0)
            val = ''.join([x for x in fd.readlines() if not x.startswith('#')])
            os.unlink(path)
            return val
        except:
            try:
                os.unlink(path)
            except:
                pass
            falcon.util.error(_("Launching an external editor (%s) failed") % editor)

class Boolean(Question):
    num_newt_widgets = 1
    def add_newt_widgets(self, form, current):
        self.cb = snack.Checkbox(self.question, current)
        form.add(self.cb, form.x, form.last+1)
        form.last += 1
    def get_answer(self):
        return self.cb.value()
        
def yesno(question, default=None):
    if falcon.conf.force_yes:
        return True
    if falcon.conf.force_no:
        return False
    #return Select(question, ((_("Yes"), True), (_("No"), False))).ask(default)
    ret = raw_input(question + " ")
    return ret.lower() in ['y','yes','ok','on','1'];

Generated by  Doxygen 1.6.0   Back to index