diff --git a/src/app/__init__.pyc b/src/app/__init__.pyc index f4d8f8e..6f6052c 100644 Binary files a/src/app/__init__.pyc and b/src/app/__init__.pyc differ diff --git a/src/app/dialogs/__init__.pyc b/src/app/dialogs/__init__.pyc index beb12ab..7f9bde9 100644 Binary files a/src/app/dialogs/__init__.pyc and b/src/app/dialogs/__init__.pyc differ diff --git a/src/app/dialogs/advanced_config.pyc b/src/app/dialogs/advanced_config.pyc index a335ba9..0614b01 100644 Binary files a/src/app/dialogs/advanced_config.pyc and b/src/app/dialogs/advanced_config.pyc differ diff --git a/src/app/dialogs/base_window.py b/src/app/dialogs/base_window.py index c2bd57c..887b1e7 100644 --- a/src/app/dialogs/base_window.py +++ b/src/app/dialogs/base_window.py @@ -17,11 +17,11 @@ import header import footer from app.dialogs.controller import Controller from app.images import image_store -from app.dialogs.model import Model +from app.dialogs.config_model import Model class BaseWindow(wx.Frame): - def __init__(self, BodyPanel): + def __init__(self, body_panel, model): wx.Frame.__init__( self, parent=None, @@ -29,13 +29,13 @@ class BaseWindow(wx.Frame): title=os.path.basename(__file__), size=(610,530) ) + + self._model = model - self._model = Model.GetInstance() - self._payload = None self._controller = None self._init_properties() - self._init_components(BodyPanel) + self._init_components(body_panel) self._do_layout() self._init_controller() self.registerControllers() @@ -50,7 +50,7 @@ class BaseWindow(wx.Frame): def _init_components(self, BodyPanel): # init components self.head_panel = header.FrameHeader( - heading="Settings", + heading=("Settings"), subheading = self._model.description, image_path=image_store.settings2, parent=self, @@ -78,10 +78,11 @@ class BaseWindow(wx.Frame): def _init_controller(self): self._controller = Controller( - base = self, - head_panel = self.head_panel, - body_panel = self.body_panel, - footer_panel = self.cfg_foot_panel) + base_frame = self, + head_panel = self.head_panel, + body_panel = self.body_panel, + footer_panel = self.cfg_foot_panel, + model = self._model) def registerControllers(self): for panel in self.panels: diff --git a/src/app/dialogs/body.pyc b/src/app/dialogs/body.pyc index c34317b..aa3097d 100644 Binary files a/src/app/dialogs/body.pyc and b/src/app/dialogs/body.pyc differ diff --git a/src/app/dialogs/component_factory.pyc b/src/app/dialogs/component_factory.pyc index 9e82262..072ae31 100644 Binary files a/src/app/dialogs/component_factory.pyc and b/src/app/dialogs/component_factory.pyc differ diff --git a/src/app/dialogs/config_model.py b/src/app/dialogs/config_model.py new file mode 100644 index 0000000..db0460b --- /dev/null +++ b/src/app/dialogs/config_model.py @@ -0,0 +1,65 @@ +''' +Created on Jan 23, 2014 + +@author: Chris +''' + +import sys +import types +from model.source_parser import ArgumentError +from app.dialogs.action_sorter import ActionSorter + + + +class Model(object): + + def __init__(self, parser): + self._parser = parser + self.description = parser.description + + self.action_groups = ActionSorter(self._parser._actions) + + self._payload = None + + + def HasPositionals(self): + if self.action_groups._positionals: + return True + return False + + def IsValidArgString(self, arg_string): + if isinstance(self._Parse(arg_string), str): + return False + return True + + def _Parse(self, arg_string): + try: + print self._parser.error + self._parser.parse_args(arg_string.split()) + return True + except ArgumentError as e: + return str(e) + + def GetErrorMsg(self, arg_string): + return self._FormatMsg(self._Parse(arg_string)) + + def _FormatMsg(self, msg): + output = list(msg) + if ':' in output: + output[output.index(':')] = ':\n ' + return ''.join(output) + + def AddToArgv(self, arg_string): + sys.argv.extend(arg_string.split()) + + + +if __name__ == '__main__': + pass + + +# print m2 + + + + diff --git a/src/app/dialogs/controller.py b/src/app/dialogs/controller.py index c9ecee1..1eeb1ec 100644 --- a/src/app/dialogs/controller.py +++ b/src/app/dialogs/controller.py @@ -6,7 +6,7 @@ Created on Dec 22, 2013 import wx import sys -from app.dialogs.model import Model +from app.dialogs.config_model import Model YES = 5103 NO = 5104 @@ -16,26 +16,23 @@ class Controller(object): Main controller for the gui. All controlls are delegated to this central control point. - It's kind of a bi-directional observer sort of thing, thus - weirdly initialized with references to the BaseWindows panels, - and then 'registered' with the panels . - - Args: - base = Reference to the Basewindow - head_panel = reference to the BaseWindow's Head Panel - body_panel = reference to the BaseWindow's Body Panel - footer_panel = reference to the BaseWindow's Footer Panel + base_frame = Reference to the Basewindow + head_panel = reference to the BaseWindow's Head Panel + body_panel = reference to the BaseWindow's Body Panel + footer_panel = reference to the BaseWindow's Footer Panel + model = configuration model ''' - def __init__(self, base, head_panel, body_panel, footer_panel): - self._base = base + def __init__(self, base_frame, head_panel, body_panel, + footer_panel, model): + self._base = base_frame self._head = head_panel self._body = body_panel self._foot = footer_panel - self._model = Model.GetInstance() + self._model = model def OnConfigCancel(self, event): msg = "Are you sure you want to exit?" @@ -63,8 +60,6 @@ class Controller(object): def AddPayload(self, payload): pass - - def OnMainCancel(self, event): print 'OnMaingCancel pressed!' diff --git a/src/app/dialogs/display_main.pyc b/src/app/dialogs/display_main.pyc index cd670e2..63c5c90 100644 Binary files a/src/app/dialogs/display_main.pyc and b/src/app/dialogs/display_main.pyc differ diff --git a/src/app/dialogs/footer.py b/src/app/dialogs/footer.py index f061229..e871e8c 100644 --- a/src/app/dialogs/footer.py +++ b/src/app/dialogs/footer.py @@ -17,7 +17,7 @@ class AbstractFooter(wx.Panel): self._controller = None self.cancel_button = self._button('Cancel', wx.ID_CANCEL) - self.next_button = self._button("Next", wx.ID_OK) + self.next_button = self._button("Start", wx.ID_OK) self._do_layout() diff --git a/src/app/dialogs/footer.pyc b/src/app/dialogs/footer.pyc index 45a367a..8f6dc3b 100644 Binary files a/src/app/dialogs/footer.pyc and b/src/app/dialogs/footer.pyc differ diff --git a/src/app/dialogs/header.py b/src/app/dialogs/header.py index 9610a5d..94226c8 100644 --- a/src/app/dialogs/header.py +++ b/src/app/dialogs/header.py @@ -13,8 +13,8 @@ PAD_SIZE = 10 class FrameHeader(wx.Panel): def __init__(self, - heading="Settings", - subheading="Small notification or intructional message", + heading='', + subheading='', image_path=None, dlg_style=1, **kwargs): diff --git a/src/app/dialogs/header.pyc b/src/app/dialogs/header.pyc index a6c8f57..010ac5b 100644 Binary files a/src/app/dialogs/header.pyc and b/src/app/dialogs/header.pyc differ diff --git a/src/app/dialogs/window.py b/src/app/dialogs/window.py index 86a2bf8..d1497c4 100644 --- a/src/app/dialogs/window.py +++ b/src/app/dialogs/window.py @@ -24,26 +24,23 @@ def wrap(): ''' import wx -import base_window import advanced_config +from base_window import BaseWindow +from app.dialogs.config_model import Model from app.dialogs import argparse_test_data -from app.dialogs.model import Model -def WithNoOptions(): pass -def WithBasicOptions(): pass def WithAdvancedOptions(parser, payload): app = wx.App(False) model = Model(parser) - frame = base_window.BaseWindow(advanced_config.AdvancedConfigPanel) - frame.AttachPayload(payload) + frame = BaseWindow(advanced_config.AdvancedConfigPanel, model) frame.Show(True) # Show the frame. app.MainLoop() if __name__ == '__main__': parser = argparse_test_data.parser - WithAdvancedOptions(parser) + WithAdvancedOptions(parser, None) diff --git a/src/app/images/__init__.pyc b/src/app/images/__init__.pyc index f326cda..7000bf3 100644 Binary files a/src/app/images/__init__.pyc and b/src/app/images/__init__.pyc differ diff --git a/src/app/images/image_store.py b/src/app/images/image_store.py index 7b08367..04daf8b 100644 --- a/src/app/images/image_store.py +++ b/src/app/images/image_store.py @@ -7,10 +7,10 @@ Convenience module for keeping the filepaths in one place. """ -computer = r"C:\Users\Chris\Documents\Gooey\src\app\images\computer.png" -computer2 = r"C:\Users\Chris\Documents\Gooey\src\app\images\computer2.png" -computer3 = r"C:\Users\Chris\Documents\Gooey\src\app\images\computer3.png" -icon = r"C:\Users\Chris\Documents\Gooey\src\app\images\icon.ico" -settings = r"C:\Users\Chris\Documents\Gooey\src\app\images\settings.png" -settings2 = r"C:\Users\Chris\Documents\Gooey\src\app\images\settings2.png" -terminal = r"C:\Users\Chris\Documents\Gooey\src\app\images\terminal.png" +computer = r"C:\Users\Chris\Dropbox\pretty_gui\Gooey\src\app\images\computer.png" +computer2 = r"C:\Users\Chris\Dropbox\pretty_gui\Gooey\src\app\images\computer2.png" +computer3 = r"C:\Users\Chris\Dropbox\pretty_gui\Gooey\src\app\images\computer3.png" +icon = r"C:\Users\Chris\Dropbox\pretty_gui\Gooey\src\app\images\icon.ico" +settings = r"C:\Users\Chris\Dropbox\pretty_gui\Gooey\src\app\images\settings.png" +settings2 = r"C:\Users\Chris\Dropbox\pretty_gui\Gooey\src\app\images\settings2.png" +terminal = r"C:\Users\Chris\Dropbox\pretty_gui\Gooey\src\app\images\terminal.png" diff --git a/src/app/images/image_store.pyc b/src/app/images/image_store.pyc index 01e0271..1a3a91c 100644 Binary files a/src/app/images/image_store.pyc and b/src/app/images/image_store.pyc differ diff --git a/src/experiments/command.py b/src/experiments/command.py index 0b21f8f..b61c752 100644 --- a/src/experiments/command.py +++ b/src/experiments/command.py @@ -4,19 +4,35 @@ Created on Jan 7, 2014 @author: Chris ''' -class Command(object): +import types + +class Fooer(object): def __init__(self): - pass - - def execute(self): - pass - - -class NextButton(Command): - def execute(self): - print "Next Button" + self.a=1 + self.b=2 + self.c=3 -class CancelButton(Command): - def execute(self): - print 'Cancel button!' + def error(self, msg): + print msg + + +class Barer(object): + def __init__(self): + self._fooer = Fooer() + def __getattr__(self, a): + return getattr(self._fooer, a) + +class Bazzer(object): + def __init__(self): + self._f = Fooer() + + +def error2(self, msg): + print 'HEY! I\'ve been patched!' + +b = Barer() + +b.error = types.MethodType(error2, b) + +b.error('asdf') diff --git a/src/languages/eng.py b/src/languages/eng.py new file mode 100644 index 0000000..75d5f5b --- /dev/null +++ b/src/languages/eng.py @@ -0,0 +1,25 @@ +''' +Created on Jan 25, 2014 + +@author: Chris +''' + +import json + + +if __name__ == '__main__': + english = { + 'settings':'Settings', + 'cancel':'Cancel', + 'next':'Next', + 'simple_config':'Enter Command Line Arguments', + 'required_args_msg':'Required Arguments', + 'optional_args_msg':'Optional Arguments', + 'running':'Running', + "sure_you_want_to_exit":"Are you sure you want to exit?", + 'close_program': 'Close Program?' + + } + + with open('english.json', 'wb') as f: + f.write(json.dumps(english, indent=4, sort_keys=True)) \ No newline at end of file diff --git a/src/languages/english.json b/src/languages/english.json index 89507a1..f93374f 100644 --- a/src/languages/english.json +++ b/src/languages/english.json @@ -1 +1,9 @@ -{ +{ + "cancel": "Cancel", + "next": "Next", + "optional_args_msg": "Optional Arguments", + "required_args_msg": "Required Arguments", + "running": "Running", + "settings": "Settings", + "simple_config": "Enter Command Line Arguments" +} \ No newline at end of file diff --git a/src/languages/french.json b/src/languages/french.json new file mode 100644 index 0000000..c97b382 --- /dev/null +++ b/src/languages/french.json @@ -0,0 +1,9 @@ +{ + "cancel": "Annuler", + "next": "Suivant", + "optional_args_msg": "Arguments optionnels", + "required_args_msg": "Arguments obligatoires", + "running": "fonctionnement", + "settings": "Paramètres", + "simple_config": "Entrez arguments de ligne de commande" +} \ No newline at end of file diff --git a/src/mockapplication/mockapp.py b/src/mockapplication/mockapp.py index 5c67289..3c30b0c 100644 --- a/src/mockapplication/mockapp.py +++ b/src/mockapplication/mockapp.py @@ -10,16 +10,26 @@ from time import sleep as _sleep from argparse import ArgumentParser from model.gooey import Gooey + + + + @Gooey def main(): - my_cool_parser = ArgumentParser(description="Mock application to test @Gui's functionality") - my_cool_parser.add_argument('filename', help="bla bla bla") + my_cool_parser = ArgumentParser(description="Mock application to test Gooey's functionality") +# my_cool_parser.add_argument('filename', help="bla bla bla") my_cool_parser.add_argument('-c', '--countdown', default=10, type=int, help='sets the time to count down from') my_cool_parser.add_argument("-s", "--showtime", action="store_true", help="display the countdown timer") my_cool_parser.add_argument("-w", "--whatevs", default="No, NOT whatevs", help="...") + print 'inside of main(), my_cool_parser =', my_cool_parser args = my_cool_parser.parse_args() + print sys.argv + print args.countdown + print args.showtime + + start_time = _time() print 'Counting down from %s' % args.countdown while _time() - start_time < args.countdown: @@ -31,5 +41,6 @@ def main(): print 'Finished running the program. Byeeeeesss!' if __name__ == '__main__': -# sys.argv.extend('-c 5'.split()) +# sys.argv.extend('asdf -c 5 -s'.split()) +# print sys.argv main() \ No newline at end of file diff --git a/src/model/__init__.pyc b/src/model/__init__.pyc index 33c4e96..60218f5 100644 Binary files a/src/model/__init__.pyc and b/src/model/__init__.pyc differ diff --git a/src/model/codegen.pyc b/src/model/codegen.pyc index d104fe4..f8301ef 100644 Binary files a/src/model/codegen.pyc and b/src/model/codegen.pyc differ diff --git a/src/model/gooey.py b/src/model/gooey.py index 86846e5..3c45f89 100644 --- a/src/model/gooey.py +++ b/src/model/gooey.py @@ -8,10 +8,12 @@ import os import sys import argparse import source_parser +from app.dialogs.config_model import Model from app.dialogs import window +from model.i18n import I18N -def Gooey(f=None, advanced=True, basic=False): +def Gooey(f=None, advanced=True, language='english'): ''' Decorator for client code's main function. Entry point for the GUI generator. @@ -23,6 +25,7 @@ def Gooey(f=None, advanced=True, basic=False): Launched ''' +# print locals() # Handles if the passed in object is instance # of ArgumentParser. If so, it's being called as @@ -45,9 +48,25 @@ def Gooey(f=None, advanced=True, basic=False): def build(f): def inner(): module_path = get_caller_path() - prog_name = get_program_name(module_path) - parser = source_parser.pull_parser_from(module_path) + parser = source_parser.extract_parser(module_path) + print 'parser in inner', parser + i18n = I18N(language) + if not parser: + print 'shit fuck!' + # run basic program with info window + return +# config_model = Model(parser) +# arg_string = 'asdf 5 -s' +# if not config_model.IsValidArgString(arg_string): +# error = config_model.GetErrorMsg(arg_string) +# raise ValueError("you suck, son! \n%s" % error) +# config_model.AddToArgv(arg_string) +# f() +# +# if advanced: window.WithAdvancedOptions(parser, f) +# else: +# pass # run simple congig version inner.__name__ = f.__name__ return inner diff --git a/src/model/i18n.py b/src/model/i18n.py new file mode 100644 index 0000000..10cfa2b --- /dev/null +++ b/src/model/i18n.py @@ -0,0 +1,45 @@ +''' +Created on Jan 25, 2014 + +@author: Chris +''' + +import os +import sys +import json + +class I18N(object): + ''' + Provides Internationalization for all text within the + program. + ''' + _instance = None + def __init__(self, language='english'): + ''' Create an I18N object ''' + self._dict = self._load(language) + + def __new__(cls, *a, **kw): + if cls._instance is None: + cls._instance = super(I18N, cls).__new__(cls, *a, **kw) + return cls._instance + + def _load(self, language): + lang_dir = os.path.join(os.getcwd(), '..', 'languages') + lang_path = os.path.join(lang_dir, language + '.json') + try: + with open(lang_path.lower(), 'rb') as f: + return json.load(f) + except IOError: + raise IOError(''.join(['Language "{}" not found. Make sure that your ', + 'translation file is in the languages directory']).format(language)) + + def __getitem__(self, item): + return self._dict[item] + + +if __name__ == '__main__': + pass + + + + \ No newline at end of file diff --git a/src/model/i18n_unittest.py b/src/model/i18n_unittest.py new file mode 100644 index 0000000..fcfea05 --- /dev/null +++ b/src/model/i18n_unittest.py @@ -0,0 +1,25 @@ +''' +Created on Jan 25, 2014 + +@author: Chris +''' + +from i18n import I18N +import unittest + + +class Test(unittest.TestCase): + + + def setUp(self): + pass + + def testI18nThrowsIOErrorOnBadPath(self): + with self.assertRaises(IOError): + I18N('franch') + + + +if __name__ == "__main__": + #import sys;sys.argv = ['', 'Test.testName'] + unittest.main() \ No newline at end of file diff --git a/src/model/source_parser.py b/src/model/source_parser.py index 721673a..f19c1c6 100644 --- a/src/model/source_parser.py +++ b/src/model/source_parser.py @@ -13,12 +13,12 @@ client code. import os import ast import sys +import types import random import codegen import argparse import cStringIO from itertools import chain -from functools import partial from argparse import ArgumentParser from argparse import RawDescriptionHelpFormatter from app.dialogs.action_sorter import ActionSorter @@ -28,6 +28,10 @@ class ParserError(Exception): '''Thrown when the parser can't find argparse functions the client code''' pass +class ArgumentError(Exception): + '''Thrown when the parser is supplied with an incorrect argument format''' + pass + class ParserFromSource(object): ''' @@ -41,8 +45,9 @@ class ParserFromSource(object): ''' def __init__(self, source_code): self._parser_instance = self._build_argparser_from_client_source(source_code) - # redirect future getattr requests -# self.__getattr__ = self._delegator + self._parser_instance.error = types.MethodType( + self._ErrorAsString, + self._parser_instance) def _build_argparser_from_client_source(self, source_code): ''' @@ -108,6 +113,15 @@ class ParserFromSource(object): Auto-delegates everything to the ArgumentParser instance''' return getattr(self._parser_instance, attr) + @staticmethod + def _ErrorAsString(self, msg): + ''' + Monkey patch for parser.error + Returns the error string rather than + printing and silently exiting. + ''' + raise ArgumentError(msg) + def parse_source_file(file_name): ''' @@ -143,7 +157,8 @@ def parse_source_file(file_name): main_block = find_argparse_location(search_locations) if not main_block: - raise ParserError("Could not locate AugmentParser assignment.") + raise None +# raise ParserError("Could not locate AugmentParser assignment.") argparse_assign_obj = [node for node in main_block.body if has_instantiator(node, 'ArgumentParser')] @@ -217,10 +232,12 @@ def convert_to_python(ast_source): return map(codegen.to_source, ast_source) -def pull_parser_from(modulepath): +def extract_parser(modulepath): ast_source = parse_source_file(modulepath) - python_code = convert_to_python(ast_source) - return ParserFromSource(python_code) + if ast_source: + python_code = convert_to_python(ast_source) + return ParserFromSource(python_code) + return None if __name__ == '__main__': diff --git a/src/themes/__init__.py b/src/themes/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/src/themes/thm.py b/src/themes/thm.py new file mode 100644 index 0000000..bd73fbd --- /dev/null +++ b/src/themes/thm.py @@ -0,0 +1,14 @@ +''' +Created on Jan 25, 2014 + +@author: Chris +''' + +import json + +if __name__ == '__main__': + a = { + 'font_size': 8, + 'bold_font_family': 'default', + + } \ No newline at end of file