From ae266cc11dc88202e8d92ac5c35126bb34f9d9f9 Mon Sep 17 00:00:00 2001 From: meisnate12 Date: Tue, 28 Feb 2023 12:06:45 -0500 Subject: [PATCH] [106] update images remaining open --- VERSION | 2 +- modules/config.py | 6 +- modules/overlays.py | 290 ++++++++++++++++++++++---------------------- modules/plex.py | 5 +- 4 files changed, 152 insertions(+), 151 deletions(-) diff --git a/VERSION b/VERSION index 9a78eeef..a4b5279c 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -1.18.3-develop105 +1.18.3-develop106 diff --git a/modules/config.py b/modules/config.py index a8bccf42..2d3402a0 100644 --- a/modules/config.py +++ b/modules/config.py @@ -774,9 +774,9 @@ class ConfigFile: else: logger.error("Config Error: operations must be a dictionary") - def error_check(attr, service): - logger.error(f"Config Error: Operation {attr} cannot be {params[attr]} without a successful {service} Connection") - params[attr] = None + def error_check(err_attr, service): + logger.error(f"Config Error: Operation {err_attr} cannot be {params[err_attr]} without a successful {service} Connection") + params[err_attr] = None for mass_key in operations.meta_operations: if params[mass_key] == "omdb" and self.OMDb is None: diff --git a/modules/overlays.py b/modules/overlays.py index b720320e..c1ce6b92 100644 --- a/modules/overlays.py +++ b/modules/overlays.py @@ -189,159 +189,158 @@ class Overlays: elif self.library.reapply_overlays or changed_image or overlay_change: try: canvas_width, canvas_height = overlay.get_canvas_size(item) - - new_poster = Image.open(poster.location if poster else has_original) - exif_tags = new_poster.getexif() - exif_tags[0x04bc] = "overlay" - new_poster = new_poster.convert("RGB").resize((canvas_width, canvas_height), Image.LANCZOS) - - if blur_num > 0: - new_poster = new_poster.filter(ImageFilter.GaussianBlur(blur_num)) - - def get_text(text_overlay): - full_text = text_overlay.name[5:-1] - for format_var in overlay.vars_by_type[text_overlay.level]: - if f"<<{format_var}" in full_text and format_var == "originally_available[": - mod = re.search("<>", full_text).group(1) - format_var = "originally_available" - elif f"<<{format_var}>>" in full_text and format_var.endswith(tuple(m for m in overlay.double_mods)): - mod = format_var[-2:] - format_var = format_var[:-2] - elif f"<<{format_var}>>" in full_text and format_var.endswith(tuple(m for m in overlay.single_mods)): - mod = format_var[-1] - format_var = format_var[:-1] - elif f"<<{format_var}>>" in full_text: - mod = "" - else: - continue - if format_var == "show_title": - actual_attr = "parentTitle" if text_overlay.level == "season" else "grandparentTitle" - elif format_var in plex.attribute_translation: - actual_attr = plex.attribute_translation[format_var] - else: - actual_attr = format_var - if format_var == "bitrate": - actual_value = None - for media in item.media: - current = int(media.bitrate) - if actual_value is None: - actual_value = current - if mod == "": - break - elif mod == "H" and current > actual_value: - actual_value = current - elif mod == "L" and current < actual_value: - actual_value = current - else: - if not hasattr(item, actual_attr) or getattr(item, actual_attr) is None: - raise Failed(f"Overlay Warning: No {full_text} found") - actual_value = getattr(item, actual_attr) - if format_var == "versions": - actual_value = len(actual_value) - if self.config.Cache: - cache_store = actual_value.strftime("%Y-%m-%d") if format_var in overlay.date_vars else actual_value - self.config.Cache.update_overlay_special_text(item.ratingKey, format_var, cache_store) - sub_value = None - if format_var == "originally_available": - if mod: - sub_value = "<>" - final_value = actual_value.strftime(mod) - else: - final_value = actual_value.strftime("%Y-%m-%d") - elif format_var == "runtime": - if mod == "H": - final_value = int((actual_value / 60000) // 60) - elif mod == "M": - final_value = int((actual_value / 60000) % 60) + with Image.open(poster.location if poster else has_original) as new_poster: + exif_tags = new_poster.getexif() + exif_tags[0x04bc] = "overlay" + new_poster = new_poster.convert("RGB").resize((canvas_width, canvas_height), Image.LANCZOS) + + if blur_num > 0: + new_poster = new_poster.filter(ImageFilter.GaussianBlur(blur_num)) + + def get_text(text_overlay): + full_text = text_overlay.name[5:-1] + for format_var in overlay.vars_by_type[text_overlay.level]: + if f"<<{format_var}" in full_text and format_var == "originally_available[": + mod = re.search("<>", full_text).group(1) + format_var = "originally_available" + elif f"<<{format_var}>>" in full_text and format_var.endswith(tuple(m for m in overlay.double_mods)): + mod = format_var[-2:] + format_var = format_var[:-2] + elif f"<<{format_var}>>" in full_text and format_var.endswith(tuple(m for m in overlay.single_mods)): + mod = format_var[-1] + format_var = format_var[:-1] + elif f"<<{format_var}>>" in full_text: + mod = "" else: - final_value = int(actual_value / 60000) - elif mod == "%": - final_value = int(actual_value * 10) - elif mod == "#": - final_value = str(actual_value)[:-2] if str(actual_value).endswith(".0") else actual_value - elif mod == "W": - final_value = num2words(int(actual_value)) - elif mod == "0": - final_value = f"{int(actual_value):02}" - elif mod == "00": - final_value = f"{int(actual_value):03}" - elif mod == "/": - final_value = f"{float(actual_value) / 2:.1f}" - elif mod == "U": - final_value = str(actual_value).upper() - elif mod == "L": - final_value = str(actual_value).lower() - elif mod == "P": - final_value = str(actual_value).title() - else: - final_value = actual_value - if sub_value: - full_text = re.sub(sub_value, str(final_value), full_text) - else: - full_text = full_text.replace(f"<<{format_var}{mod}>>", str(final_value)) - return str(full_text) - - for over_name in applied_names: - current_overlay = properties[over_name] - if current_overlay.name.startswith("text"): - if "<<" in current_overlay.name: - image_box = current_overlay.image.size if current_overlay.image else None - try: - overlay_image, addon_box = current_overlay.get_backdrop((canvas_width, canvas_height), box=image_box, text=get_text(current_overlay)) - except Failed as e: - logger.warning(e) continue - new_poster.paste(overlay_image, (0, 0), overlay_image) - else: - 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.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: - new_poster.paste(overlay_image, (0, 0), overlay_image) - new_poster.paste(current_overlay.image, overlay_box, current_overlay.image) - else: - new_poster = new_poster.resize(current_overlay.image.size, Image.LANCZOS) - new_poster.paste(current_overlay.image, (0, 0), current_overlay.image) - new_poster = new_poster.resize((canvas_width, canvas_height), Image.LANCZOS) - - for queue, weights in queue_overlays.items(): - cords = self.library.queues[queue] - sorted_weights = sorted(weights.items(), reverse=True) - for o, cord in enumerate(cords): - if len(sorted_weights) <= o: - break - over_name = sorted_weights[o][1] + if format_var == "show_title": + actual_attr = "parentTitle" if text_overlay.level == "season" else "grandparentTitle" + elif format_var in plex.attribute_translation: + actual_attr = plex.attribute_translation[format_var] + else: + actual_attr = format_var + if format_var == "bitrate": + actual_value = None + for media in item.media: + current = int(media.bitrate) + if actual_value is None: + actual_value = current + if mod == "": + break + elif mod == "H" and current > actual_value: + actual_value = current + elif mod == "L" and current < actual_value: + actual_value = current + else: + if not hasattr(item, actual_attr) or getattr(item, actual_attr) is None: + raise Failed(f"Overlay Warning: No {full_text} found") + actual_value = getattr(item, actual_attr) + if format_var == "versions": + actual_value = len(actual_value) + if self.config.Cache: + cache_store = actual_value.strftime("%Y-%m-%d") if format_var in overlay.date_vars else actual_value + self.config.Cache.update_overlay_special_text(item.ratingKey, format_var, cache_store) + sub_value = None + if format_var == "originally_available": + if mod: + sub_value = "<>" + final_value = actual_value.strftime(mod) + else: + final_value = actual_value.strftime("%Y-%m-%d") + elif format_var == "runtime": + if mod == "H": + final_value = int((actual_value / 60000) // 60) + elif mod == "M": + final_value = int((actual_value / 60000) % 60) + else: + final_value = int(actual_value / 60000) + elif mod == "%": + final_value = int(actual_value * 10) + elif mod == "#": + final_value = str(actual_value)[:-2] if str(actual_value).endswith(".0") else actual_value + elif mod == "W": + final_value = num2words(int(actual_value)) + elif mod == "0": + final_value = f"{int(actual_value):02}" + elif mod == "00": + final_value = f"{int(actual_value):03}" + elif mod == "/": + final_value = f"{float(actual_value) / 2:.1f}" + elif mod == "U": + final_value = str(actual_value).upper() + elif mod == "L": + final_value = str(actual_value).lower() + elif mod == "P": + final_value = str(actual_value).title() + else: + final_value = actual_value + if sub_value: + full_text = re.sub(sub_value, str(final_value), full_text) + else: + full_text = full_text.replace(f"<<{format_var}{mod}>>", str(final_value)) + return str(full_text) + + for over_name in applied_names: current_overlay = properties[over_name] if current_overlay.name.startswith("text"): - image_box = current_overlay.image.size if current_overlay.image else None - try: - overlay_image, addon_box = current_overlay.get_backdrop((canvas_width, canvas_height), box=image_box, text=get_text(current_overlay), new_cords=cord) - except Failed as e: - logger.warning(e) - continue - new_poster.paste(overlay_image, (0, 0), overlay_image) + if "<<" in current_overlay.name: + image_box = current_overlay.image.size if current_overlay.image else None + try: + overlay_image, addon_box = current_overlay.get_backdrop((canvas_width, canvas_height), box=image_box, text=get_text(current_overlay)) + except Failed as e: + logger.warning(e) + continue + new_poster.paste(overlay_image, (0, 0), overlay_image) + else: + 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.get_canvas(item) + new_poster.paste(overlay_image, (0, 0), overlay_image) else: - if current_overlay.has_back: - overlay_image, overlay_box = current_overlay.get_backdrop((canvas_width, canvas_height), box=current_overlay.image.size, new_cords=cord) + if current_overlay.has_coordinates(): + overlay_image, overlay_box = current_overlay.get_canvas(item) + if current_overlay.portrait is not None: + new_poster.paste(overlay_image, (0, 0), overlay_image) + new_poster.paste(current_overlay.image, overlay_box, current_overlay.image) + else: + new_poster = new_poster.resize(current_overlay.image.size, Image.LANCZOS) + new_poster.paste(current_overlay.image, (0, 0), current_overlay.image) + new_poster = new_poster.resize((canvas_width, canvas_height), Image.LANCZOS) + + for queue, weights in queue_overlays.items(): + cords = self.library.queues[queue] + sorted_weights = sorted(weights.items(), reverse=True) + for o, cord in enumerate(cords): + if len(sorted_weights) <= o: + break + over_name = sorted_weights[o][1] + current_overlay = properties[over_name] + if current_overlay.name.startswith("text"): + image_box = current_overlay.image.size if current_overlay.image else None + try: + overlay_image, addon_box = current_overlay.get_backdrop((canvas_width, canvas_height), box=image_box, text=get_text(current_overlay), new_cords=cord) + except Failed as e: + logger.warning(e) + continue new_poster.paste(overlay_image, (0, 0), overlay_image) + if current_overlay.image: + new_poster.paste(current_overlay.image, addon_box, current_overlay.image) else: - overlay_box = current_overlay.get_coordinates((canvas_width, canvas_height), box=current_overlay.image.size, new_cords=cord) - new_poster.paste(current_overlay.image, overlay_box, current_overlay.image) - temp = os.path.join(self.library.overlay_folder, "temp.jpg") - new_poster.save(temp, exif=exif_tags) - self.library.upload_poster(item, temp) - self.library.edit_tags("label", item, add_tags=["Overlay"], do_print=False) - poster_compare = poster.compare if poster else item.thumb - logger.info(f"{item_title[:60]:<60} | Overlays Applied: {', '.join(over_names)}") + if current_overlay.has_back: + overlay_image, overlay_box = current_overlay.get_backdrop((canvas_width, canvas_height), box=current_overlay.image.size, new_cords=cord) + new_poster.paste(overlay_image, (0, 0), overlay_image) + else: + overlay_box = current_overlay.get_coordinates((canvas_width, canvas_height), box=current_overlay.image.size, new_cords=cord) + new_poster.paste(current_overlay.image, overlay_box, current_overlay.image) + temp = os.path.join(self.library.overlay_folder, "temp.jpg") + new_poster.save(temp, exif=exif_tags) + self.library.upload_poster(item, temp) + self.library.edit_tags("label", item, add_tags=["Overlay"], do_print=False) + poster_compare = poster.compare if poster else item.thumb + logger.info(f"{item_title[:60]:<60} | Overlays Applied: {', '.join(over_names)}") except (OSError, BadRequest, SyntaxError) as e: logger.stacktrace() raise Failed(f"{item_title[:60]:<60} | Overlay Error: {e}") @@ -359,6 +358,9 @@ class Overlays: logger.error("") logger.error(f"Overlays Attempted on {item_title}: {', '.join(over_names)}") logger.exorcise() + for _, over in properties.items(): + if over.image: + over.image.close() overlay_run_time = str(datetime.now() - overlay_start).split('.')[0] logger.info("") logger.separator(f"Finished {self.library.name} Library Overlays\nOverlays Run Time: {overlay_run_time}") diff --git a/modules/plex.py b/modules/plex.py index 06dcbf44..e62be53b 100644 --- a/modules/plex.py +++ b/modules/plex.py @@ -1367,9 +1367,8 @@ class Plex(Library): for file in util.glob_filter(os.path.join(item_asset_directory, "*.*")): if file.lower().endswith((".png", ".jpg", ".jpeg", "webp")) and not re.match(r"s\d+e\d+|season\d+", file.lower()): try: - image = Image.open(file) - _w, _h = image.size - image.close() + with Image.open(file) as image: + _w, _h = image.size if not poster and _h >= _w: new_path = os.path.join(os.path.dirname(file), f"poster{os.path.splitext(file)[1].lower()}") os.rename(file, new_path)