From 402edf0784be2df60d3e0bced347ab1bec586635 Mon Sep 17 00:00:00 2001 From: Blackwhitebear8 Date: Sun, 6 Jul 2025 17:32:17 +0200 Subject: [PATCH] Update modules/visual_route.py --- modules/visual_route.py | 61 +++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 36 deletions(-) diff --git a/modules/visual_route.py b/modules/visual_route.py index c6e7fdc..099591e 100644 --- a/modules/visual_route.py +++ b/modules/visual_route.py @@ -67,10 +67,11 @@ def _parse_bgp_paths_to_graph(bgp_data: str) -> dict: for line in lines[paths_header_index + 1:]: stripped_line = line.strip() if not stripped_line: continue + is_new_path_line = False if line.startswith(' ') and not line.startswith(' '): - first_word = stripped_line.split(' ')[0] - if first_word.isdigit() or stripped_line == "Local": + first_word = stripped_line.split(' ')[0].replace(',', '') + if first_word.isdigit(): is_new_path_line = True if is_new_path_line: @@ -83,32 +84,30 @@ def _parse_bgp_paths_to_graph(bgp_data: str) -> dict: except StopIteration: return {"nodes": [], "edges": []} - all_paths_info, best_path_info = [], None + all_paths_info = [] + best_path_info = None for block in path_blocks: - + block_text = "\n".join(block) clean_lines = [line for line in block if not line.strip().startswith("AddPath ID:")] block_text_for_check = "\n".join(clean_lines) - is_best = bool(re.search(r'\bbest\b', block_text_for_check, re.IGNORECASE)) is_multipath = 'multipath' in block_text_for_check.lower() - - block_text_full = "\n".join(block) + path_line = block[0].strip() path_asns_raw = [] - if path_line != "Local": - for part in path_line.split(' '): - clean_part = part.replace(',', '').strip() - if clean_part.isdigit(): - path_asns_raw.append(clean_part) - else: - break + for part in path_line.split(' '): + clean_part = part.replace(',', '').strip() + if clean_part.isdigit(): + path_asns_raw.append(clean_part) + else: + break path_asns = list(dict.fromkeys(path_asns_raw)) - local_pref_match = re.search(r'localpref (\d+)', block_text_full) + local_pref_match = re.search(r'localpref (\d+)', block_text) local_pref = int(local_pref_match.group(1)) if local_pref_match else None - next_hop_match = re.search(r'^\s*([\da-fA-F:.]+)\s+from', block_text_full, re.MULTILINE) + next_hop_match = re.search(r'^\s*([\da-fA-F:.]+)\s+from', block_text, re.MULTILINE) next_hop = next_hop_match.group(1) if next_hop_match else None - community_match = re.search(r'Large Community: ([\d:]+)', block_text_full) + community_match = re.search(r'Large Community: ([\d:]+)', block_text) community = community_match.group(1) if community_match else None category = 'other' if community: @@ -135,37 +134,27 @@ def _parse_bgp_paths_to_graph(bgp_data: str) -> dict: y_pos_counter_up, y_pos_counter_down = 1, 1 for i, path_info in enumerate(ordered_paths): lane_y = 0 - if not path_info['is_best']: - if y_pos_counter_up <= y_pos_counter_down: - lane_y = y_pos_counter_up * Y_SEPARATION - y_pos_counter_up += 1 - else: - lane_y = -y_pos_counter_down * Y_SEPARATION - y_pos_counter_down += 1 + if i > 0: + if y_pos_counter_up <= y_pos_counter_down: lane_y = y_pos_counter_up * Y_SEPARATION; y_pos_counter_up += 1 + else: lane_y = -y_pos_counter_down * Y_SEPARATION; y_pos_counter_down += 1 style, is_active_path = {}, False if path_info['is_best']: - style = {"node_color": '#FADBD8', "edge_color": '#C0392B', "width": 3, "dashes": False, "path_type": " (best)"} - is_active_path = True + style = {"node_color": '#FADBD8', "edge_color": '#C0392B', "width": 3, "dashes": False, "path_type": " (best)"}; is_active_path = True elif path_info['is_multipath']: - style = {"node_color": '#FDEBD0', "edge_color": '#F39C12', "width": 2, "dashes": False, "path_type": " (multipath)"} - is_active_path = True + style = {"node_color": '#FDEBD0', "edge_color": '#F39C12', "width": 2, "dashes": False, "path_type": " (multipath)"}; is_active_path = True else: - style = {"node_color": '#D6DBDF', "edge_color": '#2C3E50', "width": 1, "dashes": True, "path_type": ""} - is_active_path = False + style = {"node_color": '#D6DBDF', "edge_color": '#2C3E50', "width": 1, "dashes": True, "path_type": ""}; is_active_path = False path_node_ids = [] for j, asn in enumerate(path_info['asns']): unique_node_id = f"AS{asn}-{i}" path_node_ids.append(unique_node_id) - as_name = AS_NAME_CACHE.get(asn, "") - wrapped_name = '\n'.join(textwrap.wrap(as_name, width=AS_NAME_WRAP_WIDTH)) if as_name else "" + as_name = AS_NAME_CACHE.get(asn, ""); wrapped_name = '\n'.join(textwrap.wrap(as_name, width=AS_NAME_WRAP_WIDTH)) if as_name else "" base_label = f"AS{asn}" - if j == 0 and path_info['local_pref'] is not None: - base_label += f" (LP: {path_info['local_pref']})" + if j == 0 and path_info['local_pref'] is not None: base_label += f" (LP: {path_info['local_pref']})" label = f"{base_label}\n{wrapped_name}" - if j == 0 and path_info['next_hop']: - label += f"\nNext Hop: {path_info['next_hop']}{style['path_type']}" + if j == 0 and path_info['next_hop']: label += f"\nNext Hop: {path_info['next_hop']}{style['path_type']}" nodes.append({"id": unique_node_id, "label": label, "color": style['node_color'], "x": (j + 1) * X_SEPARATION, "y": lane_y, "fixed": True, "path_category": path_info['category'], "is_active": is_active_path}) full_chain = [ROUTER_NAME] + path_node_ids + [prefix]