Files
scientific-surfing/scientific_surfing/cli.py

177 lines
7.7 KiB
Python

"""
Command-line interface for scientific-surfing package.
"""
import argparse
import sys
from scientific_surfing.subscription_manager import SubscriptionManager
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')
return parser
def main() -> None:
"""Main CLI entry point."""
parser = create_parser()
args = parser.parse_args()
if not args.command:
parser.print_help()
return
try:
if args.command == 'subscription':
if not hasattr(args, 'subcommand') or not args.subcommand:
parser.parse_args(['subscription', '--help'])
return
manager = SubscriptionManager()
if args.subcommand == 'add':
manager.add_subscription(args.name, args.url)
elif args.subcommand == 'refresh':
manager.refresh_subscription(args.name)
elif args.subcommand == 'rm':
manager.delete_subscription(args.name)
elif args.subcommand == 'rename':
manager.rename_subscription(args.name, args.new_name)
elif args.subcommand == 'activate':
manager.activate_subscription(args.name)
elif args.subcommand == 'list':
manager.list_subscriptions()
elif args.subcommand == 'storage':
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
from scientific_surfing.corecfg_manager import CoreConfigManager
from scientific_surfing.core_manager import CoreManager
core_config_manager = CoreConfigManager()
core_manager = CoreManager(core_config_manager)
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()
elif args.core_config_command == 'upgrade':
core_manager.update(version=args.version, force=args.force)
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
from scientific_surfing.corecfg_manager import CoreConfigManager
from scientific_surfing.core_manager import CoreManager
core_config_manager = CoreConfigManager()
core_manager = CoreManager(core_config_manager)
if args.core_command == 'update':
core_manager.update(version=args.version, force=args.force)
else:
parser.parse_args(['core', '--help'])
else:
parser.print_help()
except KeyboardInterrupt:
print("\n❌ Operation cancelled by user")
sys.exit(1)
except Exception as e:
print(f"❌ Error: {e}")
sys.exit(1)
if __name__ == '__main__':
main()