]> jfr.im git - yt-dlp.git/commitdiff
`--match-filter -` to interactively ask for each video
authorpukkandan <redacted>
Thu, 28 Apr 2022 14:33:26 +0000 (20:03 +0530)
committerpukkandan <redacted>
Thu, 28 Apr 2022 14:34:40 +0000 (20:04 +0530)
README.md
yt_dlp/YoutubeDL.py
yt_dlp/minicurses.py
yt_dlp/options.py
yt_dlp/utils.py

index d401acb21fde6288d9d472d2ad0a6e6138093e52..ca931aba3f85c48952c1f38a1ebb514112d6d0ec 100644 (file)
--- a/README.md
+++ b/README.md
@@ -451,7 +451,9 @@ ## Video Selection:
                                      those that have a like count more than 100
                                      (or the like field is not available) and
                                      also has a description that contains the
-                                     phrase "cats & dogs" (ignoring case)
+                                     phrase "cats & dogs" (ignoring case). Use
+                                     "--match-filter -" to interactively ask
+                                     whether to download each video
     --no-match-filter                Do not use generic video filter (default)
     --no-playlist                    Download only the video, if the URL refers
                                      to a video and a playlist
index 4351699b6aa20989a37540616bebbad774d75a15..78345f87aa36b888b5b26150e5045c57207140de 100644 (file)
@@ -413,6 +413,8 @@ class YoutubeDL:
                        every video.
                        If it returns a message, the video is ignored.
                        If it returns None, the video is downloaded.
+                       If it returns utils.NO_DEFAULT, the user is interactively
+                       asked whether to download the video.
                        match_filter_func in utils.py is one example for this.
     no_color:          Do not emit color codes in output.
     geo_bypass:        Bypass geographic restriction via faking X-Forwarded-For
@@ -878,6 +880,7 @@ def trouble(self, message=None, tb=None, is_error=True):
     Styles = Namespace(
         HEADERS='yellow',
         EMPHASIS='light blue',
+        FILENAME='green',
         ID='green',
         DELIM='blue',
         ERROR='red',
@@ -1303,7 +1306,17 @@ def check_filter():
                 except TypeError:
                     # For backward compatibility
                     ret = None if incomplete else match_filter(info_dict)
-                if ret is not None:
+                if ret is NO_DEFAULT:
+                    while True:
+                        filename = self._format_screen(self.prepare_filename(info_dict), self.Styles.FILENAME)
+                        reply = input(self._format_screen(
+                            f'Download "{filename}"? (Y/n): ', self.Styles.EMPHASIS)).lower().strip()
+                        if reply in {'y', ''}:
+                            return None
+                        elif reply == 'n':
+                            return f'Skipping {video_title}'
+                    return True
+                elif ret is not None:
                     return ret
             return None
 
index 9fd679a48dcf7b99be9ad5713cc7d661bb4e45a5..a867fd2898162f18ab05d0172e622f18df34cbfb 100644 (file)
@@ -69,6 +69,7 @@ def format_text(text, f):
             raise SyntaxError(f'Invalid format {" ".join(tokens)!r} in {f!r}')
 
     if fg_color or bg_color:
+        text = text.replace(CONTROL_SEQUENCES['RESET'], f'{fg_color}{bg_color}')
         return f'{fg_color}{bg_color}{text}{CONTROL_SEQUENCES["RESET"]}'
     else:
         return text
index 73bc88b8989da84af1b8491380b92c6486d85efb..725ab89dbec9333146d10526d51a0af2c2f91842 100644 (file)
@@ -471,7 +471,8 @@ def _dict_from_options_callback(
             '!is_live --match-filter "like_count>?100 & description~=\'(?i)\\bcats \\& dogs\\b\'" '
             'matches only videos that are not live OR those that have a like count more than 100 '
             '(or the like field is not available) and also has a description '
-            'that contains the phrase "cats & dogs" (ignoring case)'))
+            'that contains the phrase "cats & dogs" (ignoring case). '
+            'Use "--match-filter -" to interactively ask whether to download each video'))
     selection.add_option(
         '--no-match-filter',
         metavar='FILTER', dest='match_filter', action='store_const', const=None,
index 7faee62ac8a59fd1c2174ee67772f80a8c968ca9..0612139e020fb2008a53b6c72d03b2dcd3954972 100644 (file)
@@ -3407,11 +3407,15 @@ def match_str(filter_str, dct, incomplete=False):
 def match_filter_func(filters):
     if not filters:
         return None
-    filters = variadic(filters)
+    filters = set(variadic(filters))
 
-    def _match_func(info_dict, *args, **kwargs):
-        if any(match_str(f, info_dict, *args, **kwargs) for f in filters):
-            return None
+    interactive = '-' in filters
+    if interactive:
+        filters.remove('-')
+
+    def _match_func(info_dict, incomplete=False):
+        if not filters or any(match_str(f, info_dict, incomplete) for f in filters):
+            return NO_DEFAULT if interactive and not incomplete else None
         else:
             video_title = info_dict.get('title') or info_dict.get('id') or 'video'
             filter_str = ') | ('.join(map(str.strip, filters))