Cleanup of TclCommand and migrated a few more commands to new architecture.

This commit is contained in:
Juan Pablo Caram
2016-10-18 11:36:58 -04:00
parent e6f01cc834
commit 261054f1cf
8 changed files with 272 additions and 78 deletions

View File

@@ -12,26 +12,28 @@ class TclCommand(object):
# FlatCAMApp
app = None
# logger
# Logger
log = None
# array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon)
# List of all command aliases, to be able use old names
# for backward compatibility (add_poly, add_polygon)
aliases = []
# dictionary of types from Tcl command, needs to be ordered
# Dictionary of types from Tcl command, needs to be ordered
# OrderedDict should be like collections.OrderedDict([(key,value),(key2,value2)])
arg_names = collections.OrderedDict([
('name', str)
])
# dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value
# dictionary of types from Tcl command, needs to be ordered.
# This is for options like -optionname value.
# OrderedDict should be like collections.OrderedDict([(key,value),(key2,value2)])
option_types = collections.OrderedDict()
# array of mandatory options for current Tcl command: required = {'name','outname'}
# List of mandatory options for current Tcl command: required = {'name','outname'}
required = ['name']
# structured help for current command, args needs to be ordered
# Structured help for current command, args needs to be ordered
# OrderedDict should be like collections.OrderedDict([(key,value),(key2,value2)])
help = {
'main': "undefined help.",
@@ -42,21 +44,27 @@ class TclCommand(object):
'examples': []
}
# original incoming arguments into command
# Original incoming arguments into command
original_args = None
def __init__(self, app):
self.app = app
if self.app is None:
raise TypeError('Expected app to be FlatCAMApp instance.')
if not isinstance(self.app, FlatCAMApp.App):
raise TypeError('Expected FlatCAMApp, got %s.' % type(app))
self.log = self.app.log
def raise_tcl_error(self, text):
"""
this method pass exception from python into TCL as error, so we get stacktrace and reason
this is only redirect to self.app.raise_tcl_error
This method pass exception from python into TCL as error
so we get stacktrace and reason.
This is only redirect to self.app.raise_tcl_error
:param text: text of error
:return: none
"""
@@ -65,14 +73,17 @@ class TclCommand(object):
def get_current_command(self):
"""
get current command, we are not able to get it from TCL we have to reconstruct it
Get current command, we are not able to get it from TCL we have to reconstruct it.
:return: current command
"""
command_string = []
command_string.append(self.aliases[0])
command_string = [self.aliases[0]]
if self.original_args is not None:
for arg in self.original_args:
command_string.append(arg)
return " ".join(command_string)
def get_decorated_help(self):
@@ -83,22 +94,36 @@ class TclCommand(object):
"""
def get_decorated_command(alias_name):
command_string = []
for arg_key, arg_type in self.help['args'].items():
command_string.append(get_decorated_argument(arg_key, arg_type, True))
return "> " + alias_name + " " + " ".join(command_string)
def get_decorated_argument(help_key, help_text, in_command=False):
"""
:param help_key: Name of the argument.
:param help_text:
:param in_command:
:return:
"""
option_symbol = ''
if help_key in self.arg_names:
arg_type = self.arg_names[help_key]
type_name = str(arg_type.__name__)
in_command_name = "<" + type_name + ">"
#in_command_name = help_key + "<" + type_name + ">"
in_command_name = help_key
elif help_key in self.option_types:
option_symbol = '-'
arg_type = self.option_types[help_key]
type_name = str(arg_type.__name__)
in_command_name = option_symbol + help_key + " <" + type_name + ">"
else:
option_symbol = ''
type_name = '?'
@@ -168,7 +193,7 @@ class TclCommand(object):
def check_args(self, args):
"""
Check arguments and options for right types
Check arguments and options for right types
:param args: arguments from tcl to check
:return: named_args, unnamed_args
@@ -214,29 +239,16 @@ class TclCommand(object):
return named_args, unnamed_args
def raise_tcl_unknown_error(self, unknownException):
def raise_tcl_unknown_error(self, unknown_exception):
"""
raise Exception if is different type than TclErrorException
this is here mainly to show unknown errors inside TCL shell console
:param unknownException:
:param unknown_exception:
:return:
"""
#if not isinstance(unknownException, self.TclErrorException):
# self.raise_tcl_error("Unknown error: %s" % str(unknownException))
#else:
raise unknownException
def raise_tcl_error(self, text):
"""
this method pass exception from python into TCL as error, so we get stacktrace and reason
:param text: text of error
:return: raise exception
"""
# becouse of signaling we cannot call error to TCL from here but when task is finished
# also nonsiglaned arwe handled here to better exception handling and diplay after command is finished
raise self.app.TclErrorException(text)
raise unknown_exception
def execute_wrapper(self, *args):
"""
@@ -291,6 +303,10 @@ class TclCommandSignaled(TclCommand):
it handles all neccessary stuff about blocking and passing exeptions
"""
@abc.abstractmethod
def execute(self, args, unnamed_args):
raise NotImplementedError("Please Implement this method")
output = None
def execute_call(self, args, unnamed_args):

View File

@@ -0,0 +1,50 @@
from ObjectCollection import *
import TclCommand
class TclCommandGetSys(TclCommand.TclCommand):
"""
Tcl shell command to get the value of a system variable
example:
get_sys excellon_zeros
"""
# List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon)
aliases = ['get_sys', 'getsys']
# Dictionary of types from Tcl command, needs to be ordered
arg_names = collections.OrderedDict([
('name', str)
])
# Dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value
option_types = collections.OrderedDict([
])
# array of mandatory options for current Tcl command: required = {'name','outname'}
required = ['name']
# structured help for current command, args needs to be ordered
help = {
'main': "Returns the value of the system variable.",
'args': collections.OrderedDict([
('name', 'Name of the system variable.'),
]),
'examples': ['get_sys excellon_zeros']
}
def execute(self, args, unnamed_args):
"""
:param args:
:param unnamed_args:
:return:
"""
name = args['name']
if name in self.app.defaults:
return self.app.defaults[name]

View File

@@ -46,7 +46,7 @@ class TclCommandJoinGeometry(TclCommand.TclCommand):
:return:
"""
outname = args['name']
outname = args['outname']
obj_names = unnamed_args
objs = []

View File

@@ -8,7 +8,7 @@ class TclCommandOpenExcellon(TclCommand.TclCommandSignaled):
"""
# array of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon)
aliases = ['open_gerber']
aliases = ['open_excellon']
# Dictionary of types from Tcl command, needs to be ordered.
# For positional arguments
@@ -45,4 +45,6 @@ class TclCommandOpenExcellon(TclCommand.TclCommandSignaled):
:return: None or exception
"""
self.app.open_excellon(args['filename'], **args)
filename = args.pop('filename')
self.app.open_excellon(filename, **args)

View File

@@ -0,0 +1,73 @@
from ObjectCollection import *
import TclCommand
class TclCommandSetSys(TclCommand.TclCommand):
"""
Tcl shell command to set the value of a system variable
example:
"""
# List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon)
aliases = ['set_sys', 'setsys']
# Dictionary of types from Tcl command, needs to be ordered
arg_names = collections.OrderedDict([
('name', str),
('value', str)
])
# Dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value
option_types = collections.OrderedDict([
])
# array of mandatory options for current Tcl command: required = {'name','outname'}
required = ['name', 'value']
# structured help for current command, args needs to be ordered
help = {
'main': "Sets the value of the system variable.",
'args': collections.OrderedDict([
('name', 'Name of the system variable.'),
('value', 'Value to set.')
]),
'examples': []
}
def execute(self, args, unnamed_args):
"""
:param args:
:param unnamed_args:
:return:
"""
param = args['name']
value = args['value']
# TCL string to python keywords:
tcl2py = {
"None": None,
"none": None,
"false": False,
"False": False,
"true": True,
"True": True
}
if param in self.app.defaults:
try:
value = tcl2py[value]
except KeyError:
pass
self.app.defaults[param] = value
self.app.propagate_defaults()
self.raise_tcl_error("No such system parameter \"{}\".".format(param))

View File

@@ -0,0 +1,47 @@
from ObjectCollection import *
import TclCommand
class TclCommandVersion(TclCommand.TclCommand):
"""
Tcl shell command to check the program version.
example:
"""
# List of all command aliases, to be able use old names for backward compatibility (add_poly, add_polygon)
aliases = ['version']
# Dictionary of types from Tcl command, needs to be ordered
arg_names = collections.OrderedDict([
])
# Dictionary of types from Tcl command, needs to be ordered , this is for options like -optionname value
option_types = collections.OrderedDict([
])
# array of mandatory options for current Tcl command: required = {'name','outname'}
required = []
# structured help for current command, args needs to be ordered
help = {
'main': "Checks the program version.",
'args': collections.OrderedDict([
]),
'examples': []
}
def execute(self, args, unnamed_args):
"""
:param args:
:param unnamed_args:
:return:
"""
self.app.version_check()

View File

@@ -19,6 +19,7 @@ import tclCommands.TclCommandExteriors
import tclCommands.TclCommandGeoCutout
import tclCommands.TclCommandGeoUnion
import tclCommands.TclCommandGetNames
import tclCommands.TclCommandGetSys
import tclCommands.TclCommandImportSvg
import tclCommands.TclCommandInteriors
import tclCommands.TclCommandIsolate
@@ -40,8 +41,10 @@ import tclCommands.TclCommandPlot
import tclCommands.TclCommandSaveProject
import tclCommands.TclCommandScale
import tclCommands.TclCommandSetActive
import tclCommands.TclCommandSetSys
import tclCommands.TclCommandSubtractPoly
import tclCommands.TclCommandSubtractRectangle
import tclCommands.TclCommandVersion
import tclCommands.TclCommandWriteGCode
@@ -65,7 +68,7 @@ def register_all_commands(app, commands):
I have no enough knowledge about python's anatomy. Would be nice to include all classes which are descendant etc.
:param app: FlatCAMApp
:param commands: array of commands which should be modified
:param commands: List of commands being updated
:return: None
"""