diff --git a/README.md b/README.md index dcd870decb..dcb433810e 100644 --- a/README.md +++ b/README.md @@ -273,7 +273,7 @@ Then simply run `make`. You can also run `make yt-dlp` instead to compile only t --no-mark-watched Do not mark videos watched (default) --no-colors Do not emit color codes in output --compat-options OPTS Options that can help keep compatibility - with youtube-dl and youtube-dlc + with youtube-dl or youtube-dlc configurations by reverting some of the changes made in yt-dlp. See "Differences in default behavior" for details diff --git a/yt_dlp/__init__.py b/yt_dlp/__init__.py index d6479b3ffe..36b2eddbab 100644 --- a/yt_dlp/__init__.py +++ b/yt_dlp/__init__.py @@ -257,35 +257,7 @@ def _real_main(argv=None): else: date = DateRange(opts.dateafter, opts.datebefore) - def parse_compat_opts(): - parsed_compat_opts, compat_opts = set(), opts.compat_opts[::-1] - while compat_opts: - actual_opt = opt = compat_opts.pop().lower() - if opt == 'youtube-dl': - compat_opts.extend(['-multistreams', 'all']) - elif opt == 'youtube-dlc': - compat_opts.extend(['-no-youtube-channel-redirect', '-no-live-chat', 'all']) - elif opt == 'all': - parsed_compat_opts.update(all_compat_opts) - elif opt == '-all': - parsed_compat_opts = set() - else: - if opt[0] == '-': - opt = opt[1:] - parsed_compat_opts.discard(opt) - else: - parsed_compat_opts.update([opt]) - if opt not in all_compat_opts: - parser.error('Invalid compatibility option %s' % actual_opt) - return parsed_compat_opts - - all_compat_opts = [ - 'filename', 'format-sort', 'abort-on-error', 'format-spec', 'no-playlist-metafiles', - 'multistreams', 'no-live-chat', 'playlist-index', 'list-formats', 'no-direct-merge', - 'no-youtube-channel-redirect', 'no-youtube-unavailable-videos', 'no-attach-info-json', - 'embed-thumbnail-atomicparsley', 'seperate-video-versions', 'no-clean-infojson', 'no-keep-subs', - ] - compat_opts = parse_compat_opts() + compat_opts = opts.compat_opts def _unused_compat_opt(name): if name not in compat_opts: diff --git a/yt_dlp/options.py b/yt_dlp/options.py index f2d5deb683..1499991a11 100644 --- a/yt_dlp/options.py +++ b/yt_dlp/options.py @@ -122,6 +122,30 @@ def parseOpts(overrideArguments=None): parser.values, option.dest, current + value if append is True else value + current) + def _set_from_options_callback( + option, opt_str, value, parser, + delim=',', allowed_values=None, process=str.lower, aliases={}): + current = getattr(parser.values, option.dest) + values = [process(value)] if delim is None else process(value).split(delim)[::-1] + while values: + actual_val = val = values.pop() + if val == 'all': + current.update(allowed_values) + elif val == '-all': + current = set() + elif val in aliases: + values.extend(aliases[val]) + else: + if val[0] == '-': + val = val[1:] + current.discard(val) + else: + current.update([val]) + if allowed_values is not None and val not in allowed_values: + raise optparse.OptionValueError(f'wrong {option.metavar} for {opt_str}: {actual_val}') + + setattr(parser.values, option.dest, current) + def _dict_from_options_callback( option, opt_str, value, parser, allowed_keys=r'[\w-]+', delimiter=':', default_key=None, process=None, multiple_keys=True): @@ -241,10 +265,21 @@ def parseOpts(overrideArguments=None): help='Do not emit color codes in output') general.add_option( '--compat-options', - metavar='OPTS', dest='compat_opts', default=[], - action='callback', callback=_list_from_options_callback, type='str', - help=( - 'Options that can help keep compatibility with youtube-dl and youtube-dlc ' + metavar='OPTS', dest='compat_opts', default=set(), type='str', + action='callback', callback=_set_from_options_callback, + callback_kwargs={ + 'allowed_values': { + 'filename', 'format-sort', 'abort-on-error', 'format-spec', 'no-playlist-metafiles', + 'multistreams', 'no-live-chat', 'playlist-index', 'list-formats', 'no-direct-merge', + 'no-youtube-channel-redirect', 'no-youtube-unavailable-videos', 'no-attach-info-json', + 'embed-thumbnail-atomicparsley', 'seperate-video-versions', 'no-clean-infojson', 'no-keep-subs', + }, + 'aliases': { + 'youtube-dl': ['-multistreams', 'all'], + 'youtube-dlc': ['-no-youtube-channel-redirect', '-no-live-chat', 'all'], + } + }, help=( + 'Options that can help keep compatibility with youtube-dl or youtube-dlc ' 'configurations by reverting some of the changes made in yt-dlp. ' 'See "Differences in default behavior" for details'))