import codecs
import io
+import itertools
import os
import random
import re
)
from .compat import (
compat_getpass,
+ compat_shlex_quote,
workaround_optparse_bug9161,
)
from .cookies import SUPPORTED_BROWSERS
from .extractor import gen_extractors, list_extractors
from .extractor.common import InfoExtractor
from .extractor.adobepass import MSO_INFO
-from .postprocessor.ffmpeg import (
+from .postprocessor import (
FFmpegExtractAudioPP,
FFmpegSubtitlesConvertorPP,
FFmpegThumbnailsConvertorPP,
FFmpegVideoConvertorPP,
FFmpegVideoRemuxerPP,
+ MetadataFromFieldPP,
+ MetadataParserPP,
)
-from .postprocessor.metadatafromfield import MetadataFromFieldPP
from .YoutubeDL import YoutubeDL
if re.match(InfoExtractor.FormatSort.regex, f) is None:
parser.error('invalid format sort string "%s" specified' % f)
- if opts.metafromfield is None:
- opts.metafromfield = []
+ def metadataparser_actions(f):
+ if isinstance(f, str):
+ cmd = '--parse-metadata %s' % compat_shlex_quote(f)
+ try:
+ actions = [MetadataFromFieldPP.to_action(f)]
+ except Exception as err:
+ parser.error(f'{cmd} is invalid; {err}')
+ else:
+ cmd = '--replace-in-metadata %s' % ' '.join(map(compat_shlex_quote, f))
+ actions = ((MetadataParserPP.Actions.REPLACE, x, *f[1:]) for x in f[0].split(','))
+
+ for action in actions:
+ try:
+ MetadataParserPP.validate_action(*action)
+ except Exception as err:
+ parser.error(f'{cmd} is invalid; {err}')
+ yield action
+
+ if opts.parse_metadata is None:
+ opts.parse_metadata = []
if opts.metafromtitle is not None:
- opts.metafromfield.append('title:%s' % opts.metafromtitle)
- for f in opts.metafromfield:
- if re.match(MetadataFromFieldPP.regex, f) is None:
- parser.error('invalid format string "%s" specified for --parse-metadata' % f)
+ opts.parse_metadata.append('title:%s' % opts.metafromtitle)
+ opts.parse_metadata = list(itertools.chain(*map(metadataparser_actions, opts.parse_metadata)))
any_getting = opts.forceprint or opts.geturl or opts.gettitle or opts.getid or opts.getthumbnail or opts.getdescription or opts.getfilename or opts.getformat or opts.getduration or opts.dumpjson or opts.dump_single_json
any_printing = opts.print_json
# PostProcessors
postprocessors = []
- if opts.metafromfield:
+ if opts.parse_metadata:
postprocessors.append({
- 'key': 'MetadataFromField',
- 'formats': opts.metafromfield,
+ 'key': 'MetadataParser',
+ 'actions': opts.parse_metadata,
# Run this immediately after extraction is complete
'when': 'pre_process'
})