diff --git a/.github/workflows/develop.yml b/.github/workflows/develop.yml index d7c89cf9..58afa73c 100644 --- a/.github/workflows/develop.yml +++ b/.github/workflows/develop.yml @@ -18,6 +18,7 @@ jobs: webhook_id: ${{ secrets.DEVELOP_WEBHOOK_ID }} webhook_token: ${{ secrets.DEVELOP_WEBHOOK_TOKEN }} title: Plex Meta Manager Develop Commits + message: "@Develop Notifications" commits: "true" username: Metabot avatar_url: https://raw.githubusercontent.com/meisnate12/Plex-Meta-Manager/develop/.github/pmm.png diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index aeae719d..af68b96f 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -15,9 +15,10 @@ jobs: - name: Send Discord Commit Notification uses: meisnate12/discord-notifications@master with: - webhook_id: ${{ secrets.BUILD_WEBHOOK_ID }} - webhook_token: ${{ secrets.BUILD_WEBHOOK_TOKEN }} + webhook_id: ${{ secrets.NIGHTLY_WEBHOOK_ID }} + webhook_token: ${{ secrets.NIGHTLY_WEBHOOK_TOKEN }} title: Nightly Commits + message: "@Nightly Notifications" commits: "true" username: Metabot avatar_url: https://raw.githubusercontent.com/meisnate12/Plex-Meta-Manager/nightly/.github/pmm.png diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 06de3d4a..876922f5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,6 +18,6 @@ jobs: webhook_token: ${{ secrets.RELEASE_WEBHOOK_TOKEN }} release: true title: Plex Meta Manager Release VERSION + message: "@Master Notifications" username: Metabot - avatar_url: https://raw.githubusercontent.com/meisnate12/Plex-Meta-Manager/master/.github/pmm.png - message: "@everyone" \ No newline at end of file + avatar_url: https://raw.githubusercontent.com/meisnate12/Plex-Meta-Manager/master/.github/pmm.png \ No newline at end of file diff --git a/VERSION b/VERSION index 4770e71a..9f9ec2f3 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.16.5-develop28 +1.16.5-develop29 diff --git a/docs/config/settings.md b/docs/config/settings.md index 0299c75a..ffac1c7f 100644 --- a/docs/config/settings.md +++ b/docs/config/settings.md @@ -53,6 +53,7 @@ The available setting attributes which can be set at each level are outlined bel | [`playlist_sync_to_users`](#playlist-sync-to-users) | ✅ | ❌ | ✅ | | [`custom_repo`](#custom-repo) | ✅ | ❌ | ❌ | | [`verify_ssl`](#verify-ssl) | ✅ | ❌ | ❌ | +| [`check_nightly`](#check-nightly) | ✅ | ❌ | ❌ | ## Cache Cache the Plex GUID and associated IDs for each library item for faster subsequent processing. The cache file is created in the same directory as the configuration file. @@ -529,6 +530,21 @@ Specify where the `repo` attribute's base is when defining `metadata_paths` and ## Verify SSL Turn SSL Verification on or off. + + + + + + + + + +
Default Valuetrue
Allowed Valuestrue or false +
+ +## Check Nightly +Will check nightly for updates instead of develop. + diff --git a/docs/metadata/overlay.md b/docs/metadata/overlay.md index 9a2735ac..963a1b83 100644 --- a/docs/metadata/overlay.md +++ b/docs/metadata/overlay.md @@ -56,17 +56,17 @@ You can specify the Overlay Name in 3 ways. 3. Using a dictionary for more overlay location options. -| Attribute | Description | Required | -|:-----------|:--------------------------------------------------------------------------------------------------------------|:--------:| -| `name` | Name of the overlay. Each overlay name should be unique. | ✅ | -| `url` | URL of Overlay Image Onlin. | ❌ | -| `git` | Location in the [Configs Repo](https://github.com/meisnate12/Plex-Meta-Manager-Configs) of the Overlay Image. | ❌ | -| `repo` | Location in the [Custom Repo](../config/settings.md#custom-repo) of the Overlay Image. | ❌ | -| `group` | Name of the Grouping for this overlay. **`priority` is required when using `group`** | ❌ | -| `priority` | Priority of this overlay in its group. **`group` is required when using `priority`** | ❌ | +| Attribute | Description | Required | +|:----------|:--------------------------------------------------------------------------------------------------------------|:--------:| +| `name` | Name of the overlay. Each overlay name should be unique. | ✅ | +| `url` | URL of Overlay Image Onlin. | ❌ | +| `git` | Location in the [Configs Repo](https://github.com/meisnate12/Plex-Meta-Manager-Configs) of the Overlay Image. | ❌ | +| `repo` | Location in the [Custom Repo](../config/settings.md#custom-repo) of the Overlay Image. | ❌ | +| `group` | Name of the Grouping for this overlay. **`weight` is required when using `group`** | ❌ | +| `weight` | Weight of this overlay in its group. **`group` is required when using `weight`** | ❌ | * If `url`, `git`, and `repo` are all not defined then PMM will look in your `config/overlays` folder for a `.png` file named the same as the `name` attribute. -* Only one overlay with the highest priority per group will be applied. +* Only one overlay with the highest weight per group will be applied. ```yaml overlays: diff --git a/modules/builder.py b/modules/builder.py index 8ba4e2be..a6a9e384 100644 --- a/modules/builder.py +++ b/modules/builder.py @@ -270,7 +270,7 @@ class CollectionBuilder: self.suppress_overlays = [] self.overlay_group = None - self.overlay_priority = None + self.overlay_weight = None if self.overlay: if "overlay" in methods: logger.debug("") @@ -282,13 +282,13 @@ class CollectionBuilder: self.overlay = str(data[methods["overlay"]]["name"]) if "group" in data[methods["overlay"]] and data[methods["overlay"]]["group"]: self.overlay_group = str(data[methods["overlay"]]["group"]) - if "priority" in data[methods["overlay"]] and data[methods["overlay"]]["priority"]: - pri = util.check_num(data[methods["overlay"]]["group"]) + if "weight" in data[methods["overlay"]] and data[methods["overlay"]]["weight"]: + pri = util.check_num(data[methods["overlay"]]["weight"]) if pri is None: - raise Failed(f"{self.Type} Error: overlay priority must be a number") - self.overlay_priority = pri + raise Failed(f"{self.Type} Error: overlay weight must be a number") + self.overlay_weight = pri else: - raise Failed(f"{self.Type} Error: overlay group and overlay priority must be used together") + raise Failed(f"{self.Type} Error: overlay group and overlay weight must be used together") if "git" in data[methods["overlay"]] and data[methods["overlay"]]["git"]: url = f"{util.github_base}{data[methods['overlay']]['git']}.png" elif "repo" in data[methods["overlay"]] and data[methods["overlay"]]["repo"]: @@ -2151,7 +2151,7 @@ class CollectionBuilder: def check_filters(self, item, display): if (self.filters or self.tmdb_filters) and not self.details["only_filter_missing"]: logger.ghost(f"Filtering {display} {item.title}") - self.library.reload(item) + item = self.library.reload(item) if self.tmdb_filters and isinstance(item, (Movie, Show)): if item.ratingKey not in self.library.movie_rating_key_map and item.ratingKey not in self.library.show_rating_key_map: logger.warning(f"Filter Error: No {'TMDb' if self.library.is_movie else 'TVDb'} ID found for {item.title}") diff --git a/modules/config.py b/modules/config.py index 3f93803f..59cdf315 100644 --- a/modules/config.py +++ b/modules/config.py @@ -68,7 +68,6 @@ class ConfigFile: self.default_dir = default_dir self.read_only = attrs["read_only"] if "read_only" in attrs else False self.version = attrs["version"] if "version" in attrs else None - self.latest_version = attrs["latest_version"] if "latest_version" in attrs else None self.no_missing = attrs["no_missing"] if "no_missing" in attrs else None self.test_mode = attrs["test"] if "test" in attrs else False self.trace_mode = attrs["trace"] if "trace" in attrs else False @@ -319,10 +318,13 @@ class ConfigFile: "playlist_sync_to_users": check_for_attribute(self.data, "playlist_sync_to_users", parent="settings", default="all", default_is_none=True), "verify_ssl": check_for_attribute(self.data, "verify_ssl", parent="settings", var_type="bool", default=True), "custom_repo": check_for_attribute(self.data, "custom_repo", parent="settings", default_is_none=True), + "check_nightly": check_for_attribute(self.data, "check_nightly", parent="settings", var_type="bool", default=False), "assets_for_all": check_for_attribute(self.data, "assets_for_all", parent="settings", var_type="bool", default=False, save=False, do_print=False) } self.custom_repo = self.general["custom_repo"].replace("https://github.com/", "https://raw.githubusercontent.com/") if self.general["custom_repo"] else None + self.latest_version = util.current_version(self.version, nightly=self.general["check_nightly"]) + self.session = requests.Session() if not self.general["verify_ssl"]: self.session.verify = False diff --git a/modules/library.py b/modules/library.py index 7d7bed97..39891993 100644 --- a/modules/library.py +++ b/modules/library.py @@ -187,7 +187,7 @@ class Library(ABC): new_poster.save(temp_image) self.upload_poster(item, temp_image) self.edit_tags("label", item, add_tags=[f"{overlay_name} Overlay"]) - self.reload(item) + self.reload(item, force=True) poster_uploaded = True logger.info(f"Detail: Overlay: {overlay_name} applied to {item.title}") except (OSError, BadRequest) as e: @@ -231,7 +231,7 @@ class Library(ABC): pass @abstractmethod - def reload(self, item): + def reload(self, item, force=False): pass @abstractmethod diff --git a/modules/meta.py b/modules/meta.py index 40a7f8c2..1e38a598 100644 --- a/modules/meta.py +++ b/modules/meta.py @@ -424,7 +424,7 @@ class MetadataFile(DataFile): person_limit = util.parse("Config", "limit", dynamic_data, parent=f"{map_name} data", methods=person_methods, datatype="int", default=25, minimum=1) if "limit" in person_methods else None for i, item in enumerate(library.get_all(), 1): try: - self.library.reload(item) + item = self.library.reload(item) for person in getattr(item, f"{auto_type}s")[:person_depth]: if person.id not in people: people[person.id] = {"name": person.tag, "count": 0} diff --git a/modules/operations.py b/modules/operations.py index e1b404ba..6cda07c2 100644 --- a/modules/operations.py +++ b/modules/operations.py @@ -68,7 +68,7 @@ class Operations: for i, item in enumerate(items, 1): try: - self.library.reload(item) + item = self.library.reload(item) except Failed as e: logger.error(e) continue diff --git a/modules/overlays.py b/modules/overlays.py index 242baab2..bae0352f 100644 --- a/modules/overlays.py +++ b/modules/overlays.py @@ -37,8 +37,8 @@ class Overlays: if builder.overlay not in settings: settings[builder.overlay] = { - "keys": [], "suppress": [], "group": None, - "priority": None, "updated": False, "image": None + "keys": [], "suppress": builder.suppress_overlays, "group": builder.overlay_group, + "weight": builder.overlay_weight, "updated": False, "image": None } for method, value in builder.builders: @@ -64,9 +64,6 @@ class Overlays: if added_titles: logger.debug(f"{len(added_titles)} Titles Found: {added_titles}") logger.info(f"{len(added_titles) if added_titles else 'No'} Items found for {builder.overlay}") - - if builder.suppress_overlays: - settings[builder.overlay]["suppress"] = builder.suppress_overlays except Failed as e: logger.error(e) @@ -75,7 +72,7 @@ class Overlays: if over_attrs["group"]: if over_attrs["group"] not in overlay_groups: overlay_groups[over_attrs["group"]] = {} - overlay_groups[over_attrs["group"]][overlay_name] = over_attrs["priority"] + overlay_groups[over_attrs["group"]][overlay_name] = over_attrs["weight"] for rk in over_attrs["keys"]: for suppress_name in over_attrs["suppress"]: if suppress_name in settings and rk in settings[suppress_name]["keys"]: @@ -254,7 +251,7 @@ class Overlays: new_poster.save(temp, "PNG") self.library.upload_poster(item, temp) self.library.edit_tags("label", item, add_tags=["Overlay"], do_print=False) - self.library.reload(item) + self.library.reload(item, force=True) poster_compare = poster.compare if poster else item.thumb logger.info(f"Detail: Overlays: {', '.join(over_names)} applied to {item.title}") except (OSError, BadRequest) as e: diff --git a/modules/plex.py b/modules/plex.py index 8722cb96..571e249b 100644 --- a/modules/plex.py +++ b/modules/plex.py @@ -390,10 +390,6 @@ class Plex(Library): terms = {"title=": title} return self.Plex.search(libtype=libtype, **terms) - @retry(stop_max_attempt_number=6, wait_fixed=10000, retry_on_exception=util.retry_if_not_plex) - def get_labeled_items(self, label): - return self.search(label=label) - @retry(stop_max_attempt_number=6, wait_fixed=10000, retry_on_exception=util.retry_if_not_plex) def fetchItem(self, data): return self.PlexServer.fetchItem(data) @@ -464,18 +460,21 @@ class Plex(Library): collection.sortUpdate(sort=data) @retry(stop_max_attempt_number=6, wait_fixed=10000, retry_on_exception=util.retry_if_not_plex) - def reload(self, item, force=True): + def reload(self, item, force=False): is_full = False + cached_item = item if item.ratingKey in self.cached_items: cached_item, is_full = self.cached_items[item.ratingKey] try: - if not is_full: - item.reload(checkFiles=False, includeAllConcerts=False, includeBandwidths=False, includeChapters=False, - includeChildren=False, includeConcerts=False, includeExternalMedia=False, includeExtras=False, - includeFields=False, includeGeolocation=False, includeLoudnessRamps=False, includeMarkers=False, - includeOnDeck=False, includePopularLeaves=False, includeRelated=False, - includeRelatedCount=0, includeReviews=False, includeStations=False) + if not is_full or force: + cached_item.reload(checkFiles=False, includeAllConcerts=False, includeBandwidths=False, + includeChapters=False, includeChildren=False, includeConcerts=False, + includeExternalMedia=False, includeExtras=False, includeFields=False, + includeGeolocation=False, includeLoudnessRamps=False, includeMarkers=False, + includeOnDeck=False, includePopularLeaves=False, includeRelated=False, + includeRelatedCount=0, includeReviews=False, includeStations=False) self.cached_items[item.ratingKey] = (item, True) + return cached_item except (BadRequest, NotFound) as e: logger.stacktrace() raise Failed(f"Item Failed to Load: {e}") @@ -498,7 +497,7 @@ class Plex(Library): item.uploadArt(url=image.location) else: item.uploadArt(filepath=image.location) - self.reload(item) + self.reload(item, force=True) except BadRequest as e: item.refresh() raise Failed(e) @@ -793,7 +792,7 @@ class Plex(Library): _remove_tags = [t.lower() for t in remove_tags] if remove_tags else [] _sync_tags = [t.lower() for t in sync_tags] if sync_tags else [] try: - self.reload(obj) + obj = self.reload(obj) _item_tags = [item_tag.tag.lower() for item_tag in getattr(obj, key)] except BadRequest: _item_tags = [] diff --git a/modules/util.py b/modules/util.py index 3941f951..e8f0786c 100644 --- a/modules/util.py +++ b/modules/util.py @@ -95,14 +95,22 @@ def make_ordinal(n): def add_zero(number): return str(number) if len(str(number)) > 1 else f"0{number}" -def current_version(develop=False): - url = f"https://raw.githubusercontent.com/meisnate12/Plex-Meta-Manager/{'develop' if develop else 'master'}/VERSION" +def current_version(version, nightly=False): + if nightly: + return get_version("nightly") + elif version[2] > 0: + new_version = get_version("develop") + return get_version("nightly") if new_version[2] < version[2] else new_version + else: + return get_version("master") + +def get_version(level): + url = f"https://raw.githubusercontent.com/meisnate12/Plex-Meta-Manager/{level}/VERSION" try: return parse_version(requests.get(url).content.decode().strip()) except requests.exceptions.ConnectionError: return None - def parse_version(version): split_version = version.split("-develop") return version, split_version[0], int(split_version[1]) if len(split_version) > 1 else 0 diff --git a/plex_meta_manager.py b/plex_meta_manager.py index a72f4c2d..81cfdd12 100644 --- a/plex_meta_manager.py +++ b/plex_meta_manager.py @@ -11,8 +11,8 @@ except ModuleNotFoundError: print("Requirements Error: Requirements are not installed") sys.exit(0) -if sys.version_info[0] != 3 or sys.version_info[1] < 6: - print("Version Error: Version: %s.%s.%s incompatible please use Python 3.6+" % (sys.version_info[0], sys.version_info[1], sys.version_info[2])) +if sys.version_info[0] != 3 or sys.version_info[1] < 7: + print("Version Error: Version: %s.%s.%s incompatible please use Python 3.7+" % (sys.version_info[0], sys.version_info[1], sys.version_info[2])) sys.exit(0) parser = argparse.ArgumentParser() @@ -86,7 +86,6 @@ screen_width = get_arg("PMM_WIDTH", args.width, arg_int=True) debug = get_arg("PMM_DEBUG", args.debug, arg_bool=True) trace = get_arg("PMM_TRACE", args.trace, arg_bool=True) - if screen_width < 90 or screen_width > 300: print(f"Argument Error: width argument invalid: {screen_width} must be an integer between 90 and 300 using the default 100") screen_width = 100 @@ -150,8 +149,7 @@ def start(attrs): logger.info_center("|_| |_|\\___/_/\\_\\ |_| |_|\\___|\\__\\__,_| |_| |_|\\__,_|_| |_|\\__,_|\\__, |\\___|_| ") logger.info_center(" |___/ ") logger.info(f" Version: {version[0]}") - - latest_version = util.current_version() + latest_version = util.current_version(version) new_version = latest_version[0] if latest_version and (version[1] != latest_version[1] or (version[2] and version[2] < latest_version[2])) else None if new_version: logger.info(f" Newest Version: {new_version}") @@ -166,7 +164,6 @@ def start(attrs): attrs["time_obj"] = start_time attrs["read_only"] = read_only_config attrs["version"] = version - attrs["latest_version"] = latest_version attrs["no_missing"] = no_missing logger.separator(debug=True) logger.debug(f"--config (PMM_CONFIG): {config_file}")
Default Value