]> jfr.im git - yt-dlp.git/blobdiff - yt_dlp/postprocessor/metadataparser.py
Fix bug in 66cf3e1001b6d9a2829fe834c3f9103b0890918e
[yt-dlp.git] / yt_dlp / postprocessor / metadataparser.py
index 96aac9beba65fb402f3f848d42b49b4c714d88a8..5bc435da360b7f21ec92529c82666d960183d776 100644 (file)
@@ -1,5 +1,4 @@
 import re
-
 from enum import Enum
 
 from .common import PostProcessor
@@ -16,7 +15,7 @@ def __init__(self, downloader, actions):
         for f in actions:
             action = f[0]
             assert isinstance(action, self.Actions)
-            self._actions.append(getattr(self, action._value_)(*f[1:]))
+            self._actions.append(getattr(self, action.value)(*f[1:]))
 
     @classmethod
     def validate_action(cls, action, *data):
@@ -26,12 +25,17 @@ def validate_action(cls, action, *data):
         '''
         if not isinstance(action, cls.Actions):
             raise ValueError(f'{action!r} is not a valid action')
-        getattr(cls, action._value_)(cls, *data)
+        getattr(cls, action.value)(cls, *data)  # So this can raise error to validate
 
     @staticmethod
     def field_to_template(tmpl):
         if re.match(r'[a-zA-Z_]+$', tmpl):
             return f'%({tmpl})s'
+
+        from ..YoutubeDL import YoutubeDL
+        err = YoutubeDL.validate_outtmpl(tmpl)
+        if err:
+            raise err
         return tmpl
 
     @staticmethod
@@ -66,7 +70,7 @@ def f(info):
             self.write_debug(f'Searching for {out_re.pattern!r} in {template!r}')
             match = out_re.search(data_to_parse)
             if match is None:
-                self.report_warning(f'Could not interpret {inp!r} as {out!r}')
+                self.to_screen(f'Could not interpret {inp!r} as {out!r}')
                 return
             for attribute, value in match.groupdict().items():
                 info[attribute] = value
@@ -80,7 +84,7 @@ def replacer(self, field, search, replace):
         def f(info):
             val = info.get(field)
             if val is None:
-                self.report_warning(f'Video does not have a {field}')
+                self.to_screen(f'Video does not have a {field}')
                 return
             elif not isinstance(val, str):
                 self.report_warning(f'Cannot replace in field {field} since it is a {type(val).__name__}')
@@ -99,18 +103,23 @@ def f(info):
 class MetadataFromFieldPP(MetadataParserPP):
     @classmethod
     def to_action(cls, f):
-        match = re.match(r'(?P<in>.*?)(?<!\\):(?P<out>.+)$', f)
+        match = re.match(r'(?s)(?P<in>.*?)(?<!\\):(?P<out>.+)$', f)
         if match is None:
             raise ValueError(f'it should be FROM:TO, not {f!r}')
         return (
             cls.Actions.INTERPRET,
             match.group('in').replace('\\:', ':'),
-            match.group('out'))
+            match.group('out'),
+        )
 
     def __init__(self, downloader, formats):
-        MetadataParserPP.__init__(self, downloader, [self.to_action(f) for f in formats])
+        super().__init__(downloader, [self.to_action(f) for f in formats])
 
 
-class MetadataFromTitlePP(MetadataParserPP):  # for backward compatibility
+# Deprecated
+class MetadataFromTitlePP(MetadataParserPP):
     def __init__(self, downloader, titleformat):
-        MetadataParserPP.__init__(self, downloader, [(self.Actions.INTERPRET, 'title', titleformat)])
+        super().__init__(downloader, [(self.Actions.INTERPRET, 'title', titleformat)])
+        self.deprecation_warning(
+            'yt_dlp.postprocessor.MetadataFromTitlePP is deprecated '
+            'and may be removed in a future version. Use yt_dlp.postprocessor.MetadataFromFieldPP instead')