From 45016689fa9fe53418dcf5ce0431eb3b34426d28 Mon Sep 17 00:00:00 2001 From: pukkandan Date: Sat, 23 Jan 2021 11:27:27 +0530 Subject: [PATCH] Standardized function for creating dict from repeated options --- README.md | 9 +++++---- youtube_dlc/__init__.py | 29 +++++------------------------ youtube_dlc/options.py | 30 ++++++++++++++++++++++++------ 3 files changed, 34 insertions(+), 34 deletions(-) diff --git a/README.md b/README.md index 643b53349d..ebfad3781d 100644 --- a/README.md +++ b/README.md @@ -435,7 +435,7 @@ Then simply type this --referer URL Specify a custom referer, use if the video access is restricted to one domain --add-header FIELD:VALUE Specify a custom HTTP header and its value, - separated by a colon ':'. You can use this + separated by a colon ":". You can use this option multiple times --bidi-workaround Work around terminals that lack bidirectional text support. Requires bidiv @@ -554,8 +554,8 @@ Then simply type this supported: mp4|flv|ogg|webm|mkv|avi) --postprocessor-args NAME:ARGS Give these arguments to the postprocessors. Specify the postprocessor/executable name - and the arguments separated by a colon ':' - to give the argument to only the specified + and the arguments separated by a colon ":" + to give the argument to the specified postprocessor/executable. Supported postprocessors are: SponSkrub, ExtractAudio, VideoRemuxer, VideoConvertor, @@ -569,7 +569,8 @@ Then simply type this to different postprocessors. You can also specify "PP+EXE:ARGS" to give the arguments to the specified executable only when being - used by the specified postprocessor (Alias: + used by the specified postprocessor. You + can use this option multiple times (Alias: --ppa) -k, --keep-video Keep the intermediate video file on disk after post-processing diff --git a/youtube_dlc/__init__.py b/youtube_dlc/__init__.py index 90479c6ff1..01b1a347b2 100644 --- a/youtube_dlc/__init__.py +++ b/youtube_dlc/__init__.py @@ -70,14 +70,7 @@ def _real_main(argv=None): std_headers['Referer'] = opts.referer # Custom HTTP headers - if opts.headers is not None: - for h in opts.headers: - if ':' not in h: - parser.error('wrong header formatting, it should be key:value, not "%s"' % h) - key, value = h.split(':', 1) - if opts.verbose: - write_string('[debug] Adding header from command line option %s:%s\n' % (key, value)) - std_headers[key] = value + std_headers.update(opts.headers) # Dump user agent if opts.dump_user_agent: @@ -337,21 +330,9 @@ def _real_main(argv=None): if opts.external_downloader_args: external_downloader_args = compat_shlex_split(opts.external_downloader_args) - postprocessor_args = {} - if opts.postprocessor_args is not None: - for string in opts.postprocessor_args: - mobj = re.match(r'(?P\w+(?:\+\w+)?):(?P.*)$', string) - if mobj is None: - if 'sponskrub' not in postprocessor_args: # for backward compatibility - postprocessor_args['sponskrub'] = [] - if opts.verbose: - write_string('[debug] Adding postprocessor args from command line option sponskrub: \n') - pp_key, pp_args = 'default', string - else: - pp_key, pp_args = mobj.group('pp').lower(), mobj.group('args') - if opts.verbose: - write_string('[debug] Adding postprocessor args from command line option %s: %s\n' % (pp_key, pp_args)) - postprocessor_args[pp_key] = compat_shlex_split(pp_args) + if 'default-compat' in opts.postprocessor_args and 'default' not in opts.postprocessor_args: + opts.postprocessor_args.setdefault('sponskrub', []) + opts.postprocessor_args['default'] = opts.postprocessor_args['default-compat'] match_filter = ( None if opts.match_filter is None @@ -486,7 +467,7 @@ def _real_main(argv=None): 'hls_prefer_native': opts.hls_prefer_native, 'hls_use_mpegts': opts.hls_use_mpegts, 'external_downloader_args': external_downloader_args, - 'postprocessor_args': postprocessor_args, + 'postprocessor_args': opts.postprocessor_args, 'cn_verification_proxy': opts.cn_verification_proxy, 'geo_verification_proxy': opts.geo_verification_proxy, 'config_location': opts.config_location, diff --git a/youtube_dlc/options.py b/youtube_dlc/options.py index f1fc9adb24..3e7be14510 100644 --- a/youtube_dlc/options.py +++ b/youtube_dlc/options.py @@ -104,6 +104,20 @@ def parseOpts(overrideArguments=None): def _comma_separated_values_options_callback(option, opt_str, value, parser): setattr(parser.values, option.dest, value.split(',')) + def _dict_from_multiple_values_options_callback( + option, opt_str, value, parser, allowed_keys=r'[\w-]+', delimiter=':', default_key=None, process=None): + + out_dict = getattr(parser.values, option.dest) + mobj = re.match(r'(?i)(?P%s)%s(?P.*)$' % (allowed_keys, delimiter), value) + if mobj is not None: + key, val = mobj.group('key').lower(), mobj.group('val') + elif default_key is not None: + key, val = default_key, value + else: + raise optparse.OptionValueError( + 'wrong %s formatting; it should be %s, not "%s"' % (opt_str, option.metavar, value)) + out_dict[key] = process(val) if callable(process) else val + # No need to wrap help messages if we're on a wide console columns = compat_get_terminal_size().columns max_width = columns if columns else 80 @@ -651,8 +665,9 @@ def parseOpts(overrideArguments=None): ) workarounds.add_option( '--add-header', - metavar='FIELD:VALUE', dest='headers', action='append', - help='Specify a custom HTTP header and its value, separated by a colon \':\'. You can use this option multiple times', + metavar='FIELD:VALUE', dest='headers', default={}, type='str', + action='callback', callback=_dict_from_multiple_values_options_callback, + help='Specify a custom HTTP header and its value, separated by a colon ":". You can use this option multiple times', ) workarounds.add_option( '--bidi-workaround', @@ -975,18 +990,21 @@ def parseOpts(overrideArguments=None): metavar='FORMAT', dest='recodevideo', default=None, help='Re-encode the video into another format if re-encoding is necessary (currently supported: mp4|flv|ogg|webm|mkv|avi)') postproc.add_option( - '--postprocessor-args', '--ppa', metavar='NAME:ARGS', - dest='postprocessor_args', action='append', + '--postprocessor-args', '--ppa', + metavar='NAME:ARGS', dest='postprocessor_args', default={}, type='str', + action='callback', callback=_dict_from_multiple_values_options_callback, + callback_kwargs={'default_key': 'default-compat', 'allowed_keys': r'\w+(?:\+\w+)?', 'process': compat_shlex_split}, help=( 'Give these arguments to the postprocessors. ' 'Specify the postprocessor/executable name and the arguments separated by a colon ":" ' - 'to give the argument to only the specified postprocessor/executable. Supported postprocessors are: ' + 'to give the argument to the specified postprocessor/executable. Supported postprocessors are: ' 'SponSkrub, ExtractAudio, VideoRemuxer, VideoConvertor, EmbedSubtitle, Metadata, Merger, ' 'FixupStretched, FixupM4a, FixupM3u8, SubtitlesConvertor and EmbedThumbnail. ' 'The supported executables are: SponSkrub, FFmpeg, FFprobe, avconf, avprobe and AtomicParsley. ' 'You can use this option multiple times to give different arguments to different postprocessors. ' 'You can also specify "PP+EXE:ARGS" to give the arguments to the specified executable ' - 'only when being used by the specified postprocessor (Alias: --ppa)')) + 'only when being used by the specified postprocessor. ' + 'You can use this option multiple times (Alias: --ppa)')) postproc.add_option( '-k', '--keep-video', action='store_true', dest='keepvideo', default=False,