diff --git a/VERSION.txt b/VERSION.txt index daab415..cd69980 100644 --- a/VERSION.txt +++ b/VERSION.txt @@ -1 +1 @@ -6.5.0-d \ No newline at end of file +6.6.0-d \ No newline at end of file diff --git a/scripttease/library/overlays/posix.py b/scripttease/library/overlays/posix.py index eee10d4..f2881e3 100644 --- a/scripttease/library/overlays/posix.py +++ b/scripttease/library/overlays/posix.py @@ -1,6 +1,6 @@ # Imports -from commonkit import indent +from commonkit import indent, split_csv import os from ..commands import Command @@ -19,6 +19,7 @@ __all__ = ( "mkdir", "move", "perms", + "prompt", "remove", "rename", "rsync", @@ -27,6 +28,7 @@ __all__ = ( "symlink", "touch", "Function", + "Prompt", ) # Functions @@ -313,6 +315,19 @@ def perms(path, group=None, mode=None, owner=None, recursive=False, **kwargs): return Command("\n".join(a), **kwargs) +def prompt(name, back_title="Input", choices=None, default=None, fancy=False, help_text=None, label=None, **kwargs): + return Prompt( + name, + back_title=back_title, + choices=choices, + default=default, + fancy=fancy, + help_text=help_text, + label=label, + **kwargs + ) + + def remove(path, force=False, recursive=False, **kwargs): """Remove a file or directory. @@ -560,6 +575,135 @@ class Function(object): return "\n".join(a) + +class Prompt(Command): + """Prompt the user for input.""" + + def __init__(self, name, back_title="Input", choices=None, default=None, fancy=False, help_text=None, label=None, + **kwargs): + """Initialize a prompt for user input. + + :param name: The variable name. + :type name: str + + :param back_title: The back title of the input. Used only when ``dialog`` is enabled. + :type back_title: str + + :param choices: Valid choices for the variable. May be given as a list of strings or a comma separated string. + :type choices: list[str] | str + + :param default: The default value of the variable. + + :param fancy: Indicates the dialog command should be used. + :type fancy: bool + + :param help_text: Additional text to display. Only use when ``fancy`` is ``True``. + :type help_text: str + + :param label: The label of the prompt. + + """ + self.back_title = back_title + self.default = default + self.dialog_enabled = fancy + self.help_text = help_text + self.label = label or name.replace("_", " ").title() + self.variable_name = name + + if type(choices) in (list, tuple): + self.choices = choices + elif type(choices) is str: + self.choices = split_csv(choices, smart=False) + # for i in choices.split(","): + # self.choices.append(i.strip()) + else: + self.choices = None + + kwargs.setdefault("comment", "prompt user for %s input" % name) + + super().__init__(name, **kwargs) + + def get_statement(self, cd=False, suppress_comment=False): + """Get the statement using dialog or read.""" + if self.dialog_enabled: + return self._get_dialog_statement() + + return self._get_read_statement() + + def _get_dialog_statement(self): + """Get the dialog statement.""" + a = list() + + a.append('dialog --clear --backtitle "%s" --title "%s"' % (self.back_title, self.label)) + + if self.choices is not None: + a.append('--menu "%s" 15 40 %s' % (self.help_text or "Select", len(self.choices))) + count = 1 + for choice in self.choices: + a.append('"%s" %s' % (choice, count)) + count += 1 + + a.append('2>/tmp/input.txt') + else: + if self.help_text is not None: + a.append('--inputbox "%s"' % self.help_text) + else: + a.append('--inputbox ""') + + a.append('8 60 2>/tmp/input.txt') + + b = list() + + b.append('touch /tmp/input.txt') + b.append(" ".join(a)) + + b.append('%s=$(/tmp/input.txt' in s + assert 'testing=$(/tmp/input.txt' in s + assert 'testing=$(