@@ -18,11 +18,13 @@ def cli():
1818
1919
2020@cli .command ()
21- @click .option ('--config' , '-c' , required = True , help = 'Path to YAML configuration file' )
22- @click .option ('--env-file' , '-e' , default = '.env' , help = 'Path to .env file' )
23- @click .option ('--route' , '-r' , help = 'Run specific route only' )
24- @click .option ('--dry-run' , is_flag = True , help = 'Show what would be executed without running' )
25- @click .option ('--verbose' , '-v' , is_flag = True , help = 'Verbose output' )
21+ @click .option ("--config" , "-c" , required = True , help = "Path to YAML configuration file" )
22+ @click .option ("--env-file" , "-e" , default = ".env" , help = "Path to .env file" )
23+ @click .option ("--route" , "-r" , help = "Run specific route only" )
24+ @click .option (
25+ "--dry-run" , is_flag = True , help = "Show what would be executed without running"
26+ )
27+ @click .option ("--verbose" , "-v" , is_flag = True , help = "Verbose output" )
2628def run (config , env_file , route , dry_run , verbose ):
2729 """Run routes from configuration file"""
2830
@@ -34,7 +36,7 @@ def run(config, env_file, route, dry_run, verbose):
3436
3537 # Load and validate config
3638 try :
37- with open (config , 'r' ) as f :
39+ with open (config , "r" ) as f :
3840 config_data = yaml .safe_load (f )
3941 except Exception as e :
4042 click .echo (f"❌ Error loading config: { e } " , err = True )
@@ -67,94 +69,103 @@ def update_env_file(env_path, required_vars):
6769 env_path = Path (env_path )
6870 existing_vars = set ()
6971 env_lines = []
70-
72+
7173 # Read existing .env file if it exists
7274 if env_path .exists ():
73- with open (env_path , 'r' ) as f :
75+ with open (env_path , "r" ) as f :
7476 for line in f :
7577 line = line .strip ()
76- if line and not line .startswith ('#' ):
77- var_name = line .split ('=' )[0 ].strip ()
78+ if line and not line .startswith ("#" ):
79+ var_name = line .split ("=" )[0 ].strip ()
7880 existing_vars .add (var_name )
7981 env_lines .append (f"{ line } \n " )
8082 else :
8183 env_lines .append (f"{ line } \n " if line else "\n " )
82-
84+
8385 # Add missing variables
8486 added_vars = []
8587 for var in sorted (required_vars ):
8688 if var not in existing_vars :
8789 env_lines .append (f"{ var } =\n " )
8890 added_vars .append (var )
89-
91+
9092 # Write back to .env file
9193 if added_vars :
92- with open (env_path , 'w' ) as f :
94+ with open (env_path , "w" ) as f :
9395 f .writelines (env_lines )
94-
96+
9597 return added_vars
9698
99+
97100def extract_env_vars (template_content ):
98101 """Extract environment variables from template content."""
99102 import re
103+
100104 # Find all {{VARIABLE}} patterns
101- pattern = r' {{\s*([A-Z0-9_]+)\s*}}'
105+ pattern = r" {{\s*([A-Z0-9_]+)\s*}}"
102106 matches = re .findall (pattern , template_content )
103-
107+
104108 # Also check for env_vars section in YAML
105109 env_vars = set (matches )
106110 try :
107111 import yaml
112+
108113 config = yaml .safe_load (template_content )
109- if ' env_vars' in config and isinstance (config [' env_vars' ], list ):
110- env_vars .update (var for var in config [' env_vars' ] if isinstance (var , str ))
114+ if " env_vars" in config and isinstance (config [" env_vars" ], list ):
115+ env_vars .update (var for var in config [" env_vars" ] if isinstance (var , str ))
111116 except Exception :
112117 pass
113-
118+
114119 return sorted (env_vars )
115120
121+
116122@cli .command ()
117- @click .option ('--template' , '-t' , type = click .Choice (['camera' , 'grpc' , 'email' , 'full' ]),
118- default = 'camera' , help = 'Template type to generate' )
119- @click .option ('--output' , '-o' , default = 'routes.yaml' , help = 'Output file name' )
120- @click .option ('--no-env' , is_flag = True , help = 'Skip updating .env file' )
123+ @click .option (
124+ "--template" ,
125+ "-t" ,
126+ type = click .Choice (["camera" , "grpc" , "email" , "full" ]),
127+ default = "camera" ,
128+ help = "Template type to generate" ,
129+ )
130+ @click .option ("--output" , "-o" , default = "routes.yaml" , help = "Output file name" )
131+ @click .option ("--no-env" , is_flag = True , help = "Skip updating .env file" )
121132def init (template , output , no_env ):
122133 """Generate sample configuration file and update .env with required variables"""
123134 templates = {
124- ' camera' : get_camera_template (),
125- ' grpc' : get_grpc_template (),
126- ' email' : get_email_template (),
127- ' full' : get_full_template ()
135+ " camera" : get_camera_template (),
136+ " grpc" : get_grpc_template (),
137+ " email" : get_email_template (),
138+ " full" : get_full_template (),
128139 }
129140
130141 template_content = templates [template ]
131142
132143 # Write the configuration file
133- with open (output , 'w' ) as f :
144+ with open (output , "w" ) as f :
134145 f .write (template_content )
135146
136147 click .echo (f"✓ Generated { template } template in { output } " )
137-
148+
138149 # Handle .env file
139150 if not no_env : # Only update .env if --no-env flag is not set
140151 env_vars = extract_env_vars (template_content )
141152 if env_vars :
142- added = update_env_file (' .env' , env_vars )
153+ added = update_env_file (" .env" , env_vars )
143154 if added :
144155 click .echo ("\n ✓ Added the following environment variables to .env:" )
145156 for var in added :
146157 click .echo (f" - { var } " )
147158 click .echo ("\n 📝 Please edit .env and set the appropriate values" )
148-
159+
149160 click .echo (f"\n 📝 Edit the configuration and run: dialogchain run -c { output } " )
150161
151162
152163@cli .command ()
153- @click .option (' --config' , '-c' , required = True , help = ' Path to YAML configuration file' )
164+ @click .option (" --config" , "-c" , required = True , help = " Path to YAML configuration file" )
154165def validate (config ):
155166 """Validate configuration file"""
156167 try :
157- with open (config , 'r' ) as f :
168+ with open (config , "r" ) as f :
158169 config_data = yaml .safe_load (f )
159170
160171 engine = CamelRouterEngine (config_data )
@@ -310,46 +321,64 @@ def main():
310321
311322
312323@cli .command ()
313- @click .option ('--network' , '-n' , default = '192.168.1.0/24' ,
314- help = 'Network to scan in CIDR notation' )
315- @click .option ('--service' , '-s' , multiple = True ,
316- type = click .Choice (['rtsp' , 'smtp' , 'imap' , 'http' , 'all' ]),
317- help = 'Service types to scan for' )
318- @click .option ('--output' , '-o' , type = click .Path (),
319- help = 'Save results to a file' )
320- @click .option ('--timeout' , '-t' , type = float , default = 2.0 ,
321- help = 'Timeout in seconds for each connection attempt' )
322- @click .option ('--verbose/--quiet' , default = True ,
323- help = 'Show/hide detailed output' )
324- async def scan (network : str , service : List [str ], output : Optional [str ],
325- timeout : float , verbose : bool ):
324+ @click .option (
325+ "--network" , "-n" , default = "192.168.1.0/24" , help = "Network to scan in CIDR notation"
326+ )
327+ @click .option (
328+ "--service" ,
329+ "-s" ,
330+ multiple = True ,
331+ type = click .Choice (["rtsp" , "smtp" , "imap" , "http" , "all" ]),
332+ help = "Service types to scan for" ,
333+ )
334+ @click .option ("--output" , "-o" , type = click .Path (), help = "Save results to a file" )
335+ @click .option (
336+ "--timeout" ,
337+ "-t" ,
338+ type = float ,
339+ default = 2.0 ,
340+ help = "Timeout in seconds for each connection attempt" ,
341+ )
342+ @click .option ("--verbose/--quiet" , default = True , help = "Show/hide detailed output" )
343+ async def scan (
344+ network : str ,
345+ service : List [str ],
346+ output : Optional [str ],
347+ timeout : float ,
348+ verbose : bool ,
349+ ):
326350 """Scan network for common services like RTSP, SMTP, IMAP, etc."""
327351 try :
328- if not service or ' all' in service :
352+ if not service or " all" in service :
329353 service_types = None
330354 else :
331355 service_types = list (service )
332-
356+
333357 if verbose :
334- click .echo (f"🔍 Scanning network { network } for services: { service_types or 'all' } " )
335-
358+ click .echo (
359+ f"🔍 Scanning network { network } for services: { service_types or 'all' } "
360+ )
361+
336362 scanner = NetworkScanner (timeout = timeout )
337- services = await scanner .scan_network (network = network , service_types = service_types )
338-
363+ services = await scanner .scan_network (
364+ network = network , service_types = service_types
365+ )
366+
339367 # Format and display results
340368 result = NetworkScanner .format_service_list (services )
341369 click .echo ("\n " + result )
342-
370+
343371 # Save to file if requested
344372 if output :
345373 output_path = Path (output )
346374 output_path .write_text (result )
347375 click .echo (f"\n ✓ Results saved to { output_path } " )
348-
376+
349377 except Exception as e :
350378 click .echo (f"❌ Error during scan: { e } " , err = True )
351379 if verbose :
352380 import traceback
381+
353382 traceback .print_exc ()
354383 return 1
355384
@@ -359,5 +388,5 @@ def main():
359388 cli ()
360389
361390
362- if __name__ == ' __main__' :
363- main ()
391+ if __name__ == " __main__" :
392+ main ()
0 commit comments