ytdl-sub/src/ytdl_sub/cli/main_args_parser.py
Jesse Bannon 4105c2ed40
[FEATURE] No longer require a config.yaml (#763)
The only required field in a config was `working_directory`. This is now optional (defaults to `.ytdl-sub-working-directory`) making it so a config is no longer required. This sets the stage to onboard noob users who will solely use prebuilt presets in a single subscription file
2023-10-18 09:58:37 -07:00

186 lines
5.8 KiB
Python

import argparse
import dataclasses
from typing import List
from ytdl_sub import __local_version__
from ytdl_sub.utils.logger import LoggerLevels
DEFAULT_CONFIG_FILE_NAME: str = "config.yaml"
@dataclasses.dataclass
class CLIArgument:
short: str
long: str
is_positional: bool = False
class MainArguments:
CONFIG = CLIArgument(
short="-c",
long="--config",
)
DRY_RUN = CLIArgument(
short="-d",
long="--dry-run",
is_positional=True,
)
LOG_LEVEL = CLIArgument(
short="-l",
long="--log-level",
is_positional=True,
)
TRANSACTION_LOG = CLIArgument(
short="-t",
long="--transaction-log",
is_positional=True,
)
SUPPRESS_TRANSACTION_LOG = CLIArgument(
short="-st",
long="--suppress-transaction-log",
is_positional=True,
)
@classmethod
def all(cls) -> List[CLIArgument]:
"""
Returns
-------
List of MainArgument classes
"""
return [
cls.CONFIG,
cls.DRY_RUN,
cls.LOG_LEVEL,
cls.TRANSACTION_LOG,
cls.SUPPRESS_TRANSACTION_LOG,
]
@classmethod
def all_arguments(cls) -> List[str]:
"""
Returns
-------
List of all string args that can be used in the CLI
"""
all_args = []
for arg in cls.all():
all_args.extend([arg.short, arg.long])
return all_args
###################################################################################################
# SHARED OPTIONS
def _add_shared_arguments(arg_parser: argparse.ArgumentParser, suppress_defaults: bool) -> None:
"""
Add shared arguments to sub parsers. Needed to be able to specify args after positional args.
i.e. support both ``ytdl-sub --dry-run sub`` and ``ytdl-sub sub --dry-run``
Parameters
----------
arg_parser
The parser to add shared args to
suppress_defaults
bool. Suppress sub parser defaults so they do not override the defaults in the parent parser
"""
arg_parser.add_argument(
MainArguments.CONFIG.short,
MainArguments.CONFIG.long,
metavar="CONFIGPATH",
type=str,
help=f"path to the config yaml, uses {DEFAULT_CONFIG_FILE_NAME} if not provided",
default=argparse.SUPPRESS if suppress_defaults else None, # Default is set downstream
)
arg_parser.add_argument(
MainArguments.DRY_RUN.short,
MainArguments.DRY_RUN.long,
action="store_true",
help="preview what a download would output, "
"does not perform any video downloads or writes to output directories",
default=argparse.SUPPRESS if suppress_defaults else False,
)
arg_parser.add_argument(
MainArguments.LOG_LEVEL.short,
MainArguments.LOG_LEVEL.long,
metavar="|".join(LoggerLevels.names()),
type=str,
help="level of logs to print to console, defaults to info",
default=argparse.SUPPRESS if suppress_defaults else LoggerLevels.INFO.name,
choices=LoggerLevels.names(),
dest="ytdl_sub_log_level",
)
arg_parser.add_argument(
MainArguments.TRANSACTION_LOG.short,
MainArguments.TRANSACTION_LOG.long,
metavar="TRANSACTIONPATH",
type=str,
help="path to store the transaction log output of all files added, modified, deleted",
default=argparse.SUPPRESS if suppress_defaults else "",
)
arg_parser.add_argument(
MainArguments.SUPPRESS_TRANSACTION_LOG.short,
MainArguments.SUPPRESS_TRANSACTION_LOG.long,
action="store_true",
help="do not output transaction logs to console or file",
default=argparse.SUPPRESS if suppress_defaults else False,
)
###################################################################################################
# GLOBAL PARSER
parser = argparse.ArgumentParser(
description="ytdl-sub: Automate download and adding metadata with YoutubeDL",
)
parser.add_argument("-v", "--version", action="version", version="%(prog)s " + __local_version__)
_add_shared_arguments(parser, suppress_defaults=False)
subparsers = parser.add_subparsers(dest="subparser")
###################################################################################################
# SUBSCRIPTION PARSER
class SubArguments:
UPDATE_WITH_INFO_JSON = CLIArgument(
short="-u",
long="--update-with-info-json",
)
subscription_parser = subparsers.add_parser("sub")
_add_shared_arguments(subscription_parser, suppress_defaults=True)
subscription_parser.add_argument(
"subscription_paths",
metavar="SUBPATH",
nargs="*",
help="path to subscription files, uses subscriptions.yaml if not provided",
default=["subscriptions.yaml"],
)
subscription_parser.add_argument(
SubArguments.UPDATE_WITH_INFO_JSON.short,
SubArguments.UPDATE_WITH_INFO_JSON.long,
action="store_true",
help="update all subscriptions with the current config using info.json files",
default=False,
)
###################################################################################################
# DOWNLOAD PARSER
download_parser = subparsers.add_parser("dl")
###################################################################################################
# VIEW PARSER
class ViewArguments:
SPLIT_CHAPTERS = CLIArgument(
short="-sc",
long="--split-chapters",
)
view_parser = subparsers.add_parser("view")
_add_shared_arguments(view_parser, suppress_defaults=True)
view_parser.add_argument(
ViewArguments.SPLIT_CHAPTERS.short,
ViewArguments.SPLIT_CHAPTERS.long,
action="store_true",
help="View source variables after splitting by chapters",
)
view_parser.add_argument("url", help="URL to view source variables for")