Browse Source

deprecate controller

pull/150/head
chriskiehl 9 years ago
parent
commit
38d2d42390
4 changed files with 199 additions and 208 deletions
  1. 276
      gooey/gui/controller.py
  2. 107
      gooey/gui/presenter.py
  3. 8
      gooey/gui/processor.py
  4. 16
      gooey/gui/windows/base_window.py

276
gooey/gui/controller.py

@ -30,147 +30,147 @@ class Controller(object):
self.presentation = Presenter(self.view, MyModel(self.build_spec))
self.presentation.initialize_view()
self._process = None
# self._process = None
# wire up all the observers
pub.subscribe(self.on_cancel, events.WINDOW_CANCEL)
pub.subscribe(self.on_stop, events.WINDOW_STOP)
# pub.subscribe(self.on_cancel, events.WINDOW_CANCEL)
# pub.subscribe(self.on_stop, events.WINDOW_STOP)
# pub.subscribe(self.on_start, events.WINDOW_START)
pub.subscribe(self.on_restart, events.WINDOW_RESTART)
pub.subscribe(self.on_close, events.WINDOW_CLOSE)
pub.subscribe(self.on_edit, events.WINDOW_EDIT)
def on_edit(self):
pub.send_message(events.WINDOW_CHANGE, view_name=views.CONFIG_SCREEN)
def on_close(self):
if self.ask_stop():
self.view.Destroy()
sys.exit()
def on_restart(self):
self.on_start()
def manual_restart(self):
self.on_start()
def on_cancel(self):
msg = i18n._('sure_you_want_to_exit')
result = self.view.show_dialog(msg, i18n._('close_program'), wx.YES_NO)
if result == YES:
self.view.Destroy()
sys.exit()
def on_start(self):
print self.presentation.view.required_section.get_values()
print self.presentation.view.optional_section.get_values()
# if not self.skipping_config() and not self.required_section_complete():
# return self.view.show_dialog(i18n._('error_title'), i18n._('error_required_fields'), wx.ICON_ERROR)
#
# cmd_line_args = self.view.GetOptions()
# command = '{} --ignore-gooey {}'.format(self.build_spec['target'], cmd_line_args)
# pub.send_message(events.WINDOW_CHANGE, view_name=views.RUNNING_SCREEN)
# self.run_client_code(command)
def on_stop(self):
self.ask_stop()
def ask_stop(self):
if not self.running():
return True
if self.build_spec['disable_stop_button']:
return False
msg = i18n._('sure_you_want_to_stop')
result = self.view.show_dialog(msg, i18n._('stop_task'), wx.YES_NO)
if result == YES:
self.stop()
return True
return False
def stop(self):
if self.running():
taskkill(self._process.pid)
def running(self):
return self._process and self._process.poll() is None
def run_client_code(self, command):
env = os.environ.copy()
env["GOOEY"] = "1"
print "run command:", command
p = subprocess.Popen(command, bufsize=1, stdout=subprocess.PIPE,
stderr=subprocess.STDOUT, shell=True, env=env)
self._process = p
pool = Pool(1)
pool.apply_async(self.read_stdout, (p, self.process_result))
def read_stdout(self, process, callback):
while True:
line = process.stdout.readline()
if not line:
break
wx.CallAfter(self.view.PublishConsoleMsg, line)
progress = self.progress_from_line(line)
if progress is not None:
wx.CallAfter(self.view.UpdateProgressBar, progress)
wx.CallAfter(callback, process)
def progress_from_line(self, text):
progress_regex = self.build_spec['progress_regex']
if not progress_regex:
return None
match = re.search(progress_regex, text.strip())
if not match:
return None
progress_expr = self.build_spec['progress_expr']
if progress_expr:
return self._eval_progress(match, progress_expr)
else:
return self._search_progress(match)
def _search_progress(self, match):
try:
return int(float(match.group(1)))
except:
return None
def _eval_progress(self, match, eval_expr):
def safe_float(x):
try:
return float(x)
except ValueError:
return x
_locals = {k: safe_float(v) for k, v in match.groupdict().items()}
if "x" not in _locals:
_locals["x"] = [safe_float(x) for x in match.groups()]
try:
return int(float(eval(eval_expr, {}, _locals)))
except:
return None
def process_result(self, process):
_stdout, _ = process.communicate()
if process.returncode == 0:
pub.send_message(events.WINDOW_CHANGE, view_name=views.SUCCESS_SCREEN)
self.success_dialog()
else:
pub.send_message(events.WINDOW_CHANGE, view_name=views.ERROR_SCREEN)
self.error_dialog()
# def skipping_config(self):
# return self.build_spec['manual_start']
#
# def required_section_complete(self):
# required_section = self.view.GetRequiredArgs()
# if len(required_section) == 0:
# return True # no requirements!
# return not any(req == '' for req in required_section)
def success_dialog(self):
self.view.show_dialog(i18n._("execution_finished"), i18n._('success_message'), wx.ICON_INFORMATION)
def error_dialog(self):
self.view.show_dialog(i18n._('error_title'), i18n._('uh_oh'), wx.ICON_ERROR)
# pub.subscribe(self.on_restart, events.WINDOW_RESTART)
# pub.subscribe(self.on_close, events.WINDOW_CLOSE)
# pub.subscribe(self.on_edit, events.WINDOW_EDIT)
#
# def on_edit(self):
# pub.send_message(events.WINDOW_CHANGE, view_name=views.CONFIG_SCREEN)
#
# def on_close(self):
# if self.ask_stop():
# self.view.Destroy()
# sys.exit()
#
# def on_restart(self):
# self.on_start()
#
# def manual_restart(self):
# self.on_start()
#
# def on_cancel(self):
# msg = i18n._('sure_you_want_to_exit')
# result = self.view.show_dialog(msg, i18n._('close_program'), wx.YES_NO)
# if result == YES:
# self.view.Destroy()
# sys.exit()
#
# def on_start(self):
# print self.presentation.view.required_section.get_values()
# print self.presentation.view.optional_section.get_values()
# # if not self.skipping_config() and not self.required_section_complete():
# # return self.view.show_dialog(i18n._('error_title'), i18n._('error_required_fields'), wx.ICON_ERROR)
# #
# # cmd_line_args = self.view.GetOptions()
# # command = '{} --ignore-gooey {}'.format(self.build_spec['target'], cmd_line_args)
# # pub.send_message(events.WINDOW_CHANGE, view_name=views.RUNNING_SCREEN)
# # self.run_client_code(command)
#
# def on_stop(self):
# self.ask_stop()
#
# def ask_stop(self):
# if not self.running():
# return True
# if self.build_spec['disable_stop_button']:
# return False
# msg = i18n._('sure_you_want_to_stop')
# result = self.view.show_dialog(msg, i18n._('stop_task'), wx.YES_NO)
# if result == YES:
# self.stop()
# return True
# return False
#
# def stop(self):
# if self.running():
# taskkill(self._process.pid)
#
# def running(self):
# return self._process and self._process.poll() is None
#
# def run_client_code(self, command):
# env = os.environ.copy()
# env["GOOEY"] = "1"
# print "run command:", command
# p = subprocess.Popen(command, bufsize=1, stdout=subprocess.PIPE,
# stderr=subprocess.STDOUT, shell=True, env=env)
# self._process = p
# pool = Pool(1)
# pool.apply_async(self.read_stdout, (p, self.process_result))
#
# def read_stdout(self, process, callback):
# while True:
# line = process.stdout.readline()
# if not line:
# break
# wx.CallAfter(self.view.PublishConsoleMsg, line)
# progress = self.progress_from_line(line)
# if progress is not None:
# wx.CallAfter(self.view.UpdateProgressBar, progress)
# wx.CallAfter(callback, process)
#
# def progress_from_line(self, text):
# progress_regex = self.build_spec['progress_regex']
# if not progress_regex:
# return None
# match = re.search(progress_regex, text.strip())
# if not match:
# return None
# progress_expr = self.build_spec['progress_expr']
# if progress_expr:
# return self._eval_progress(match, progress_expr)
# else:
# return self._search_progress(match)
#
# def _search_progress(self, match):
# try:
# return int(float(match.group(1)))
# except:
# return None
#
# def _eval_progress(self, match, eval_expr):
# def safe_float(x):
# try:
# return float(x)
# except ValueError:
# return x
# _locals = {k: safe_float(v) for k, v in match.groupdict().items()}
# if "x" not in _locals:
# _locals["x"] = [safe_float(x) for x in match.groups()]
# try:
# return int(float(eval(eval_expr, {}, _locals)))
# except:
# return None
#
# def process_result(self, process):
# _stdout, _ = process.communicate()
# if process.returncode == 0:
# pub.send_message(events.WINDOW_CHANGE, view_name=views.SUCCESS_SCREEN)
# self.success_dialog()
# else:
# pub.send_message(events.WINDOW_CHANGE, view_name=views.ERROR_SCREEN)
# self.error_dialog()
#
# # def skipping_config(self):
# # return self.build_spec['manual_start']
# #
# # def required_section_complete(self):
# # required_section = self.view.GetRequiredArgs()
# # if len(required_section) == 0:
# # return True # no requirements!
# # return not any(req == '' for req in required_section)
#
# def success_dialog(self):
# self.view.show_dialog(i18n._("execution_finished"), i18n._('success_message'), wx.ICON_INFORMATION)
#
# def error_dialog(self):
# self.view.show_dialog(i18n._('error_title'), i18n._('uh_oh'), wx.ICON_ERROR)
def run(self):
self.view.Show(True)

107
gooey/gui/presenter.py

@ -3,8 +3,10 @@ from collections import namedtuple
import subprocess
import sys
from gooey.gui import component_builder
from gooey.gui.controller2 import ProcessController
from gooey.gui.processor import ProcessController
from gooey.gui.lang.i18n import _
from gooey.gui.model import States
from gooey.gui.pubsub import pub
@ -21,7 +23,14 @@ class Presenter(object):
self.model.progress_expr
)
pub.subscribe(self.on_cancel, events.WINDOW_CANCEL)
pub.subscribe(self.on_stop, events.WINDOW_STOP)
pub.subscribe(self.on_start, events.WINDOW_START)
pub.subscribe(self.on_restart, events.WINDOW_RESTART)
pub.subscribe(self.on_edit, events.WINDOW_EDIT)
pub.subscribe(self.on_close, events.WINDOW_CLOSE)
# console statuses from the other thread
pub.subscribe(self.on_new_message, 'console_update')
@ -46,14 +55,19 @@ class Presenter(object):
self.syncronize_from_model()
def on_edit(self):
self.model.update_state(States.CONFIGURING)
self.syncronize_from_model()
def on_restart(self):
self.on_start()
def on_start(self):
self.update_model()
if not self.model.is_valid():
self.view.show_missing_args_dialog()
return self.view.show_missing_args_dialog()
command = self.model.build_command_line_string()
self.client_runner.run(command)
self.model.update_state(States.RUNNNING)
self.syncronize_from_model()
@ -63,7 +77,6 @@ class Presenter(object):
def on_progress_change(self, progress):
# observes changes coming from the subprocess
print 'Progress:', progress
self.view.update_progress_aync(progress)
def on_client_done(self):
@ -73,14 +86,32 @@ class Presenter(object):
self.model.update_state(States.ERROR)
self.syncronize_from_model()
def update_model(self):
self.update_list(self.model.required_args, self.view.required_section.get_values())
self.update_list(self.model.optional_args, self.view.optional_section.get_values())
self.syncronize_from_model()
def on_cancel(self):
if self.view.confirm_exit_dialog():
self.view.Destroy()
sys.exit()
def on_stop(self):
self.ask_stop()
def on_close(self):
if self.ask_stop():
self.view.Destroy()
sys.exit()
def ask_stop(self):
if self.view.confirm_stop_dialog():
self.stop()
return True
return False
def stop(self):
self.client_runner.stop()
def update_list(self, collection, new_values):
for index, val in enumerate(new_values):
@ -94,6 +125,8 @@ class Presenter(object):
# update heading titles
self.view.heading_title = self.model.heading_title
self.view.heading_subtitle = self.model.heading_subtitle
if not self.model.stop_button_disabled:
self.view.enable_stop_button()
# refresh the widgets
for index, widget in enumerate(self.view.required_section):
@ -132,63 +165,3 @@ class Presenter(object):
self.view.show('error_symbol', 'edit_button', 'restart_button', 'close_button', 'runtime_display')
self.view.Layout()
# def process_result(self, process):
# _stdout, _ = process.communicate()
# if process.returncode == 0:
# self.model.update_state(States.SUCCESS)
# self.syncronize_from_model()
# # pub.send_message(events.WINDOW_CHANGE, view_name=views.SUCCESS_SCREEN)
# # self.success_dialog()
# else:
# self.model.update_state(States.ERROR)
# self.syncronize_from_model()
# # pub.send_message(events.WINDOW_CHANGE, view_name=views.ERROR_SCREEN)
# # self.error_dialog()
# # FOOTER
# def _init_pages(self):
# def config():
# self.hide_all_buttons()
# self.cancel_button.Show()
# self.start_button.Show()
# self.Layout()
#
# def running():
# self.hide_all_buttons()
# self.stop_button.Show()
# self.progress_bar.Show()
# self.progress_bar.Pulse()
# self.Layout()
#
# def success():
# self.hide_all_buttons()
# self.progress_bar.Hide()
# self.edit_button.Show()
# self.restart_button.Show()
# self.close_button.Show()
# self.Layout()
#
# def error():
# success()
#
# self.layouts = locals()
#
# # BODY
# def _init_pages(self):
#
# def config():
# self.config_panel.Show()
# self.runtime_display.Hide()
#
# def running():
# self.config_panel.Hide()
# self.runtime_display.Show()
# self.Layout()
#
# def success():
# running()
#
# def error():
# running()
#
# self.layouts = locals()

8
gooey/gui/processor.py

@ -8,6 +8,7 @@ from multiprocessing.dummy import Pool
from gooey.gui.pubsub import pub
from gooey.gui.util.casting import safe_float
from gooey.gui.util.functional import unit, bind
from gooey.gui.util.taskkill import taskkill
class ProcessController(object):
@ -25,6 +26,13 @@ class ProcessController(object):
raise Exception('Not started!')
self._process.poll()
def stop(self):
if self.running():
taskkill(self._process.pid)
def running(self):
return self._process and self.poll() is None
def run(self, command):
env = os.environ.copy()
env["GOOEY"] = "1"

16
gooey/gui/windows/base_window.py

@ -9,7 +9,7 @@ from distutils import config
import wx
from gooey.gui.pubsub import pub
from gooey.gui.lang import i18n
from gooey.gui.lang.i18n import _
from gooey.gui.windows.advanced_config import ConfigPanel
from gooey.gui.windows.runtime_display_panel import RuntimeDisplay
from gooey.gui import image_repository, events
@ -17,6 +17,9 @@ from gooey.gui.util import wx_util
from gooey.gui.windows import footer, header, layouts
YES = 5103
NO = 5104
class BaseWindow(wx.Frame):
def __init__(self, build_spec, layout_type):
wx.Frame.__init__(self, parent=None, id=-1)
@ -153,7 +156,7 @@ class BaseWindow(wx.Frame):
# init gui
# _desc = self.build_spec['program_description']
# self.head_panel = header.FrameHeader(
# heading=i18n._("settings_title"),
# heading=_("settings_title"),
# subheading=_desc or '',
# parent=self)
self.runtime_display = RuntimeDisplay(self)
@ -272,8 +275,15 @@ class BaseWindow(wx.Frame):
return result
def show_missing_args_dialog(self):
self.show_dialog(i18n._('error_title'), i18n._('error_required_fields'), wx.ICON_ERROR)
self.show_dialog(_('error_title'), _('error_required_fields'), wx.ICON_ERROR)
def confirm_exit_dialog(self):
result = self.show_dialog(_('sure_you_want_to_exit'), _('close_program'), wx.YES_NO)
return result == YES
def confirm_stop_dialog(self):
result = self.show_dialog(_('sure_you_want_to_stop'), _('stop_task'), wx.YES_NO)
return result == YES
if __name__ == '__main__':
pass
Loading…
Cancel
Save