269 lines
12 KiB
Python
269 lines
12 KiB
Python
"""
|
|
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.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')
|
|
|
|
|
|
# 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')
|
|
|
|
# Service management commands
|
|
service_parser = core_subparsers.add_parser('service', help='Manage mihomo as a system service')
|
|
service_subparsers = service_parser.add_subparsers(dest='service_command', help='Service operations')
|
|
|
|
# Install service command
|
|
install_service_parser = service_subparsers.add_parser('install', help='Install mihomo as a system service')
|
|
install_service_parser.add_argument('--name', default='mihomo', help='Service name (default: mihomo)')
|
|
install_service_parser.add_argument('--description', default='Mihomo proxy service', help='Service description')
|
|
|
|
# Uninstall service command
|
|
uninstall_service_parser = service_subparsers.add_parser('uninstall', help='Uninstall mihomo system service')
|
|
uninstall_service_parser.add_argument('--name', default='mihomo', help='Service name (default: mihomo)')
|
|
|
|
# Start service command
|
|
start_service_parser = service_subparsers.add_parser('start', help='Start mihomo system service')
|
|
start_service_parser.add_argument('--name', default='mihomo', help='Service name (default: mihomo)')
|
|
|
|
# Stop service command
|
|
stop_service_parser = service_subparsers.add_parser('stop', help='Stop mihomo system service')
|
|
stop_service_parser.add_argument('--name', default='mihomo', help='Service name (default: mihomo)')
|
|
|
|
# Restart service command
|
|
restart_service_parser = service_subparsers.add_parser('restart', help='Restart mihomo system service')
|
|
restart_service_parser.add_argument('--name', default='mihomo', help='Service name (default: mihomo)')
|
|
|
|
# Status service command
|
|
status_service_parser = service_subparsers.add_parser('status', help='Check mihomo system service status')
|
|
status_service_parser.add_argument('--name', default='mihomo', help='Service name (default: mihomo)')
|
|
|
|
# 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)
|
|
elif args.core_command == 'service':
|
|
if not hasattr(args, 'service_command') or not args.service_command:
|
|
parser.parse_args(['core', 'service', '--help'])
|
|
return
|
|
|
|
if args.service_command == 'install':
|
|
success = core_manager.install_service(
|
|
service_name=args.name,
|
|
description=args.description
|
|
)
|
|
if not success:
|
|
sys.exit(1)
|
|
elif args.service_command == 'uninstall':
|
|
success = core_manager.uninstall_service(service_name=args.name)
|
|
if not success:
|
|
sys.exit(1)
|
|
elif args.service_command == 'start':
|
|
success = core_manager.start_service(service_name=args.name)
|
|
if not success:
|
|
sys.exit(1)
|
|
elif args.service_command == 'stop':
|
|
success = core_manager.stop_service(service_name=args.name)
|
|
if not success:
|
|
sys.exit(1)
|
|
elif args.service_command == 'restart':
|
|
success = core_manager.restart_service(service_name=args.name)
|
|
if not success:
|
|
sys.exit(1)
|
|
elif args.service_command == 'status':
|
|
status = core_manager.get_service_status(service_name=args.name)
|
|
print(f"Service '{args.name}' status: {status}")
|
|
else:
|
|
parser.parse_args(['core', 'service', '--help'])
|
|
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() |