[26] added groups and priority

pull/858/head
meisnate12 3 years ago
parent 0b1ca97403
commit 2cc4d0fa43

@ -1 +1 @@
1.16.5-develop25 1.16.5-develop26

@ -56,14 +56,17 @@ You can specify the Overlay Name in 3 ways.
3. Using a dictionary for more overlay location options. 3. Using a dictionary for more overlay location options.
| Attribute | Description | Required | | Attribute | Description | Required |
|:----------|:-------------------------------------------------------------------------------------------------------------|:--------:| |:-----------|:--------------------------------------------------------------------------------------------------------------|:--------:|
| `name` | Name of the overlay. Each overlay name should be unique. | ✅ | | `name` | Name of the overlay. Each overlay name should be unique. | ✅ |
| `url` | URL of Overlay Image Online | ❌ | | `url` | URL of Overlay Image Onlin. | ❌ |
| `git` | Location in the [Configs Repo](https://github.com/meisnate12/Plex-Meta-Manager-Configs) of the Overlay Image | ❌ | | `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 | ❌ | | `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`** | ❌ |
* 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. * 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.
```yaml ```yaml
overlays: overlays:

@ -269,6 +269,8 @@ class CollectionBuilder:
methods[attr.lower()] = attr methods[attr.lower()] = attr
self.suppress_overlays = [] self.suppress_overlays = []
self.overlay_group = None
self.overlay_priority = None
if self.overlay: if self.overlay:
if "overlay" in methods: if "overlay" in methods:
logger.debug("") logger.debug("")
@ -278,6 +280,15 @@ class CollectionBuilder:
if "name" not in data[methods["overlay"]] or not data[methods["overlay"]]["name"]: if "name" not in data[methods["overlay"]] or not data[methods["overlay"]]["name"]:
raise Failed(f"{self.Type} Error: overlay must have the name attribute") raise Failed(f"{self.Type} Error: overlay must have the name attribute")
self.overlay = str(data[methods["overlay"]]["name"]) 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 pri is None:
raise Failed(f"{self.Type} Error: overlay priority must be a number")
self.overlay_priority = pri
else:
raise Failed(f"{self.Type} Error: overlay group and overlay priority must be used together")
if "git" in data[methods["overlay"]] and data[methods["overlay"]]["git"]: if "git" in data[methods["overlay"]] and data[methods["overlay"]]["git"]:
url = f"{util.github_base}{data[methods['overlay']]['git']}.png" url = f"{util.github_base}{data[methods['overlay']]['git']}.png"
elif "repo" in data[methods["overlay"]] and data[methods["overlay"]]["repo"]: elif "repo" in data[methods["overlay"]] and data[methods["overlay"]]["repo"]:
@ -1889,8 +1900,14 @@ class CollectionBuilder:
for name, key in names: for name, key in names:
if name not in used and re.compile(reg).search(name): if name not in used and re.compile(reg).search(name):
valid_list.append((name, key) if plex_search else key) valid_list.append((name, key) if plex_search else key)
if not valid_list:
error = f"Plex Error: {attribute}: No matches found with regex pattern {data}"
if validate:
raise Failed(error)
else:
logger.error(error)
return valid_list return valid_list
elif attribute in plex.tag_attributes and modifier in ["", ".not", ".regex"]: elif attribute in plex.tag_attributes and modifier in ["", ".not"]:
if attribute in plex.tmdb_attributes: if attribute in plex.tmdb_attributes:
final_values = [] final_values = []
for value in util.get_list(data): for value in util.get_list(data):

@ -18,18 +18,15 @@ class Overlays:
logger.info("") logger.info("")
logger.separator(f"{self.library.name} Library Overlays") logger.separator(f"{self.library.name} Library Overlays")
logger.info("") logger.info("")
overlay_to_keys = {}
key_to_item = {} key_to_item = {}
os.makedirs(self.library.overlay_backup, exist_ok=True) os.makedirs(self.library.overlay_backup, exist_ok=True)
overlay_updated = {}
overlay_images = {}
key_to_overlays = {} key_to_overlays = {}
overlay_attrs = {}
if self.library.remove_overlays: if self.library.remove_overlays:
logger.info("") logger.info("")
logger.separator(f"Removing Overlays for the {self.library.name} Library") logger.separator(f"Removing Overlays for the {self.library.name} Library")
logger.info("") logger.info("")
else: else:
overlay_suppression = {}
for overlay_file in self.library.overlay_files: for overlay_file in self.library.overlay_files:
for k, v in overlay_file.overlays.items(): for k, v in overlay_file.overlays.items():
try: try:
@ -38,8 +35,17 @@ class Overlays:
logger.separator(f"Gathering Items for {k} Overlay", space=False, border=False) logger.separator(f"Gathering Items for {k} Overlay", space=False, border=False)
if builder.overlay not in overlay_to_keys: if builder.overlay not in overlay_attrs:
overlay_to_keys[builder.overlay] = [] overlay_attrs[builder.overlay] = {
"keys": [], "suppress": [], "group": None,
"priority": None, "updated": False, "image": None
}
for method, value in builder.builders:
logger.debug("")
logger.debug(f"Builder: {method}: {value}")
logger.info("")
builder.filter_and_save_items(builder.gather_ids(method, value))
if builder.filters or builder.tmdb_filters: if builder.filters or builder.tmdb_filters:
logger.info("") logger.info("")
@ -48,48 +54,68 @@ class Overlays:
for filter_key, filter_value in builder.tmdb_filters: for filter_key, filter_value in builder.tmdb_filters:
logger.info(f"Collection Filter {filter_key}: {filter_value}") logger.info(f"Collection Filter {filter_key}: {filter_value}")
for method, value in builder.builders: added_titles = []
logger.debug("") if builder.added_items:
logger.debug(f"Builder: {method}: {value}") for item in builder.added_items:
logger.info("") key_to_item[item.ratingKey] = item
builder.filter_and_save_items(builder.gather_ids(method, value)) added_titles.append(item.title)
if builder.added_items: if item.ratingKey not in overlay_attrs[builder.overlay]["keys"]:
for item in builder.added_items: overlay_attrs[builder.overlay]["keys"].append(item.ratingKey)
key_to_item[item.ratingKey] = item if added_titles:
if item.ratingKey not in overlay_to_keys[builder.overlay]: logger.debug(f"{len(added_titles)} Titles Found: {added_titles}")
overlay_to_keys[builder.overlay].append(item.ratingKey) logger.info(f"{len(added_titles) if added_titles else 'No'} Items found for {builder.overlay}")
if builder.suppress_overlays: if builder.suppress_overlays:
overlay_suppression[builder.overlay] = builder.suppress_overlays overlay_attrs[builder.overlay]["suppress"] = builder.suppress_overlays
except Failed as e: except Failed as e:
logger.error(e) logger.error(e)
for over_name, suppress_names in overlay_suppression.items(): overlay_groups = {}
for rk in overlay_to_keys[over_name]: for overlay_name, over_attrs in overlay_attrs.items():
for suppress_name in suppress_names: if overlay_attrs["group"]:
if suppress_name in overlay_to_keys and rk in overlay_to_keys[suppress_name]: if overlay_attrs["group"] not in overlay_groups:
overlay_to_keys[suppress_name].remove(rk) overlay_groups[overlay_attrs["group"]] = {}
overlay_groups[overlay_attrs["group"]][overlay_name] = overlay_attrs["priority"]
for overlay_name, over_keys in overlay_to_keys.items(): for rk in over_attrs["keys"]:
if overlay_name == "blur": for suppress_name in over_attrs["suppress"]:
overlay_updated[overlay_name] = False if suppress_name in overlay_attrs and rk in overlay_attrs[suppress_name]["keys"]:
overlay_images[overlay_name] = None overlay_attrs[suppress_name]["keys"].remove(rk)
else: if not overlay_name.startswith("blur"):
clean_name, _ = util.validate_filename(overlay_name) clean_name, _ = util.validate_filename(overlay_name)
image_compare = None image_compare = None
if self.config.Cache: if self.config.Cache:
_, image_compare, _ = self.config.Cache.query_image_map(overlay_name, f"{self.library.image_table_name}_overlays") _, image_compare, _ = self.config.Cache.query_image_map(overlay_name, f"{self.library.image_table_name}_overlays")
overlay_file = os.path.join(self.library.overlay_folder, f"{clean_name}.png") overlay_file = os.path.join(self.library.overlay_folder, f"{clean_name}.png")
overlay_size = os.stat(overlay_file).st_size overlay_size = os.stat(overlay_file).st_size
overlay_updated[overlay_name] = not image_compare or str(overlay_size) != str(image_compare) overlay_attrs[overlay_name]["updated"] = not image_compare or str(overlay_size) != str(image_compare)
overlay_images[overlay_name] = Image.open(overlay_file).convert("RGBA") overlay_attrs[overlay_name]["image"] = Image.open(overlay_file).convert("RGBA")
if self.config.Cache: if self.config.Cache:
self.config.Cache.update_image_map(overlay_name, f"{self.library.image_table_name}_overlays", overlay_name, overlay_size) self.config.Cache.update_image_map(overlay_name, f"{self.library.image_table_name}_overlays", overlay_name, overlay_size)
for over_key in over_keys:
for overlay_name, over_attrs in overlay_attrs.items():
for over_key in over_attrs["keys"]:
if over_key not in key_to_overlays: if over_key not in key_to_overlays:
key_to_overlays[over_key] = (key_to_item[over_key], []) key_to_overlays[over_key] = (key_to_item[over_key], [])
key_to_overlays[over_key][1].append(overlay_name) key_to_overlays[over_key][1].append(overlay_name)
for over_key, (item, over_names) in key_to_overlays.items():
group_status = {}
for over_name in over_names:
for overlay_group, group_names in overlay_groups.items():
if over_name in group_names:
if overlay_group not in group_status:
group_status[overlay_group] = []
group_status[overlay_group].append(over_name)
for gk, gv in group_status.items():
if len(gv) > 1:
final = None
for v in gv:
if final is None or overlay_groups[gk][v] > overlay_groups[gk][final]:
final = v
for v in gv:
if final != v:
key_to_overlays[over_key][1].remove(v)
def find_poster_url(plex_item): def find_poster_url(plex_item):
if isinstance(plex_item, Movie): if isinstance(plex_item, Movie):
if plex_item.ratingKey in self.library.movie_rating_key_map: if plex_item.ratingKey in self.library.movie_rating_key_map:
@ -166,7 +192,7 @@ class Overlays:
overlay_change = True overlay_change = True
if not overlay_change: if not overlay_change:
for over_name in over_names: for over_name in over_names:
if over_name not in overlay_compare or overlay_updated[over_name]: if over_name not in overlay_compare or overlay_attrs[over_name]["updated"]:
overlay_change = True overlay_change = True
clean_name, _ = util.validate_filename(item.title) clean_name, _ = util.validate_filename(item.title)
@ -232,8 +258,8 @@ class Overlays:
new_poster = new_poster.filter(ImageFilter.GaussianBlur(blur_num)) new_poster = new_poster.filter(ImageFilter.GaussianBlur(blur_num))
for over_name in over_names: for over_name in over_names:
if not over_name.startswith("blur"): if not over_name.startswith("blur"):
new_poster = new_poster.resize(overlay_images[over_name].size, Image.ANTIALIAS) new_poster = new_poster.resize(overlay_attrs[over_name]["image"].size, Image.ANTIALIAS)
new_poster.paste(overlay_images[over_name], (0, 0), overlay_images[over_name]) new_poster.paste(overlay_attrs[over_name]["image"], (0, 0), overlay_attrs[over_name]["image"])
new_poster.save(temp, "PNG") new_poster.save(temp, "PNG")
self.library.upload_poster(item, temp) self.library.upload_poster(item, temp)
self.library.edit_tags("label", item, add_tags=["Overlay"], do_print=False) self.library.edit_tags("label", item, add_tags=["Overlay"], do_print=False)

@ -485,6 +485,12 @@ def run_collection(config, library, metadata, requested_collections):
logger.info("") logger.info("")
logger.info(f"Sync Mode: {'sync' if builder.sync else 'append'}") logger.info(f"Sync Mode: {'sync' if builder.sync else 'append'}")
for method, value in builder.builders:
logger.debug("")
logger.debug(f"Builder: {method}: {value}")
logger.info("")
builder.filter_and_save_items(builder.gather_ids(method, value))
if builder.filters or builder.tmdb_filters: if builder.filters or builder.tmdb_filters:
logger.info("") logger.info("")
for filter_key, filter_value in builder.filters: for filter_key, filter_value in builder.filters:
@ -492,12 +498,6 @@ def run_collection(config, library, metadata, requested_collections):
for filter_key, filter_value in builder.tmdb_filters: for filter_key, filter_value in builder.tmdb_filters:
logger.info(f"Collection Filter {filter_key}: {filter_value}") logger.info(f"Collection Filter {filter_key}: {filter_value}")
for method, value in builder.builders:
logger.debug("")
logger.debug(f"Builder: {method}: {value}")
logger.info("")
builder.filter_and_save_items(builder.gather_ids(method, value))
if len(builder.added_items) > 0 and len(builder.added_items) + builder.beginning_count >= builder.minimum and builder.build_collection: if len(builder.added_items) > 0 and len(builder.added_items) + builder.beginning_count >= builder.minimum and builder.build_collection:
items_added, items_unchanged = builder.add_to_collection() items_added, items_unchanged = builder.add_to_collection()
library.stats["added"] += items_added library.stats["added"] += items_added
@ -649,13 +649,6 @@ def run_playlists(config):
logger.info("") logger.info("")
logger.info(f"Sync Mode: {'sync' if builder.sync else 'append'}") logger.info(f"Sync Mode: {'sync' if builder.sync else 'append'}")
if builder.filters or builder.tmdb_filters:
logger.info("")
for filter_key, filter_value in builder.filters:
logger.info(f"Playlist Filter {filter_key}: {filter_value}")
for filter_key, filter_value in builder.tmdb_filters:
logger.info(f"Playlist Filter {filter_key}: {filter_value}")
method, value = builder.builders[0] method, value = builder.builders[0]
logger.debug("") logger.debug("")
logger.debug(f"Builder: {method}: {value}") logger.debug(f"Builder: {method}: {value}")
@ -673,6 +666,13 @@ def run_playlists(config):
builder.filter_and_save_items(ids) builder.filter_and_save_items(ids)
if builder.filters or builder.tmdb_filters:
logger.info("")
for filter_key, filter_value in builder.filters:
logger.info(f"Playlist Filter {filter_key}: {filter_value}")
for filter_key, filter_value in builder.tmdb_filters:
logger.info(f"Playlist Filter {filter_key}: {filter_value}")
if len(builder.added_items) >= builder.minimum: if len(builder.added_items) >= builder.minimum:
items_added, items_unchanged = builder.add_to_collection() items_added, items_unchanged = builder.add_to_collection()
stats["added"] += items_added stats["added"] += items_added

Loading…
Cancel
Save