Skip to content

Commit 056ff63

Browse files
author
Tom Softreck
committed
update
1 parent 4b83b55 commit 056ff63

22 files changed

+1361
-650
lines changed

src/dialogchain/__init__.py

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -26,19 +26,19 @@
2626
from .connectors import *
2727

2828
__all__ = [
29-
'CamelRouterEngine',
30-
'Processor',
31-
'ExternalProcessor',
32-
'FilterProcessor',
33-
'TransformProcessor',
34-
'AggregateProcessor',
35-
'Source',
36-
'Destination',
37-
'RTSPSource',
38-
'TimerSource',
39-
'EmailDestination',
40-
'HTTPDestination',
41-
'MQTTDestination',
42-
'FileDestination',
43-
'LogDestination'
44-
]
29+
"CamelRouterEngine",
30+
"Processor",
31+
"ExternalProcessor",
32+
"FilterProcessor",
33+
"TransformProcessor",
34+
"AggregateProcessor",
35+
"Source",
36+
"Destination",
37+
"RTSPSource",
38+
"TimerSource",
39+
"EmailDestination",
40+
"HTTPDestination",
41+
"MQTTDestination",
42+
"FileDestination",
43+
"LogDestination",
44+
]

src/dialogchain/cli.py

Lines changed: 85 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -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")
2628
def 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+
97100
def 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")
121132
def 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")
154165
def 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

Comments
 (0)