aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergey M․ <dstftw@gmail.com>2017-02-15 23:12:10 +0700
committerSergey M․ <dstftw@gmail.com>2017-02-15 23:12:10 +0700
commitdb13c16ef8968613680e2bbc85f373c3e74faf98 (patch)
treeb7de19af0734d99a33310f8935c7f0ed7b52c341
parent1bd05345ea4b91598ec04b8e0d33fd14f9e2eddc (diff)
downloadyoutube-dl-db13c16ef8968613680e2bbc85f373c3e74faf98.zip
youtube-dl-db13c16ef8968613680e2bbc85f373c3e74faf98.tar.gz
youtube-dl-db13c16ef8968613680e2bbc85f373c3e74faf98.tar.bz2
[utils] Add support for quoted string literals in --match-filter (closes #8050, closes #12142, closes #12144)
-rw-r--r--test/test_YoutubeDL.py24
-rw-r--r--youtube_dl/utils.py9
2 files changed, 31 insertions, 2 deletions
diff --git a/test/test_YoutubeDL.py b/test/test_YoutubeDL.py
index 8bf00be..d07c35b 100644
--- a/test/test_YoutubeDL.py
+++ b/test/test_YoutubeDL.py
@@ -1,4 +1,5 @@
#!/usr/bin/env python
+# coding: utf-8
from __future__ import unicode_literals
@@ -606,6 +607,8 @@ class TestYoutubeDL(unittest.TestCase):
'duration': 30,
'filesize': 10 * 1024,
'playlist_id': '42',
+ 'uploader': "變態妍字幕版 太妍 тест",
+ 'creator': "тест ' 123 ' тест--",
}
second = {
'id': '2',
@@ -616,6 +619,7 @@ class TestYoutubeDL(unittest.TestCase):
'description': 'foo',
'filesize': 5 * 1024,
'playlist_id': '43',
+ 'uploader': "тест 123",
}
videos = [first, second]
@@ -656,6 +660,26 @@ class TestYoutubeDL(unittest.TestCase):
res = get_videos(f)
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):
entries = [{
'id': compat_str(i),
diff --git a/youtube_dl/utils.py b/youtube_dl/utils.py
index 1279a90..07c07be 100644
--- a/youtube_dl/utils.py
+++ b/youtube_dl/utils.py
@@ -2383,6 +2383,7 @@ def _match_one(filter_part, dct):
\s*(?P<op>%s)(?P<none_inclusive>\s*\?)?\s*
(?:
(?P<intval>[0-9.]+(?:[kKmMgGtTpPeEzZyY]i?[Bb]?)?)|
+ (?P<quote>["\'])(?P<quotedstrval>(?:\\.|(?!(?P=quote)|\\).)+?)(?P=quote)|
(?P<strval>(?![0-9.])[a-z0-9A-Z]*)
)
\s*$
@@ -2391,7 +2392,8 @@ def _match_one(filter_part, dct):
if m:
op = COMPARISON_OPERATORS[m.group('op')]
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
# a number we should respect the origin of the original field
# and process comparison value as a string (see
@@ -2401,7 +2403,10 @@ def _match_one(filter_part, dct):
if m.group('op') not in ('=', '!='):
raise ValueError(
'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:
try:
comparison_value = int(m.group('intval'))