[25] more minor fixes

pull/921/head
meisnate12 3 years ago
parent 6d27ca508c
commit 64e67d4109

@ -1 +1 @@
1.17.0-develop24
1.17.0-develop25

@ -24,6 +24,8 @@ plex:
| `empty_trash` | Runs Empty Trash on the Server after all Metadata Files are run | false | ❌ |
| `optimize` | Runs Optimize on the Server after all Metadata Files are run | false | ❌ |
* **Do Not Use the Plex Token found in Plex's Preferences.xml file**
* This script can be run on a remote Plex server, but be sure that the `url` provided is publicly addressable, and it's recommended to use `HTTPS`.
* If you need help finding your Plex authentication token, please see Plex's [support article](https://support.plex.tv/articles/204059436-finding-an-authentication-token-x-plex-token/).

@ -106,7 +106,7 @@ Specify the time of day that Plex Meta Manager will run.
</tr>
<tr>
<th>Default Value</th>
<td colspan="2"><code>03:00</code></td>
<td colspan="2"><code>05:00</code></td>
</tr>
<tr>
<th>Available Values</th>

@ -16,6 +16,7 @@ These are the attributes which can be used within the Overlay File:
|:--------------------------------------------------------|:-------------------------------------------------------------------------------------------------------------------|
| [`templates`](templates) | contains definitions of templates that can be leveraged by multiple overlays |
| [`external_templates`](templates.md#external-templates) | contains [path types](../config/paths) that point to external templates that can be leveraged by multiple overlays |
| [`queues`](#overlay-queues) | contains the positional attributes of queues |
| [`overlays`](#overlays-attributes) | contains definitions of overlays you wish to add |
* `overlays` is required in order to run the Overlay File.
@ -67,14 +68,15 @@ overlays:
There are many attributes available when using overlays to edit how they work.
| Attribute | Description | Required |
|:--------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------:|
|:---------------------------|:------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|:--------:|
| `name` | Name of the overlay. Each overlay name should be unique. | &#9989; |
| `file` | Local location of the Overlay Image. | &#10060; |
| `url` | URL of Overlay Image Online. | &#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. Only one overlay with the highest weight per group will be applied.<br>**`weight` is required when using `group`**<br>**Values:** group name | &#10060; |
| `weight` | Weight of this overlay in its group.<br>**`group` is required when using `weight`**<br>**Values:** Integer | &#10060; |
| [`group`](#overlay-groups) | Name of the Grouping for this overlay. Only one overlay with the highest weight per group will be applied.<br>**`weight` is required when using `group`**<br>**Values:** group name | &#10060; |
| [`queue`](#overlay-queues) | Name of the Queue for this overlay. Define `queue` positions using the `queues` attribute at the top level of an Overlay File. Overlay with the highest weight is applied to the first position and so on.<br>**`weight` is required when using `queue`**<br>**Values:** queue name | &#10060; |
| `weight` | Weight of this overlay in its group or queue.<br>**`group` or `queue` is required when using `weight`**<br>**Values:** Integer 0 or greater | &#10060; |
| `horizontal_offset` | Horizontal Offset of this overlay. Can be a %.<br>**`vertical_offset` is required when using `horizontal_offset`**<br>**Value:** Integer 0 or greater or 0%-100% | &#10060; |
| `horizontal_align` | Horizontal Alignment of the overlay.<br>**Values:** `left`, `center`, `right` | &#10060; |
| `vertical_offset` | Vertical Offset of this overlay. Can be a %.<br>**`horizontal_offset` is required when using `vertical_offset`**<br>**Value:** Integer 0 or greater or 0%-100% | &#10060; |
@ -108,7 +110,7 @@ overlays:
imdb_chart: top_movies
overlay:
name: IMDB-Top-250
repo: PMM/overlays/images/IMDB-Top-250
git: PMM/overlays/images/IMDB-Top-250
horizontal_offset: 0
horizontal_align: right
vertical_offset: 0
@ -134,7 +136,6 @@ overlays:
![](blur.png)
### Text Overlay
You can add text as an overlay using the special `text()` overlay name. Anything inside the parentheses will be added as an overlay onto the image. Ex `text(4K)` adds `4K` to the image.
@ -173,6 +174,89 @@ overlays:
back_height: 105
```
### Overlay Groups
Overlay groups are defined by the name given to the `group` attribute. Only one overlay with the highest weight per group will be applied.
This is an example where the Multi-Audio overlay will be applied over the Dual-Audio overlay for every item found by both.
```yaml
overlays:
Dual-Audio:
overlay:
name: Dual-Audio
git: PMM/overlays/images/Dual-Audio
group: audio_language
weight: 10
horizontal_offset: 0
horizontal_align: center
vertical_offset: 15
vertical_align: bottom
plex_all: true
filters:
audio_language.count_gt: 1
Multi-Audio:
overlay:
name: Multi-Audio
git: PMM/overlays/images/Multi-Audio
group: audio_language
weight: 20
horizontal_offset: 0
horizontal_align: center
vertical_offset: 15
vertical_align: bottom
plex_all: true
filters:
audio_language.count_gt: 2
```
### Overlay Queues
Overlay queues are defined by the name given to the `queue` attribute. The overlay with the highest weight is put into the first queue position, then the second highest is placed in the second queue position and so on.
You can define the queue positions by using the `queues` attribute at the top level of an Overlay File. You can define as many positions as you want.
```yaml
queues:
custom_queue_name:
- horizontal_offset: 300 # This is the first position
horizontal_align: center
vertical_offset: 1375
vertical_align: top
- horizontal_offset: 300 # This is the second position
horizontal_align: center
vertical_offset: 1250
vertical_align: top
overlays:
IMDb:
imdb_chart: popular_movies
overlay:
name: text(IMDb Popular)
queue: custom_queue_name
weight: 20
font: fonts/Inter-Medium.ttf
font_size: 65
font_color: "#FFFFFF"
back_color: "#00000099"
back_radius: 30
back_width: 380
back_height: 105
TMDb:
tmdb_popular: 100
overlay:
name: text(TMDb Popular)
queue: custom_queue_name
weight: 10
font: fonts/Inter-Medium.ttf
font_size: 65
font_color: "#FFFFFF"
back_color: "#00000099"
back_radius: 30
back_width: 400
back_height: 105
```
## Suppress Overlays
You can add `suppress_overlays` to an overlay definition and give it a list or comma separated string of overlay names you want suppressed from this item if this overlay is attached to the item.

@ -2293,7 +2293,7 @@ class CollectionBuilder:
tmdb_paths = []
tvdb_paths = []
for item in self.items:
if "item_assets" in self.item_details and self.library.asset_directory and "Overlay" not in [la.tag for la in item.labels]:
if "item_assets" in self.item_details and self.library.asset_directory and "Overlay" not in [la.tag for la in self.library.item_labels(item)]:
self.library.find_and_upload_assets(item)
self.library.edit_tags("label", item, add_tags=add_tags, remove_tags=remove_tags, sync_tags=sync_tags)
path = os.path.dirname(str(item.locations[0])) if self.library.is_movie else str(item.locations[0])

@ -79,7 +79,7 @@ class Operations:
logger.error(e)
continue
logger.ghost(f"Processing: {i}/{len(items)} {item.title}")
current_labels = [la.tag for la in item.labels] if self.library.assets_for_all or self.library.mass_imdb_parental_labels else []
current_labels = [la.tag for la in self.library.item_labels(item)] if self.library.assets_for_all or self.library.mass_imdb_parental_labels else []
if self.library.assets_for_all and self.library.asset_directory and "Overlay" not in current_labels:
self.library.find_and_upload_assets(item)

@ -86,7 +86,7 @@ class Overlays:
image, image_compare, overlay_compare = self.config.Cache.query_image_map(item.ratingKey, f"{self.library.image_table_name}_overlays")
overlay_compare = [] if overlay_compare is None else util.get_list(overlay_compare, split="|")
has_overlay = any([item_tag.tag.lower() == "overlay" for item_tag in item.labels])
has_overlay = any([item_tag.tag.lower() == "overlay" for item_tag in self.library.item_labels(item)])
compare_names = {properties[ov].get_overlay_compare(): ov for ov in over_names}
blur_num = 0

@ -529,6 +529,10 @@ class Plex(Library):
def collection_order_query(self, collection, data):
collection.sortUpdate(sort=data)
@retry(stop_max_attempt_number=6, wait_fixed=10000, retry_on_exception=util.retry_if_not_plex)
def item_labels(self, item):
return item.labels
@retry(stop_max_attempt_number=6, wait_fixed=10000, retry_on_exception=util.retry_if_not_plex)
def reload(self, item, force=False):
is_full = False
@ -640,6 +644,7 @@ class Plex(Library):
def scan_user(server, username):
try:
for playlist in server.playlists():
if isinstance(playlist, Playlist):
if playlist.title not in playlists:
playlists[playlist.title] = []
playlists[playlist.title].append(username)
@ -1244,7 +1249,7 @@ class Plex(Library):
if filter_attr == "has_collection":
filter_check = len(item.collections) > 0
elif filter_attr == "has_overlay":
for label in item.labels:
for label in self.item_labels(item):
if label.tag.lower().endswith(" overlay") or label.tag.lower() == "overlay":
filter_check = True
break

@ -945,7 +945,7 @@ class Overlay:
self.horizontal_align, self.horizontal_offset, self.vertical_align, self.vertical_offset = parse_cords(self.data, "overlay")
if (self.horizontal_offset is None and self.vertical_offset is not None) or (self.vertical_offset is None and self.horizontal_offset is not None):
raise Failed(f"Overlay Error: overlay attribute's must be used together")
raise Failed(f"Overlay Error: overlay attribute's horizontal_offset and vertical_offset must be used together")
def color(attr):
if attr in self.data and self.data[attr]:
@ -966,7 +966,7 @@ class Overlay:
elif back_width >= 0 and back_height >= 0:
self.back_box = (back_width, back_height)
self.has_back = True if self.back_color or self.back_line_color else False
if self.has_back and not self.has_coordinates():
if self.has_back and not self.has_coordinates() and not self.queue:
raise Failed(f"Overlay Error: horizontal_offset and vertical_offset are required when using a backdrop")
def get_and_save_image(image_url):

@ -1,4 +1,5 @@
import argparse, os, sys, time, traceback, uuid
import argparse, os, sys, time, uuid
from concurrent.futures import ProcessPoolExecutor
from datetime import datetime
try:
@ -18,7 +19,7 @@ parser = argparse.ArgumentParser()
parser.add_argument("-db", "--debug", dest="debug", help=argparse.SUPPRESS, action="store_true", default=False)
parser.add_argument("-tr", "--trace", dest="trace", help=argparse.SUPPRESS, action="store_true", default=False)
parser.add_argument("-c", "--config", dest="config", help="Run with desired *.yml file", type=str)
parser.add_argument("-t", "--time", "--times", dest="times", help="Times to update each day use format HH:MM (Default: 03:00) (comma-separated list)", default="05:00", type=str)
parser.add_argument("-t", "--time", "--times", dest="times", help="Times to update each day use format HH:MM (Default: 05:00) (comma-separated list)", default="05:00", type=str)
parser.add_argument("-re", "--resume", dest="resume", help="Resume collection run from a specific collection", type=str)
parser.add_argument("-r", "--run", dest="run", help="Run without the scheduler", action="store_true", default=False)
parser.add_argument("-is", "--ignore-schedules", dest="ignore_schedules", help="Run ignoring collection schedules", action="store_true", default=False)
@ -115,8 +116,10 @@ from modules.config import ConfigFile
from modules.util import Failed, NotScheduled, Deleted
def my_except_hook(exctype, value, tb):
for _line in traceback.format_exception(etype=exctype, value=value, tb=tb):
logger.critical(_line)
if issubclass(exctype, KeyboardInterrupt):
sys.__excepthook__(exctype, value, tb)
else:
logger.critical("Uncaught Exception", exc_info=(exctype, value, tb))
sys.excepthook = my_except_hook
@ -144,6 +147,10 @@ if not uuid_num:
plexapi.BASE_HEADERS["X-Plex-Client-Identifier"] = str(uuid_num)
def process(attrs):
with ProcessPoolExecutor(max_workers=1) as executor:
executor.submit(start, *[attrs])
def start(attrs):
logger.add_main_handler()
logger.separator()
@ -845,9 +852,10 @@ def run_playlists(config):
logger.remove_playlist_handler(playlist_log_name)
return status, stats
if __name__ == "__main__":
try:
if run or test or collections or libraries or metadata_files or resume:
start({
process({
"config_file": config_file,
"test": test,
"delete": delete,
@ -871,7 +879,7 @@ try:
else:
raise Failed(f"Argument Error: blank time argument")
for time_to_run in valid_times:
schedule.every().day.at(time_to_run).do(start, {"config_file": config_file, "time": time_to_run, "delete": delete, "library_first": library_first, "trace": trace})
schedule.every().day.at(time_to_run).do(process, {"config_file": config_file, "time": time_to_run, "delete": delete, "library_first": library_first, "trace": trace})
while True:
schedule.run_pending()
if not no_countdown:

Loading…
Cancel
Save