diff --git a/VERSION b/VERSION index 154d5881..87631de9 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.16.5-develop38 +1.16.5-develop39 diff --git a/docs/config/libraries.md b/docs/config/libraries.md index f841fdd2..dbf219fe 100644 --- a/docs/config/libraries.md +++ b/docs/config/libraries.md @@ -141,7 +141,7 @@ libraries: - file: config/Overlays.yml ``` -### Remove Overlays +#### Remove Overlays You can remove overlays from a library by adding `remove_overlays: true` to `overlay_path`. diff --git a/docs/config/paths.md b/docs/config/paths.md index 7927cd39..aa2a3eab 100644 --- a/docs/config/paths.md +++ b/docs/config/paths.md @@ -12,11 +12,15 @@ The path types are outlined as follows: * `- git:` refers to a metadata file which is hosted on the [Configs Repo](https://github.com/meisnate12/Plex-Meta-Manager-Configs). * `- repo:` refers to a metadata file which is hosted on a custom repository specified aby the user with the [`custom_repo` Setting Attribute](settings.md#custom-repo). -## Template Variables +## YAML Controls -[Template Variables](../metadata/templates.md#template-variables) can be added to every template in any defined YAML file by adding the `template_variables` attribute to the dictionary defining the file. +You can have some control of yaml files from inside your Configuration file by using YAML Controls. -### Example +### Template Variables + +You can define [Template Variables](../metadata/templates.md#template-variables) that will be added to every template in the associated YAML file by adding the `template_variables` attribute to the dictionary defining the file. + +#### Example ```yaml libraries: @@ -26,6 +30,10 @@ libraries: template_variables: schedule_separator: never collection_mode: hide + - git: PMM/actor # Notice how the `-` starts this "section" + template_variables: + schedule_separator: never + collection_mode: hide ``` In this example there will be two template variables added to every template in the git file PMM/genre. @@ -34,6 +42,26 @@ In this example there will be two template variables added to every template in What these variables will do depends on how they're defined in the Metadata File. +### Schedule + +Each [`metadata_path`](libraries.md#metadata-path), [`overlay_path`](libraries.md#overlay-path), or [`playlist_files`](libraries.md#metadata-path) can be scheduled by adding the `schedule` attribute to the dictionary defining the file. + +Below is an example of a scheduled Metadata File, Overlay File, and Playlist File: + +```yaml +libraries: + Movies: + schedule: weekly(saturday) + metadata_path: + - file: config/Movies.yml + schedule: weekly(friday) + overlay_path: + - git: PMM/overlays/imdb +playlist_files: + - file: config/Playlists.yml + schedule: weekly(sunday) +``` + ## Metadata Path The [`metadata_path`](libraries.md#metadata-path) attribute is defined under the [`libraries`](libraries) attribute in your [Configuration File](configuration). @@ -67,6 +95,39 @@ Within the above example, PMM will: +## Overlay Path + +The [`overlay_path`](libraries.md#overlay-path) attribute is defined under the [`libraries`](libraries) attribute in your [Configuration File](configuration). + +### Example + +
+ Click to Expand +
+ +In this example, multiple overlay file path types are defined for the `"TV Shows"` library: + +```yaml +libraries: + TV Shows: + overlay_apth: + - file: config/overlays.yml + - folder: config/overlay configs/ + - git: PMM/overlays/imdb + - repo: overlays + - url: https://somewhere.com/Overlays.yml +``` + +Within the above example, PMM will: + +* First, look within the root of the PMM directory (also known as `config/`) for a metadata file named `overlays.yml`. If this file does not exist, PMM will skip the entry and move to the next one in the list. +* Then, look within the root of the PMM directory (also known as `config/`) for a directory called `overlay configs`, and then load any metadata files within that directory. +* Then, look at the [meisnate12 folder](https://github.com/meisnate12/Plex-Meta-Manager-Configs/tree/master/meisnate12) within the GitHub Configs Repo for a file called `PMM/overlays/imdb.yml` which it finds [here](https://github.com/meisnate12/Plex-Meta-Manager-Configs/blob/master/PMM/overlays/imdb.yml). +* Then, look at the within the Custom Defined Repo for a file called `overlays.yml`. +* Finally, load the metadata file located at `https://somewhere.com/Overlays.yml` + +
+ ## Playlist Files The [`playlist_files`](libraries.md#playlist-files-attribute) at the top level in your [Configuration File](configuration). diff --git a/docs/metadata/details/schedule.md b/docs/metadata/details/schedule.md index 853d27bb..5c0d789e 100644 --- a/docs/metadata/details/schedule.md +++ b/docs/metadata/details/schedule.md @@ -17,6 +17,27 @@ libraries: mass_critic_rating_update: tmdb ``` +Below is an example of a scheduled Metadata File, Overlay File, and Playlist File: +```yaml +libraries: + Movies: + metadata_path: + - file: config/Movies.yml + schedule: weekly(friday) + - git: meisnate12/MovieCharts + - git: meisnate12/Studios + - git: meisnate12/IMDBGenres + - git: meisnate12/People + overlay_path: + - git: PMM/overlays/imdb + schedule: weekly(saturday) + operations: + mass_critic_rating_update: tmdb +playlist_files: + - file: config/Playlists.yml + schedule: weekly(sunday) +``` + Below is an example of a scheduled collection: ```yaml collections: diff --git a/modules/config.py b/modules/config.py index e48e61ea..d1895c81 100644 --- a/modules/config.py +++ b/modules/config.py @@ -80,6 +80,7 @@ class ConfigFile: self.requested_libraries = util.get_list(attrs["libraries"]) if "libraries" in attrs else None self.requested_metadata_files = util.get_list(attrs["metadata_files"]) if "metadata_files" in attrs else None self.resume_from = attrs["resume"] if "resume" in attrs else None + current_time = datetime.now() yaml.YAML().allow_duplicate_keys = True try: @@ -486,7 +487,7 @@ class ConfigFile: default_playlist_file = os.path.abspath(os.path.join(self.default_dir, "playlists.yml")) logger.warning(f"Config Warning: playlist_files attribute is blank using default: {default_playlist_file}") paths_to_check = [default_playlist_file] - files = util.load_files(paths_to_check, "playlist_files") + files = util.load_files(paths_to_check, "playlist_files", (current_time, self.run_hour, self.ignore_schedules)) if not files: raise Failed("Config Error: No Paths Found for playlist_files") for file_type, playlist_file, temp_vars, asset_directory in files: @@ -560,7 +561,6 @@ class ConfigFile: self.libraries = [] libs = check_for_attribute(self.data, "libraries", throw=True) - current_time = datetime.now() for library_name, lib in libs.items(): if self.requested_libraries and library_name not in self.requested_libraries: @@ -729,7 +729,7 @@ class ConfigFile: if lib and "metadata_path" in lib: if not lib["metadata_path"]: raise Failed("Config Error: metadata_path attribute is blank") - files = util.load_files(lib["metadata_path"], "metadata_path") + files = util.load_files(lib["metadata_path"], "metadata_path", (current_time, self.run_hour, self.ignore_schedules)) if not files: raise Failed("Config Error: No Paths Found for metadata_path") params["metadata_path"] = files @@ -774,16 +774,12 @@ class ConfigFile: err = e if err: raise NotScheduled(f"{err}\n\nOverlays not scheduled to run") + params["overlay_path"] = files except NotScheduled as e: logger.error(e) params["overlay_path"] = [] params["remove_overlays"] = False - - - - params["overlay_path"] = files - logger.info("") logger.separator("Plex Configuration", space=False, border=False) params["plex"] = { diff --git a/modules/util.py b/modules/util.py index 2ce74df7..af9426f2 100644 --- a/modules/util.py +++ b/modules/util.py @@ -291,7 +291,7 @@ def time_window(tw): else: return tw -def load_files(files_to_load, method, file_type="yml"): +def load_files(files_to_load, method, file_type="yml", schedule=None): files = [] for file in get_list(files_to_load, split=False): if isinstance(file, dict): @@ -302,10 +302,11 @@ def load_files(files_to_load, method, file_type="yml"): if "asset_directory" in file and file["asset_directory"] and os.path.exists(file["asset_directory"]): asset_directory = file["asset_directory"] + current = [] def check_dict(attr, name): if attr in file: if file[attr]: - files.append((name, file[attr], temp_vars, asset_directory)) + current.append((name, file[attr], temp_vars, asset_directory)) else: logger.error(f"Config Error: {method} {attr} is blank") @@ -321,9 +322,27 @@ def load_files(files_to_load, method, file_type="yml"): else: yml_files = glob_filter(os.path.join(file["folder"], f"*.{file_type}")) if yml_files: - files.extend([("File", yml, temp_vars, asset_directory) for yml in yml_files]) + current.extend([("File", yml, temp_vars, asset_directory) for yml in yml_files]) else: logger.error(f"Config Error: No {file_type.upper()} (.{file_type}) files found in {file['folder']}") + + if schedule and "schedule" in file and file["schedule"]: + current_time, run_hour, ignore_schedules = schedule + logger.debug(f"Value: {file['schedule']}") + err = None + try: + schedule_check("schedule", file["schedule"], current_time, run_hour) + except NotScheduledRange as e: + err = e + except NotScheduled as e: + if not ignore_schedules: + err = e + if err: + logger.warning(f"{err}\n\nMetadata File{'s' if len(current) > 1 else ''} not scheduled to run") + for file_type, file_path, temp_vars, asset_directory in current: + logger.warning(f"{file_type}: {file_path}") + continue + files.extend(current) else: if os.path.exists(file): files.append(("File", file, {}, None))