swarm-debug 0.1.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,153 @@
1
+ import os
2
+ import json
3
+ import colorsys
4
+ from typing import Union
5
+ from backend.core.models.Directory import Directory
6
+ from backend.core.DEFAULTS import DEFAULT_COLOR, DEFAULT_TOGGLED, DEFAULT_SET_MANUALLY, DEFAULT_SET_MANUALLY_EMOJI, TOGGLE_FILE, DEFAULT_EMOJI
7
+ from backend.core.models.DebugFile import DebugFile
8
+ from collections import OrderedDict
9
+
10
+ def merge_directories(json_dir: Directory, scanned_dir: Directory):
11
+ """
12
+ Merges two Directory instances: one loaded from JSON (json_dir) and one built from scanning (scanned_dir).
13
+ The values from json_dir take precedence where attributes overlap.
14
+ It matches based on full directory and file structure, not just file names.
15
+ """
16
+ # print(f"Merging JSON_DIR: {json_dir.path}\n with SCAN_DIR: {scanned_dir.path}")
17
+ json_abspaths, json_instances = json_dir.get_ordered_abspaths_and_instances()
18
+ # print(f"json_abspaths: {json_abspaths}")
19
+ scanned_abspaths, scanned_instances = scanned_dir.get_ordered_abspaths_and_instances()
20
+ # print(f"scanned_abspaths: {scanned_abspaths}")
21
+
22
+ def find_matching_in_structure(scanned_child: Union[DebugFile, Directory], json_dir: Directory):
23
+ assert json_dir in json_instances, f"JSON_DIR: {json_dir.path} not in json_instances"
24
+ assert scanned_child in scanned_instances, f"SCANNED_CHILD: {scanned_child.path} not in scanned_instances"
25
+ scanned_id = scanned_instances.index(scanned_child)
26
+ scanned_abspath = scanned_abspaths[scanned_id]
27
+ json_instance = None
28
+ try:
29
+ json_id = json_abspaths.index(scanned_abspath)
30
+ json_instance = json_instances[json_id]
31
+ # print(f"Match found: {scanned_child.path} == {json_instance.path}")
32
+ except ValueError:
33
+ # print(f"SCANNED_ABSPATH: {scanned_abspath} not in JSON_ABSPATHS")
34
+ pass
35
+ return json_instance
36
+
37
+ def construct_merged_dir(json_dir: Directory, scanned_dir: Directory):
38
+ for scanned_child in scanned_dir.children:
39
+ # Use the new recursive function to find the corresponding child in the JSON directory structure
40
+ matching_json_child = find_matching_in_structure(scanned_child, json_dir)
41
+
42
+ if isinstance(scanned_child, DebugFile) and matching_json_child:
43
+ scanned_child.color = matching_json_child.color
44
+ scanned_child.is_toggled = matching_json_child.is_toggled
45
+ scanned_child.set_manually = matching_json_child.set_manually
46
+ scanned_child.set_manually_emoji = matching_json_child.set_manually_emoji
47
+ scanned_child.emoji = matching_json_child.emoji
48
+
49
+ elif isinstance(scanned_child, Directory) and matching_json_child:
50
+ scanned_child.color = matching_json_child.color
51
+ scanned_child.is_toggled = matching_json_child.is_toggled
52
+ scanned_child.set_manually = matching_json_child.set_manually
53
+ scanned_child.set_manually_emoji = matching_json_child.set_manually_emoji
54
+ scanned_child.emoji = matching_json_child.emoji
55
+
56
+ # Recursively merge the subdirectories
57
+ construct_merged_dir(matching_json_child, scanned_child)
58
+ else:
59
+ scanned_child.color = DEFAULT_COLOR
60
+ scanned_child.is_toggled = DEFAULT_TOGGLED
61
+ scanned_child.set_manually = DEFAULT_SET_MANUALLY
62
+ scanned_child.set_manually_emoji = DEFAULT_SET_MANUALLY_EMOJI
63
+ scanned_child.emoji = DEFAULT_EMOJI
64
+
65
+ construct_merged_dir(json_dir, scanned_dir)
66
+
67
+
68
+ def update_debug_toggles(save_to_file=True) -> Directory:
69
+ # print(f"[update_debug_toggles]: START")
70
+ json_loaded_dir = None
71
+ if os.path.exists(TOGGLE_FILE):
72
+ with open(TOGGLE_FILE, 'r', encoding='utf-8') as file:
73
+ try:
74
+ json_data = json.load(file)
75
+ json_loaded_dir = Directory("")
76
+ json_loaded_dir = Directory(path="",
77
+ color=json_data[0].get('color', DEFAULT_COLOR),
78
+ is_toggled=json_data[0].get('is_toggled', DEFAULT_TOGGLED),
79
+ set_manually=json_data[0].get('set_manually', DEFAULT_SET_MANUALLY),
80
+ set_manually_emoji=json_data[0].get('set_manually_emoji', DEFAULT_SET_MANUALLY_EMOJI),
81
+ emoji=json_data[0].get('emoji', DEFAULT_EMOJI)
82
+ )
83
+ # print(f"Root: {json_loaded_dir}")
84
+ # print("Json Children 1:")
85
+ # [print(child.path) for child in json_loaded_dir.children]
86
+
87
+ json_loaded_dir.load_from_json(json_data[0]['children']) # Assuming the root is in json_data[0]
88
+ # print("Json Children 2:")
89
+ # [print(child.path) for child in json_loaded_dir.children]
90
+
91
+ except json.JSONDecodeError:
92
+ ValueError("Error: JSON file could not be decoded.")
93
+ else:
94
+ print("No JSON file found")
95
+ # 1. Create a directory structure from the filesystem scan
96
+ # print("Scanning directory...")
97
+ scanned_dir = Directory(path="",
98
+ color=json_loaded_dir.color if json_loaded_dir else DEFAULT_COLOR,
99
+ is_toggled=json_loaded_dir.is_toggled if json_loaded_dir else DEFAULT_TOGGLED,
100
+ set_manually=json_loaded_dir.set_manually if json_loaded_dir else DEFAULT_SET_MANUALLY,
101
+ set_manually_emoji=json_loaded_dir.set_manually_emoji if json_loaded_dir else DEFAULT_SET_MANUALLY_EMOJI,
102
+ emoji=json_loaded_dir.emoji if json_loaded_dir else DEFAULT_EMOJI
103
+ )
104
+ # print(f"\n\nNum Children 1: {len(scanned_dir.children)}")
105
+ # [print(child.path) for child in scanned_dir.children]
106
+ scanned_dir.build_structure()
107
+ # print(f"\n\nNum Children 2: {len(scanned_dir.children)}")
108
+ # [print(child.path) for child in scanned_dir.children]
109
+ scanned_dir.prune_empty()
110
+ # print(f"\n\nNum Children 3: {len(scanned_dir.children)}")
111
+ # [print(child.path) for child in scanned_dir.children]
112
+
113
+ # print("1.1 Merged Dir First Child: ", scanned_dir.children[0])
114
+ # 4. Propagate the toggled state and color through the merged structure
115
+ scanned_dir.propagate_toggled_state()
116
+ # print(f"\n\nNum Children 4: {len(scanned_dir.children)}")
117
+ # [print(child.path) for child in scanned_dir.children]
118
+
119
+ # 3. Merge the two directory structures
120
+ if json_loaded_dir:
121
+ merge_directories(json_loaded_dir, scanned_dir)
122
+
123
+ # print(f"\n\nNum Children 5: {len(scanned_dir.children)}")
124
+ scanned_dir.propagate_color()
125
+ output = dir_to_output_format(scanned_dir)
126
+ # print(f"\n\nNum Children 6: {len(scanned_dir.children)}")
127
+
128
+
129
+ # 5. Write the updated structure back to the JSON file
130
+ if save_to_file:
131
+ with open(TOGGLE_FILE, 'w', encoding='utf-8') as file:
132
+ json.dump(output, file, ensure_ascii=False, indent=4)
133
+ # print(f"[update_debug_toggles]: END")
134
+ return scanned_dir
135
+
136
+ def dir_to_output_format(input_dir):
137
+ root_node = {
138
+ "name": "root",
139
+ "color": input_dir.color,
140
+ "is_toggled": input_dir.is_toggled,
141
+ "set_manually": input_dir.set_manually,
142
+ "set_manually_emoji": input_dir.set_manually_emoji,
143
+ "emoji": input_dir.emoji,
144
+ "children": input_dir.to_dict()["children"]
145
+ }
146
+ return [ordered(root_node)]
147
+
148
+ def ordered(obj):
149
+ if isinstance(obj, dict):
150
+ return OrderedDict((k, ordered(v)) for k, v in obj.items())
151
+ if isinstance(obj, list):
152
+ return [ordered(x) for x in obj]
153
+ return obj
@@ -0,0 +1,3 @@
1
+ from backend.core.utils.color_adjuster import rgb_to_ansi, bold_and_italicize_text, hex_to_rgb
2
+ from backend.core.utils.debug_arg_parser import is_text, is_error, is_fstring
3
+ from backend.core.utils.path_mngr import get_abspath, get_root_rel_path
@@ -0,0 +1,13 @@
1
+
2
+ def rgb_to_ansi(rgb):
3
+ return '\033[38;2;{};{};{}m'.format(*rgb)
4
+
5
+ def bold_and_italicize_text(text):
6
+ return f"\033[1m\033[3m{text}\033[0m"
7
+
8
+ def hex_to_rgb(hex_code):
9
+ # Remove the '#' symbol if it exists
10
+ hex_code = hex_code.lstrip('#')
11
+
12
+ # Convert the hex code to RGB
13
+ return tuple(int(hex_code[i:i+2], 16) for i in (0, 2, 4))
@@ -0,0 +1,22 @@
1
+ x = "y"
2
+
3
+ def is_fstring(arg_name):
4
+ if not isinstance(arg_name, str):
5
+ return False
6
+ # print(f"arg_name: {arg_name}")
7
+ fstring_start_values = ["f'", "f\""]
8
+ num_start_matches = sum(arg_name.startswith(start_value) for start_value in fstring_start_values)
9
+ conditions = [num_start_matches == 1]
10
+ return all(conditions)
11
+
12
+ def is_text(arg_value, arg_name):
13
+ arg_is_text = isinstance(arg_value, str) and len(arg_name) > 2 and arg_name[1:len(arg_name)-1] == arg_value and not arg_name.endswith(")")
14
+ if not arg_is_text:
15
+ arg_is_text = is_fstring(arg_name)
16
+ # print(f"is_text: {arg_is_text}")
17
+ return arg_is_text
18
+
19
+ def is_error(arg_value, arg_name):
20
+ arg_is_error = isinstance(arg_value, Exception) or "error" in str(arg_value).lower() or "error" in str(arg_name).lower()
21
+ return arg_is_error
22
+
@@ -0,0 +1,15 @@
1
+ import os
2
+ from backend.core.DEFAULTS import get_root_dir
3
+
4
+
5
+ def get_abspath(path: str):
6
+ return os.path.join(get_root_dir(), path)
7
+
8
+
9
+ def get_root_rel_path(path: str):
10
+ root = get_root_dir()
11
+ assert path.startswith(root)
12
+ path = path[len(root):]
13
+ while path.startswith(os.sep):
14
+ path = path[1:]
15
+ return path