|
|
import os from collections import OrderedDict, namedtuple from itertools import chain from gooey.gui.lang.i18n import _ from gooey.gui.util.quoting import quote
import wx
ArgumentGroup = namedtuple('ArgumentGroup', 'name command required_args optional_args')
class MyWidget(object): # TODO: Undumbify damn # TODO: Undumbify _value/value access
def __init__(self, type, title, help, default, nargs, commands, choices): self.type = type self.title = title self.help = help self.default = default self._value = default self.nargs = nargs self.commands = commands self.choices = choices
@property def value(self): # TODO: split into stategy or subclass thingie if self.type == 'CheckBox': return self.commands[0] if self._value else None if self.type == 'RadioGroup': try: return self.commands[self._value.index(True)][0] except ValueError: return None if self.type == 'MultiFileChooser': value = ' '.join(quote(x) for x in self._value.split(os.pathsep) if x) if self.commands and value: return u'{} {}'.format(self.commands[0], value) return value or None if self.type == 'Textarea': if self.commands and self._value: return '{} {}'.format(self.commands[0], quote(self._value.encode('unicode_escape'))) else: return quote(self._value.encode('unicode_escape')) if self._value else '' if self.type == 'CommandField': if self.commands and self._value: return u'{} {}'.format(self.commands[0], self._value) else: return self._value or None
if self.type == 'Counter': '''
Returns str(option_string * DropDown Value) e.g. -vvvvv '''
if not str(self._value).isdigit(): return None arg = str(self.commands[0]).replace('-', '') repeated_args = arg * int(self._value) return '-' + repeated_args if self.type == 'Listbox': if self.commands and self._value: return u'{} {}'.format(self.commands[0], ' '.join(map(quote, self._value))) else: return ' '.join(map(quote, self._value)) if self._value else '' if self.type == 'Dropdown': if self._value == 'Select Option': return None elif self.commands and self._value: return u'{} {}'.format(self.commands[0], quote(self._value)) else: return quote(self._value) if self._value else '' else: if self.commands and self._value: if not self.nargs: v = quote(self._value) else: v = self._value return u'{0} {1}'.format(self.commands[0], v) else: if not self._value: return None elif not self.nargs: return quote(self._value) else: return self._value
@value.setter def value(self, val): self._value = val
@classmethod def from_dict(cls, data): def maybe_unpack(collection, attr): # TODO: RadioGroups need to support defaults try: if isinstance(collection, list): return [item[attr] for item in collection] return collection[attr] except: return None
details = data['data'] return cls( data['type'], maybe_unpack(details, 'display_name'), maybe_unpack(details, 'help'), maybe_unpack(details, 'default'), maybe_unpack(details, 'nargs'), maybe_unpack(details, 'commands'), maybe_unpack(details, 'choices') )
class States(object): CONFIGURING = 'configuring' RUNNNING = 'running' SUCCESS = 'success' ERROR = 'error' STOPPED = 'stopped'
class MyModel(object): '''
'''
def wrap(self, groups): output = OrderedDict() for name, group in groups.items(): output[name] = ArgumentGroup( name, group['command'], *self.group_arguments(group['contents']) ) return output
def __init__(self, build_spec):
self.current_state = States.CONFIGURING
self.build_spec = build_spec self.layout_type = self.build_spec.get('layout_type')
self.auto_start = self.build_spec.get('auto_start') self.progress_regex = self.build_spec.get('progress_regex') self.progress_expr = self.build_spec.get('progress_expr') self.disable_progress_bar_animation = self.build_spec['disable_progress_bar_animation']
self.program_name = self.build_spec.get('program_name') self.default_size = self.build_spec.get('default_size')
self.heading_title = _("settings_title") self.heading_subtitle = self.build_spec['program_description'] or ''
self.use_monospace_font = self.build_spec.get('monospace_display') self.stop_button_disabled = self.build_spec['disable_stop_button']
self.argument_groups = self.wrap(self.build_spec.get('widgets', {})) self.active_group = next(iter(self.argument_groups))
self.num_required_cols = self.build_spec['num_required_cols'] self.num_optional_cols = self.build_spec['num_optional_cols']
self.text_states = { States.CONFIGURING: { 'title': _("settings_title"), 'subtitle': self.build_spec['program_description'] or '' }, States.RUNNNING: { 'title': _("running_title"), 'subtitle': _('running_msg') }, States.SUCCESS: { 'title': _('finished_title'), 'subtitle': _('finished_msg') }, States.ERROR: { 'title': _('finished_title'), 'subtitle': _('finished_error') } }
@property def required_args(self): return self.argument_groups[self.active_group].required_args
@property def optional_args(self): return self.argument_groups[self.active_group].optional_args
def update_state(self, state): self.current_state = state
text = self.text_states[state] self.heading_title = text['title'] self.heading_subtitle = text['subtitle']
def is_valid(self): # TODO: fix skipping_config.. whatever that did # currently breaks when you supply it as a decorator option # return self.skipping_config() and self.required_section_complete() return self.is_required_section_complete()
def skipping_config(self): return self.build_spec['manual_start']
def is_required_section_complete(self): error_found = False for arg in self.required_args: widget = arg.widget_instance.widget_pack.widget if arg.value: widget.SetBackgroundColour(wx.NullColour) else: if not error_found: error_found = True widget.SetFocus() widget.SetBackgroundColour("#EF9A9A")
widget.Refresh()
return not error_found
def build_command_line_string(self): optional_args = [arg.value for arg in self.optional_args] required_args = [c.value for c in self.required_args if c.commands] position_args = [c.value for c in self.required_args if not c.commands] if position_args: position_args.insert(0, "--") cmd_string = ' '.join(list(filter(None, chain(required_args, optional_args, position_args)))) if self.layout_type == 'column': cmd_string = u'{} {}'.format(self.argument_groups[self.active_group].command, cmd_string) return u'{} --ignore-gooey {}'.format(self.build_spec['target'], cmd_string)
def group_arguments(self, widget_list): is_required = lambda widget: widget['required'] not_checkbox = lambda widget: widget['type'] != 'CheckBox'
required_args, optional_args = self.partition(widget_list, is_required) if self.build_spec['group_by_type']: optional_args = chain(*self.partition(optional_args, not_checkbox)) return list(map(self.to_object, required_args)), list(map(self.to_object, optional_args))
@staticmethod def partition(collection, condition): return list(filter(condition, collection)), list(filter(lambda x: not condition(x), collection))
def to_object(self, data): details = data['data'] return MyWidget( data['type'], self.maybe_unpack(details, 'display_name'), self.maybe_unpack(details, 'help'), self.maybe_unpack(details, 'default'), self.maybe_unpack(details, 'nargs'), self.maybe_unpack(details, 'commands'), self.maybe_unpack(details, 'choices') )
@staticmethod def maybe_unpack(collection, attr): # TODO: RadioGroups need to support defaults try: if isinstance(collection, list): return [item[attr] for item in collection] return collection[attr] except: return None
|