def do_enable_statistics(self, args): """ Enabled statistics collection Author: Jake Reddock Syntax: enable_statistics """ self.statistics = StatisticsCreator("statistics") self.statistics.create_tables() print("Statistics collecting is turned on")
def test_statistics_creator_create_tables(self): """ Is the table needed for storing data being created? Author: Jake """ statistics = StatisticsCreator("UnitTest") statistics.create_tables() self.assertEqual(statistics.db.query("""SELECT name FROM sqlite_master WHERE type='table' AND name='ClassData';""").fetch()[0]['name'], "ClassData")
def process_class(self, some_class): # Process the found class, and store in global modules # Find any functions with-in the class name = some_class.__name__ module_name = some_class.__module__ # create module for current file in global modules list if module_name not in self.modules: self.modules[module_name] = list() super_classes = [] super_classes_names = [] # Only creates class_nodes that have unique name, stops duplicate class_nodes # Strips any random objects, only leaves proper class names for class_object in some_class.__bases__: if class_object.__name__ != 'object': if class_object.__name__ not in super_classes_names: super_classes.append(class_object) super_classes_names.append(class_object.__name__) # create class node and append to current module class_node = ClassNode(name, super_classes) self.modules[module_name].append(class_node) # create list of functions in class for (name, something) in inspect.getmembers(some_class): if inspect.ismethod(something) or inspect.isfunction(something): # get the class from the functions element function_class = something.__qualname__.split('.')[0] # only add function if the current class is the same as the # selected functions class if some_class.__name__ == function_class: # create list of attributes in class with constructor if something.__name__ == "__init__": attributes = something.__code__.co_names for attribute in attributes: self.process_attribute( attribute, class_node, self.get_visibility_of_string(attribute)) self.process_function( something, class_node, self.get_visibility_of_string(something.__name__)) # Edited By Jake statistics = StatisticsCreator("statistics") statistics.insert_class(class_node)
def parse_arguments(self): # Create Logic for your arguments here # Created by Jake if self.args.statistics: self.statistics = StatisticsCreator("statistics") self.statistics.create_tables() print("Statistics collecting is turned on") # Created by Braeden if self.args.file is not None: self.files = self.args.file print("Files selected: ") print(*self.files, sep="\n") # Created by Michael Huang if self.args.output is not None: self.output = self.args.output print("Now setting names of output files")
def test_statistics_creator(self): """ Is the database being created when the class is created? Author: Jake """ statistics = StatisticsCreator("UnitTest") self.assertIsNotNone(statistics.db.conn)
def test_statistics_creator_retrieve_class(self): """ Can class data be fetched from the database? Author: Jake """ classnode = ClassNode("TestName") classnode.add_attribute("AttributeOne", "+") classnode.add_function("FunctionOne", "AParameter", "+") statistics = StatisticsCreator("UnitTest") statistics.create_tables() statistics.insert_class(classnode) self.assertEqual(statistics.get_class_data()[0].class_name, 'TestName')
def test_statistics_creator_insert_class(self): """ Can class data be inserted into the database? Author: Jake """ classnode = ClassNode("TestName") classnode.add_attribute("AttributeOne", "+") classnode.add_function("FunctionOne", "AParameter", "+") statistics = StatisticsCreator("UnitTest") statistics.create_tables() statistics.insert_class(classnode) result = statistics.db.query("""SELECT className FROM ClassData WHERE className='TestName'""") self.assertEqual(result.fetch()[0]['className'], "TestName")
class Controller(Cmd): def __init__(self): Cmd.__init__(self) # Command line argument variables self.files = None self.statistics = None self.extracted_modules = None self.output = None self.args = self.register_arguments() self.parse_arguments() self.prompt = '> ' # Created By Jake def run_console(self): self.cmdloop('Starting prompt...\n' 'Type "help" for commands') # Created by Jake def register_arguments(self): # Create your commands in here parser = argparse.ArgumentParser() # Created by Braeden parser.add_argument("-f", "--file", nargs="+", help="Multiple file input for parse") # Created By Jake Reddock parser.add_argument("-s", "--statistics", action='store_true', help="Print Statistics for classes uploaded") # Created By Michael Huang parser.add_argument("-o", "--output", help="Setting name of the output location") return parser.parse_args() # Created By Jake Reddock def parse_arguments(self): # Create Logic for your arguments here # Created by Jake if self.args.statistics: self.statistics = StatisticsCreator("statistics") self.statistics.create_tables() print("Statistics collecting is turned on") # Created by Braeden if self.args.file is not None: self.files = self.args.file print("Files selected: ") print(*self.files, sep="\n") # Created by Michael Huang if self.args.output is not None: self.output = self.args.output print("Now setting names of output files") def do_enable_statistics(self, args): """ Enabled statistics collection Author: Jake Reddock Syntax: enable_statistics """ self.statistics = StatisticsCreator("statistics") self.statistics.create_tables() print("Statistics collecting is turned on") def do_show_statistics(self, args): """ Show statistics about the analysed classes Author: Jake Reddock Syntax: show_statistics Requires: enable_statistics, output_to_dot """ if self.statistics is not None: if self.extracted_modules is not None: print("Creating graph, please wait...") self.statistics.show_graph_data() else: print("Please run the \"output_to_dot\" to command") else: print( "Statistics collecting is not enabled, type \"enable_statistics\" to enable" ) def do_change_python_files(self, args): """ Change input files that are to be parsed by system Author: Braeden Syntax: change_python_files <filenames.py> """ user_args = args.split() if len(user_args) > 0: self.files = [args] else: print("Syntax Error: change_python_files <filenames.py>") # Edited By Jake def do_output_to_dot(self, args): """ Parse and output the file into a UML diagram Author: Braeden Syntax: output_to_dot [-a|-m] [-a] Hides all attributes on class diagram [-m] Hides all methods on class diagram """ user_options = args.split() hide_attributes = False hide_methods = False if len(user_options) > 0: if "-a" in user_options: hide_attributes = True if "-m" in user_options: hide_methods = True self.run_parser(self, hide_attributes, hide_methods) def do_set_input_file(self, args): """ Sets the input file that will be converted into a UML diagram. Author: Jake Reddock Syntax: set_input_file [file_name] """ if len(args) == 0: root = Tk() self.files = filedialog.askopenfilenames( initialdir="C:/", title="Select Input File", filetypes=(("Python Files", "*.py"), ("all files", "*.*"))) root.withdraw() else: self.files = [args] if self.files == "": print("No input file selected.") else: print("Input file selected:") print(*self.files, sep="\n") # Created by Michael Huang def do_output_to_file(self, args): """ Sets the output of the class diagram to a file location. Author: Michael Huang Syntax: output_to_file output_to_file [path] """ from shutil import copyfile if len(args) == 0: root = Tk() root.filename = filedialog.askdirectory() print(root.filename) root.withdraw() copyfile('tmp/class.png', root.filename + '/class.png') else: try: copyfile('tmp/class.png', args + '/class.png') print('The output to the file destination was successful.') except FileNotFoundError as f: print('Failed to find a file: %s' % f) print('Please specify a valid file path.') except: print('Unexpected error has occurred.') @staticmethod def do_output_to_png(args): """ Converts dot file into PNG Author: Braeden """ return call(['dot', '-Tpng', 'tmp/class.dot', '-o', 'tmp/class.png']) # Edited by Jake @staticmethod def run_parser(self, hide_attributes, hide_methods): if len(self.files) > 0: # Initiate processor processor = model.FileProcessor() processor.process_files(self.files) self.extracted_modules = processor.get_modules() new_uml = uml_out.MakeUML(hide_attributes, hide_methods) return new_uml.create_class_diagram(self.extracted_modules) else: print("Error: No files were set, use command change_python_files") def do_validate_py(self, args): ''' Validates a single file as executable python code. Author: Peter ''' files = [] if type(args) == str: files.append(args) elif type(args) == list: files = args check_code = validate.CodeValidator() validated_file = check_code.validate_files(files) def do_save_to_csv(self, params): ''' Saves specified file to csv. [command_line] input_file output_file Author: Peter ''' # print(params, type(params)) input_file = [] if params == '': params = 'plants.py output.csv' args = params.split(' ') # print(args) if len(args) >= 1: input_file.append(args[0]) output_file = 'output.csv' if len(args) >= 2: output_file = args[1] if input_file[0].endswith('.py'): fileprocessor = model.FileProcessor() fileprocessor.process_files(input_file) modules = fileprocessor.get_modules() # print(modules) csv_writer = csv.CSV_handler() if csv_writer.write_csv_file(modules, output_file): print('File successfully saved as {}'.format(output_file)) def do_load_csv_for_uml(self, params): ''' Loads csv file and creates UML diagram [command line] [file.csv] Author: Peter ''' if params == '': params = 'output.csv' args = params.split(' ') print(args) if len(args) >= 1: input_file = args[0] if input_file.endswith('.csv'): csvloader = csv.CSV_handler() module = csvloader.open_file(input_file) makediagram = uml_out.MakeUML(True, True) if makediagram.create_class_diagram(module): print("{} successfully converted to UML class diagram".format( input_file)) def do_pickle_modules(self, filename='plants.py'): ''' Load modules from single file and save them using pickle Author: Peter Command: pickle_modules filename eg pickle_modules plants.py ''' file = [filename] parser = model.FileProcessor() parser.process_files(file) modules = parser.get_modules() pickler = pickle_modules.PickleModules() return pickler.save(modules) def load_pickle(self): ''' Loads previously saved module using pickle Author: Peter Command: load_pickle ''' pickler = pickle_modules.PickleModules() return pickler.load() def do_quit(self, other): ''' Quits programme. Author: Peter ''' print("Goodbye ......") return True