""" Read configuration as binary, parse as folder tree, and dump working mapping structure """ import grpc import sys import io sys.path.append(r'C:\DEV\COPILOT\geutebruck-api\src\api') if sys.platform == 'win32': sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8') sys.stderr = io.TextIOWrapper(sys.stderr.buffer, encoding='utf-8') from protos import configuration_pb2 from protos import configuration_pb2_grpc def print_folder_tree(node, indent=0, max_depth=10): """Print folder tree structure recursively""" if indent > max_depth: return prefix = " " * indent # Print this node if node.type == "folder": print(f"{prefix}{node.name}/ (folder)") if node.children: for child in node.children: print_folder_tree(child, indent + 1, max_depth) elif node.type == "string": # Truncate long strings value = node.string_value if len(node.string_value) < 80 else node.string_value[:77] + "..." print(f"{prefix}{node.name} = \"{value}\" (string)") elif node.type == "int32": print(f"{prefix}{node.name} = {node.int_value} (int32)") elif node.type == "int64": print(f"{prefix}{node.name} = {node.int_value} (int64)") elif node.type == "int16": print(f"{prefix}{node.name} = {node.int_value} (int16)") elif node.type == "byte": print(f"{prefix}{node.name} = {node.int_value} (byte)") elif node.type == "boolean": print(f"{prefix}{node.name} = {bool(node.int_value)} (boolean)") else: print(f"{prefix}{node.name} ({node.type})") print("="*70) print("DUMPING FOLDER TREE STRUCTURE OF WORKING MAPPING") print("="*70) channel = grpc.insecure_channel('localhost:50051') stub = configuration_pb2_grpc.ConfigurationServiceStub(channel) # Use ReadConfiguration to get the parsed folder tree print("\n1. Reading configuration...") request = configuration_pb2.ReadConfigurationRequest() response = stub.ReadConfiguration(request) if not response.success: print(f" [ERROR] {response.error_message}") sys.exit(1) print(f" File size: {response.file_size} bytes") print(f" Total nodes: {response.statistics.total_nodes}") # The nodes list is flat - we need to search for MappingRules marker print("\n2. Searching for MappingRules marker...") mapping_rules_nodes = [] in_mapping_rules = False current_mapping_nodes = [] current_mapping_name = None for i, node in enumerate(response.nodes): # Look for marker nodes if node.node_type == "marker": if node.name == "MappingRules": in_mapping_rules = True print(f" Found MappingRules at node {i}") elif in_mapping_rules: # Another marker means we've left MappingRules in_mapping_rules = False break if in_mapping_rules: mapping_rules_nodes.append(node) # Track individual mappings (they're separated by property markers) if node.node_type == "property": # Save previous mapping if any if current_mapping_nodes and current_mapping_name: # Check if this is a working mapping if "CrossSwitch" in current_mapping_name or "C_" in current_mapping_name: print(f"\n3. Found working mapping: '{current_mapping_name}'") print(f" Total nodes in mapping: {len(current_mapping_nodes)}") print(f"\n4. Node details:") for j, mnode in enumerate(current_mapping_nodes[:50]): # First 50 nodes print(f" [{j}] {mnode.node_type:10} | offset {mnode.start_offset:6}-{mnode.end_offset:6} | name: '{mnode.name}' | value: '{mnode.value[:50] if len(mnode.value) < 50 else mnode.value[:47] + '...'}'") print("\n" + "="*70) print("DONE - Found working mapping structure above") print("="*70) sys.exit(0) # Start new mapping current_mapping_nodes = [node] # The caption should be in the next string node current_mapping_name = None else: current_mapping_nodes.append(node) # Capture the mapping name (first string node is usually the caption) if node.node_type == "string" and current_mapping_name is None: current_mapping_name = node.value print("\n[ERROR] No working mapping found") print(f"Total nodes in MappingRules: {len(mapping_rules_nodes)}")