Source code for gatenet.cli.commands.hotspot

"""
hotspot.py — Implements the 'hotspot' CLI command for Wi-Fi hotspot management.
"""
import json
import sys
from rich.console import Console
from rich.table import Table
from rich.panel import Panel
from rich.text import Text

from gatenet.hotspot import Hotspot, HotspotConfig, SecurityConfig, SecurityType


[docs] def cmd_hotspot(args): """ Wi-Fi hotspot management CLI command. Provides functionality to create, start, stop, and manage Wi-Fi access points. Supports various security configurations and device monitoring. Args: args (argparse.Namespace): action (str): Action to perform ('start', 'stop', 'status', 'devices', 'generate-password') ssid (str, optional): SSID name for the hotspot password (str, optional): Password for the hotspot (if secured) interface (str, optional): Network interface to use (default: wlan0) ip_range (str, optional): IP range for DHCP (default: 192.168.4.0/24) gateway (str, optional): Gateway IP (default: 192.168.4.1) channel (int, optional): Wi-Fi channel (default: 6) security (str, optional): Security type (open, wpa, wpa2, wpa3) hidden (bool, optional): Create hidden SSID output (str, optional): Output format (table, json, plain) Example: .. code-block:: bash gatenet hotspot start --ssid MyHotspot --password mypass123 --security wpa2 gatenet hotspot status --output json gatenet hotspot devices --output table gatenet hotspot stop gatenet hotspot generate-password --length 16 Returns: None """ console = Console() output_format = getattr(args, 'output', 'table') try: if args.action == 'generate-password': _handle_generate_password(args, console, output_format) elif args.action == 'start': _handle_start_hotspot(args, console, output_format) elif args.action == 'stop': _handle_stop_hotspot(console, output_format) elif args.action == 'status': _handle_hotspot_status(console, output_format) elif args.action == 'devices': _handle_connected_devices(console, output_format) else: console.print(f"[red]Unknown action: {args.action}[/red]") sys.exit(1) except Exception as e: if output_format == 'json': result = {"error": str(e), "success": False} console.print(json.dumps(result, indent=2)) else: console.print(f"[red]Error: {e}[/red]") sys.exit(1)
def _handle_generate_password(args, console, output_format): """Generate a secure password for hotspot use.""" length = getattr(args, 'length', 12) password = SecurityConfig.generate_password(length) if output_format == 'json': result = { "password": password, "length": len(password), "strength": "strong", "success": True } console.print(json.dumps(result, indent=2)) elif output_format == 'plain': console.print(password) else: panel = Panel( f"[green]{password}[/green]", title="Generated Password", subtitle=f"Length: {len(password)} characters", border_style="green" ) console.print(panel) def _handle_start_hotspot(args, console, output_format): """Start a Wi-Fi hotspot.""" if not args.ssid: console.print("[red]Error: SSID is required to start hotspot[/red]") sys.exit(1) # Parse and validate security configuration security_type, password = _parse_security_config(args, console) # Create hotspot configuration config = _create_hotspot_config(args, password, security_type) # Create and start hotspot hotspot = Hotspot(config) success = hotspot.start() # Output results _output_start_result(args, config, security_type, success, console, output_format) def _parse_security_config(args, console): """Parse security configuration from arguments.""" security_type = SecurityType.OPEN if hasattr(args, 'security') and args.security: try: security_type = SecurityType(args.security.lower()) except ValueError: console.print(f"[red]Invalid security type: {args.security}[/red]") sys.exit(1) # Validate password if security is not open password = args.password if security_type != SecurityType.OPEN and not password: console.print("[red]Error: Password is required for secured networks[/red]") sys.exit(1) return security_type, password def _create_hotspot_config(args, password, security_type): """Create hotspot configuration from arguments.""" return HotspotConfig( ssid=args.ssid, password=password if security_type != SecurityType.OPEN else None, interface=getattr(args, 'interface', 'wlan0'), ip_range=getattr(args, 'ip_range', '192.168.4.0/24'), gateway=getattr(args, 'gateway', '192.168.4.1'), channel=getattr(args, 'channel', 6), hidden=getattr(args, 'hidden', False) ) def _output_start_result(args, config, security_type, success, console, output_format): """Output the start hotspot result.""" if output_format == 'json': result = { "success": success, "ssid": args.ssid, "security": security_type.value, "interface": config.interface, "gateway": config.gateway, "message": "Hotspot started successfully" if success else "Failed to start hotspot" } console.print(json.dumps(result, indent=2)) elif output_format == 'plain': message = f"Hotspot '{args.ssid}' started successfully" if success else f"Failed to start hotspot '{args.ssid}'" console.print(message) else: _output_start_table(args, config, security_type, success, console) def _output_start_table(args, config, security_type, success, console): """Output start result as a table.""" if success: table = Table(title="Hotspot Started", border_style="green") table.add_column("Property", style="cyan") table.add_column("Value", style="green") table.add_row("SSID", args.ssid) table.add_row("Security", security_type.value.upper()) table.add_row("Interface", config.interface) table.add_row("Gateway", config.gateway) table.add_row("Channel", str(config.channel)) table.add_row("Hidden", "Yes" if config.hidden else "No") console.print(table) else: console.print(f"[red]Failed to start hotspot '{args.ssid}'[/red]") def _handle_stop_hotspot(console, output_format): """Stop the running hotspot.""" # For stop, we need to create a minimal config just to instantiate Hotspot # In a real implementation, you might want to store the running config config = HotspotConfig(ssid="temp") hotspot = Hotspot(config) success = hotspot.stop() if output_format == 'json': result = { "success": success, "message": "Hotspot stopped successfully" if success else "Failed to stop hotspot or no hotspot running" } console.print(json.dumps(result, indent=2)) elif output_format == 'plain': if success: console.print("Hotspot stopped successfully") else: console.print("Failed to stop hotspot or no hotspot running") else: if success: console.print("[green]Hotspot stopped successfully[/green]") else: console.print("[yellow]Failed to stop hotspot or no hotspot running[/yellow]") def _handle_hotspot_status(console, output_format): """Check hotspot status.""" # Create a minimal config for status checking config = HotspotConfig(ssid="temp") hotspot = Hotspot(config) if output_format == 'json': result = { "running": hotspot.is_running, "platform": hotspot.system, "success": True } console.print(json.dumps(result, indent=2)) elif output_format == 'plain': status = "running" if hotspot.is_running else "stopped" console.print(f"Hotspot status: {status}") else: status_color = "green" if hotspot.is_running else "red" status_text = "Running" if hotspot.is_running else "Stopped" table = Table(title="Hotspot Status", border_style=status_color) table.add_column("Property", style="cyan") table.add_column("Value", style=status_color) table.add_row("Status", status_text) table.add_row("Platform", hotspot.system) console.print(table) def _handle_connected_devices(console, output_format): """List connected devices.""" config = HotspotConfig(ssid="temp") hotspot = Hotspot(config) try: devices = hotspot.get_connected_devices() except Exception as e: _output_devices_error(e, console, output_format) return _output_devices_result(devices, console, output_format) def _output_devices_error(error, console, output_format): """Output error for connected devices command.""" if output_format == 'json': result = {"error": str(error), "success": False} console.print(json.dumps(result, indent=2)) else: console.print(f"[red]Error getting connected devices: {error}[/red]") def _output_devices_result(devices, console, output_format): """Output connected devices result.""" if output_format == 'json': result = { "devices": devices, "count": len(devices), "success": True } console.print(json.dumps(result, indent=2)) elif output_format == 'plain': _output_devices_plain(devices, console) else: _output_devices_table(devices, console) def _output_devices_plain(devices, console): """Output devices in plain format.""" if devices: for device in devices: console.print(f"{device.get('ip', 'N/A')} - {device.get('mac', 'N/A')} - {device.get('hostname', 'Unknown')}") else: console.print("No devices connected") def _output_devices_table(devices, console): """Output devices in table format.""" if devices: table = Table(title=f"Connected Devices ({len(devices)})", border_style="green") table.add_column("IP Address", style="cyan") table.add_column("MAC Address", style="yellow") table.add_column("Hostname", style="green") table.add_column("Connection Time", style="blue") for device in devices: table.add_row( device.get('ip', 'N/A'), device.get('mac', 'N/A'), device.get('hostname', 'Unknown'), device.get('connected_time', 'N/A') ) console.print(table) else: console.print("[yellow]No devices currently connected[/yellow]")