Skip to content

Commit

Permalink
[95] Perform batch operations in Plex
Browse files Browse the repository at this point in the history
  • Loading branch information
CollinHeist committed Sep 20, 2024
1 parent 9b5e13c commit 2b1c8e0
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 26 deletions.
67 changes: 42 additions & 25 deletions modules/PlexInterface2.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from datetime import datetime, timedelta
from logging import Logger
from pathlib import Path
from re import IGNORECASE, compile as re_compile
from typing import (
Expand All @@ -15,8 +14,7 @@
from fastapi import HTTPException
from PIL import Image
from plexapi.exceptions import PlexApiException
from plexapi.library import Library as PlexLibrary
from plexapi.mixins import ArtMixin, PosterMixin
from plexapi.library import LibrarySection as PlexLibrary
from plexapi.video import Episode as PlexEpisode, Season as PlexSeason
from plexapi.server import PlexServer, NotFound, Unauthorized
from plexapi.video import Show as PlexShow
Expand All @@ -26,7 +24,7 @@
)
from tenacity import retry, stop_after_attempt, wait_fixed, wait_exponential

from modules.Debug import log
from modules.Debug import Logger, log
from modules.EpisodeDataSource2 import (
EpisodeDataSource,
SearchResult,
Expand Down Expand Up @@ -100,10 +98,10 @@ class PlexInterface(MediaServer, EpisodeDataSource, SyncInterface, Interface):
and episode data, along with other attributes
"""

INTERFACE_TYPE = 'Plex'
INTERFACE_TYPE: str = 'Plex'

"""Series ID's that can be set by TMDb"""
SERIES_IDS = ('imdb_id', 'tmdb_id', 'tvdb_id')
SERIES_IDS: tuple[str] = ('imdb_id', 'tmdb_id', 'tvdb_id')

"""EXIF data to write to images if Kometa integration is enabled"""
EXIF_TAG = {'key': 0x4242, 'data': 'titlecard'}
Expand Down Expand Up @@ -390,6 +388,7 @@ def get_all_episodes(self,
all_episodes = []
for plex_episode in series.episodes(container_size=500):
# Skip if episode has no season or episode number
plex_episode: PlexEpisode
if (plex_episode.parentIndex is None
or plex_episode.index is None):
log.warning(f'Episode {plex_episode} of {series_info} in '
Expand Down Expand Up @@ -757,7 +756,7 @@ def get_libraries(self) -> list[str]:
before_sleep=lambda _:log.warning('Cannot upload image, retrying..'),
reraise=True)
def __retry_upload(self,
entry: Union[ArtMixin, PosterMixin],
entry: Union[PlexShow, PlexSeason, PlexEpisode],
image: Union[str, Path],
kind: Literal['art', 'poster'] = 'poster',
*,
Expand Down Expand Up @@ -854,23 +853,30 @@ def load_title_cards(self,
for episode, card in episode_and_cards
]

# Go through each episode within Plex, set title cards
skipped, loaded = [], []
# Find episodes which have a matching Card to load
skipped: list[str] = []
matched_episodes: list[tuple[PlexEpisode, 'Episode', EpisodeInfo, 'Card']] = []
for plex_episode in series.episodes(container_size=100):
# Skip episode if no matching episode was provided
plex_episode: PlexEpisode = plex_episode
found = False
plex_episode: PlexEpisode
for episode, episode_info, card in infos:
if episode_info == plex_episode:
found = True
matched_episodes.append(
(plex_episode, episode, episode_info, card)
)
break
if not found:
# Episode never matched
else:
skipped.append(plex_episode.seasonEpisode)
continue

# Shrink image if necessary, skip if cannot be compressed
# pylint: disable=undefined-loop-variable
# Prepare batch edits on all these episodes
library.batchMultiEdits([ep[0] for ep in matched_episodes])

# Upload card for all matched episodes
loaded: list[tuple['Episode', 'Card']] = []
for plex_episode, episode, episode_info, card in matched_episodes:
# Shrink image if necesssary, skipping if uncompressable
if (image := self.compress_image(card.card_file, log=log)) is None:
skipped.append(plex_episode.seasonEpisode)
continue

# Upload card
Expand All @@ -895,7 +901,12 @@ def load_title_cards(self,
else:
loaded.append((episode, card))

log.trace(f'Not loading Card into {", ".join(skipped)} for {series_info}')
# Save batch edits
library.saveMultiEdits()

if skipped:
log.trace(f'Not loading Card into {", ".join(skipped)} for '
f'{series_info}')
return loaded


Expand Down Expand Up @@ -925,7 +936,7 @@ def load_season_posters(self,
return None

for season in series.seasons():
season: PlexSeason = season
season: PlexSeason
# Skip if there is no poster for this season
if not (poster := posters.get(season.index)):
continue
Expand Down Expand Up @@ -1173,11 +1184,17 @@ def remove_series_labels(self,
or not (series := self.__get_series(library, series_info, log=log))):
return None

# Remove labels from all Episodes
for plex_episode in series.episodes(container_size=500):
plex_episode: PlexEpisode
log.debug(f'Removed {labels} from {plex_episode.labels} of '
f'{plex_episode}')
plex_episode.removeLabel(labels)
# Get all Episodes for batch edits
episodes: list[PlexEpisode] = series.episodes(container_size=500)
library.batchMultiEdits(episodes)

# Remove all indicated labels
for episode in episodes:
log.debug(f'Removed {labels} from {episode.labels} of '
f'{episode}')
episode.removeLabel(labels)

# Finalize batch edits
library.saveMultiEdits()

return None
2 changes: 1 addition & 1 deletion modules/ref/version_webui
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v2.0-alpha.12.0-webui94
v2.0-alpha.12.0-webui95

0 comments on commit 2b1c8e0

Please sign in to comment.