Skip to content

Commit 498f6ee

Browse files
author
Tom Softreck
committed
update
1 parent a4e3f76 commit 498f6ee

File tree

3 files changed

+185
-63
lines changed

3 files changed

+185
-63
lines changed

Makefile

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -294,36 +294,45 @@ run-iot: setup-env
294294
@echo "🚀 Running IoT example..."
295295
@make run-example EXAMPLE=iot
296296

297+
# Network scanning scripts
298+
SCAN_SCRIPT=scripts/network_scanner.py
299+
PRINTER_SCRIPT=scripts/printer_scanner.py
300+
301+
# Network scanning
297302
scan-network:
298303
@echo "🔍 Scanning network for devices..."
299-
@python -c "from dialogchain.scanner import NetworkScanner; import asyncio; \
300-
scanner = NetworkScanner(); \
301-
services = asyncio.run(scanner.scan_network()); \
302-
print('\n'.join(f'{s.ip}:{s.port} - {s.service} ({s.banner})' for s in services))"
304+
@python3 $(SCAN_SCRIPT) --network 192.168.1.0/24
303305

304306
scan-cameras:
305-
@echo "📷 Scanning for cameras..."
306-
@python -c "from dialogchain.scanner import NetworkScanner; import asyncio; \
307-
scanner = NetworkScanner(); \
308-
services = asyncio.run(scanner.scan_network(service_types=['rtsp'])); \
309-
print('\n'.join(f'Camera found at rtsp://{s.ip}:{s.port}' for s in services))"
307+
@echo "📷 Scanning for cameras (RTSP, HTTP, ONVIF, etc.)..."
308+
@python3 $(SCAN_SCRIPT) --network 192.168.1.0/24 --service rtsp,http,https,onvif,rtmp,rtmps,rtmpt,rtmpts,rtmpe,rtmpte,rtmfp --port 80-90,443,554,8000-8090,8443,8554,8888,9000-9001,10000-10001
309+
310+
scan-camera:
311+
@echo "🔍 Scanning camera at $(IP)..."
312+
@python3 $(SCAN_SCRIPT) --network $(IP) --service rtsp,http,https,onvif --port 80,81,82,83,84,85,86,87,88,89,90,443,554,8000,8001,8002,8080,8081,8082,8083,8084,8085,8086,8087,8088,8089,8090,8443,8554,8888,9000,9001,10000,10001 --verbose
310313

311314
scan-printers:
312-
@echo "🖨️ Scanning for printers..."
313-
@python -c "import cups; conn = cups.Connection(); \
314-
printers = conn.getPrinters(); \
315-
[print(f'Printer: {p} - {printers[p]["device-uri"]}') for p in printers]"
315+
@echo "🖨️ Listing available printers..."
316+
@python3 $(PRINTER_SCRIPT) list
316317

317318
print-test:
318319
@echo "🖨️ Sending test page to default printer..."
319-
@python -c "import cups; conn = cups.Connection(); \
320-
printers = conn.getPrinters(); \
321-
if printers: \
322-
printer = list(printers.keys())[0]; \
323-
job_id = conn.printFile(printer, '/dev/stdin', 'Test Print', {'raw': 'True'}); \
324-
print(f'✅ Sent test page to {printer} (Job ID: {job_id})'); \
325-
else: \
326-
print('❌ No printers found')" < <(echo 'Hello from DialogChain! This is a test print.')
320+
@echo "Hello from DialogChain! This is a test print." | python3 $(PRINTER_SCRIPT) print
321+
322+
# Advanced scanning options
323+
scan-network-detailed:
324+
@echo "🔍 Detailed network scan (slower but more thorough)..."
325+
@python3 $(SCAN_SCRIPT) --network 192.168.1.0/24 --service rtsp,http,https,ssh,vnc
326+
327+
scan-custom-network:
328+
@echo "🔍 Scanning custom network (usage: make scan-custom-network NETWORK=192.168.0.0/24)"
329+
@python3 $(SCAN_SCRIPT) --network $(or $(NETWORK),192.168.1.0/24)
330+
331+
scan-custom-ports:
332+
@echo "🔍 Scanning custom ports (usage: make scan-custom-ports PORTS=80,443,8080)"
333+
@python3 $(SCAN_SCRIPT) --port $(or $(PORTS),80,443,8080)
334+
335+
327336

328337
run-simple: setup-env
329338
@echo "🚀 Running simple example..."

scripts/network_scanner.py

100644100755
Lines changed: 64 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -104,32 +104,78 @@ async def main():
104104
"""Main function for command-line usage."""
105105
parser = argparse.ArgumentParser(description='Network scanner for DialogChain')
106106
parser.add_argument('--network', '-n', default='192.168.1.0/24',
107-
help='Network to scan in CIDR notation')
107+
help='Network to scan in CIDR notation (default: 192.168.1.0/24)')
108108
parser.add_argument('--service', '-s', action='append',
109-
help='Service types to scan (rtsp, http, etc.)')
110-
parser.add_argument('--port', '-p', type=int, action='append',
111-
help='Specific ports to scan')
109+
help='Service types to scan (rtsp, http, https, ssh, etc.)')
110+
parser.add_argument('--port', '-p', default=None,
111+
help='Comma-separated list of ports or port ranges to scan (e.g., 80,443,8000-9000)')
112112
parser.add_argument('--timeout', '-t', type=float, default=1.0,
113-
help='Connection timeout in seconds')
113+
help='Connection timeout in seconds (default: 1.0)')
114+
parser.add_argument('--verbose', '-v', action='store_true',
115+
help='Show detailed output')
114116

115117
args = parser.parse_args()
116118

119+
# Process ports from --port argument
120+
ports = []
121+
if args.port:
122+
for port_str in args.port.split(','):
123+
port_str = port_str.strip()
124+
if '-' in port_str:
125+
# Handle port ranges (e.g., 8000-9000)
126+
try:
127+
start, end = map(int, port_str.split('-'))
128+
ports.extend(range(start, end + 1))
129+
except (ValueError, IndexError):
130+
print(f"Warning: Invalid port range '{port_str}'. Skipping...")
131+
elif port_str.isdigit():
132+
ports.append(int(port_str))
133+
117134
scanner = SimpleNetworkScanner(timeout=args.timeout)
118-
services = await scanner.scan_network(
119-
network=args.network,
120-
ports=args.port,
121-
service_types=args.service
122-
)
123135

124-
# Print results
125-
print("\nScan Results:")
126-
print("-" * 60)
127-
print(f"{'IP':<15} {'Port':<6} {'Service':<10} {'Status'}")
128-
print("-" * 60)
136+
if args.verbose:
137+
print(f"Starting network scan on {args.network}")
138+
if ports:
139+
print(f"Scanning ports: {', '.join(map(str, ports))}")
140+
if args.service:
141+
print(f"Scanning services: {', '.join(args.service)}")
142+
143+
try:
144+
services = await scanner.scan_network(
145+
network=args.network,
146+
ports=ports if ports else None,
147+
service_types=args.service
148+
)
149+
150+
# Filter only active services
151+
active_services = [s for s in services if s.is_up]
152+
153+
if args.verbose or not active_services:
154+
print("\nScan Results:")
155+
print("-" * 60)
156+
print(f"{'IP':<15} {'Port':<6} {'Service':<10} {'Status'}")
157+
print("-" * 60)
158+
159+
if not active_services:
160+
print("No active services found.")
161+
if not args.verbose:
162+
print("Use -v for more detailed output.")
163+
return
164+
165+
for svc in sorted(active_services, key=lambda x: (x.ip, x.port)):
166+
status = "UP"
167+
print(f"{svc.ip:<15} {svc.port:<6} {svc.service:<10} {status}")
168+
169+
except KeyboardInterrupt:
170+
print("\nScan interrupted by user.")
171+
except Exception as e:
172+
print(f"\nError during scan: {e}")
173+
if args.verbose:
174+
import traceback
175+
traceback.print_exc()
176+
return 1
129177

130-
for svc in sorted(services, key=lambda x: (x.ip, x.port)):
131-
status = "UP" if svc.is_up else "DOWN"
132-
print(f"{svc.ip:<15} {svc.port:<6} {svc.service:<10} {status}")
178+
return 0
133179

134180
if __name__ == "__main__":
135181
asyncio.run(main())

scripts/printer_scanner.py

100644100755
Lines changed: 91 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -56,38 +56,105 @@ def print_text(text: str, printer_name: Optional[str] = None) -> int:
5656

5757
def main() -> int:
5858
"""Main function for command-line usage."""
59-
parser = argparse.ArgumentParser(description='Printer scanner for DialogChain')
60-
subparsers = parser.add_subparsers(dest='command', required=True)
59+
parser = argparse.ArgumentParser(
60+
description='Printer scanner for DialogChain',
61+
formatter_class=argparse.RawDescriptionHelpFormatter,
62+
epilog='''Examples:
63+
%(prog)s list
64+
%(prog)s print
65+
%(prog)s print --printer "My Printer" --text "Test page"
66+
'''
67+
)
68+
69+
subparsers = parser.add_subparsers(dest='command', required=True, title='commands')
6170

6271
# List command
63-
list_parser = subparsers.add_parser('list', help='List available printers')
72+
list_parser = subparsers.add_parser(
73+
'list',
74+
help='List available printers',
75+
description='List all available printers with their details'
76+
)
77+
list_parser.add_argument(
78+
'--verbose', '-v',
79+
action='store_true',
80+
help='Show detailed printer information'
81+
)
6482

6583
# Print command
66-
print_parser = subparsers.add_parser('print', help='Print a test page')
67-
print_parser.add_argument('--printer', '-p', help='Printer name (default: default printer)')
68-
print_parser.add_argument('--text', '-t', default='Hello from DialogChain!',
69-
help='Text to print')
84+
print_parser = subparsers.add_parser(
85+
'print',
86+
help='Print a test page',
87+
description='Print a test page to the specified or default printer'
88+
)
89+
print_parser.add_argument(
90+
'--printer', '-p',
91+
help='Printer name (default: default printer)'
92+
)
93+
print_parser.add_argument(
94+
'--text', '-t',
95+
default='Hello from DialogChain!\nThis is a test print.',
96+
help='Text to print (default: a test message)'
97+
)
98+
print_parser.add_argument(
99+
'--file', '-f',
100+
help='File to print (overrides --text if specified)'
101+
)
70102

71103
args = parser.parse_args()
72104

73-
if args.command == 'list':
74-
printers = list_printers()
75-
if not printers:
76-
print("No printers found")
77-
return 1
105+
try:
106+
if args.command == 'list':
107+
printers = list_printers()
108+
if not printers:
109+
print("❌ No printers found on the system")
110+
print("\nMake sure CUPS is installed and running:")
111+
print(" On Ubuntu/Debian: sudo apt install cups")
112+
print(" On RHEL/CentOS: sudo yum install cups")
113+
print(" Start service: sudo systemctl start cups")
114+
return 1
115+
116+
print(f"\n🖨️ Found {len(printers)} printer(s):")
117+
print("=" * 60)
78118

79-
print("\nAvailable Printers:")
80-
print("-" * 60)
81-
for name, attrs in printers.items():
82-
print(f"Name: {name}")
83-
print(f" URI: {attrs.get('device-uri', 'N/A')}")
84-
print(f" Info: {attrs.get('printer-info', 'N/A')}")
85-
print(f" State: {attrs.get('printer-state-message', 'N/A')}")
86-
print("-" * 60)
87-
return 0
88-
89-
elif args.command == 'print':
90-
return print_text(args.text, args.printer)
119+
for i, (name, attrs) in enumerate(printers.items(), 1):
120+
print(f"{i}. {name}")
121+
print(f" URI: {attrs.get('device-uri', 'N/A')}")
122+
123+
if args.verbose:
124+
print(" Details:")
125+
for key, value in attrs.items():
126+
if key != 'device-uri':
127+
print(f" {key}: {value}")
128+
129+
if i < len(printers):
130+
print("-" * 60)
131+
132+
print("=" * 60)
133+
return 0
134+
135+
elif args.command == 'print':
136+
if args.file:
137+
try:
138+
with open(args.file, 'r') as f:
139+
content = f.read()
140+
print(f"📄 Printing file: {args.file}")
141+
except Exception as e:
142+
print(f"❌ Error reading file: {e}")
143+
return 1
144+
else:
145+
content = args.text
146+
print("📝 Printing text content...")
147+
148+
return print_text(content, args.printer)
149+
150+
except KeyboardInterrupt:
151+
print("\nOperation cancelled by user.")
152+
return 1
153+
except Exception as e:
154+
print(f"\n❌ An error occurred: {e}")
155+
import traceback
156+
traceback.print_exc()
157+
return 1
91158

92159
return 0
93160

0 commit comments

Comments
 (0)