From 02e4da805069fa4a0334fc50792151c0792ca62c Mon Sep 17 00:00:00 2001 From: hasslesstech Date: Sun, 28 Apr 2024 15:17:31 +0300 Subject: [PATCH 1/2] =?UTF-8?q?table-generator:=20=D0=B4=D0=BE=D0=B4=D0=B0?= =?UTF-8?q?=D0=B2=20=D0=BF=D1=96=D0=B4=D1=82=D1=80=D0=B8=D0=BC=D0=BA=D1=83?= =?UTF-8?q?=20=D0=B0=D0=B2=D1=82=D0=BE=D0=BC=D0=B0=D1=82=D0=B8=D1=87=D0=BD?= =?UTF-8?q?=D0=BE=D1=97=20=D0=BA=D0=BE=D0=BD=D0=B2=D0=B5=D1=80=D1=82=D0=B0?= =?UTF-8?q?=D1=86=D1=96=D1=97=20use-case-=D1=84=D0=B0=D0=B9=D0=BB=D1=96?= =?UTF-8?q?=D0=B2=20=D1=83=20Activity-=D0=B4=D1=96=D0=B0=D0=B3=D1=80=D0=B0?= =?UTF-8?q?=D0=BC=D0=B8=20(=D0=B4=D0=BB=D1=8F=20=D0=B0=D0=B2=D1=82=D0=BE?= =?UTF-8?q?=D0=BC=D0=B0=D1=82=D0=B8=D0=B7=D0=B0=D1=86=D1=96=D1=97=20=D0=BF?= =?UTF-8?q?=D1=96=D0=B4=D1=82=D1=80=D0=B8=D0=BC=D0=BA=D0=B8=20=D0=BB=D0=B0?= =?UTF-8?q?=D0=B1.=20=D1=80=D0=BE=D0=B1=D0=BE=D1=82=D0=B8=20=E2=84=963)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- utils/table-generator/convert.py | 131 ++++++++++++++++++++- utils/table-generator/update-activities.sh | 13 ++ 2 files changed, 142 insertions(+), 2 deletions(-) create mode 100755 utils/table-generator/update-activities.sh diff --git a/utils/table-generator/convert.py b/utils/table-generator/convert.py index 6fbce50..859762c 100755 --- a/utils/table-generator/convert.py +++ b/utils/table-generator/convert.py @@ -34,6 +34,27 @@ def convert_usecase_v1(filename, data): 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] += "
" + i[1] + else: + merged_lines.append(i) + + return generate_table_with_activity_diagram(merged_lines) + def generate_table(raw_table_data): table_lines = raw_table_data transposed_table = list(zip(*table_lines)) @@ -60,15 +81,101 @@ def generate_table(raw_table_data): return "\n".join(formatted_table_lines) +def convert_line_to_activity_diagram(line): + split_line = line[1].split("
") + + 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 {exceptions}\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__": # parse args files = [] + write_to_file = AUTO write_to_stdout = AUTO usecase_formatting = AUTO verbose = AUTO process_table_files = AUTO + convert_to_activity_diagram = AUTO file_output_path = None # 1 pass (argument harvest) @@ -104,6 +211,12 @@ if __name__=="__main__": elif i in ["-nt", "--no-process-table"]: 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"]: 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: if verbose == YES: 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: 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: if verbose >= AUTO: 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: formatted_table_data = convert_generic_v1(data) diff --git a/utils/table-generator/update-activities.sh b/utils/table-generator/update-activities.sh new file mode 100755 index 0000000..af44f7f --- /dev/null +++ b/utils/table-generator/update-activities.sh @@ -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 -- 2.40.1 From 1da28409386fa765978282f3d48021c79178b829 Mon Sep 17 00:00:00 2001 From: hasslesstech Date: Sun, 28 Apr 2024 15:51:25 +0300 Subject: [PATCH 2/2] =?UTF-8?q?table-generator:=20=D0=B4=D0=BE=D0=B4=D0=B0?= =?UTF-8?q?=D0=B2=20activities.md=20=D1=82=D0=B0=20=D0=BA=D0=B0=D1=82?= =?UTF-8?q?=D0=B0=D0=BB=D0=BE=D0=B3=20activities/=20=D0=B4=D0=BE=20.gitign?= =?UTF-8?q?ore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index b7d877d..3597c7c 100644 --- a/.gitignore +++ b/.gitignore @@ -106,3 +106,5 @@ dist # utils/table-generator generated files utils/table-generator/tables/ utils/table-generator/tables.md +utils/table-generator/activities/ +utils/table-generator/activities.md -- 2.40.1