[29] add nightly check and cached is reloaded

This commit is contained in:
meisnate12 2022-04-22 11:24:44 -04:00
parent d91c6bf635
commit 8d1725d397
15 changed files with 76 additions and 55 deletions

View file

@ -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

View file

@ -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

View file

@ -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"
avatar_url: https://raw.githubusercontent.com/meisnate12/Plex-Meta-Manager/master/.github/pmm.png

View file

@ -1 +1 @@
1.16.5-develop28
1.16.5-develop29

View file

@ -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.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>
<td><code>true</code></td>
</tr>
<tr>
<th>Allowed Values</th>
<td><code>true</code> or <code>false</code>
</td>
</tr>
</table>
## Check Nightly
Will check nightly for updates instead of develop.
<table class="dualTable colwidths-auto align-default table">
<tr>
<th>Default Value</th>

View file

@ -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. | &#9989; |
| `url` | URL of Overlay Image Onlin. | &#10060; |
| `git` | Location in the [Configs Repo](https://github.com/meisnate12/Plex-Meta-Manager-Configs) of the Overlay Image. | &#10060; |
| `repo` | Location in the [Custom Repo](../config/settings.md#custom-repo) of the Overlay Image. | &#10060; |
| `group` | Name of the Grouping for this overlay. **`priority` is required when using `group`** | &#10060; |
| `priority` | Priority of this overlay in its group. **`group` is required when using `priority`** | &#10060; |
| Attribute | Description | Required |
|:----------|:--------------------------------------------------------------------------------------------------------------|:--------:|
| `name` | Name of the overlay. Each overlay name should be unique. | &#9989; |
| `url` | URL of Overlay Image Onlin. | &#10060; |
| `git` | Location in the [Configs Repo](https://github.com/meisnate12/Plex-Meta-Manager-Configs) of the Overlay Image. | &#10060; |
| `repo` | Location in the [Custom Repo](../config/settings.md#custom-repo) of the Overlay Image. | &#10060; |
| `group` | Name of the Grouping for this overlay. **`weight` is required when using `group`** | &#10060; |
| `weight` | Weight of this overlay in its group. **`group` is required when using `weight`** | &#10060; |
* 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:

View file

@ -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}")

View file

@ -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

View file

@ -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

View file

@ -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}

View file

@ -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

View file

@ -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:

View file

@ -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 = []

View file

@ -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

View file

@ -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}")