Skip to content

Commit

Permalink
Add support for updated episodes (#34)
Browse files Browse the repository at this point in the history
* Add support for updated episodes

* Update notification for updated episodes
  • Loading branch information
RemiRigal authored May 2, 2022
1 parent 4c667a6 commit cc5e6bd
Show file tree
Hide file tree
Showing 4 changed files with 83 additions and 27 deletions.
23 changes: 15 additions & 8 deletions plex_auto_languages/alerts/status.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,25 @@ def process(self, plex: PlexServer):
return
logger.info("[Status] Library scan complete")

# Get all recently added episodes
for section in plex.get_all_show_sections():
recent = section.searchEpisodes(filters={"addedAt>>": "5m"})
if len(recent) == 0:
continue
logger.debug(f"[Status] Found {len(recent)} newly added episode(s) in section {section}")
for item in recent:
added, updated = plex.cache.refresh_library_cache()

# Process recently added episodes
if len(added) > 0:
logger.debug(f"[Status] Found {len(added)} newly added episode(s)")
for item in added:
# Check if the item has already been processed
if item.key in plex.cache.newly_added and plex.cache.newly_added[item.key] == item.addedAt:
continue
plex.cache.newly_added[item.key] = item.addedAt

# Change tracks for all users
logger.info(f"[Status] Processing newly added episode {plex.get_episode_short_name(item)}")
plex.process_new_episode(item.key)
plex.process_new_or_updated_episode(item.key)

# Process updated episodes
if len(updated) > 0:
logger.debug(f"[Status] Found {len(updated)} updated episode(s)")
for item in updated:
# Change tracks for all users
logger.info(f"[Status] Processing updated episode {plex.get_episode_short_name(item)}")
plex.process_new_or_updated_episode(item.key, new=False)
2 changes: 1 addition & 1 deletion plex_auto_languages/alerts/timeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,4 @@ def process(self, plex: PlexServer):

# Change tracks for all users
logger.info(f"[Timeline] Processing newly added episode {plex.get_episode_short_name(item)}")
plex.process_new_episode(self.item_id)
plex.process_new_or_updated_episode(self.item_id)
41 changes: 23 additions & 18 deletions plex_auto_languages/plex_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
from plex_auto_languages.plex_alert_handler import PlexAlertHandler
from plex_auto_languages.track_changes import TrackChanges
from plex_auto_languages.utils.notifier import Notifier
from plex_auto_languages.plex_server_cache import PlexServerCache


logger = get_logger()
Expand All @@ -24,12 +25,29 @@ def __init__(self, url: str, token: str):
self._plex_url = url
self._plex = BasePlexServer(url, token)

@property
def unique_id(self):
return self._plex.machineIdentifier

def fetch_item(self, item_id: Union[str, int]):
try:
return self._plex.fetchItem(item_id)
except NotFound:
return None

def episodes(self):
return self._plex.library.all(libtype="episode")

def get_recently_added_episodes(self, minutes: int):
episodes = []
for section in self.get_show_sections():
recent = section.searchEpisodes(filters={"addedAt>>": f"{minutes}m"})
episodes.extend(recent)
return episodes

def get_show_sections(self):
return [s for s in self._plex.library.sections() if isinstance(s, ShowSection)]

@staticmethod
def get_last_watched_or_first_episode(show: Show):
watched_episodes = show.watched()
Expand Down Expand Up @@ -67,7 +85,7 @@ def __init__(self, url: str, token: str, notifier: Notifier, config: Configurati
logger.info(f"Successfully connected as user '{self.username}' (id: {self.user_id})")
self._alert_handler = None
self._alert_listener = None
self.cache = PlexCache()
self.cache = PlexServerCache(self)

@property
def is_alive(self):
Expand Down Expand Up @@ -118,7 +136,7 @@ def get_user_by_id(self, user_id: Union[int, str]):
return None
return matching_users[0]

def process_new_episode(self, item_id: Union[int, str]):
def process_new_or_updated_episode(self, item_id: Union[int, str], new: bool = True):
for user_id in self.get_all_user_ids():
# Switch to the user's Plex instance
user_plex = self.get_plex_instance_of_user(user_id)
Expand All @@ -140,7 +158,7 @@ def process_new_episode(self, item_id: Union[int, str]):
if user is None:
return
self.change_default_tracks_if_needed(user.name, reference, episodes=[user_item], notify=False)
self.notify_new_episode(self.fetch_item(item_id))
self.notify_updated_or_new_episode(self.fetch_item(item_id), new)

def change_default_tracks_if_needed(self, username: str, episode: Episode, episodes: List[Episode] = None,
notify: bool = True):
Expand Down Expand Up @@ -173,8 +191,8 @@ def notify_changes(self, track_changes: TrackChanges):
title = f"PlexAutoLanguages - {track_changes.reference_name}"
self.notifier.notify_user(title, track_changes.description, track_changes.username)

def notify_new_episode(self, episode: Episode):
title = "PlexAutoLanguages - New episode"
def notify_updated_or_new_episode(self, episode: Episode, new: bool):
title = f"PlexAutoLanguages - {'New' if new else 'Updated'} episode"
message = (
f"Episode: {self.get_episode_short_name(episode)}\n"
f"Updated language for all users"
Expand All @@ -185,9 +203,6 @@ def notify_new_episode(self, episode: Episode):
return
self.notifier.notify(title, message)

def get_all_show_sections(self):
return [s for s in self._plex.library.sections() if isinstance(s, ShowSection)]

def start_deep_analysis(self):
min_date = datetime.now() - timedelta(days=1)
history = self._plex.history(mindate=min_date)
Expand All @@ -197,13 +212,3 @@ def start_deep_analysis(self):
continue
episode.reload()
self.change_default_tracks_if_needed(user.name, episode)


class PlexCache():

def __init__(self):
self.session_states = {} # session_key: session_state
self.default_streams = {} # item_key: (audio_stream_id, substitle_stream_id)
self.user_clients = {} # client_identifier: user_id
self.newly_added = {} # episode_id: added_at
self.recent_activities = {} # (user_id, item_id): timestamp
44 changes: 44 additions & 0 deletions plex_auto_languages/plex_server_cache.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
from __future__ import annotations
from typing import TYPE_CHECKING

from plex_auto_languages.utils.logger import get_logger

if TYPE_CHECKING:
from plex_auto_languages.plex_server import PlexServer


logger = get_logger()


class PlexServerCache():

def __init__(self, plex: PlexServer):
self._plex = plex
# Alerts cache
self.session_states = {} # session_key: session_state
self.default_streams = {} # item_key: (audio_stream_id, substitle_stream_id)
self.user_clients = {} # client_identifier: user_id
self.newly_added = {} # episode_id: added_at
self.recent_activities = {} # (user_id, item_id): timestamp
# Library cache
self.episode_parts = {}
# Initialization
logger.info("Scanning all episodes from the library, this action can take a few seconds")
self.refresh_library_cache()
logger.info(f"Scanned {len(self.episode_parts)} episodes from the library")

def refresh_library_cache(self):
logger.debug("[Cache] Refreshing library cache")
added = []
updated = []
new_episode_parts = {}
for episode in self._plex.episodes():
part_list = new_episode_parts.setdefault(episode.key, [])
for part in episode.iterParts():
part_list.append(part.key)
if episode.key in self.episode_parts and set(self.episode_parts[episode.key]) != set(part_list):
updated.append(episode)
elif episode.key not in self.episode_parts:
added.append(episode)
self.episode_parts = new_episode_parts
return added, updated

0 comments on commit cc5e6bd

Please sign in to comment.