def generate(diagram_name, output_dir, sd_context): generated_files = gen_plantuml.generate(diagram_name, output_dir, sd_context) puml_path = generated_files[0] png_path = os.path.join(output_dir, diagram_name + '.png') if plantuml.PlantUML().processes_file(puml_path, png_path): generated_files.append(png_path) return generated_files
def generate(diagram_name, output_dir, sd_context, options=None): server_url = options.get('server_url', DEFAULT_SERVER_URL) generated_files = gen_plantuml.generate(diagram_name, output_dir, sd_context, options) puml_path = generated_files[0] png_path = os.path.join(output_dir, diagram_name + '.png') if plantuml.PlantUML(server_url).processes_file(puml_path, png_path): generated_files.append(png_path) return generated_files
def write_svg(self): """ Returns PUML from the system as a SVG image. Requires plantuml library. """ import plantuml puml = self.write_puml() server = plantuml.PlantUML(url=self.url) svg = server.processes(puml) return svg
def generate_state_diagram(self, file="default-state-diagram.txt"): """Outputs a png file relaying the state diagram, starting from the node the function was called from""" self.update_probabilities() with open(file, "w") as f: f.write("@startuml\n") f.write("hide empty description\n") print(self, file=f) f.write("@enduml") puml = plantuml.PlantUML("http://www.plantuml.com/plantuml/img/") puml.processes_file(file)
def generate_eM_diagram(self, file="default-em-diagram.txt"): with open(file, "w") as f: f.write("@startuml\n") f.write("hide empty description\n") for start, branches in self.transitions.items(): for end, prob in branches.items(): print(f"({start}) --> ({end}) : {prob}\n", file=f) f.write("@enduml") puml = plantuml.PlantUML("http://www.plantuml.com/plantuml/img/") puml.processes_file(file) pass
def closeuml(): ''' Closes plantuml diagram syntax and tries to generate the image. Intended to be called on program exit ''' LOGGER.info("@enduml") try: import plantuml LOGGER.debug("Generating image at %s.png" % MAIN_FILE_NAME) plantuml.PlantUML().processes_file('%s.log' % MAIN_FILE_NAME, outfile='%s.png' % MAIN_FILE_NAME) except Exception, captured_except: LOGGER.debug('Unable to generate image file') LOGGER.debug(captured_except)
def generate_plantuml(self, activities): """ Generate a PlantUML File from a tasks array. """ from .puml_templates import puml_template from .puml_templates import skinparam_template rendered = Template(puml_template).render( skinparam=skinparam_template, activities=activities) plantUML = plantuml.PlantUML( url="http://www.plantuml.com/plantuml/png/") url = plantUML.get_url(plantuml_text=rendered) with open(self.destination, "w") as f: f.write(rendered) print(url)
def main(): """ This function calls get_info() in order to get a dictionary with everything it needs. After printing that dictionary, using the PlantUML library, it creates a new UML diagram. For every image in the running directory, the function adds the paths to to_concat array and then calls concat_images with all those paths. :return: it creates uml_no images with a single UML diagram per image, then it calls concat_images >> main() """ unique = str(time.time()) info = get_info() print(info) to_concat = [] uml = plantuml.PlantUML() uml_no = 0 for d in info: retry = 0 uml_no += 1 file_name = (str(uml_no) + '-' + unique + '.png') while True: if retry == 3: print "Can't get image after 3 tries. Will try with the next image..." break with open(file_name, 'wb') as out: try: out.write(uml.processes(dict2uml.dict2plantuml(d))) break except: retry += 1 if os.path.isfile(file_name): to_concat += [file_name] if len(to_concat) is 0: print "No images found." print "Folder may be empty." exit() concat_images(to_concat, unique)
def run(self, lines): try: import plantuml except: print("WARNING: Plantuml not installed for this python version: ext.uml disabled.") return lines text = '\n'.join(lines) pat = re.compile(UML_RE, re.DOTALL|re.M) ms = pat.findall(text) if not ms: return lines puml = plantuml.PlantUML(**self.config) for m in ms: uml = m[1] url = puml.get_url(uml) text = pat.sub('<img src="%s"/>'%(url), text, 1) return text.split('\n')
import requests import os.path import plantuml # PLANTUML_RELEASE_URL = 'https://github.com/plantuml/plantuml/releases/download/v1.2021.14/plantuml-1.2021.14.jar' # PLANTUML_JAR = 'plantuml.jar' # if os.path.isfile(PLANTUML_JAR) is False: # r = requests.get(PLANTUML_RELEASE_URL, allow_redirects=True) # open(PLANTUML_JAR, 'wb').write(r.content) # stream = os.popen('/usr/libexec/java_home -v11 plantuml.jar "./**.puml"') # output = stream.read() puml = plantuml.PlantUML(url='http://www.plantuml.com/plantuml/img/') for file in os.listdir("./"): if file.endswith(".puml"): input_file = file output_file = "../images/" + file.replace(".puml", ".png") puml.processes_file(input_file, output_file) print("Diagram", output_file, "is generated")
def setUp(self): self.url = self.computer_partition.getConnectionParameterDict()["url"] self.plantuml = plantuml.PlantUML( url='{}/png/'.format(self.url), http_opts={"disable_ssl_certificate_validation": True})
def calc(): puml = plantuml.PlantUML('{}/{}/'.format(server, mode)) response = requests.get(puml.get_url(puml_input)) response.raise_for_status() return response.content
1:line.find(")")].replace( ',', '')) implementation = ( line[line.find("class") + len("class") + 1:line.find("(")].replace(',', '')) implementations.append(implementation) for name in implementations: if name in found_list: pass else: impl_dict = {inherits: temp_dict} found_list.append(name) relations.append(impl_dict) else: relations.append(temp_dict) found_list.append(class_line) return relations if __name__ == "__main__": info = get_info() print(info) uml = plantuml.PlantUML() uml_no = 0 for d in info: uml_no += 1 file_name = (str(uml_no) + '.png') with open(file_name, 'wb') as out: out.write(uml.processes(dict2uml.dict2plantuml(d)))
f.write("@enduml") f.close() # modify public, private, protected symbols replace_in_file(output_file, "private", "-") replace_in_file(output_file, "protected", "#") replace_in_file(output_file, "public", "~") def insert_legend(): image = Image.open("uml_diagram.png") legend = Image.open("uml_legend.png") legend = legend.resize( (int(legend.size[0] * 0.3), int(legend.size[1] * 0.3))) image_copy = image.copy() position = ((image_copy.width - legend.width), (image_copy.height - legend.height)) image.paste(legend, position) #Saved in the same relative location image.save("uml_diagram.png") plantuml = plantuml.PlantUML("http://www.plantuml.com/plantuml/img/") plantuml.processes_file("./uml_output.txt", "./uml_diagram.png") insert_legend()
def main(args): # -> None: # Globals global UsedEntities_df global Entities global MaxLevel if args.debug: print("args:", args) if (args.inputType == "excel"): InputFile = args.excelfile else: print("ERROR: Currently only Excel input are allowed.") exitGrapher(1) OutputFile = args.outputfile EntitiesHDR = 0 RelationsHDR = 0 TypesHDR = 0 scale = "scale max 1800 width" #MaxLevel=0 MaxLevel = args.LimitMaxLevel if (args.createcopy): # We make a copy of the file to ensure we have access to it. command = "echo F|xcopy /Q /Y /F \"" + InputFile + "\" \"" + args.copyFileName + "\"" if args.debug: print('command:', command) result = os.system(command) if args.debug: print('result:', result) InputFile = args.copyFileName Entities = "" Dependencies = "" containerList = [] prioritisedContainers = [] # define Python user-defined exceptions class Error(Exception): """Base class for other exceptions""" pass class CircularReferenceError(Error): """Raised when a circular reference has been detected""" pass def populateChildren(prioritisedEntities, currentEntity, currentLevel): """This is a recursive function to populate the list with the children of a container""" global MaxLevel global UsedEntities_df if (MaxLevel == 0 or MaxLevel > currentLevel): currentLevel = currentLevel + 1 # First populate current Entity in list of prioritised entities if args.debug: print('currentEntity: ', currentEntity) #print('Level', currentLevel, ' - currentEntityName: ',currentEntity[1]['EntityName']) prioritisedEntities = prioritisedEntities.append( { 'EntityName': currentEntity[1]['EntityName'], 'Type': currentEntity[1]['Type'], 'Container': currentEntity[1]['Container'], 'Description': currentEntity[1]['Description'], 'OptionalDescription': currentEntity[1]['OptionalDescription'], 'ShowOptional': currentEntity[1]['ShowOptional'], 'Level': currentLevel }, ignore_index=True) # Also populate current Entity in Entities string for UML global Entities Entities = Entities + "state " + currentEntity[1]['EntityName'] if (pd.notna(currentEntity[1]['Type'])): Entities = Entities + "<<" + currentEntity[1]['Type'] + ">>" Entities = Entities + " { \n" if (pd.notna(currentEntity[1]['Description'])): Entities = Entities + currentEntity[1][ 'EntityName'] + " : " + currentEntity[1][ 'Description'] + "\n" if (pd.notna(currentEntity[1]['ShowOptional'])): showOptional = (currentEntity[1]['ShowOptional'] != "N") else: showOptional = True if (showOptional and pd.notna(currentEntity[1]['OptionalDescription'])): Entities = Entities + currentEntity[1][ 'EntityName'] + " : " + currentEntity[1][ 'OptionalDescription'] + "\n" # Get list of children and loop through them currentEntityName = currentEntity[1]['EntityName'] with warnings.catch_warnings(): warnings.simplefilter(action='ignore', category=FutureWarning) childEntities = (UsedEntities_df.loc[ UsedEntities_df['Container'] == currentEntityName]) if args.debug: print('Level', currentLevel, ' - childEntities: ', childEntities) # Only add children if needed for childEntity in childEntities.iterrows(): prioritisedEntities = populateChildren(prioritisedEntities, childEntity, currentLevel) Entities = Entities + "}\n" else: if args.debug: print("INFO: Not adding children below level ", currentLevel) return prioritisedEntities skinparam = "skinparam state { \n" legend = "state Legend { \n" # ToDo: Add options to load from CSV file or from database. try: excel_types_df = pd.read_excel( InputFile, sheet_name='Types', header=TypesHDR, usecols=['Type', 'Description', 'HTML_Color'], engine='xlrd') except ValueError as e: print("ERROR: Reading the TYPE definitions failed: ", e) exitGrapher(2) except PermissionError as e: print("ERROR: ", e) print("Maybe try the -c option to make a copy.") exitGrapher(3) try: excel_entities_df = pd.read_excel(InputFile, sheet_name='Entities', header=EntitiesHDR, usecols=[ 'EntityName', 'Type', 'Container', 'Description', 'OptionalDescription', 'ShowOptional', 'Special' ]) except ValueError as e: print("ERROR: Reading the ENTITY definitions failed: ", e) exitGrapher(4) except PermissionError as e: print("ERROR: ", e) print("Maybe try the -c option to make a copy.") exitGrapher(5) try: excel_dependencies_df = pd.read_excel( InputFile, sheet_name='Relationships', header=RelationsHDR, usecols=['Entity', 'Dependency', 'Description']) except ValueError as e: print("ERROR: Reading the RELATIONSHIP definitions failed: ", e) exitGrapher(6) except PermissionError as e: print("ERROR: ", e) print("Maybe try the -c option to make a copy.") exitGrapher(7) #Step 1: Get list of all types (First from types used by Entities and then properties defined by Types sheet) UsedTypes = pd.DataFrame( excel_entities_df)['Type'].dropna().unique().tolist() if args.debug: print("Typelist: ", UsedTypes) DefinedTypes = pd.DataFrame( excel_types_df)['Type'].dropna().str.strip().unique().tolist() for usedType in UsedTypes: for index, row in excel_types_df.loc[excel_types_df['Type'] == usedType].iterrows(): #Add type to skinparam skinparam = skinparam + " backgroundColor<<" + row[ 'Type'] + ">> " + row['HTML_Color'] + " \n" #Add type to legend legend = legend + "state " + row['Type'] + "<<" + row[ 'Type'] + ">> { \n" + " " + row['Type'] + " : " + row[ 'Description'] + "\n } \n" #Finally add closing part of skinparam and legend skinparam = skinparam + "} \n" legend = legend + "state Undefined { \n Undefined: This type is not defined \n } \n}" #Step 2: #containerList = pd.DataFrame(excel_entities_df)['Container'].dropna().str.strip().unique().tolist() #Step 3: # Build list of Entities without containers. This will be our driver for outside loop # For each entity build a list of dependant entities and loop through - Do recursively # Add check for circular reference UsedEntities_df = excel_entities_df.loc[ excel_entities_df['EntityName'].notnull()] if (len(UsedEntities_df.index) == 0): print( "ERROR: No Entities defined. Define at least the starting Entity.") exitGrapher(8) # Add the containers to the UsedEntities_df if not there already. UsedContainers = pd.DataFrame( excel_entities_df)['Container'].dropna().unique().tolist() for container in UsedContainers: if args.debug: print("container: ", container) #if ( excel_entities_df.loc[excel_entities_df['EntityName'] == container ].count() == 0): #Check if container is defined as entity. If not add it. if ((excel_entities_df.loc[excel_entities_df['EntityName'] == container]).empty ): #Check if container is defined as entity. If not add it. # Add the container to the UsedEntities_df if args.debug: print("Adding container: ", container) UsedEntities_df = UsedEntities_df.append( { 'EntityName': container, 'Type': pd.NA, 'Container': pd.NA, 'Description': pd.NA, 'OptionalDescription': pd.NA, 'ShowOptional': pd.NA, 'Special': pd.NA }, ignore_index=True) if args.debug: print("UsedEntities: ", UsedEntities_df) topLevelEntities = UsedEntities_df.loc[ UsedEntities_df['Container'].isnull()] #UsedEntities = pd.DataFrame(excel_entities_df)['EntityName'].dropna().str.strip().unique().tolist() if args.debug: print("topLevelEntities: ", topLevelEntities) prioritisedEntities = pd.DataFrame(columns=[ 'EntityName', 'Type', 'Container', 'Description', 'OptionalDescription', 'ShowOptional', 'Level' ]) # ToDo: Filter by entity/entities must be done in this next loop for Entity in topLevelEntities.iterrows(): #print("usedEntity: ",usedEntity) prioritisedEntities = populateChildren(prioritisedEntities, Entity, 0) #for index, curEntity in excel_entities_df.loc[excel_entities_df['Container'].isnull()].iterrows(): # print("curEntity: ",curEntity) if args.debug: print("prioritisedEntities:", prioritisedEntities) # Step 4: Now add the dependencies # ToDo: Only add dependencies as needed. UsedDependencies_df = excel_dependencies_df.loc[ excel_dependencies_df['Entity'].notnull()] for index, Dependency in UsedDependencies_df.iterrows(): # Only add dependency to output if either entity or dependency is in prioritisedEntities if ((not (prioritisedEntities.loc[prioritisedEntities['EntityName'] == Dependency['Entity']]).empty) or (not (prioritisedEntities.loc[prioritisedEntities['EntityName'] == Dependency['Dependency']]).empty)): if args.debug: print("test:", Dependency['Entity']) if (pd.isna(Dependency['Dependency'])): Dependencies = Dependencies + "[*]" else: Dependencies = Dependencies + Dependency['Dependency'] Dependencies = Dependencies + " --> " + Dependency['Entity'] if (pd.notna(Dependency['Description'])): Dependencies = Dependencies + " : " + Dependency['Description'] Dependencies = Dependencies + "\n" try: plantUMLText = scale + "\n" + skinparam + "\n" + legend + "\n" + Entities + "\n" + Dependencies + "\n" #plantUMLText=scale+"\n"+skinparam+"\n"+Entities+"\n"+Dependencies+"\n" print('plantUMLText=<{}>'.format(plantUMLText)) callPlantUML = plantuml.PlantUML(url=args.server) img = callPlantUML.processes(plantUMLText) f = open(OutputFile, "wb") f.write(img) f.close() except plantuml.PlantUMLConnectionError: print("ERROR: Error connecting or talking to PlantUML Server") except plantuml.PlantUMLHTTPError: print("ERROR: Request to PlantUML server returned HTTP Error.") except plantuml.PlantUMLError: print("ERROR: The generated code is incorrect") except: raise Exception