pull/1123/head
cpt-kuesel 2 years ago
commit c631fe390a

@ -1 +1 @@
1.17.3-develop133
1.17.3-develop138

@ -40,7 +40,7 @@ templates:
episode_air_date: <<last>>
plex_all: <<all>>
filters:
tmdb_status1: <<tmdb>>
tmdb_status: <<tmdb>>
overlays:

@ -24,7 +24,7 @@ variables:
item: Article
key_names:
Action: Action
Actors: Acteurs et actrices
Actors: Acteurs et Actrices
Adventure: Aventure
Arabic: Arabes
Audio Language: Langue audio
@ -38,7 +38,7 @@ key_names:
Czech: Tchèques
Danish: Danois
Decade: Décennie
Directors: Directeurs et Directrices
Directors: Réalisateurs
Drama: Dramatiques
Dutch: Néerlandais
Easter: Pâques

@ -215,7 +215,9 @@ Tag search can take multiple values as a **list or a comma-separated string**.
| `decade` | Uses the year tag to match the decade | &#9989; | &#10060; | &#10060; |
| `director` | Uses the director tags to match | &#9989; | &#10060; | &#10060; |
| `genre` | Uses the genre tags to match | &#9989; | &#9989; | &#10060; |
| `label` | Uses the label tags to match | &#9989; | &#9989; | &#10060; |
| `label` | Uses the label tags to match for top level collections | &#9989; | &#9989; | &#10060; |
| `season_label` | Uses the label tags to match for season collections | &#10060; | &#9989; | &#10060; |
| `episode_label` | Uses the label tags to match for episode collections | &#10060; | &#9989; | &#10060; |
| `network` | Uses the network tags to match<br>**Only works with the New Plex TV Agent** | &#10060; | &#9989; | &#10060; |
| `producer` | Uses the actor tags to match | &#9989; | &#10060; | &#10060; |
| `resolution` | Uses the resolution tags to match | &#9989; | &#9989; | &#10060; |
@ -228,6 +230,7 @@ Tag search can take multiple values as a **list or a comma-separated string**.
| `artist_country` | Uses the Artist's Country attribute to match | &#10060; | &#10060; | &#9989; |
| `artist_mood` | Uses the Artist's Mood attribute to match | &#10060; | &#10060; | &#9989; |
| `artist_style` | Uses the Artist's Style attribute to match | &#10060; | &#10060; | &#9989; |
| `artist_label` | Uses the Artist's Label attribute to match | &#10060; | &#10060; | &#9989; |
| `album_genre` | Uses the Album's Genre attribute to match | &#10060; | &#10060; | &#9989; |
| `album_mood` | Uses the Album's Mood attribute to match | &#10060; | &#10060; | &#9989; |
| `album_style` | Uses the Album's Style attribute to match | &#10060; | &#10060; | &#9989; |
@ -238,6 +241,7 @@ Tag search can take multiple values as a **list or a comma-separated string**.
| `album_label` | Uses the Album's Label attribute to match | &#10060; | &#10060; | &#9989; |
| `track_mood` | Uses the Track's Mood attribute to match | &#10060; | &#10060; | &#9989; |
| `track_source` | Uses the Track's Style attribute to match | &#10060; | &#10060; | &#9989; |
| `track_label` | Uses the Track's Label attribute to match | &#10060; | &#10060; | &#9989; |
## Date Searches

@ -156,7 +156,9 @@ Tag filter can take multiple values as a **list or a comma-separated string**.
| `decade` | Uses the year tag to match the decade | &#9989; | &#10060; | &#10060; |
| `director` | Uses the director tags to match | &#9989; | &#10060; | &#10060; |
| `genre` | Uses the genre tags to match | &#9989; | &#9989; | &#10060; |
| `label` | Uses the label tags to match | &#9989; | &#9989; | &#10060; |
| `label` | Uses the label tags to match for top level collections | &#9989; | &#9989; | &#10060; |
| `season_label` | Uses the label tags to match for season collections | &#10060; | &#9989; | &#10060; |
| `episode_label` | Uses the label tags to match for episode collections | &#10060; | &#9989; | &#10060; |
| `network` | Uses the network tags to match<br>**Only works with the New Plex TV Agent** | &#10060; | &#9989; | &#10060; |
| `producer` | Uses the actor tags to match | &#9989; | &#10060; | &#10060; |
| `resolution` | Uses the resolution tags to match | &#9989; | &#9989; | &#10060; |
@ -169,6 +171,7 @@ Tag filter can take multiple values as a **list or a comma-separated string**.
| `artist_country` | Uses the Artist's Country attribute to match | &#10060; | &#10060; | &#9989; |
| `artist_mood` | Uses the Artist's Mood attribute to match | &#10060; | &#10060; | &#9989; |
| `artist_style` | Uses the Artist's Style attribute to match | &#10060; | &#10060; | &#9989; |
| `artist_label` | Uses the Artist's Label attribute to match | &#10060; | &#10060; | &#9989; |
| `album_genre` | Uses the Album's Genre attribute to match | &#10060; | &#10060; | &#9989; |
| `album_mood` | Uses the Album's Mood attribute to match | &#10060; | &#10060; | &#9989; |
| `album_style` | Uses the Album's Style attribute to match | &#10060; | &#10060; | &#9989; |
@ -179,6 +182,7 @@ Tag filter can take multiple values as a **list or a comma-separated string**.
| `album_label` | Uses the Album's Label attribute to match | &#10060; | &#10060; | &#9989; |
| `track_mood` | Uses the Track's Mood attribute to match | &#10060; | &#10060; | &#9989; |
| `track_source` | Uses the Track's Style attribute to match | &#10060; | &#10060; | &#9989; |
| `track_label` | Uses the Track's Label attribute to match | &#10060; | &#10060; | &#9989; |
## Date Filters

@ -1880,7 +1880,6 @@ class CollectionBuilder:
def build_url_arg(arg, mod=None, arg_s=None, mod_s=None):
arg_key = plex.search_translation[attr] if attr in plex.search_translation else attr
arg_key = f"{sort_type}.label" if arg_key == "label" and sort_type in ["season", "episode", "album", "track"] else arg_key
arg_key = plex.show_translation[arg_key] if self.library.is_show and arg_key in plex.show_translation else arg_key
if mod is None:
mod = plex.modifier_translation[modifier] if modifier in plex.modifier_translation else modifier

@ -765,7 +765,10 @@ class ConfigFile:
"add_blank_entries": True
}
if lib["operations"]["metadata_backup"] and isinstance(lib["operations"]["metadata_backup"], dict):
params["metadata_backup"]["path"] = check_for_attribute(lib["operations"]["metadata_backup"], "path", var_type="path", default=params["metadata_backup"]["path"], save=False)
try:
params["metadata_backup"]["path"] = check_for_attribute(lib["operations"]["metadata_backup"], "path", var_type="path", save=False)
except Failed as e:
logger.debug(f"{e} using default {params['metadata_backup']['path']}")
params["metadata_backup"]["exclude"] = check_for_attribute(lib["operations"]["metadata_backup"], "exclude", var_type="comma_list", default_is_none=True, save=False)
params["metadata_backup"]["sync_tags"] = check_for_attribute(lib["operations"]["metadata_backup"], "sync_tags", var_type="bool", default=False, save=False)
params["metadata_backup"]["add_blank_entries"] = check_for_attribute(lib["operations"]["metadata_backup"], "add_blank_entries", var_type="bool", default=True, save=False)

@ -262,12 +262,15 @@ class DataFile:
language = variables["language"] if "language" in variables else "default"
translation_variables = {k: v[language if language in v else "default"] for k, v in self.translations.items()}
key_name_variables = {}
for var_key, var_value in self.key_names.items():
if var_key == "library_type" and language in var_value:
variables[var_key] = var_value[language].lower()
variables[f"{var_key}U"] = var_value[language]
elif language in var_value:
translation_variables[var_key] = var_value[language]
key_name_variables[var_key] = var_value[language]
if "key_name" in variables and variables["key_name"] in key_name_variables:
variables["key_name"] = key_name_variables[variables["key_name"]]
def replace_var(input_item, search_dicts):
if not isinstance(search_dicts, list):

@ -1,13 +1,16 @@
import os, re, time
from datetime import datetime
from PIL import Image, ImageColor, ImageDraw, ImageFont
from modules import util
from modules.util import Failed
from PIL import Image, ImageColor, ImageDraw, ImageFont
from plexapi.audio import Album
from plexapi.video import Episode
logger = util.logger
portrait_dim = (1000, 1500)
landscape_dim = (1920, 1080)
square_dim = (1000, 1000)
old_special_text = [f"{a}{s}" for a in ["audience_rating", "critic_rating", "user_rating"] for s in ["", "0", "%", "#"]]
float_vars = ["audience_rating", "critic_rating", "user_rating"]
int_vars = ["runtime", "season_number", "episode_number", "episode_count", "versions"]
@ -106,6 +109,13 @@ def parse_cords(data, parent, required=False):
return horizontal_align, horizontal_offset, vertical_align, vertical_offset
def get_canvas_size(item):
if isinstance(item, Episode):
return landscape_dim
elif isinstance(item, Album):
return square_dim
else:
return portrait_dim
class Overlay:
def __init__(self, config, library, original_mapping_name, overlay_data, suppress, level):
@ -122,6 +132,8 @@ class Overlay:
self.landscape_box = None
self.portrait = None
self.portrait_box = None
self.square = None
self.square_box = None
self.group = None
self.queue = None
self.weight = None
@ -326,9 +338,11 @@ class Overlay:
box = self.image.size if self.image else None
self.portrait, self.portrait_box = self.get_backdrop(portrait_dim, box=box, text=self.name[5:-1])
self.landscape, self.landscape_box = self.get_backdrop(landscape_dim, box=box, text=self.name[5:-1])
self.square, self.square_box = self.get_backdrop(square_dim, box=box, text=self.name[5:-1])
elif self.name.startswith("backdrop"):
self.portrait, self.portrait_box = self.get_backdrop(portrait_dim, box=self.back_box)
self.landscape, self.landscape_box = self.get_backdrop(landscape_dim, box=self.back_box)
self.square, self.square_box = self.get_backdrop(square_dim, box=self.back_box)
else:
if not self.path:
clean_name, _ = util.validate_filename(self.name)
@ -345,6 +359,7 @@ class Overlay:
if self.has_coordinates():
self.portrait, self.portrait_box = self.get_backdrop(portrait_dim, box=self.image.size)
self.landscape, self.landscape_box = self.get_backdrop(landscape_dim, box=self.image.size)
self.square, self.square_box = self.get_backdrop(square_dim, box=self.image.size)
if self.config.Cache:
self.config.Cache.update_image_map(self.mapping_name, f"{self.library.image_table_name}_overlays", self.mapping_name, overlay_size)
except OSError:
@ -500,3 +515,11 @@ class Overlay:
else:
ha, ho, va, vo = new_cords
return get_cord(ho, canvas_box[0], box[0], ha), get_cord(vo, canvas_box[1], box[1], va)
def get_canvas(self, item):
if isinstance(item, Episode):
return self.landscape, self.landscape_box
elif isinstance(item, Album):
return self.square, self.square_box
else:
return self.portrait, self.portrait_box

@ -193,8 +193,7 @@ class Overlays:
logger.error(f"{item_title[:60]:<60} | Overlay Error: No poster found")
elif self.library.reapply_overlays or changed_image or overlay_change:
try:
canvas_width = 1920 if isinstance(item, Episode) else 1000
canvas_height = 1080 if isinstance(item, Episode) else 1500
canvas_width, canvas_height = overlay.get_canvas_size(item)
new_poster = Image.open(poster.location if poster else has_original) \
.convert("RGB").resize((canvas_width, canvas_height), Image.ANTIALIAS)
@ -296,20 +295,18 @@ class Overlays:
continue
new_poster.paste(overlay_image, (0, 0), overlay_image)
else:
overlay_image = current_overlay.landscape if isinstance(item, Episode) else current_overlay.portrait
addon_box = current_overlay.landscape_box if isinstance(item, Episode) else current_overlay.portrait_box
overlay_image, addon_box = current_overlay.get_canvas(item)
new_poster.paste(overlay_image, (0, 0), overlay_image)
if current_overlay.image:
new_poster.paste(current_overlay.image, addon_box, current_overlay.image)
elif current_overlay.name == "backdrop":
overlay_image = current_overlay.landscape if isinstance(item, Episode) else current_overlay.portrait
overlay_image, _ = current_overlay.get_canvas(item)
new_poster.paste(overlay_image, (0, 0), overlay_image)
else:
if current_overlay.has_coordinates():
overlay_image, overlay_box = current_overlay.get_canvas(item)
if current_overlay.portrait is not None:
overlay_image = current_overlay.landscape if isinstance(item, Episode) else current_overlay.portrait
new_poster.paste(overlay_image, (0, 0), overlay_image)
overlay_box = current_overlay.landscape_box if isinstance(item, Episode) else current_overlay.portrait_box
new_poster.paste(current_overlay.image, overlay_box, current_overlay.image)
else:
new_poster = new_poster.resize(current_overlay.image.size, Image.ANTIALIAS)

@ -51,6 +51,8 @@ search_translation = {
"unplayed_episodes": "show.unwatchedLeaves",
"season_collection": "season.collection",
"episode_collection": "episode.collection",
"season_label": "season.label",
"episode_label": "episode.label",
"artist_title": "artist.title",
"artist_user_rating": "artist.userRating",
"artist_genre": "artist.genre",
@ -61,6 +63,7 @@ search_translation = {
"artist_added": "artist.addedAt",
"artist_last_played": "artist.lastViewedAt",
"artist_unmatched": "artist.unmatched",
"artist_label": "artist.label",
"album_title": "album.title",
"album_year": "album.year",
"album_decade": "album.decade",
@ -90,7 +93,8 @@ search_translation = {
"track_last_rated": "track.lastRatedAt",
"track_added": "track.addedAt",
"track_trash": "track.trash",
"track_source": "track.source"
"track_source": "track.source",
"track_label": "track.label"
}
show_translation = {
"title": "show.title",
@ -254,6 +258,8 @@ show_only_searches = [
"network", "network.not",
"season_collection", "season_collection.not",
"episode_collection", "episode_collection.not",
"season_label", "season_label.not",
"episode_label", "episode_label.not",
"episode_title", "episode_title.not", "episode_title.is", "episode_title.isnot", "episode_title.begins", "episode_title.ends",
"episode_added", "episode_added.not", "episode_added.before", "episode_added.after",
"episode_air_date", "episode_air_date.not",
@ -291,8 +297,8 @@ search_display = {"added": "Date Added", "release": "Release Date", "hdr": "HDR"
tag_attributes = [
"actor", "audio_language", "collection", "content_rating", "country", "director", "genre", "label", "network",
"producer", "resolution", "studio", "subtitle_language", "writer", "season_collection", "episode_collection", "edition",
"artist_genre", "artist_collection", "artist_country", "artist_mood", "artist_style", "album_genre", "album_mood",
"album_style", "album_format", "album_type", "album_collection", "album_source", "album_label", "track_mood", "track_source"
"artist_genre", "artist_collection", "artist_country", "artist_mood", "artist_label", "artist_style", "album_genre", "album_mood",
"album_style", "album_format", "album_type", "album_collection", "album_source", "album_label", "track_mood", "track_source", "track_label"
]
tag_modifiers = ["", ".not", ".regex"]
no_not_mods = ["resolution", "decade", "album_decade"]

Loading…
Cancel
Save