92 lines
3.9 KiB
Python
92 lines
3.9 KiB
Python
#!/usr/bin/env python3
|
|
import sys
|
|
import argparse
|
|
|
|
# Import the functions that define and execute the logic for each subcommand
|
|
from .list_formats_tool import add_list_formats_parser, main_list_formats
|
|
from .get_info_tool import add_get_info_parser, main_get_info
|
|
from .download_tool import add_download_parser, main_download
|
|
from .stress_policy_tool import add_stress_policy_parser, main_stress_policy
|
|
from .stress_formats_tool import add_stress_formats_parser, main_stress_formats
|
|
from .cookie_tool import add_cookie_tool_parser, main_cookie_tool
|
|
from .download_aria_tool import add_download_aria_parser, main_download_aria
|
|
from .download_native_py_tool import add_download_native_py_parser, main_download_native_py
|
|
|
|
def main():
|
|
"""
|
|
Main entry point for the yt-ops-client CLI.
|
|
Parses arguments and dispatches to the appropriate subcommand function.
|
|
"""
|
|
# Workaround for argparse behavior with positional arguments that start with a hyphen.
|
|
# If the command is 'get-info' and the last argument looks like a video ID
|
|
# starting with a '-', we insert '--' before it to tell argparse to treat it
|
|
# as a positional argument, not an option. This assumes the URL is the last argument.
|
|
if len(sys.argv) >= 3 and sys.argv[1] == 'get-info':
|
|
last_arg = sys.argv[-1]
|
|
# A YouTube video ID is 11 characters.
|
|
if last_arg.startswith('-') and len(last_arg) == 11:
|
|
import re
|
|
if re.fullmatch(r'-[a-zA-Z0-9_-]{10}', last_arg):
|
|
# Only insert '--' if it's not already the preceding argument.
|
|
# This prevents `stress_policy_tool` which already adds '--' from causing an error.
|
|
if sys.argv[-2] != '--':
|
|
sys.argv.insert(len(sys.argv) - 1, '--')
|
|
|
|
parser = argparse.ArgumentParser(
|
|
description="YT Ops Client Tools",
|
|
formatter_class=argparse.RawTextHelpFormatter
|
|
)
|
|
subparsers = parser.add_subparsers(dest='command', help='Available sub-commands')
|
|
|
|
# Add subparsers from each tool module
|
|
add_list_formats_parser(subparsers)
|
|
add_get_info_parser(subparsers)
|
|
|
|
# Create a top-level 'download' command with its own subcommands
|
|
download_parser = subparsers.add_parser(
|
|
'download',
|
|
help='Download using different methods.',
|
|
description='Provides access to various download tools. Use "download <method> --help" for details.'
|
|
)
|
|
download_subparsers = download_parser.add_subparsers(dest='download_command', help='Available downloaders', required=True)
|
|
add_download_parser(download_subparsers) # Adds 'cli' subcommand
|
|
add_download_native_py_parser(download_subparsers) # Adds 'py' subcommand
|
|
add_download_aria_parser(download_subparsers) # Adds 'aria-rpc' subcommand
|
|
|
|
add_stress_policy_parser(subparsers)
|
|
add_stress_formats_parser(subparsers)
|
|
add_cookie_tool_parser(subparsers)
|
|
|
|
args = parser.parse_args()
|
|
|
|
# If no command is provided, print help and exit.
|
|
if not args.command:
|
|
parser.print_help()
|
|
return 1
|
|
|
|
# Dispatch to the correct main function based on the command
|
|
if args.command == 'list-formats':
|
|
return main_list_formats(args)
|
|
elif args.command == 'get-info':
|
|
return main_get_info(args)
|
|
elif args.command == 'download':
|
|
if args.download_command == 'cli':
|
|
return main_download(args)
|
|
elif args.download_command == 'py':
|
|
return main_download_native_py(args)
|
|
elif args.download_command == 'aria-rpc':
|
|
return main_download_aria(args)
|
|
elif args.command == 'stress-policy':
|
|
return main_stress_policy(args)
|
|
elif args.command == 'stress-formats':
|
|
return main_stress_formats(args)
|
|
elif args.command == 'convert-cookies':
|
|
return main_cookie_tool(args)
|
|
|
|
# This path should not be reachable if a command is required or handled above.
|
|
parser.print_help()
|
|
return 1
|
|
|
|
if __name__ == "__main__":
|
|
sys.exit(main())
|