mirror of
				https://github.com/yt-dlp/yt-dlp.git
				synced 2025-10-31 06:35:12 +00:00 
			
		
		
		
	[utils] Add support for quoted string literals in --match-filter (closes #8050, closes #12142, closes #12144)
This commit is contained in:
		| @@ -1,4 +1,5 @@ | |||||||
| #!/usr/bin/env python | #!/usr/bin/env python | ||||||
|  | # coding: utf-8 | ||||||
|  |  | ||||||
| from __future__ import unicode_literals | from __future__ import unicode_literals | ||||||
|  |  | ||||||
| @@ -606,6 +607,8 @@ class TestYoutubeDL(unittest.TestCase): | |||||||
|             'duration': 30, |             'duration': 30, | ||||||
|             'filesize': 10 * 1024, |             'filesize': 10 * 1024, | ||||||
|             'playlist_id': '42', |             'playlist_id': '42', | ||||||
|  |             'uploader': "變態妍字幕版 太妍 тест", | ||||||
|  |             'creator': "тест ' 123 ' тест--", | ||||||
|         } |         } | ||||||
|         second = { |         second = { | ||||||
|             'id': '2', |             'id': '2', | ||||||
| @@ -616,6 +619,7 @@ class TestYoutubeDL(unittest.TestCase): | |||||||
|             'description': 'foo', |             'description': 'foo', | ||||||
|             'filesize': 5 * 1024, |             'filesize': 5 * 1024, | ||||||
|             'playlist_id': '43', |             'playlist_id': '43', | ||||||
|  |             'uploader': "тест 123", | ||||||
|         } |         } | ||||||
|         videos = [first, second] |         videos = [first, second] | ||||||
|  |  | ||||||
| @@ -656,6 +660,26 @@ class TestYoutubeDL(unittest.TestCase): | |||||||
|         res = get_videos(f) |         res = get_videos(f) | ||||||
|         self.assertEqual(res, ['1']) |         self.assertEqual(res, ['1']) | ||||||
|  |  | ||||||
|  |         f = match_filter_func('uploader = "變態妍字幕版 太妍 тест"') | ||||||
|  |         res = get_videos(f) | ||||||
|  |         self.assertEqual(res, ['1']) | ||||||
|  |  | ||||||
|  |         f = match_filter_func('uploader != "變態妍字幕版 太妍 тест"') | ||||||
|  |         res = get_videos(f) | ||||||
|  |         self.assertEqual(res, ['2']) | ||||||
|  |  | ||||||
|  |         f = match_filter_func('creator = "тест \' 123 \' тест--"') | ||||||
|  |         res = get_videos(f) | ||||||
|  |         self.assertEqual(res, ['1']) | ||||||
|  |  | ||||||
|  |         f = match_filter_func("creator = 'тест \\' 123 \\' тест--'") | ||||||
|  |         res = get_videos(f) | ||||||
|  |         self.assertEqual(res, ['1']) | ||||||
|  |  | ||||||
|  |         f = match_filter_func(r"creator = 'тест \' 123 \' тест--' & duration > 30") | ||||||
|  |         res = get_videos(f) | ||||||
|  |         self.assertEqual(res, []) | ||||||
|  |  | ||||||
|     def test_playlist_items_selection(self): |     def test_playlist_items_selection(self): | ||||||
|         entries = [{ |         entries = [{ | ||||||
|             'id': compat_str(i), |             'id': compat_str(i), | ||||||
|   | |||||||
| @@ -2383,6 +2383,7 @@ def _match_one(filter_part, dct): | |||||||
|         \s*(?P<op>%s)(?P<none_inclusive>\s*\?)?\s* |         \s*(?P<op>%s)(?P<none_inclusive>\s*\?)?\s* | ||||||
|         (?: |         (?: | ||||||
|             (?P<intval>[0-9.]+(?:[kKmMgGtTpPeEzZyY]i?[Bb]?)?)| |             (?P<intval>[0-9.]+(?:[kKmMgGtTpPeEzZyY]i?[Bb]?)?)| | ||||||
|  |             (?P<quote>["\'])(?P<quotedstrval>(?:\\.|(?!(?P=quote)|\\).)+?)(?P=quote)| | ||||||
|             (?P<strval>(?![0-9.])[a-z0-9A-Z]*) |             (?P<strval>(?![0-9.])[a-z0-9A-Z]*) | ||||||
|         ) |         ) | ||||||
|         \s*$ |         \s*$ | ||||||
| @@ -2391,7 +2392,8 @@ def _match_one(filter_part, dct): | |||||||
|     if m: |     if m: | ||||||
|         op = COMPARISON_OPERATORS[m.group('op')] |         op = COMPARISON_OPERATORS[m.group('op')] | ||||||
|         actual_value = dct.get(m.group('key')) |         actual_value = dct.get(m.group('key')) | ||||||
|         if (m.group('strval') is not None or |         if (m.group('quotedstrval') is not None or | ||||||
|  |             m.group('strval') is not None or | ||||||
|             # If the original field is a string and matching comparisonvalue is |             # If the original field is a string and matching comparisonvalue is | ||||||
|             # a number we should respect the origin of the original field |             # a number we should respect the origin of the original field | ||||||
|             # and process comparison value as a string (see |             # and process comparison value as a string (see | ||||||
| @@ -2401,7 +2403,10 @@ def _match_one(filter_part, dct): | |||||||
|             if m.group('op') not in ('=', '!='): |             if m.group('op') not in ('=', '!='): | ||||||
|                 raise ValueError( |                 raise ValueError( | ||||||
|                     'Operator %s does not support string values!' % m.group('op')) |                     'Operator %s does not support string values!' % m.group('op')) | ||||||
|             comparison_value = m.group('strval') or m.group('intval') |             comparison_value = m.group('quotedstrval') or m.group('strval') or m.group('intval') | ||||||
|  |             quote = m.group('quote') | ||||||
|  |             if quote is not None: | ||||||
|  |                 comparison_value = comparison_value.replace(r'\%s' % quote, quote) | ||||||
|         else: |         else: | ||||||
|             try: |             try: | ||||||
|                 comparison_value = int(m.group('intval')) |                 comparison_value = int(m.group('intval')) | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user
	 Sergey M․
					Sergey M․