From 5f75f4525f42b10d1eb0ec87cfb6bdf32b779a53 Mon Sep 17 00:00:00 2001 From: Ryan Rector Date: Sat, 7 Feb 2026 16:47:17 -0700 Subject: [PATCH 1/2] add a whitelist option for "keywords as tags" --- python/scraper_config.py | 6 ++++ .../resource.language.en_gb/strings.po | 8 ++++++ .../resource.language.en_us/strings.po | 8 ++++++ resources/settings.xml | 28 +++++++++++++++++++ 4 files changed, 50 insertions(+) diff --git a/python/scraper_config.py b/python/scraper_config.py index 141ac6cf..43db8485 100644 --- a/python/scraper_config.py +++ b/python/scraper_config.py @@ -75,6 +75,9 @@ def _configure_default_rating(details, settings): def _configure_tags(details, settings): if not settings.getSettingBool('add_tags'): del details['info']['tag'] + elif settings.getSettingBool('enable_tag_whitelist'): + whitelist = set(tag.strip().lower() for tag in settings.getStringList('tag_whitelist')) + details['info']['tag'] = [tag for tag in details['info']['tag'] if tag.lower() in whitelist] return details # pylint: disable=invalid-name @@ -102,6 +105,9 @@ def getSettingNumber(self, id): def getSettingString(self, id): return self._inner_get_setting(id, basestring, '') + def getStringList(self, id): + return self._inner_get_setting(id, list, []) + def _inner_get_setting(self, setting_id, setting_type, default): value = self.data.get(setting_id) if isinstance(value, setting_type): diff --git a/resources/language/resource.language.en_gb/strings.po b/resources/language/resource.language.en_gb/strings.po index c11749d5..729530a4 100644 --- a/resources/language/resource.language.en_gb/strings.po +++ b/resources/language/resource.language.en_gb/strings.po @@ -88,6 +88,14 @@ msgctxt "#30015" msgid "Maximum number of each artwork type - many artwork can cause an error scraping to MySQL database" msgstr "" +msgctxt "#30016" +msgid "Only add whitelisted keywords as tags" +msgstr "" + +msgctxt "#30017" +msgid "Tag whitelist" +msgstr "" + msgctxt "#30100" msgid "Language for Fanart.tv artwork" msgstr "" diff --git a/resources/language/resource.language.en_us/strings.po b/resources/language/resource.language.en_us/strings.po index 9fa36742..39079558 100644 --- a/resources/language/resource.language.en_us/strings.po +++ b/resources/language/resource.language.en_us/strings.po @@ -89,6 +89,14 @@ msgctxt "#30015" msgid "Maximum number of each artwork type - many artwork can cause an error scraping to MySQL database" msgstr "" +msgctxt "#30016" +msgid "Only add whitelisted keywords as tags" +msgstr "" + +msgctxt "#30017" +msgid "Tag whitelist" +msgstr "" + msgctxt "#30100" msgid "Language for Fanart.tv artwork" msgstr "" diff --git a/resources/settings.xml b/resources/settings.xml index bc22d8a3..331a79fa 100644 --- a/resources/settings.xml +++ b/resources/settings.xml @@ -261,6 +261,34 @@ true + + 0 + false + + + true + + + + 0 + aftercreditsstinger, duringcreditsstinger + + + + + + , + true + + + true + true + + + true + 15019 + + 4 0 From a9a42c56df52d4a7ddbc5212bef937b1e7d67f73 Mon Sep 17 00:00:00 2001 From: Ryan Rector Date: Sat, 7 Feb 2026 17:20:14 -0700 Subject: [PATCH 2/2] add and fix test --- test/unittests/test_scraper_config.py | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/test/unittests/test_scraper_config.py b/test/unittests/test_scraper_config.py index cececc25..f019faa6 100644 --- a/test/unittests/test_scraper_config.py +++ b/test/unittests/test_scraper_config.py @@ -1,6 +1,6 @@ # pylint: disable=invalid-name,protected-access,too-many-lines,unused-argument import unittest -from unittest.mock import MagicMock +from unittest.mock import MagicMock, call from python import scraper_config @@ -201,14 +201,14 @@ def test_configure_tags__true(self): tags = ["tag 1", "tag 2"] input_details = {'info': {'tag': tags}} input_settings = MagicMock(spec=['getSettingBool']) - input_settings.getSettingBool.return_value = True + input_settings.getSettingBool.side_effect = [True, False] expected_output = {'info': {'tag': tags}} actual_output = scraper_config._configure_tags(input_details, input_settings) self.assertListEqual(expected_output['info']['tag'], actual_output['info']['tag']) - input_settings.getSettingBool.assert_called_once_with('add_tags') + input_settings.getSettingBool.assert_has_calls([call('add_tags'), call('enable_tag_whitelist')]) def test_configure_tags__false(self): input_details = {'info': {'tag': ["tag 1", "tag 2"]}} @@ -222,6 +222,21 @@ def test_configure_tags__false(self): self.assertDictEqual(expected_output['info'], actual_output['info']) input_settings.getSettingBool.assert_called_once_with('add_tags') + def test_configure_tags__whitelist(self): + tags = ["tag 1", "tag 2"] + input_details = {'info': {'tag': tags}} + input_settings = MagicMock(spec=['getSettingBool', 'getStringList']) + input_settings.getSettingBool.return_value = True + input_settings.getStringList.return_value = ["tag 1", "tag 3"] + + expected_output = {'info': {'tag': ["tag 1"]}} + + actual_output = scraper_config._configure_tags(input_details, input_settings) + + self.assertListEqual(expected_output['info']['tag'], actual_output['info']['tag']) + input_settings.getSettingBool.assert_has_calls([call('add_tags'), call('enable_tag_whitelist')]) + input_settings.getStringList.assert_called_once_with('tag_whitelist') + class TestPathSpecificSettings(unittest.TestCase): def test_getSettingString(self):