""" Command-line interface for scientific-surfing package. """ import argparse import sys from scientific_surfing.storage import StorageManager from scientific_surfing.subscription_manager import SubscriptionManager from scientific_surfing.corecfg_manager import CoreConfigManager from scientific_surfing.corecfg_manager import CoreConfigManager from scientific_surfing.core_manager import CoreManager from scientific_surfing.hook_manager import HookManager def create_parser() -> argparse.ArgumentParser: """Create the argument parser.""" parser = argparse.ArgumentParser( description="Scientific Surfing - CLI for managing clash RSS subscriptions" ) subparsers = parser.add_subparsers(dest='command', help='Available commands') # Subscription commands subscription_parser = subparsers.add_parser('subscription', help='Manage subscriptions') subscription_subparsers = subscription_parser.add_subparsers(dest='subcommand', help='Subscription operations') # Add subscription command add_parser = subscription_subparsers.add_parser('add', help='Add a new subscription') add_parser.add_argument('name', help='Custom name for the subscription') add_parser.add_argument('url', help='Clash RSS subscription URL') # Refresh subscription command refresh_parser = subscription_subparsers.add_parser('refresh', help='Refresh a subscription') refresh_parser.add_argument('name', help='Name of the subscription to refresh') # Delete subscription command (rm) delete_parser = subscription_subparsers.add_parser('rm', help='Delete a subscription') delete_parser.add_argument('name', help='Name of the subscription to delete') # Rename subscription command rename_parser = subscription_subparsers.add_parser('rename', help='Rename a subscription') rename_parser.add_argument('name', help='Current name of the subscription') rename_parser.add_argument('new_name', help='New name for the subscription') # Activate subscription command activate_parser = subscription_subparsers.add_parser('activate', help='Activate a subscription') activate_parser.add_argument('name', help='Name of the subscription to activate') # List subscriptions command list_parser = subscription_subparsers.add_parser('list', help='List all subscriptions') # Storage info command storage_parser = subscription_subparsers.add_parser('storage', help='Show storage information') # Core config commands core_config_parser = subparsers.add_parser('core-config', help='Manage core configuration') core_config_subparsers = core_config_parser.add_subparsers(dest='core_config_command', help='Configuration operations') # Import config import_parser = core_config_subparsers.add_parser('import', help='Import configuration from file') import_parser.add_argument('source', help='Path to configuration file to import') # Export config export_parser = core_config_subparsers.add_parser('export', help='Export configuration to file') export_parser.add_argument('destination', help='Path to save configuration file') # Edit config edit_parser = core_config_subparsers.add_parser('edit', help='Edit configuration with system editor') # Reset config reset_parser = core_config_subparsers.add_parser('reset', help='Reset configuration to default values') # Show config show_parser = core_config_subparsers.add_parser('show', help='Show current configuration') # Apply config apply_parser = core_config_subparsers.add_parser('apply', help='Apply active subscription to generate final config') # Upgrade mihomo binary upgrade_parser = core_config_subparsers.add_parser('upgrade', help='Download and upgrade mihomo binary from GitHub releases') upgrade_parser.add_argument('--version', help='Specific version to download (e.g., v1.18.5). If not specified, downloads latest') upgrade_parser.add_argument('--force', action='store_true', help='Force download even if binary already exists') # Core commands core_parser = subparsers.add_parser('core', help='Manage scientific-surfing core components') core_subparsers = core_parser.add_subparsers(dest='core_command', help='Core operations') # Update core command update_parser = core_subparsers.add_parser('update', help='Update scientific-surfing core components') update_parser.add_argument('--version', help='Specific version to download (e.g., v1.18.5). If not specified, downloads latest') update_parser.add_argument('--force', action='store_true', help='Force update even if binary already exists') # Hook commands hook_parser = subparsers.add_parser('hook', help='Manage hook scripts') hook_subparsers = hook_parser.add_subparsers(dest='hook_command', help='Hook operations') # Init hooks command init_parser = hook_subparsers.add_parser('init', help='Initialize hooks directory with template scripts') # Show hooks command list_hooks_parser = hook_subparsers.add_parser('list', help='Show hooks directory location and list scripts') # Edit hook command edit_hook_parser = hook_subparsers.add_parser('edit', help='Edit a hook script') edit_hook_parser.add_argument('script', help='Name of the script to edit') # Remove hook command rm_hook_parser = hook_subparsers.add_parser('rm', help='Remove a hook script') rm_hook_parser.add_argument('script', help='Name of the script to remove') return parser def main() -> None: """Main CLI entry point.""" parser = create_parser() args = parser.parse_args() if not args.command: parser.print_help() return storage = StorageManager() subscription_manager = SubscriptionManager(storage) core_config_manager = CoreConfigManager(subscription_manager) core_manager = CoreManager(core_config_manager) hook_manager = HookManager(storage) try: if args.command == 'subscription': if not hasattr(args, 'subcommand') or not args.subcommand: parser.parse_args(['subscription', '--help']) return if args.subcommand == 'add': subscription_manager.add_subscription(args.name, args.url) elif args.subcommand == 'refresh': subscription_manager.refresh_subscription(args.name) elif args.subcommand == 'rm': subscription_manager.delete_subscription(args.name) elif args.subcommand == 'rename': subscription_manager.rename_subscription(args.name, args.new_name) elif args.subcommand == 'activate': subscription_manager.activate_subscription(args.name) elif args.subcommand == 'list': subscription_manager.list_subscriptions() elif args.subcommand == 'storage': subscription_manager.show_storage_info() else: parser.parse_args(['subscription', '--help']) elif args.command == 'core-config': if not hasattr(args, 'core_config_command') or not args.core_config_command: parser.parse_args(['core-config', '--help']) return if args.core_config_command == 'import': core_config_manager.import_config(args.source) elif args.core_config_command == 'export': core_config_manager.export_config(args.destination) elif args.core_config_command == 'edit': core_config_manager.edit_config() elif args.core_config_command == 'reset': core_config_manager.reset_config() elif args.core_config_command == 'show': core_config_manager.show_config() elif args.core_config_command == 'apply': core_config_manager.apply() else: parser.parse_args(['core-config', '--help']) elif args.command == 'core': if not hasattr(args, 'core_command') or not args.core_command: parser.parse_args(['core', '--help']) return if args.core_command == 'update': core_manager.update(version=args.version, force=args.force) else: parser.parse_args(['core', '--help']) elif args.command == 'hook': if not hasattr(args, 'hook_command') or not args.hook_command: parser.parse_args(['hook', '--help']) return if args.hook_command == 'init': hook_manager.init() elif args.hook_command == 'list': hook_manager.list() elif args.hook_command == 'edit': hook_manager.edit(args.script) elif args.hook_command == 'rm': hook_manager.rm(args.script) else: parser.parse_args(['hook', '--help']) else: parser.print_help() except KeyboardInterrupt: print("\nāŒ Operation cancelled by user") sys.exit(1) except Exception as e: print(f"āŒ Error: {e}") raise sys.exit(1) if __name__ == '__main__': main()