1+ # 23.12.25
2+
3+ import re
4+ from pathlib import Path
5+ from typing import List , Tuple
6+ from datetime import datetime
7+
8+
9+ def extract_service_info (init_file : Path ) -> Tuple [str , str , bool , bool ]:
10+ """
11+ Extract _stream_type, _drm and _deprecate from a service __init__.py file
12+
13+ Args:
14+ init_file: Path to the __init__.py file
15+
16+ Returns:
17+ Tuple of (service_name, stream_type, drm, deprecate)
18+ """
19+ service_name = init_file .parent .name
20+ stream_type = "N/A"
21+ drm = False
22+ deprecate = False
23+
24+ try :
25+ with open (init_file , 'r' , encoding = 'utf-8' ) as f :
26+ content = f .read ()
27+
28+ # Extract _stream_type
29+ stream_match = re .search (r'_stream_type\s*=\s*["\'](\w+)["\']' , content )
30+ if stream_match :
31+ stream_type = stream_match .group (1 )
32+
33+ # Extract _drm
34+ drm_match = re .search (r'_drm\s*=\s*(True|False)' , content )
35+ if drm_match :
36+ drm = drm_match .group (1 ) == 'True'
37+
38+ # Extract _deprecate
39+ deprecate_match = re .search (r'_deprecate\s*=\s*(True|False)' , content )
40+ if deprecate_match :
41+ deprecate = deprecate_match .group (1 ) == 'True'
42+
43+ except Exception as e :
44+ print (f"Error reading { init_file } : { e } " )
45+
46+ return service_name , stream_type , drm , deprecate
47+
48+
49+ def find_service_files (base_path : Path ) -> List [Path ]:
50+ """
51+ Find all service __init__.py files
52+
53+ Args:
54+ base_path: Base path of the project
55+
56+ Returns:
57+ List of paths to service __init__.py files
58+ """
59+ services_path = base_path / "StreamingCommunity" / "Api" / "Service"
60+ init_files = []
61+
62+ if not services_path .exists ():
63+ print (f"Services path not found: { services_path } " )
64+ return init_files
65+
66+ # Iterate through service directories
67+ for service_dir in services_path .iterdir ():
68+ if service_dir .is_dir () and not service_dir .name .startswith ('__' ):
69+ init_file = service_dir / "__init__.py"
70+ if init_file .exists ():
71+ init_files .append (init_file )
72+
73+ return sorted (init_files )
74+
75+
76+ def generate_markdown_table (services : List [Tuple [str , str , bool ]]) -> str :
77+ """
78+ Generate markdown table from services data with dynamic column widths
79+ Only includes services where _deprecate = False
80+
81+ Args:
82+ services: List of (service_name, stream_type, drm) tuples
83+
84+ Returns:
85+ Markdown formatted table
86+ """
87+ services = sorted (services , key = lambda x : x [0 ].lower ())
88+
89+ # Prepare data with display names
90+ table_data = []
91+ for service_name , stream_type , drm in services :
92+ display_name = service_name .replace ('_' , ' ' ).title ()
93+ drm_icon = "✅" if drm else "❌"
94+ table_data .append ((display_name , stream_type , drm_icon ))
95+
96+ # Calculate maximum width for each column
97+ col1_header = "Site Name"
98+ col2_header = "Stream Type"
99+ col3_header = "DRM"
100+
101+ # Start with header widths
102+ max_col1 = len (col1_header )
103+ max_col2 = len (col2_header )
104+ max_col3 = len (col3_header )
105+
106+ # Check all data rows
107+ for display_name , stream_type , drm_icon in table_data :
108+ max_col1 = max (max_col1 , len (display_name ))
109+ max_col2 = max (max_col2 , len (stream_type ))
110+ max_col3 = max (max_col3 , len (drm_icon ))
111+
112+ # Build table with dynamic widths
113+ lines = ["# Services Overview" , "" ]
114+
115+ # Header row
116+ header = f"| { col1_header .ljust (max_col1 )} | { col2_header .ljust (max_col2 )} | { col3_header .ljust (max_col3 )} |"
117+ lines .append (header )
118+
119+ # Separator row
120+ separator = f"|{ '-' * (max_col1 + 2 )} |{ '-' * (max_col2 + 2 )} |{ '-' * (max_col3 + 2 )} |"
121+ lines .append (separator )
122+
123+ # Data rows
124+ for display_name , stream_type , drm_icon in table_data :
125+ row = f"| { display_name .ljust (max_col1 )} | { stream_type .ljust (max_col2 )} | { drm_icon .ljust (max_col3 )} |"
126+ lines .append (row )
127+
128+ lines .append ("" )
129+ lines .append ("---" )
130+ lines .append ("" )
131+ lines .append (f"*Last updated: { datetime .now ().strftime ('%Y-%m-%d %H:%M:%S' )} *" )
132+ lines .append ("" )
133+
134+ return "\n " .join (lines )
135+
136+
137+ def main ():
138+ script_dir = Path (__file__ ).parent
139+ base_path = script_dir .parent .parent .parent
140+ print (f"Base path: { base_path } " )
141+
142+ # Find all service __init__.py files
143+ init_files = find_service_files (base_path )
144+ print (f"Found { len (init_files )} service files" )
145+
146+ if not init_files :
147+ print ("No service files found!" )
148+ return
149+
150+ # Extract information from each service
151+ services = []
152+ deprecated_count = 0
153+ for init_file in init_files :
154+ service_name , stream_type , drm , deprecate = extract_service_info (init_file )
155+
156+ # Only include services that are not deprecated
157+ if not deprecate :
158+ services .append ((service_name , stream_type , drm ))
159+ print (f" ✓ { service_name } : { stream_type } , DRM={ drm } " )
160+ else :
161+ deprecated_count += 1
162+ print (f" ⚠ { service_name } : DEPRECATED (skipped)" )
163+
164+ print (f"\n Active services: { len (services )} " )
165+ print (f"Deprecated services: { deprecated_count } " )
166+
167+ # Generate markdown table
168+ markdown_content = generate_markdown_table (services )
169+
170+ # Write to site.md
171+ output_file = base_path / ".github" / "doc" / "site.md"
172+ output_file .parent .mkdir (parents = True , exist_ok = True )
173+
174+ with open (output_file , 'w' , encoding = 'utf-8' ) as f :
175+ f .write (markdown_content )
176+
177+
178+ if __name__ == "__main__" :
179+ main ()
0 commit comments