diff --git a/Contents/Code/default_prefs.py b/Contents/Code/default_prefs.py index 57221500..7d344da8 100644 --- a/Contents/Code/default_prefs.py +++ b/Contents/Code/default_prefs.py @@ -22,4 +22,5 @@ int_webapp_http_port='9494', bool_webapp_log_werkzeug_messages='False', bool_migrate_locked_themes='False', + bool_migrate_locked_collection_fields='False', ) diff --git a/Contents/Code/migration_helper.py b/Contents/Code/migration_helper.py index bcb7e43c..fe1938e8 100644 --- a/Contents/Code/migration_helper.py +++ b/Contents/Code/migration_helper.py @@ -49,6 +49,7 @@ class MigrationHelper: """ # Define the migration keys as class attributes for dot notation access LOCKED_THEMES = 'locked_themes' + LOCKED_COLLECTION_FIELDS = 'locked_collection_fields' def __init__(self): self.migration_status_file = os.path.join(themerr_data_directory, 'migration_status.json') @@ -57,6 +58,7 @@ def __init__(self): # Map keys to their respective functions self.migration_functions = { self.LOCKED_THEMES: self.migrate_locked_themes, + self.LOCKED_COLLECTION_FIELDS: self.migrate_locked_collection_fields, } def _validate_migration_key(self, key, raise_exception=False): @@ -189,13 +191,16 @@ def migrate_locked_themes(): 'tv.plex.agents.movie', 'com.plexapp.agents.imdb', 'com.plexapp.agents.themoviedb', - 'dev.lizardbyte.retroarcher-plex' + 'dev.lizardbyte.retroarcher-plex', ) for section in sections: if section.agent not in contributes_to: continue # skip items with unsupported metadata agents for < v0.3.0 + if section.type != 'movie': + continue # skip non-movie sections + field = 'theme' # not sure if this unlocks themes for collections @@ -221,6 +226,50 @@ def migrate_locked_themes(): if item.isLocked(field=field): plex_api_helper.change_lock_status(item=item, field=field, lock=False) + @staticmethod + def migrate_locked_collection_fields(): + """ + Unlock fields locked in collections. + + Prior to v0.3.0, fields for collections modified by Themerr-plex were locked which leads to an issue in v0.3.0 + and newer, since Themerr-plex will not update locked fields. + """ + plex = plex_api_helper.setup_plexapi() + + plex_library = plex.library + + sections = plex_library.sections() + + # never update this list, it needs to match what was available before v0.3.0 + contributes_to = ( + 'tv.plex.agents.movie', + 'com.plexapp.agents.imdb', + 'com.plexapp.agents.themoviedb', + 'dev.lizardbyte.retroarcher-plex', + ) + + for section in sections: + if section.agent not in contributes_to: + continue # skip items with unsupported metadata agents for < v0.3.0 + + if section.type != 'movie': + continue # skip non-movie sections + + fields = [ + 'art', + 'summary', + 'thumb', + ] + + # collections were added in v0.3.0, but collect them as well for anyone who may have used a nightly build + # get all collections in the section + collections = section.collections() + + for item in collections: + for field in fields: + if item.isLocked(field=field) and item.theme: # only unlock fields for collections with themes + plex_api_helper.change_lock_status(item=item, field=field, lock=False) + def perform_migration(self, key): # type: (str) -> None """ diff --git a/Contents/DefaultPrefs.json b/Contents/DefaultPrefs.json index fdbbfa6a..868b9995 100644 --- a/Contents/DefaultPrefs.json +++ b/Contents/DefaultPrefs.json @@ -151,7 +151,14 @@ { "id": "bool_migrate_locked_themes", "type": "bool", - "label": "Migrate from < v0.3.0 (If you used Themerr before v0.3.0, set this to True)", + "label": "Migrate themes from < v0.3.0 (If you used Themerr before v0.3.0, set this to True)", + "default": "False", + "secure": "false" + }, + { + "id": "bool_migrate_locked_collection_fields", + "type": "bool", + "label": "Migrate collection metadata from < v0.3.0 (If you used Themerr before v0.3.0, set this to True)", "default": "False", "secure": "false" } diff --git a/docs/source/about/usage.rst b/docs/source/about/usage.rst index 13929b14..f0c08923 100644 --- a/docs/source/about/usage.rst +++ b/docs/source/about/usage.rst @@ -294,3 +294,28 @@ Description Default ``False`` + +Migrate themes from < v0.3.0 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Description + Prior to v0.3.0, Themerr-plex uploaded themes were locked and there was no way to determine if a theme was supplied + by Themerr-plex. Therefore, if you used Themerr-plex prior to v0.3.0, you will need to enable this setting to + automatically unlock all existing themes (for agents that Themerr-plex supports). Once the migration has completed, + the unlock function will never run again. + + If you see many of the ``Unknown provider`` status in the web UI, it is a good indication that you need to enable + this option, unless you have many themes provided by other tools. + +Default + ``False`` + +Migrate collection metadata from < v0.3.0 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Description + Prior to v0.3.0, fields for collections modified by Themerr-plex were locked which leads to an issue in v0.3.0 + and newer, since Themerr-plex will not update locked fields. + +Default + ``False`` diff --git a/tests/unit/test_migration_helper.py b/tests/unit/test_migration_helper.py index 97aa413e..897188c8 100644 --- a/tests/unit/test_migration_helper.py +++ b/tests/unit/test_migration_helper.py @@ -37,6 +37,8 @@ def migration_status_file(migration_helper_fixture): @pytest.mark.parametrize('key, raise_exception, expected_return, expected_raise', [ (migration_helper_object.LOCKED_THEMES, False, True, None), (migration_helper_object.LOCKED_THEMES, True, True, None), + (migration_helper_object.LOCKED_COLLECTION_FIELDS, False, True, None), + (migration_helper_object.LOCKED_COLLECTION_FIELDS, True, True, None), ('invalid', False, False, None), ('invalid', True, False, AttributeError), ]) @@ -51,6 +53,7 @@ def test_validate_migration_key(migration_helper_fixture, key, raise_exception, @pytest.mark.parametrize('key, expected', [ (migration_helper_object.LOCKED_THEMES, None), + (migration_helper_object.LOCKED_COLLECTION_FIELDS, None), pytest.param('invalid', None, marks=pytest.mark.xfail(raises=AttributeError)), ]) def test_get_migration_status(migration_helper_fixture, migration_status_file, key, expected): @@ -60,6 +63,7 @@ def test_get_migration_status(migration_helper_fixture, migration_status_file, k @pytest.mark.parametrize('key', [ migration_helper_object.LOCKED_THEMES, + migration_helper_object.LOCKED_COLLECTION_FIELDS, pytest.param('invalid', marks=pytest.mark.xfail(raises=AttributeError)), ]) def test_set_migration_status(migration_helper_fixture, migration_status_file, key): @@ -72,6 +76,7 @@ def test_set_migration_status(migration_helper_fixture, migration_status_file, k @pytest.mark.parametrize('key', [ migration_helper_object.LOCKED_THEMES, + migration_helper_object.LOCKED_COLLECTION_FIELDS, ]) def test_perform_migration(migration_helper_fixture, migration_status_file, key): # perform the migration twice, should return early on the second run @@ -97,3 +102,21 @@ def test_migrate_locked_themes(movies): for movie in movies.all(): assert movie.isLocked(field=field) is False, '{} for movie is still locked'.format(field) + + +@pytest.mark.parametrize('field', [ + 'art', + 'summary', + 'thumb', +]) +def test_migrate_locked_collection_fields(field, movies): + # lock all is not working, so lock manually + for item in movies.collections(): + plex_api_helper.change_lock_status(item=item, field=field, lock=True) + assert item.isLocked(field=field) is True, '{} for collection is not locked'.format(field) + + migration_helper_object.migrate_locked_collection_fields() + movies.reload() + + for item in movies.collections(): + assert item.isLocked(field=field) is False, '{} for collection is still locked'.format(field)