Merge pull request 'table-generator: додав підтримку автоматичної конвертації use-case-файлів у Activity-діаграми (додаток до лаб. роботи №3)' (#36) from shmuliar-use-case into master
Reviewed-on: hasslesstech/edu-dis-labs#36 Reviewed-by: Rhinemann <andreyfrog26@gmail.com> Reviewed-by: IO-23 Andrii Bodnar <bodnarandrew123@gmail.com>
This commit is contained in:
		
						commit
						61f9f6e5e0
					
				
							
								
								
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -106,3 +106,5 @@ dist
 | 
				
			|||||||
# utils/table-generator generated files
 | 
					# utils/table-generator generated files
 | 
				
			||||||
utils/table-generator/tables/
 | 
					utils/table-generator/tables/
 | 
				
			||||||
utils/table-generator/tables.md
 | 
					utils/table-generator/tables.md
 | 
				
			||||||
 | 
					utils/table-generator/activities/
 | 
				
			||||||
 | 
					utils/table-generator/activities.md
 | 
				
			||||||
 | 
				
			|||||||
@ -34,6 +34,27 @@ def convert_usecase_v1(filename, data):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    return generate_table(merged_lines)
 | 
					    return generate_table(merged_lines)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def convert_activity_v1(filename, data):
 | 
				
			||||||
 | 
					    split_raw_lines_from_file = [i.split(" | ") for i in data.split("\n") if i]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if '/' in filename:
 | 
				
			||||||
 | 
					        use_case_name = filename.rsplit("/", 1)[1].upper()
 | 
				
			||||||
 | 
					    elif '\\' in filename:
 | 
				
			||||||
 | 
					        use_case_name = filename.rsplit("\\", 1)[1].upper()
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        use_case_name = filename.upper()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    split_raw_lines = [["ID", use_case_name]] + split_raw_lines_from_file
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    merged_lines = []
 | 
				
			||||||
 | 
					    for i in split_raw_lines:
 | 
				
			||||||
 | 
					        if i[0].replace(" ", "") == "":
 | 
				
			||||||
 | 
					            merged_lines[-1][1] += "<br>" + i[1]
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            merged_lines.append(i)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return generate_table_with_activity_diagram(merged_lines)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def generate_table(raw_table_data):
 | 
					def generate_table(raw_table_data):
 | 
				
			||||||
    table_lines = raw_table_data
 | 
					    table_lines = raw_table_data
 | 
				
			||||||
    transposed_table = list(zip(*table_lines))
 | 
					    transposed_table = list(zip(*table_lines))
 | 
				
			||||||
@ -60,15 +81,101 @@ def generate_table(raw_table_data):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    return "\n".join(formatted_table_lines)
 | 
					    return "\n".join(formatted_table_lines)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def convert_line_to_activity_diagram(line):
 | 
				
			||||||
 | 
					    split_line = line[1].split("<br>")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    result = "@startuml\n    %PLACEHOLDER%\nstop\n@enduml"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    last_swimline_name = ""
 | 
				
			||||||
 | 
					    initiator_name = ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for i in split_line:
 | 
				
			||||||
 | 
					        clear_line = i.lstrip("1234567890. ")
 | 
				
			||||||
 | 
					        swimline_label, combined_action = clear_line.split(" ", 1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        action_and_exceptions = combined_action.split(" (")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if len(action_and_exceptions) > 1:
 | 
				
			||||||
 | 
					            action = action_and_exceptions[0].strip().capitalize()
 | 
				
			||||||
 | 
					            exceptions = action_and_exceptions[1].strip(") ").capitalize()
 | 
				
			||||||
 | 
					        else:
 | 
				
			||||||
 | 
					            action = action_and_exceptions[0].strip().capitalize()
 | 
				
			||||||
 | 
					            exceptions = ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # запам'ятовуємо назву користувача системи
 | 
				
			||||||
 | 
					        # (він завжди починає взаємодію, а, отже,
 | 
				
			||||||
 | 
					        # перша дія завжди належить йому)
 | 
				
			||||||
 | 
					        if not initiator_name:
 | 
				
			||||||
 | 
					            initiator_name = swimline_label
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # змінюємо swinline, якщо керування перейшло до іншого актора
 | 
				
			||||||
 | 
					        if last_swimline_name != swimline_label:
 | 
				
			||||||
 | 
					            result = result.replace("%PLACEHOLDER%", f"|{swimline_label}|\n    %PLACEHOLDER%")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # якщо це перша дія, то вказуємо start
 | 
				
			||||||
 | 
					            if not last_swimline_name:
 | 
				
			||||||
 | 
					                result = result.replace("%PLACEHOLDER%", f"start\n    %PLACEHOLDER%")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # зберігаємо нове ім'я актора
 | 
				
			||||||
 | 
					            last_swimline_name = swimline_label
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # прописуємо поточну дію актора
 | 
				
			||||||
 | 
					        result = result.replace("%PLACEHOLDER%", f": {action};\n    %PLACEHOLDER%")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # якщо є виключні ситуації, додаємо інформацію про них
 | 
				
			||||||
 | 
					        if exceptions:
 | 
				
			||||||
 | 
					            result = result.replace("%PLACEHOLDER%", f"note right #lightpink\n        <b>{exceptions}</b>\n    end note\n    %PLACEHOLDER%")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # впенюємося, що взаємодія закінчується на swinline користувача
 | 
				
			||||||
 | 
					    if last_swimline_name != initiator_name:
 | 
				
			||||||
 | 
					        result = result.replace("%PLACEHOLDER%", f"|{initiator_name}|\n    %PLACEHOLDER%")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    # видаляємо мітку %PLACEHOLDER%
 | 
				
			||||||
 | 
					    result = result.replace("%PLACEHOLDER%\n", "")
 | 
				
			||||||
 | 
					    return result
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def generate_table_with_activity_diagram(raw_table_data):
 | 
				
			||||||
 | 
					    table_lines = raw_table_data[:-1]
 | 
				
			||||||
 | 
					    activity_line = raw_table_data[-1]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    transposed_table = list(zip(*table_lines))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    field_sizes = [max([max([len(k)+2 for k in j.split("\n")]) for j in i]) for i in transposed_table]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    formatted_table_lines = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    l = "|"
 | 
				
			||||||
 | 
					    for i, field in enumerate(table_lines[0]):
 | 
				
			||||||
 | 
					        l += field.center(field_sizes[i])
 | 
				
			||||||
 | 
					        l += "|"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    formatted_table_lines.append(l)
 | 
				
			||||||
 | 
					    formatted_table_lines.append(f"|{'|'.join([':'+'-'*(i-2)+':' for i in field_sizes])}|")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for line in table_lines[1:]:
 | 
				
			||||||
 | 
					        l = "|"
 | 
				
			||||||
 | 
					        for i, field in enumerate(line):
 | 
				
			||||||
 | 
					            l += field.center(field_sizes[i])
 | 
				
			||||||
 | 
					            l += "|"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        formatted_table_lines.append(l)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    activity_diagram = convert_line_to_activity_diagram(activity_line)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return "\n".join(formatted_table_lines) + "\n" + activity_diagram
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__=="__main__":
 | 
					if __name__=="__main__":
 | 
				
			||||||
    # parse args
 | 
					    # parse args
 | 
				
			||||||
    files = []
 | 
					    files = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    write_to_file = AUTO
 | 
					    write_to_file = AUTO
 | 
				
			||||||
    write_to_stdout = AUTO
 | 
					    write_to_stdout = AUTO
 | 
				
			||||||
    usecase_formatting = AUTO
 | 
					    usecase_formatting = AUTO
 | 
				
			||||||
    verbose = AUTO
 | 
					    verbose = AUTO
 | 
				
			||||||
    process_table_files = AUTO
 | 
					    process_table_files = AUTO
 | 
				
			||||||
 | 
					    convert_to_activity_diagram = AUTO
 | 
				
			||||||
    file_output_path = None
 | 
					    file_output_path = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # 1 pass (argument harvest)
 | 
					    # 1 pass (argument harvest)
 | 
				
			||||||
@ -104,6 +211,12 @@ if __name__=="__main__":
 | 
				
			|||||||
            elif i in ["-nt", "--no-process-table"]:
 | 
					            elif i in ["-nt", "--no-process-table"]:
 | 
				
			||||||
                process_table_files = NO
 | 
					                process_table_files = NO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            # перетворює останню клітинку таблиці в діаграму активностей
 | 
				
			||||||
 | 
					            if i in ["-a", "--convert-to-activity-diagram"]:
 | 
				
			||||||
 | 
					                convert_to_activity_diagram = YES
 | 
				
			||||||
 | 
					            elif i in ["-na", "--no-convert-to-activity-diagram"]:
 | 
				
			||||||
 | 
					                convert_to_activity_diagram = NO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            # задає папку, в яку необхідно зберігати конвертовані таблиці
 | 
					            # задає папку, в яку необхідно зберігати конвертовані таблиці
 | 
				
			||||||
            elif i in ["-d", "--destination"]:
 | 
					            elif i in ["-d", "--destination"]:
 | 
				
			||||||
                file_output_path = sys.argv[n+2]
 | 
					                file_output_path = sys.argv[n+2]
 | 
				
			||||||
@ -133,7 +246,14 @@ if __name__=="__main__":
 | 
				
			|||||||
        elif (name.endswith(".usecase") or name.endswith(".uc")) and usecase_formatting >= AUTO:
 | 
					        elif (name.endswith(".usecase") or name.endswith(".uc")) and usecase_formatting >= AUTO:
 | 
				
			||||||
            if verbose == YES:
 | 
					            if verbose == YES:
 | 
				
			||||||
                print(f"Auto-detected use-case in file {name}\n")
 | 
					                print(f"Auto-detected use-case in file {name}\n")
 | 
				
			||||||
            formatted_table_data = convert_usecase_v1(name.rsplit(".", 1)[0], data)
 | 
					
 | 
				
			||||||
 | 
					            if convert_to_activity_diagram == YES:
 | 
				
			||||||
 | 
					                if verbose == YES:
 | 
				
			||||||
 | 
					                    print(f"Converting file {name} to activity diagram\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                formatted_table_data = convert_activity_v1(name.rsplit(".", 1)[0], data)
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                formatted_table_data = convert_usecase_v1(name.rsplit(".", 1)[0], data)
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            formatted_table_data = convert_generic_v1(data)
 | 
					            formatted_table_data = convert_generic_v1(data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -162,7 +282,14 @@ if __name__=="__main__":
 | 
				
			|||||||
        elif (name.endswith(".usecase") or name.endswith(".uc")) and usecase_formatting >= AUTO:
 | 
					        elif (name.endswith(".usecase") or name.endswith(".uc")) and usecase_formatting >= AUTO:
 | 
				
			||||||
            if verbose >= AUTO:
 | 
					            if verbose >= AUTO:
 | 
				
			||||||
                print(f"Auto-detected use-case in file {name}")
 | 
					                print(f"Auto-detected use-case in file {name}")
 | 
				
			||||||
            formatted_table_data = convert_usecase_v1(name.rsplit(".", 1)[0], data)
 | 
					
 | 
				
			||||||
 | 
					            if convert_to_activity_diagram == YES:
 | 
				
			||||||
 | 
					                if verbose == YES:
 | 
				
			||||||
 | 
					                    print(f"Converting file {name} to activity diagram\n")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                formatted_table_data = convert_activity_v1(name.rsplit(".", 1)[0], data)
 | 
				
			||||||
 | 
					            else:
 | 
				
			||||||
 | 
					                formatted_table_data = convert_usecase_v1(name.rsplit(".", 1)[0], data)
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            formatted_table_data = convert_generic_v1(data)
 | 
					            formatted_table_data = convert_generic_v1(data)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										13
									
								
								utils/table-generator/update-activities.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										13
									
								
								utils/table-generator/update-activities.sh
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					#!/bin/sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					mkdir -p activities/
 | 
				
			||||||
 | 
					./convert.py use-cases/* -a -nv -d activities/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [ -f activities.md ]; then
 | 
				
			||||||
 | 
					    rm activities.md
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for i in activities/*; do
 | 
				
			||||||
 | 
					    cat $i >> activities.md
 | 
				
			||||||
 | 
					    echo "" >> activities.md
 | 
				
			||||||
 | 
					done
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user