Browse Source

initial commit

pull/1/head
Chris Kiehl 11 years ago
commit
b731171651
52 changed files with 1844 additions and 0 deletions
  1. 17
      .project
  2. 8
      .pydevproject
  3. 3
      .settings/org.eclipse.core.resources.prefs
  4. 0
      src/app/__init__.py
  5. BIN
      src/app/__init__.pyc
  6. 0
      src/app/dialogs/__init__.py
  7. BIN
      src/app/dialogs/__init__.pyc
  8. 43
      src/app/dialogs/advanced_config.py
  9. BIN
      src/app/dialogs/advanced_config.pyc
  10. 26
      src/app/dialogs/body.py
  11. BIN
      src/app/dialogs/body.pyc
  12. 132
      src/app/dialogs/component_factory.py
  13. BIN
      src/app/dialogs/component_factory.pyc
  14. 107
      src/app/dialogs/display_main.py
  15. BIN
      src/app/dialogs/display_main.pyc
  16. 51
      src/app/dialogs/experiments.py
  17. 80
      src/app/dialogs/footer.py
  18. BIN
      src/app/dialogs/footer.pyc
  19. 71
      src/app/dialogs/header.py
  20. BIN
      src/app/dialogs/header.pyc
  21. 54
      src/app/dialogs/simple_config_panel.py
  22. 15
      src/app/dialogs/test.py
  23. 60
      src/app/images/__init__.py
  24. BIN
      src/app/images/__init__.pyc
  25. BIN
      src/app/images/computer.png
  26. BIN
      src/app/images/computer2.png
  27. BIN
      src/app/images/computer3.png
  28. BIN
      src/app/images/icon.ico
  29. 14
      src/app/images/image_store.py
  30. BIN
      src/app/images/image_store.pyc
  31. BIN
      src/app/images/images.jpg
  32. BIN
      src/app/images/terminal.png
  33. 21
      src/app/testrun.py
  34. 0
      src/app/widgets/__init__.py
  35. 0
      src/mockapplication/__init__.py
  36. 32
      src/mockapplication/mockapp.py
  37. 0
      src/model/__init__.py
  38. BIN
      src/model/__init__.pyc
  39. 572
      src/model/codegen.py
  40. BIN
      src/model/codegen.pyc
  41. 17
      src/model/controller.py
  42. BIN
      src/model/controller.pyc
  43. 141
      src/model/example_argparse_souce.py
  44. 56
      src/model/gui.py
  45. 276
      src/model/source_parser.py
  46. 34
      src/model/test_queue.py
  47. 0
      src/parser/MultiChoiceOption.py
  48. 0
      src/parser/RequiredOption.py
  49. 0
      src/parser/__init__.py
  50. 0
      src/parser/asdfasdf.py
  51. 0
      src/parser/example.py
  52. 14
      src/parser/option.py

17
.project

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>Gooey</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.python.pydev.PyDevBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.python.pydev.pythonNature</nature>
</natures>
</projectDescription>

8
.pydevproject

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<?eclipse-pydev version="1.0"?><pydev_project>
<pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH">
<path>/${PROJECT_DIR_NAME}/src</path>
</pydev_pathproperty>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property>
<pydev_property name="org.python.pydev.PYTHON_PROJECT_INTERPRETER">C:\Python27\python.exe</pydev_property>
</pydev_project>

3
.settings/org.eclipse.core.resources.prefs

@ -0,0 +1,3 @@
eclipse.preferences.version=1
encoding//src/model/codegen.py=utf-8
encoding//src/model/example_argparse_souce.py=utf-8

0
src/app/__init__.py

BIN
src/app/__init__.pyc

0
src/app/dialogs/__init__.py

BIN
src/app/dialogs/__init__.pyc

43
src/app/dialogs/advanced_config.py

@ -0,0 +1,43 @@
'''
Created on Dec 28, 2013
@author: Chris
'''
import wx
from wx.lib.scrolledpanel import ScrolledPanel
class AdvancedConfigPanel(ScrolledPanel):
'''
Abstract class for the Footer panels.
'''
def __init__(self, parent, **kwargs):
ScrolledPanel.__init__(self, parent, **kwargs)
self.SetupScrolling()
self.components = []
self.container = wx.BoxSizer(wx.VERTICAL)
self.container.AddSpacer(10)
self.AddRequiredArgsHeaderMsg()
def AddRequiredArgsHeaderMsg(self):
required_msg = wx.StaticText(self, label="Required Arguments")
self.container.Add(required_msg, 0, wx.LEFT | wx.RIGHT, 20)
def AddRequiredWidgets(self, factory):
widgets = factory._positionals
for widget in widgets:

BIN
src/app/dialogs/advanced_config.pyc

26
src/app/dialogs/body.py

@ -0,0 +1,26 @@
'''
Created on Dec 23, 2013
@author: Chris
'''
import wx
class BodyDisplayPanel(wx.Panel):
def __init__(self, parent, **kwargs):
wx.Panel.__init__(self, parent, **kwargs)
self.SetBackgroundColour('#F0F0F0')
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.AddSpacer(10)
text = wx.StaticText(self, label="Running bla bla bla")
sizer.Add(text, 0, wx.LEFT, 20)
sizer.AddSpacer(10)
self.cmd_textbox = wx.TextCtrl(
self, -1, "",
style=wx.TE_MULTILINE | wx.TE_READONLY)
sizer.Add(self.cmd_textbox, 1, wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, 20)
self.SetSizer(sizer)

BIN
src/app/dialogs/body.pyc

132
src/app/dialogs/component_factory.py

@ -0,0 +1,132 @@
'''
Created on Dec 8, 2013
@author: Chris
'''
import wx
from argparse import (
_StoreAction, _StoreConstAction,
_StoreFalseAction, _StoreTrueAction,
_CountAction, _AppendAction)
class ComponentFactory(object):
'''
So this thing is the thing that will
pull out all of the "types" from the
argparse object and turn them into the
correct wx components
COMPONENT MAP
Action WxWidget
--------------------------
store TextCtrl
store_const CheckBox
store_true CheckBox
store_False CheckBox
append TextCtrl
count DropDown
choice DropDown
_HelpAction(option_strings=['-h', '--help'], dest='help', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help='show this help message and exit', metavar=None)
_StoreAction(option_strings=[], dest='filename', nargs=None, const=None, default=None, type=None, choices=None, help='filename', metavar=None)
_StoreTrueAction(option_strings=['-r', '--recursive'], dest='recurse', nargs=0, const=True, default=False, type=None, choices=None, help='recurse into subfolders [default: %(default)s]', metavar=None)
_CountAction(option_strings=['-v', '--verbose'], dest='verbose', nargs=0, const=None, default=None, type=None, choices=None, help='set verbosity level [default: %(default)s]', metavar=None)
_AppendAction(option_strings=['-i', '--include'], dest='include', nargs=None, const=None, default=None, type=None, choices=None, help='only include paths matching this regex pattern. Note: exclude is given preference over include. [default: %(default)s]', metavar='RE')
_StoreAction(option_strings=['-e', '--exclude'], dest='exclude', nargs=None, const=None, default=None, type=None, choices=None, help='exclude paths matching this regex pattern. [default: %(default)s]', metavar='RE')
_VersionAction(option_strings=['-V', '--version'], dest='version', nargs=0, const=None, default='==SUPPRESS==', type=None, choices=None, help="show program's version number and exit", metavar=None)
_StoreAction(option_strings=['-T', '--tester'], dest='tester', nargs=None, const=None, default=None, type=None, choices=['yes', 'no'], help=None, metavar=None)
_StoreAction(option_strings=[], dest='paths', nargs='+', const=None, default=None, type=None, choices=None, help='paths to folder(s) with source file(s) [default: %(default)s]', metavar='path')
usage: example_argparse_souce.py [-h] [-r] [-v] [-i RE] [-e RE] [-V]
'''
def __init__(self, parser):
self._parser = parser
self._actions = self._parser._actions[:] # Copy all of the actions
self._positionals = self.get_positionals(self._actions)
self._choices = self.get_optionals_with_choices(self._actions)
self._optionals = self.get_optionals_without_choices(self._actions)
self._booleans = self.get_flag_style_optionals(self._actions)
self._counters = self.get_counter_actions(self._actions)
self._display('positionals', self._positionals)
self._display('choices', self._choices)
self._display('optionals', self._optionals)
self._display('booleans', self._booleans)
self._display('counters', self._counters)
def _display(self, _type, something):
for i in something:
print _type, i
def get_counter_actions(self, actions):
'''
Returns all instances of type _CountAction
'''
return [action
for action in actions
if isinstance(action, _CountAction)]
def get_positionals(self, actions):
'''
Get all required (positional) actions
'''
return [action
for action in actions
if not action.option_strings]
def get_optionals_without_choices(self, actions):
'''
All actions which are
(a) Optional, but without required choices
(b) Not of a "boolean" type (storeTrue, etc..)
(c) Of type _AppendAction
e.g. anything which has an argument style like:
>>> -f myfilename.txt
'''
boolean_actions = (
_StoreConstAction, _StoreFalseAction,
_StoreTrueAction
)
return [action
for action in actions
if action.option_strings
and not action.choices
and action not in boolean_actions]
def get_optionals_with_choices(self, actions):
'''
All optional arguments which are constrained
to specific choices.
'''
return [action
for action in actions
if action.choices]
def get_flag_style_optionals(self, actions):
'''
Gets all instances of "flag" type options.
i.e. options which either store a const, or
store boolean style options (e.g. StoreTrue).
Types:
_StoreTrueAction
_StoreFalseAction
_StoreConst
'''
return [action
for action in actions
if isinstance(action, _StoreTrueAction)
or isinstance(action, _StoreFalseAction)
or isinstance(action, _StoreConstAction)]
if __name__ == '__main__':
pass

BIN
src/app/dialogs/component_factory.pyc

107
src/app/dialogs/display_main.py

@ -0,0 +1,107 @@
'''
Created on Dec 8, 2013
@author: Chris
'''
import wx
import os
import sys
import threading
from model.controller import Controller
from app.images import image_store
from app.dialogs.header import FrameHeader
from app.dialogs.body import BodyDisplayPanel
from app.dialogs.footer import ConfigFooter
class MessagePump(object):
def __init__(self, queue):
self.queue = queue
self.stdout = sys.stdout
# Overrides stdout's write method
def write(self, text):
if text != '':
self.queue.put(text)
class MainWindow(wx.Frame):
class Listener(threading.Thread):
def __init__(self, queue, textbox):
threading.Thread.__init__(self)
self.queue = queue
self.update_text = lambda x: textbox.AppendText(x)
def run(self):
while True:
try:
stdout_msg = self.queue.get(timeout=1)
if stdout_msg != '':
self.update_text(stdout_msg)
except Exception as e:
pass # Timeout. Aint nobody care 'bout dat
def __init__(self, queue, payload=None):
wx.Frame.__init__(
self,
parent=None,
id=-1,
title=os.path.basename(__file__),
size=(640,480)
)
self._controller = Controller()
self._frame_header = FrameHeader
self._simple_config_body = None
self._adv_config_body = None
self._config_footer = None
self._output_footer = None
self._init_components()
self.queue = queue
# the client's main function
self._payload = payload
_stdout = sys.stdout
sys.stdout = MessagePump(queue)
listener = MainWindow.Listener(queue, self.panel2.cmd_textbox)
listener.start()
def _init_components(self):
# init components
self.SetMinSize((400,300))
self.icon = wx.Icon(image_store.icon, wx.BITMAP_TYPE_ICO)
self.SetIcon(self.icon)
panel1 = FrameHeader(image_path=image_store.computer3, parent=self, size=(30,90))
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(panel1, 0, wx.EXPAND)
self._draw_horizontal_line()
self.panel2 = BodyDisplayPanel(parent=self)
self.sizer.Add(self.panel2, 1, wx.EXPAND)
self.SetSizer(self.sizer)
self._draw_horizontal_line()
self.footer = ConfigFooter(self, self._controller)
self.sizer.Add(self.footer, 0, wx.EXPAND)
def _draw_horizontal_line(self):
line = wx.StaticLine(self, -1, style=wx.LI_HORIZONTAL)
line.SetSize((10, 10))
self.sizer.Add(line, 0, wx.EXPAND)

BIN
src/app/dialogs/display_main.pyc

51
src/app/dialogs/experiments.py

@ -0,0 +1,51 @@
'''
Created on Dec 28, 2013
@author: Chris
'''
import os
import wx
from wx.lib import scrolledpanel
from app.dialogs.advanced_config import AdvancedConfigPanel
class MainWindow(wx.Frame):
def __init__(self):
wx.Frame.__init__(
self,
parent=None,
id=-1,
title=os.path.basename(__file__),
size=(640,480)
)
self._init_components()
def _init_components(self):
# init components
self.SetMinSize((400,300))
panel = AdvancedConfigPanel(self)
sizer = wx.BoxSizer(wx.VERTICAL)
# for i in range(40):
# t = wx.TextCtrl(panel, -1)
# sizer.Add(t, 0)
panel.SetSizer(sizer)
_sizer = wx.BoxSizer(wx.VERTICAL)
_sizer.Add(panel, 1, wx.EXPAND)
self.SetSizer(_sizer)
def _draw_horizontal_line(self):
line = wx.StaticLine(self, -1, style=wx.LI_HORIZONTAL)
line.SetSize((10, 10))
self.sizer.Add(line, 0, wx.EXPAND)
if __name__ == '__main__':
app = wx.App(False)
frame = MainWindow()
frame.Show(True) # Show the frame.
app.MainLoop()

80
src/app/dialogs/footer.py

@ -0,0 +1,80 @@
'''
Created on Dec 23, 2013
@author: Chris
'''
import wx
class AbstractFooter(wx.Panel):
'''
Abstract class for the Footer panels.
'''
def __init__(self, parent, **kwargs):
wx.Panel.__init__(self, parent, **kwargs)
self.SetMinSize((30, 50))
self.cancel_button = self._button('Cancel', wx.ID_CANCEL)
self.next_button = self._button("Next", wx.ID_OK)
sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer.AddStretchSpacer(1)
sizer.Add(self.cancel_button, 0, wx.ALIGN_RIGHT | wx.RIGHT | wx.TOP, 20)
sizer.Add(self.next_button, 0, wx.ALIGN_RIGHT | wx.RIGHT | wx.TOP, 20)
self.SetSizer(sizer)
def _button(self,label=None, style=None):
return wx.Button(
parent=self,
id=-1,
size=(75, 23),
label=label,
style=style)
class ConfigFooter(AbstractFooter):
'''
Footer section used on the configuration
screen of the application
args:
parent: wxPython parent window
controller: controller class used in delagating all the commands
'''
def __init__(self, parent, controller, **kwargs):
AbstractFooter.__init__(self, parent, **kwargs)
self._controller = controller
self.Bind(wx.EVT_BUTTON, self.OnConfigCancel, self.cancel_button)
self.Bind(wx.EVT_BUTTON, self.OnConfigNext, self.next_button)
def OnConfigCancel(self, event):
self._controller.OnConfigCancel(event)
def OnConfigNext(self, event):
self._controller.OnConfigNext(event)
class MainFooter(AbstractFooter):
'''
Footer section used on the Main Status
screen of the application
args:
parent: wxPython parent window
controller: controller class used in delagating all the commands
'''
def __init__(self, parent, controller, **kwargs):
AbstractFooter.__init__(self, parent, **kwargs)
self._controller = controller
self.Bind(wx.EVT_BUTTON, self.OnConfigCancel, self.cancel_button)
self.Bind(wx.EVT_BUTTON, self.OnConfigNext, self.next_button)
def OnMainCancel(self, event):
self._controller.OnMainCancel(event)
def OnMainNext(self, event):
self._controller.OnMainNext(event)

BIN
src/app/dialogs/footer.pyc

71
src/app/dialogs/header.py

@ -0,0 +1,71 @@
'''
Created on Dec 23, 2013
@author: Chris
'''
import wx
class FrameHeader(wx.Panel):
def __init__(self,
heading="Doin Stuff here",
subheading="Small notification or intructional message",
image_path=None,
dlg_style=1,
**kwargs):
wx.Panel.__init__(self, **kwargs)
self.SetBackgroundColour('#ffffff')
self.SetMinSize((120, 90))
header = self._bold_static_text(label=heading)
subheader = wx.StaticText(self, label=subheading)
img = self._load_image(image_path)
sizer = wx.BoxSizer(wx.HORIZONTAL)
headings_sizer = self.build_heading_sizer(header, subheader)
sizer.Add(headings_sizer, 1, wx.ALIGN_LEFT | wx.EXPAND | wx.LEFT, 20)
sizer.Add(img, 0, wx.ALIGN_RIGHT | wx.EXPAND | wx.RIGHT, 20)
self.SetSizer(sizer)
# for i in dir(self): print i
def _load_image(self, image_path):
try:
bitmap = wx.Bitmap(image_path)
bitmap = self._resize_bitmap(bitmap)
return wx.StaticBitmap(self, -1, bitmap)
except:
raise IOError('Invalid Image path')
def _resize_bitmap(self, bmap):
'''
Resizes a bitmap to a height of 89 pixels (the
size of the top panel), while keeping aspect ratio
in tact
'''
image = wx.ImageFromBitmap(bmap)
width, height = image.GetSize()
ratio = float(width) / height
target_height = 79
image = image.Scale(target_height * ratio, target_height,
wx.IMAGE_QUALITY_HIGH
)
return wx.BitmapFromImage(image)
def _bold_static_text(self, label):
txt = wx.StaticText(self, label=label)
txt.SetFont(wx.Font(8, wx.FONTFAMILY_DEFAULT,
wx.FONTWEIGHT_NORMAL, wx.FONTWEIGHT_BOLD, False)
)
return txt
def build_heading_sizer(self, header, subheader):
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.AddStretchSpacer(1)
sizer.Add(header, 1)
sizer.Add(subheader, 1)
sizer.AddStretchSpacer(1)
return sizer

BIN
src/app/dialogs/header.pyc

54
src/app/dialogs/simple_config_panel.py

@ -0,0 +1,54 @@
'''
Created on Dec 9, 2013
@author: Chris
'''
import wx
import os
class BodyDisplayPanel(wx.Panel):
def __init__(self, parent, **kwargs):
wx.Panel.__init__(self, parent, **kwargs)
self.SetBackgroundColour('#F0F0F0')
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.AddSpacer(10)
# about_header = wx.StaticText(self, label="About")
# about_header = self._bold_static_text("About")
# about_body = wx.StaticText(self, label="This program does bla. Enter the command line args of your choice to control bla and bla.")
#
# sizer.Add(about_header, 0, wx.LEFT | wx.RIGHT, 20)
# sizer.AddSpacer(5)
# sizer.Add(about_body, 0, wx.LEFT | wx.RIGHT, 20)
sizer.AddSpacer(40)
text = self._bold_static_text("Enter Command Line Arguments")
#
sizer.Add(text, 0, wx.LEFT, 20)
sizer.AddSpacer(10)
h_sizer = wx.BoxSizer(wx.HORIZONTAL)
self.cmd_textbox = wx.TextCtrl(
self, -1, "")
h_sizer.Add(self.cmd_textbox, 1, wx.ALL | wx.EXPAND)
sizer.Add(h_sizer, 0, wx.LEFT | wx.RIGHT | wx.BOTTOM | wx.EXPAND, 20)
self.SetSizer(sizer)
def get_contents(self):
return self.cmd_textbox.GetValue()
def _bold_static_text(self, text_label):
bold = wx.Font(8, wx.FONTFAMILY_DEFAULT, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_BOLD)
text = wx.StaticText(self, label=text_label)
text.SetFont(bold)
return text

15
src/app/dialogs/test.py

@ -0,0 +1,15 @@
'''
Created on Dec 8, 2013
@author: Chris
'''
# im = Image.open(images.computer)

60
src/app/images/__init__.py

@ -0,0 +1,60 @@
'''
generates the internals of the image_store module
Nice perk of this approach is that it turns path errors into
things that lint can catch, rather than something that gets stumbled
upon randomly at runtime.
'''
import os
PATH = __path__[0]
print PATH
def render_class(assignments):
template = '''
"""
GENERATED CODE: DO NOT EDIT
Simple mapping of image names to their location on disc.
Convenience module for keeping the filepaths in one place.
"""
{variables}
'''
return template.format(variables=assignments)
def load_imagepaths():
file_extension = lambda x: os.path.splitext(x)[-1]
return [os.path.join(PATH, f) for f in os.listdir(PATH)
if file_extension(f) in ('.jpeg','.png', '.ico')]
def write_module(contents):
module_path = os.path.join(PATH, 'image_store.py')
with open(module_path, 'wb') as f:
f.write(contents)
def build_assignments(paths):
get_name = lambda x: os.path.splitext(os.path.split(x)[-1])[0]
assignments = ('%s = r"%s"' % (get_name(p), p)
for p in paths)
return '\n'.join(assignments)
paths = load_imagepaths()
assignments = build_assignments(paths)
write_module(render_class(assignments))

BIN
src/app/images/__init__.pyc

BIN
src/app/images/computer.png

Before After
Width: 256  |  Height: 256  |  Size: 35 KiB

BIN
src/app/images/computer2.png

Before After
Width: 82  |  Height: 89  |  Size: 10 KiB

BIN
src/app/images/computer3.png

Before After
Width: 256  |  Height: 203  |  Size: 77 KiB

BIN
src/app/images/icon.ico

Before After

14
src/app/images/image_store.py

@ -0,0 +1,14 @@
"""
GENERATED CODE: DO NOT EDIT
Simple mapping of image names to their location on disc.
Convenience module for keeping the filepaths in one place.
"""
computer = r"C:\Users\Chris\Dropbox\pretty_gui\Gui\src\app\images\computer.png"
computer2 = r"C:\Users\Chris\Dropbox\pretty_gui\Gui\src\app\images\computer2.png"
computer3 = r"C:\Users\Chris\Dropbox\pretty_gui\Gui\src\app\images\computer3.png"
icon = r"C:\Users\Chris\Dropbox\pretty_gui\Gui\src\app\images\icon.ico"
terminal = r"C:\Users\Chris\Dropbox\pretty_gui\Gui\src\app\images\terminal.png"

BIN
src/app/images/image_store.pyc

BIN
src/app/images/images.jpg

Before After
Width: 1232  |  Height: 3183  |  Size: 1.3 MiB

BIN
src/app/images/terminal.png

Before After
Width: 128  |  Height: 128  |  Size: 11 KiB

21
src/app/testrun.py

@ -0,0 +1,21 @@
'''
Created on Dec 8, 2013
@author: Chris
'''
import wx
import Queue
from dialogs.display_main import MainWindow
if __name__ == '__main__':
queue = Queue.Queue()
# stdoutput = sys.stdout
# out = TestObj(queue)
# sys.stdout = out
app = wx.App(False)
frame = MainWindow(queue)
frame.Show(True) # Show the frame.
app.MainLoop()

0
src/app/widgets/__init__.py

0
src/mockapplication/__init__.py

32
src/mockapplication/mockapp.py

@ -0,0 +1,32 @@
'''
Created on Dec 21, 2013
@author: Chris
'''
import sys
from time import time as _time
from time import sleep as _sleep
from argparse import ArgumentParser
import hashlib
def main():
my_cool_parser = ArgumentParser(description="Mock application to test @Gui's functionality")
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="...")
args = my_cool_parser.parse_args()
start_time = _time()
print 'Counting down from %s' % args.countdown
while _time() - start_time < args.countdown:
if args.showtime:
print 'printing message at: %s' % _time()
else:
print 'printing message at: %s' % hashlib.md5(str(_time())).hexdigest()
_sleep(.5)
print 'Finished running the program. Byeeeeesss!'
if __name__ == '__main__':
sys.argv.append('-sc 5')
main()

0
src/model/__init__.py

BIN
src/model/__init__.pyc

572
src/model/codegen.py

@ -0,0 +1,572 @@
# -*- coding: utf-8 -*-
"""
codegen
~~~~~~~
Extension to ast that allow ast -> python code generation.
:copyright: Copyright 2008 by Armin Ronacher.
:license: BSD.
"""
from ast import *
BOOLOP_SYMBOLS = {
And: 'and',
Or: 'or'
}
BINOP_SYMBOLS = {
Add: '+',
Sub: '-',
Mult: '*',
Div: '/',
FloorDiv: '//',
Mod: '%',
LShift: '<<',
RShift: '>>',
BitOr: '|',
BitAnd: '&',
BitXor: '^'
}
CMPOP_SYMBOLS = {
Eq: '==',
Gt: '>',
GtE: '>=',
In: 'in',
Is: 'is',
IsNot: 'is not',
Lt: '<',
LtE: '<=',
NotEq: '!=',
NotIn: 'not in'
}
UNARYOP_SYMBOLS = {
Invert: '~',
Not: 'not',
UAdd: '+',
USub: '-'
}
ALL_SYMBOLS = {}
ALL_SYMBOLS.update(BOOLOP_SYMBOLS)
ALL_SYMBOLS.update(BINOP_SYMBOLS)
ALL_SYMBOLS.update(CMPOP_SYMBOLS)
ALL_SYMBOLS.update(UNARYOP_SYMBOLS)
def to_source(node, indent_with=' ' * 4, add_line_information=False):
"""This function can convert a node tree back into python sourcecode.
This is useful for debugging purposes, especially if you're dealing with
custom asts not generated by python itself.
It could be that the sourcecode is evaluable when the AST itself is not
compilable / evaluable. The reason for this is that the AST contains some
more data than regular sourcecode does, which is dropped during
conversion.
Each level of indentation is replaced with `indent_with`. Per default this
parameter is equal to four spaces as suggested by PEP 8, but it might be
adjusted to match the application's styleguide.
If `add_line_information` is set to `True` comments for the line numbers
of the nodes are added to the output. This can be used to spot wrong line
number information of statement nodes.
"""
generator = SourceGenerator(indent_with, add_line_information)
generator.visit(node)
return ''.join(generator.result)
class SourceGenerator(NodeVisitor):
"""This visitor is able to transform a well formed syntax tree into python
sourcecode. For more details have a look at the docstring of the
`node_to_source` function.
"""
def __init__(self, indent_with, add_line_information=False):
self.result = []
self.indent_with = indent_with
self.add_line_information = add_line_information
self.indentation = 0
self.new_lines = 0
def write(self, x):
if self.new_lines:
if self.result:
self.result.append('\n' * self.new_lines)
self.result.append(self.indent_with * self.indentation)
self.new_lines = 0
self.result.append(x)
def newline(self, node=None, extra=0):
self.new_lines = max(self.new_lines, 1 + extra)
if node is not None and self.add_line_information:
self.write('# line: %s' % node.lineno)
self.new_lines = 1
def body(self, statements):
self.new_line = True
self.indentation += 1
for stmt in statements:
self.visit(stmt)
self.indentation -= 1
def body_or_else(self, node):
self.body(node.body)
if node.orelse:
self.newline()
self.write('else:')
self.body(node.orelse)
def signature(self, node):
want_comma = []
def write_comma():
if want_comma:
self.write(', ')
else:
want_comma.append(True)
padding = [None] * (len(node.args) - len(node.defaults))
for arg, default in zip(node.args, padding + node.defaults):
write_comma()
self.visit(arg)
if default is not None:
self.write('=')
self.visit(default)
if node.vararg is not None:
write_comma()
self.write('*' + node.vararg)
if node.kwarg is not None:
write_comma()
self.write('**' + node.kwarg)
def decorators(self, node):
for decorator in node.decorator_list:
self.newline(decorator)
self.write('@')
self.visit(decorator)
# Statements
def visit_Assign(self, node):
self.newline(node)
for idx, target in enumerate(node.targets):
if idx:
self.write(', ')
self.visit(target)
self.write(' = ')
self.visit(node.value)
def visit_AugAssign(self, node):
self.newline(node)
self.visit(node.target)
self.write(BINOP_SYMBOLS[type(node.op)] + '=')
self.visit(node.value)
def visit_ImportFrom(self, node):
self.newline(node)
self.write('from %s%s import ' % ('.' * node.level, node.module))
for idx, item in enumerate(node.names):
if idx:
self.write(', ')
self.write(item)
def visit_Import(self, node):
self.newline(node)
for item in node.names:
self.write('import ')
self.visit(item)
def visit_Expr(self, node):
self.newline(node)
self.generic_visit(node)
def visit_FunctionDef(self, node):
self.newline(extra=1)
self.decorators(node)
self.newline(node)
self.write('def %s(' % node.name)
self.signature(node.args)
self.write('):')
self.body(node.body)
def visit_ClassDef(self, node):
have_args = []
def paren_or_comma():
if have_args:
self.write(', ')
else:
have_args.append(True)
self.write('(')
self.newline(extra=2)
self.decorators(node)
self.newline(node)
self.write('class %s' % node.name)
for base in node.bases:
paren_or_comma()
self.visit(base)
# XXX: the if here is used to keep this module compatible
# with python 2.6.
if hasattr(node, 'keywords'):
for keyword in node.keywords:
paren_or_comma()
self.write(keyword.arg + '=')
self.visit(keyword.value)
if node.starargs is not None:
paren_or_comma()
self.write('*')
self.visit(node.starargs)
if node.kwargs is not None:
paren_or_comma()
self.write('**')
self.visit(node.kwargs)
self.write(have_args and '):' or ':')
self.body(node.body)
def visit_If(self, node):
self.newline(node)
self.write('if ')
self.visit(node.test)
self.write(':')
self.body(node.body)
while True:
else_ = node.orelse
if len(else_) == 1 and isinstance(else_[0], If):
node = else_[0]
self.newline()
self.write('elif ')
self.visit(node.test)
self.write(':')
self.body(node.body)
else:
self.newline()
self.write('else:')
self.body(else_)
break
def visit_For(self, node):
self.newline(node)
self.write('for ')
self.visit(node.target)
self.write(' in ')
self.visit(node.iter)
self.write(':')
self.body_or_else(node)
def visit_While(self, node):
self.newline(node)
self.write('while ')
self.visit(node.test)
self.write(':')
self.body_or_else(node)
def visit_With(self, node):
self.newline(node)
self.write('with ')
self.visit(node.context_expr)
if node.optional_vars is not None:
self.write(' as ')
self.visit(node.optional_vars)
self.write(':')
self.body(node.body)
def visit_Pass(self, node):
self.newline(node)
self.write('pass')
def visit_Print(self, node):
# XXX: python 2.6 only
self.newline(node)
self.write('print ')
want_comma = False
if node.dest is not None:
self.write(' >> ')
self.visit(node.dest)
want_comma = True
for value in node.values:
if want_comma:
self.write(', ')
self.visit(value)
want_comma = True
if not node.nl:
self.write(',')
def visit_Delete(self, node):
self.newline(node)
self.write('del ')
for idx, target in enumerate(node):
if idx:
self.write(', ')
self.visit(target)
def visit_TryExcept(self, node):
self.newline(node)
self.write('try:')
self.body(node.body)
for handler in node.handlers:
self.visit(handler)
def visit_TryFinally(self, node):
self.newline(node)
self.write('try:')
self.body(node.body)
self.newline(node)
self.write('finally:')
self.body(node.finalbody)
def visit_Global(self, node):
self.newline(node)
self.write('global ' + ', '.join(node.names))
def visit_Nonlocal(self, node):
self.newline(node)
self.write('nonlocal ' + ', '.join(node.names))
def visit_Return(self, node):
self.newline(node)
self.write('return ')
self.visit(node.value)
def visit_Break(self, node):
self.newline(node)
self.write('break')
def visit_Continue(self, node):
self.newline(node)
self.write('continue')
def visit_Raise(self, node):
# XXX: Python 2.6 / 3.0 compatibility
self.newline(node)
self.write('raise')
if hasattr(node, 'exc') and node.exc is not None:
self.write(' ')
self.visit(node.exc)
if node.cause is not None:
self.write(' from ')
self.visit(node.cause)
elif hasattr(node, 'type') and node.type is not None:
self.visit(node.type)
if node.inst is not None:
self.write(', ')
self.visit(node.inst)
if node.tback is not None:
self.write(', ')
self.visit(node.tback)
# Expressions
def visit_Attribute(self, node):
self.visit(node.value)
self.write('.' + node.attr)
def visit_Call(self, node):
want_comma = []
def write_comma():
if want_comma:
self.write(', ')
else:
want_comma.append(True)
self.visit(node.func)
self.write('(')
for arg in node.args:
write_comma()
self.visit(arg)
for keyword in node.keywords:
write_comma()
self.write(keyword.arg + '=')
self.visit(keyword.value)
if node.starargs is not None:
write_comma()
self.write('*')
self.visit(node.starargs)
if node.kwargs is not None:
write_comma()
self.write('**')
self.visit(node.kwargs)
self.write(')')
def visit_Name(self, node):
self.write(node.id)
def visit_Str(self, node):
self.write(repr(node.s))
def visit_Bytes(self, node):
self.write(repr(node.s))
def visit_Num(self, node):
self.write(repr(node.n))
def visit_Tuple(self, node):
self.write('(')
idx = -1
for idx, item in enumerate(node.elts):
if idx:
self.write(', ')
self.visit(item)
self.write(idx and ')' or ',)')
def sequence_visit(left, right):
def visit(self, node):
self.write(left)
for idx, item in enumerate(node.elts):
if idx:
self.write(', ')
self.visit(item)
self.write(right)
return visit
visit_List = sequence_visit('[', ']')
visit_Set = sequence_visit('{', '}')
del sequence_visit
def visit_Dict(self, node):
self.write('{')
for idx, (key, value) in enumerate(zip(node.keys, node.values)):
if idx:
self.write(', ')
self.visit(key)
self.write(': ')
self.visit(value)
self.write('}')
def visit_BinOp(self, node):
self.visit(node.left)
self.write(' %s ' % BINOP_SYMBOLS[type(node.op)])
self.visit(node.right)
def visit_BoolOp(self, node):
self.write('(')
for idx, value in enumerate(node.values):
if idx:
self.write(' %s ' % BOOLOP_SYMBOLS[type(node.op)])
self.visit(value)
self.write(')')
def visit_Compare(self, node):
self.write('(')
self.write(node.left)
for op, right in zip(node.ops, node.comparators):
self.write(' %s %%' % CMPOP_SYMBOLS[type(op)])
self.visit(right)
self.write(')')
def visit_UnaryOp(self, node):
self.write('(')
op = UNARYOP_SYMBOLS[type(node.op)]
self.write(op)
if op == 'not':
self.write(' ')
self.visit(node.operand)
self.write(')')
def visit_Subscript(self, node):
self.visit(node.value)
self.write('[')
self.visit(node.slice)
self.write(']')
def visit_Slice(self, node):
if node.lower is not None:
self.visit(node.lower)
self.write(':')
if node.upper is not None:
self.visit(node.upper)
if node.step is not None:
self.write(':')
if not (isinstance(node.step, Name) and node.step.id == 'None'):
self.visit(node.step)
def visit_ExtSlice(self, node):
for idx, item in node.dims:
if idx:
self.write(', ')
self.visit(item)
def visit_Yield(self, node):
self.write('yield ')
self.visit(node.value)
def visit_Lambda(self, node):
self.write('lambda ')
self.signature(node.args)
self.write(': ')
self.visit(node.body)
def visit_Ellipsis(self, node):
self.write('Ellipsis')
def generator_visit(left, right):
def visit(self, node):
self.write(left)
self.visit(node.elt)
for comprehension in node.generators:
self.visit(comprehension)
self.write(right)
return visit
visit_ListComp = generator_visit('[', ']')
visit_GeneratorExp = generator_visit('(', ')')
visit_SetComp = generator_visit('{', '}')
del generator_visit
def visit_DictComp(self, node):
self.write('{')
self.visit(node.key)
self.write(': ')
self.visit(node.value)
for comprehension in node.generators:
self.visit(comprehension)
self.write('}')
def visit_IfExp(self, node):
self.visit(node.body)
self.write(' if ')
self.visit(node.test)
self.write(' else ')
self.visit(node.orelse)
def visit_Starred(self, node):
self.write('*')
self.visit(node.value)
def visit_Repr(self, node):
# XXX: python 2.6 only
self.write('`')
self.visit(node.value)
self.write('`')
# Helper Nodes
def visit_alias(self, node):
self.write(node.name)
if node.asname is not None:
self.write(' as ' + node.asname)
def visit_comprehension(self, node):
self.write(' for ')
self.visit(node.target)
self.write(' in ')
self.visit(node.iter)
if node.ifs:
for if_ in node.ifs:
self.write(' if ')
self.visit(if_)
def visit_excepthandler(self, node):
self.newline(node)
self.write('except')
if node.type is not None:
self.write(' ')
self.visit(node.type)
if node.name is not None:
self.write(' as ')
self.visit(node.name)
self.write(':')
self.body(node.body)

BIN
src/model/codegen.pyc

17
src/model/controller.py

@ -0,0 +1,17 @@
'''
Created on Dec 22, 2013
@author: Chris
'''
class Controller(object):
'''
Main controller for the gui.
Serves as a delagation for all of the various buttons/panels/events.
'''
def __init__(self):
pass

BIN
src/model/controller.pyc

141
src/model/example_argparse_souce.py

@ -0,0 +1,141 @@
#!/usr/local/bin/python2.7
# encoding: utf-8
'''
bin.example_argparse_souce -- shortdesc
bin.example_argparse_souce is a description
It defines classes_and_methods
@author: user_name
@copyright: 2013 organization_name. All rights reserved.
@license: license
@contact: user_email
@deffield updated: Updated
'''
import sys
import os
from argparse import ArgumentParser
from argparse import RawDescriptionHelpFormatter
__all__ = []
__version__ = 0.1
__date__ = '2013-12-13'
__updated__ = '2013-12-13'
DEBUG = 1
TESTRUN = 0
PROFILE = 0
class CLIError(Exception):
'''Generic exception to raise and log different fatal errors.'''
def __init__(self, msg):
super(CLIError).__init__(type(self))
self.msg = "E: %s" % msg
def __str__(self):
return self.msg
def __unicode__(self):
return self.msg
def main(argv=None): # IGNORE:C0111
'''Command line options.'''
if argv is None:
argv = sys.argv
else:
sys.argv.extend(argv)
program_name = os.path.basename(sys.argv[0])
program_version = "v%s" % __version__
program_build_date = str(__updated__)
program_version_message = '%%(prog)s %s (%s)' % (program_version, program_build_date)
program_shortdesc = __import__('__main__').__doc__.split("\n")[1]
program_license = '''%s
Created by user_name on %s.
Copyright 2013 organization_name. All rights reserved.
Licensed under the Apache License 2.0
http://www.apache.org/licenses/LICENSE-2.0
Distributed on an "AS IS" basis without warranties
or conditions of any kind, either express or implied.
USAGE
''' % (program_shortdesc, str(__date__))
try:
# Setup argument parser
parser = ArgumentParser(description='Example Argparse Program', formatter_class=RawDescriptionHelpFormatter)
parser.add_argument("filename", help="filename")
parser.add_argument("-r", "--recursive", dest="recurse", action="store_true", help="recurse into subfolders [default: %(default)s]")
parser.add_argument("-v", "--verbose", dest="verbose", action="count", help="set verbosity level [default: %(default)s]")
parser.add_argument("-i", "--include", action="append", help="only include paths matching this regex pattern. Note: exclude is given preference over include. [default: %(default)s]", metavar="RE" )
parser.add_argument("-e", "--exclude", dest="exclude", help="exclude paths matching this regex pattern. [default: %(default)s]", metavar="RE" )
parser.add_argument('-V', '--version', action='version')
parser.add_argument('-T', '--tester', choices=['yes','no'])
parser.add_argument(dest="paths", help="paths to folder(s) with source file(s) [default: %(default)s]", metavar="path", nargs='+')
for i in parser._actions:
print i
# Process arguments
args = parser.parse_args()
paths = args.paths
verbose = args.verbose
recurse = args.recurse
inpat = args.include
expat = args.exclude
if verbose > 0:
print("Verbose mode on")
if recurse:
print("Recursive mode on")
else:
print("Recursive mode off")
if inpat and expat and inpat == expat:
raise CLIError("include and exclude pattern are equal! Nothing will be processed.")
for inpath in paths:
### do something with inpath ###
print(inpath)
return 0
except KeyboardInterrupt:
### handle keyboard interrupt ###
return 0
except Exception, e:
if DEBUG or TESTRUN:
raise(e)
indent = len(program_name) * " "
sys.stderr.write(program_name + ": " + repr(e) + "\n")
sys.stderr.write(indent + " for help use --help")
return 2
if __name__ == "__main__":
if DEBUG:
sys.argv.append("-h")
# sys.argv.append("-v")
sys.argv.append("-r")
main()
sys.exit()
if TESTRUN:
import doctest
doctest.testmod()
if PROFILE:
import cProfile
import pstats
profile_filename = 'bin.example_argparse_souce_profile.txt'
cProfile.run('main()', profile_filename)
statsfile = open("profile_stats.txt", "wb")
p = pstats.Stats(profile_filename, stream=statsfile)
stats = p.strip_dirs().sort_stats('cumulative')
stats.print_stats()
statsfile.close()
sys.exit(0)
sys.exit(main())

56
src/model/gui.py

@ -0,0 +1,56 @@
'''
Created on Dec 9, 2013
@author: Chris
'''
import wx
import sys
import time
import Queue
import datetime
import threading
from app.dialogs.display_main import MainWindow
from app.images import image_store
class MockApplication(threading.Thread):
def __init__(self):
threading.Thread.__init__(self)
self.start_time = time.time()
def run(self):
while time.time() - self.start_time < 5:
print 'printing message at: %s' % time.time()
time.sleep(.5)
print 'Exiting'
def decorator(main_func=None):
def real_decorator(main_func):
def wrapper():
main_func()
return wrapper
if callable(main_func):
return real_decorator(main_func)
return real_decorator
@decorator
def my_func():
print 'inside my_func'
if __name__ == '__main__':
queue = Queue.Queue()
app = wx.App(False)
frame = MainWindow(queue)
frame.Show(True) # Show the frame.
mock = MockApplication()
mock.start()
app.MainLoop()
#

276
src/model/source_parser.py

@ -0,0 +1,276 @@
'''
Created on Dec 11, 2013
@author: Chris
Collection of functions for extracting argparse related statements from the
client code.
'''
import os
import ast
import sys
import random
import codegen
import argparse
import cStringIO
from itertools import chain
from functools import partial
from numpy.lib.utils import _split_line
from argparse import ArgumentParser
from argparse import RawDescriptionHelpFormatter
from app.dialogs.component_factory import ComponentFactory
class ParserError(Exception):
'''Thrown when the parser can't find argparse functions the client code'''
pass
class ParserFromSource(object):
'''
Builds a parser instance from the code
extracted from the client module.
The instance is stored as a private variabel in the
class and all methods are delagted to it so that the
user of the class can treat it just as a normal argparse
instance.
'''
def __init__(self, source_code):
self._parser_instance = self._build_argparser_from_client_source(source_code)
# redirect future getattr requests
# self.__getattr__ = self._delegator
def _build_argparser_from_client_source(self, source_code):
'''
runs the client code by evaling each line.
Example input Code:
parser = ArgumentParser(description=program_license, formatter_class=RawDescriptionHelpFormatter)
parser.add_argument("-r", "--recursive", dest="recurse", action="store_true", help="recurse into subfolders [default: %(default)s]")
parser.add_argument("-v", "--verbose", dest="verbose", action="count", help="set verbosity level [default: %(default)s]")
Method extracts the instance name (e.g. parser) from the first line,
and instantiates it in a local variable by evaling the rest of the lines.
Each subsequent line updates the local variable in turn.
'''
new_source_code = self._format_source_with_new_varname('clients_parser', source_code)
# variable of the same name as the one passed into the format_source method.
# Used to hold the eval'd statements
first_line = new_source_code.pop(0)
clients_parser, assignment = self._split_line(first_line)
clients_parser = eval(assignment)
for line in new_source_code:
eval(line)
return clients_parser
def _format_source_with_new_varname(self, variable_name, source):
'''
'injects' the client code with a known variable name so that it
can be `eval`d and assigned to a variable in the local code.
For example, if the client code was:
parser = ArgumentParser(descrip...)
parser.add_argument("-r", "--re...)
parser.add_argument("-v", "--ve...)
The variable "parser" would be overwritten with a custom name. e.g.
my_parser = ArgumentParser(descrip...)
my_parser.add_argument("-r", "--re...)
'''
source_code = source[:]
first_line = source_code[0]
parser_variable, statement = self._split_line(first_line)
parser_variable = parser_variable.strip()
for index, line in enumerate(source_code):
source_code[index] = line.replace(parser_variable, variable_name)
return source_code
def _split_line(self, line):
# Splits line at the first = sign,
# joins everything after the first =
# to account for additional = signs in
# parameters
components = line.split('=')
var = components.pop(0)
return var, '='.join(components)
def __getattr__(self, attr):
'''
Auto-delegates everything to the ArgumentParser instance'''
return getattr(self._parser_instance, attr)
def parse_source_file(file_name):
'''
Parses the AST of Python file for lines containing
references to the argparse module.
returns the collection of ast objects found.
Example client code:
1. parser = ArgumentParser(desc="My help Message")
2. parser.add_argument('filename', help="Name of the file to load")
3. parser.add_argument('-f', '--format', help='Format of output \nOptions: ['md', 'html']
4. args = parser.parse_args()
Variables:
* nodes Primary syntax tree object
* _mainfunc_block main() method as found in the ast nodes
* _try_blocks Try/except/finally blocks found in the main method
* main_block The code block in which the ArgumentParser statements are located
* argparse_assign_obj The assignment of the ArgumentParser (line 1 in example code)
* parser_nodes Nodes which have parser references (lines 1-4 in example code)
* parser_var_name The instance variable of the ArgumentParser (line 1 in example code)
* ast_source The currated colleciton of all parser related nodes in the client code
'''
nodes = ast.parse(_openfile(file_name))
_mainfunc_block = find_main(nodes)
_try_blocks = find_try_blocks(_mainfunc_block)
search_locations = chain([_mainfunc_block], _try_blocks)
main_block = find_argparse_location(search_locations)
if not main_block:
raise ParserError("Could not locate AugmentParser assignment.")
argparse_assign_obj = [node for node in main_block.body
if has_instantiator(node, 'ArgumentParser')]
parser_nodes = [node for node in main_block.body
if has_assignment(node, 'add_argument')]
ast_source = chain(argparse_assign_obj, parser_nodes)
return ast_source
def find_try_blocks(block):
# Finds all try/catch/finally expressions in a given function block
_types = [ast.TryExcept, ast.TryFinally]
return [node for node in block.body
if any([isinstance(node, x) for x in _types])]
def find_main(nodes):
# Finds main function in the tree
for node in nodes.body:
if isinstance(node, ast.FunctionDef) and node.name == 'main':
return node
raise ParserError('Could not find `def main()`')
def get_assignment_name(node):
# return the variable name to which
# ArgumentParser is assigned
return node.targets[0].id
def _openfile(file_name):
with open(file_name, 'rb') as f:
return f.read()
def find_statement(block, name):
return [node for node in block.body
if has_instantiator(node, name)]
def has_instantiator(x, name):
# Checks if the astObject is one with an
# instantiation of the ArgParse class
try: return x.value.func.id == name
except: return False # Wrong type. Contine.
def has_assignment(x, name):
# Checks if the astObject is contains a
# function with a name of name
try: return x.value.func.attr == name
except: return False # Wrong type. Contine.
def is_found(stmnt):
return len(stmnt)
def has_argparse_assignment(block):
# Checks a given node for presence of an instantiation
argparse_assignment = find_statement(block, 'ArgumentParser')
return is_found(argparse_assignment)
def find_argparse_location(locations):
# Browser a collection of Nodes for the one
# containing the Argparse instantiation
for location in locations:
if has_argparse_assignment(location):
return location
return None
def convert_to_python(ast_source):
return map(codegen.to_source, ast_source)
def generate_doc(f=None, format='html', noob=1, success_msg=1):
'''
Decorator for client code's main function.
It gets the name of the calling script, loads it
into parse_pyfile(), and generates the documentation,
before finally calling the main() function to resume
execution as normal.
'''
# Handles if the passed in object is instance
# of ArgumentParser. If so, it's being called as
# a function, rather than a decorator
if isinstance(f, argparse.ArgumentParser):
filename = sys.argv[0]
build_doc_from_parser_obj(
file_name=filename,
parser_obj=f,
format=format,
noob=noob,
success_msg=success_msg
)
return
# --------------------------------- #
# Below code is all decorator stuff #
# --------------------------------- #
def get_caller_path():
# utility func for decorator
# gets the name of the calling script
tmp_sys = __import__('sys')
return tmp_sys.argv[0]
def generate_docs(f):
def inner():
module_path = get_caller_path()
path = os.path.join(*os.path.split(module_path)[:-1])
filename = '{}'.format(os.path.split(module_path)[-1])
parse_pyfile(filename, format=format, noob=noob, success_msg=success_msg)
inner.__name__ = f.__name__
return inner
if callable(f):
return generate_docs(f)
return generate_docs
if __name__ == '__main__':
ast_source = parse_source_file('example_argparse_souce.py')
python_code = convert_to_python(ast_source)
parser = ParserFromSource(python_code)
factory = ComponentFactory(parser)
#

34
src/model/test_queue.py

@ -0,0 +1,34 @@
'''
Created on Dec 9, 2013
@author: Chris
'''
# import Queue
#
# q = Queue.Queue()
#
# q.get(timeout=5)
class A(object):
def __init__(self):
self.value = 'a'
self.value2 = A.B()
class B(object):
def __init__(self):
self.value = 'asdfasdf'
def asdf(self):
print 'I was called!'
# a = A()
# print a.value
# print a.value2.asdf()
a = 'asdf.now()'
print 'asdf' in a

0
src/parser/MultiChoiceOption.py

0
src/parser/RequiredOption.py

0
src/parser/__init__.py

0
src/parser/asdfasdf.py

0
src/parser/example.py

14
src/parser/option.py

@ -0,0 +1,14 @@
'''
Created on Dec 12, 2013
@author: Chris
'''
# parser.add_argument("-r", "--recursive", dest="recurse", action="store_true", help="recurse into subfolders [default: %(default)s]")
class Option(object):
def __init__(self, arg_option):
self.arg_option = arg_option
@classmethod
def
Loading…
Cancel
Save