You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

196 lines
6.1 KiB

  1. import os
  2. from itertools import chain
  3. from gooey.gui.lang.i18n import _
  4. from gooey.gui.util.quoting import quote
  5. class MyWidget(object):
  6. def __init__(self, type, title, help, default, nargs, commands, choices):
  7. self.type = type
  8. self.title = title
  9. self.help = help
  10. self.default = default
  11. self._value = default
  12. self.nargs = nargs
  13. self.commands = commands
  14. self.choices = choices
  15. @property
  16. def value(self):
  17. # TODO: split into stategy or subclass thingie
  18. if self.type == 'CheckBox':
  19. return self.commands[0] if self._value else None
  20. if self.type == 'RadioGroup':
  21. try:
  22. return self.commands[self._value.index(True)][0]
  23. except ValueError:
  24. return None
  25. if self.type == 'MultiFileChooser':
  26. value = ' '.join(quote(x) for x in self._value.split(os.pathsep) if x)
  27. if self.commands and value:
  28. return '{} {}'.format(self.commands[0], value)
  29. return value or None
  30. # if self.type == 'TextField':
  31. # if self.commands and self._value:
  32. # return '{} {}'.format(self.commands[0], quote(self._value))
  33. # else:
  34. # return quote(self._value) if self._value else ''
  35. if self.type == 'CommandField':
  36. if self.commands and self._value:
  37. return '{} {}'.format(self.commands[0], self._value)
  38. else:
  39. return self._value or None
  40. if self.type == 'Counter':
  41. '''
  42. Returns
  43. str(option_string * DropDown Value)
  44. e.g.
  45. -vvvvv
  46. '''
  47. if not str(self._value).isdigit():
  48. return None
  49. arg = str(self.commands[0]).replace('-', '')
  50. repeated_args = arg * int(self._value)
  51. return '-' + repeated_args
  52. if self.type == 'Dropdown':
  53. if self._value == self.default:
  54. return ''
  55. elif self.commands and self._value:
  56. return '{} {}'.format(self.commands[0], quote(self._value))
  57. else:
  58. return quote(self._value) if self._value else ''
  59. else:
  60. if self.commands and self._value:
  61. return '{0} {1}'.format(self.commands[0], quote(self._value))
  62. else:
  63. return quote(self._value) if self._value else None
  64. @value.setter
  65. def value(self, val):
  66. self._value = val
  67. class States(object):
  68. CONFIGURING = 'configuring'
  69. RUNNNING = 'running'
  70. SUCCESS = 'success'
  71. ERROR = 'error'
  72. STOPPED = 'stopped'
  73. class MyModel(object):
  74. '''
  75. Needs to:
  76. - sort the args based on a strategy
  77. -
  78. '''
  79. def __init__(self, build_spec):
  80. self.current_state = States.CONFIGURING
  81. self.build_spec = build_spec
  82. self.progress_regex = self.build_spec['progress_regex']
  83. self.progress_expr = self.build_spec['progress_expr']
  84. self.program_name = self.build_spec['program_name']
  85. self.default_size = self.build_spec['default_size']
  86. self.heading_title = _("settings_title")
  87. self.heading_subtitle = self.build_spec['program_description'] or ''
  88. self.use_monospace_font = self.build_spec.get('monospace_display')
  89. self.stop_button_disabled = self.build_spec['disable_stop_button']
  90. reqs, opts = self.group_arguments(self.build_spec['widgets'])
  91. self.required_args = reqs
  92. self.optional_args = opts
  93. self.text_states = {
  94. States.CONFIGURING: {
  95. 'title': _("settings_title"),
  96. 'subtitle': self.build_spec['program_description'] or ''
  97. },
  98. States.RUNNNING: {
  99. 'title': _("running_title"),
  100. 'subtitle': _('running_msg')
  101. },
  102. States.SUCCESS: {
  103. 'title': _('finished_title'),
  104. 'subtitle': _('finished_msg')
  105. },
  106. States.ERROR: {
  107. 'title': _('finished_title'),
  108. 'subtitle': _('finished_error')
  109. }
  110. }
  111. def update_state(self, state):
  112. self.current_state = state
  113. text = self.text_states[state]
  114. self.heading_title = text['title']
  115. self.heading_subtitle = text['subtitle']
  116. def is_valid(self):
  117. # TODO: fix skipping_config.. whatever that did
  118. # currently breaks when you supply it as a decorator option
  119. # return self.skipping_config() and self.required_section_complete()
  120. return self.is_required_section_complete()
  121. def skipping_config(self):
  122. return self.build_spec['manual_start']
  123. def is_required_section_complete(self):
  124. completed_values = filter(None, [arg.value for arg in self.required_args])
  125. return len(self.required_args) == len(completed_values)
  126. def build_command_line_string(self):
  127. optional_args = [arg.value for arg in self.optional_args]
  128. required_args = [c.value for c in self.required_args if c.commands]
  129. position_args = [c.value for c in self.required_args if not c.commands]
  130. if position_args:
  131. position_args.insert(0, "--")
  132. cmd_string = ' '.join(filter(None, chain(required_args, optional_args, position_args)))
  133. return '{} --ignore-gooey {}'.format(self.build_spec['target'], cmd_string)
  134. def group_arguments(self, widget_list):
  135. is_required = lambda widget: widget['required']
  136. not_checkbox = lambda widget: widget['type'] != 'CheckBox'
  137. required_args, optional_args = self.partition(widget_list, is_required)
  138. if self.build_spec['group_by_type']:
  139. optional_args = chain(*self.partition(optional_args, not_checkbox))
  140. return map(self.to_object, required_args), map(self.to_object, optional_args)
  141. @staticmethod
  142. def partition(collection, condition):
  143. return filter(condition, collection), filter(lambda x: not condition(x), collection)
  144. def to_object(self, data):
  145. details = data['data']
  146. return MyWidget(
  147. data['type'],
  148. self.maybe_unpack(details, 'display_name'),
  149. self.maybe_unpack(details, 'help'),
  150. self.maybe_unpack(details, 'default'),
  151. self.maybe_unpack(details, 'nargs'),
  152. self.maybe_unpack(details, 'commands'),
  153. self.maybe_unpack(details, 'choices')
  154. )
  155. @staticmethod
  156. def maybe_unpack(collection, attr):
  157. # TODO: RadioGroups need to support defaults
  158. try:
  159. if isinstance(collection, list):
  160. return [item[attr] for item in collection]
  161. return collection[attr]
  162. except:
  163. return None