From 4aae0bcc2cd82e06572718b4db6eba5bc47a9e1c Mon Sep 17 00:00:00 2001 From: Philipp Wolfer Date: Mon, 31 May 2021 23:05:17 +0200 Subject: [PATCH] PICARD-2218: Allow regular expressions in $performer(pattern) --- picard/script/functions.py | 8 +++++++- test/test_script.py | 15 ++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/picard/script/functions.py b/picard/script/functions.py index 7e9d97d90..10333db48 100644 --- a/picard/script/functions.py +++ b/picard/script/functions.py @@ -761,6 +761,7 @@ def func_lenmulti(parser, multi, separator=MULTI_VALUED_JOINER): """`$performer(pattern="",join=", ")` Returns the performers where the performance type (e.g. "vocal") matches `pattern`, joined by `join`. +`pattern` can be a regular expression. _Since Picard 0.10_""" )) @@ -769,7 +770,12 @@ def func_performer(parser, pattern="", join=", "): for name, value in parser.context.items(): if name.startswith("performer:"): name, performance = name.split(':', 2) - if pattern in performance: + try: + match = bool(re.search(pattern, performance)) + except re.error: + # fall back to simple string matching if regex is invalid + match = pattern in performance + if match: values.append(value) return join.join(values) diff --git a/test/test_script.py b/test/test_script.py index 4373696d8..8a3ac48da 100644 --- a/test/test_script.py +++ b/test/test_script.py @@ -3,7 +3,7 @@ # Picard, the next-generation MusicBrainz tagger # # Copyright (C) 2007 Lukáš Lalinský -# Copyright (C) 2010, 2014, 2018-2020 Philipp Wolfer +# Copyright (C) 2010, 2014, 2018-2021 Philipp Wolfer # Copyright (C) 2012 Chad Wilson # Copyright (C) 2013 Michael Wiencek # Copyright (C) 2013, 2017-2020 Laurent Monin @@ -942,6 +942,19 @@ class ScriptParserTest(PicardTestCase): self.assertEqual({'Foo1', 'Foo2', 'Foo3', 'Drummer'}, set(result.split(', '))) self.assertScriptResultEquals("$performer(perf)", "", context) + def test_cmd_performer_regex(self): + context = Metadata() + context['performer:guitar'] = 'Foo1' + context['performer:guitars'] = 'Foo2' + context['performer:rhythm-guitar'] = 'Foo3' + context['performer:drums (drum kit)'] = 'Drummer' + result = self.parser.eval(r"$performer(^guitar)", context=context) + self.assertEqual({'Foo1', 'Foo2'}, set(result.split(', '))) + result = self.parser.eval(r"$performer(^guitar\$)", context=context) + self.assertEqual({'Foo1'}, set(result.split(', '))) + result = self.parser.eval(r"$performer(drums \()", context=context) + self.assertEqual({'Drummer'}, set(result.split(', '))) + def test_cmd_performer_custom_join(self): context = Metadata() context['performer:guitar'] = 'Foo1'