Skip to content

Commit

Permalink
Added scan Plex library option for new files after downloading subtitles
Browse files Browse the repository at this point in the history
  • Loading branch information
destpstrzy authored Jan 26, 2025
1 parent fe7b224 commit 31400c8
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 28 deletions.
6 changes: 5 additions & 1 deletion bazarr/app/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,11 @@ def check_parser_binary(value):
Validator('plex.ssl', must_exist=True, default=False, is_type_of=bool),
Validator('plex.apikey', must_exist=True, default='', is_type_of=str),
Validator('plex.movie_library', must_exist=True, default='', is_type_of=str),
Validator('plex.set_added', must_exist=True, default=False, is_type_of=bool),
Validator('plex.series_library', must_exist=True, default='', is_type_of=str),
Validator('plex.set_movie_added', must_exist=True, default=False, is_type_of=bool),
Validator('plex.set_episode_added', must_exist=True, default=False, is_type_of=bool),
Validator('plex.update_movie_library', must_exist=True, default=False, is_type_of=bool),
Validator('plex.update_series_library', must_exist=True, default=False, is_type_of=bool),

# proxy section
Validator('proxy.type', must_exist=True, default=None, is_type_of=(NoneType, str),
Expand Down
82 changes: 68 additions & 14 deletions bazarr/plex/operations.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,22 +6,76 @@

logger = logging.getLogger(__name__)

# Constants
DATETIME_FORMAT = '%Y-%m-%d %H:%M:%S'

def plex_set_added_date_now(movie_metadata):

def get_plex_server() -> PlexServer:
"""Connect to the Plex server and return the server instance."""
try:
protocol = "https://" if settings.plex.ssl else "http://"
baseurl = f"{protocol}{settings.plex.ip}:{settings.plex.port}"
return PlexServer(baseurl, settings.plex.apikey)
except Exception as e:
logger.error(f"Failed to connect to Plex server: {e}")
raise


def update_added_date(video, added_date: str) -> None:
"""Update the added date of a video in Plex."""
try:
updates = {"addedAt.value": added_date}
video.edit(**updates)
logger.info(f"Updated added date for {video.title} to {added_date}")
except Exception as e:
logger.error(f"Failed to update added date for {video.title}: {e}")
raise


def plex_set_movie_added_date_now(movie_metadata) -> None:
"""
Update the added date of a movie in Plex to the current datetime.
:param movie_metadata: Metadata object containing the movie's IMDb ID.
"""
try:
if settings.plex.ssl:
protocol_plex = "https://"
else:
protocol_plex = "http://"

baseurl = f'{protocol_plex}{settings.plex.ip}:{settings.plex.port}'
token = settings.plex.apikey
plex = PlexServer(baseurl, token)
plex = get_plex_server()
library = plex.library.section(settings.plex.movie_library)
video = library.getGuid(guid=movie_metadata.imdbId)
# Get the current date and time in the desired format
current_date = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
updates = {"addedAt.value": current_date}
video.edit(**updates)
current_date = datetime.now().strftime(DATETIME_FORMAT)
update_added_date(video, current_date)
except Exception as e:
logger.error(f"Error in plex_set_movie_added_date_now: {e}")


def plex_set_episode_added_date_now(episode_metadata) -> None:
"""
Update the added date of a TV episode in Plex to the current datetime.
:param episode_metadata: Metadata object containing the episode's IMDb ID, season, and episode number.
"""
try:
plex = get_plex_server()
library = plex.library.section(settings.plex.series_library)
show = library.getGuid(episode_metadata.imdbId)
episode = show.episode(season=episode_metadata.season, episode=episode_metadata.episode)
current_date = datetime.now().strftime(DATETIME_FORMAT)
update_added_date(episode, current_date)
except Exception as e:
logger.error(f"Error in plex_set_episode_added_date_now: {e}")


def plex_update_library(is_movie_library: bool) -> None:
"""
Trigger a library update for the specified library type.
:param is_movie_library: True for movie library, False for series library.
"""
try:
plex = get_plex_server()
library_name = settings.plex.movie_library if is_movie_library else settings.plex.series_library
library = plex.library.section(library_name)
library.update()
logger.info(f"Triggered update for library: {library_name}")
except Exception as e:
logger.error(f"A Plex error occurred: {e}")
logger.error(f"Error in plex_update_library: {e}")
27 changes: 19 additions & 8 deletions bazarr/subtitles/processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@
from utilities.path_mappings import path_mappings
from utilities.post_processing import pp_replace, set_chmod
from languages.get_languages import alpha2_from_alpha3, alpha2_from_language, alpha3_from_language, language_from_alpha3
from app.database import TableEpisodes, TableMovies, database, select
from app.database import TableShows, TableEpisodes, TableMovies, database, select
from utilities.analytics import event_tracker
from radarr.notify import notify_radarr
from sonarr.notify import notify_sonarr
from plex.operations import plex_set_added_date_now
from plex.operations import plex_set_movie_added_date_now, plex_update_library, plex_set_episode_added_date_now
from app.event_handler import event_stream

from .utils import _get_download_code3
Expand Down Expand Up @@ -77,8 +77,10 @@ def process_subtitle(subtitle, media_type, audio_language, path, max_score, is_u

if media_type == 'series':
episode_metadata = database.execute(
select(TableEpisodes.sonarrSeriesId, TableEpisodes.sonarrEpisodeId)
.where(TableEpisodes.path == path_mappings.path_replace_reverse(path)))\
select(TableShows.imdbId, TableEpisodes.sonarrSeriesId, TableEpisodes.sonarrEpisodeId,
TableEpisodes.season, TableEpisodes.episode)
.join(TableShows)\
.where(TableEpisodes.path == path_mappings.path_replace_reverse(path)))\
.first()
if not episode_metadata:
return
Expand All @@ -97,7 +99,7 @@ def process_subtitle(subtitle, media_type, audio_language, path, max_score, is_u
else:
movie_metadata = database.execute(
select(TableMovies.radarrId, TableMovies.imdbId)
.where(TableMovies.path == path_mappings.path_replace_reverse_movie(path)))\
.where(TableMovies.path == path_mappings.path_replace_reverse_movie(path)))\
.first()
if not movie_metadata:
return
Expand All @@ -116,7 +118,8 @@ def process_subtitle(subtitle, media_type, audio_language, path, max_score, is_u
if use_postprocessing is True:
command = pp_replace(postprocessing_cmd, path, downloaded_path, downloaded_language, downloaded_language_code2,
downloaded_language_code3, audio_language, audio_language_code2, audio_language_code3,
percent_score, subtitle_id, downloaded_provider, uploader, release_info, series_id, episode_id)
percent_score, subtitle_id, downloaded_provider, uploader, release_info, series_id,
episode_id)

if media_type == 'series':
use_pp_threshold = settings.general.use_postprocessing_threshold
Expand All @@ -140,14 +143,22 @@ def process_subtitle(subtitle, media_type, audio_language, path, max_score, is_u
event_stream(type='series', action='update', payload=episode_metadata.sonarrSeriesId)
event_stream(type='episode-wanted', action='delete',
payload=episode_metadata.sonarrEpisodeId)
if settings.general.use_plex is True:
if settings.plex.update_series_library is True:
plex_update_library(is_movie_library=False)
if settings.plex.set_episode_added is True:
plex_set_episode_added_date_now(episode_metadata)

else:
reversed_path = path_mappings.path_replace_reverse_movie(path)
reversed_subtitles_path = path_mappings.path_replace_reverse_movie(downloaded_path)
notify_radarr(movie_metadata.radarrId)
event_stream(type='movie-wanted', action='delete', payload=movie_metadata.radarrId)
if settings.plex.set_added is True:
plex_set_added_date_now(movie_metadata)
if settings.general.use_plex is True:
if settings.plex.set_movie_added is True:
plex_set_movie_added_date_now(movie_metadata)
if settings.plex.update_movie_library is True:
plex_update_library(is_movie_library=True)

event_tracker.track_subtitles(provider=downloaded_provider, action=action, language=downloaded_language)

Expand Down
28 changes: 24 additions & 4 deletions frontend/src/pages/Settings/Plex/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { plexEnabledKey } from "@/pages/Settings/keys";
const SettingsPlexView: FunctionComponent = () => {
return (
<Layout name="Interface">
<Section header="Use Plex integration">
<Section header="Use Plex operations">
<Check label="Enabled" settingKey={plexEnabledKey}></Check>
</Section>
<CollapseBox settingKey={plexEnabledKey}>
Expand All @@ -28,15 +28,35 @@ const SettingsPlexView: FunctionComponent = () => {
<Text label="API Token" settingKey="settings-plex-apikey"></Text>
<Check label="SSL" settingKey="settings-plex-ssl"></Check>
</Section>
<Section header="Movie editing">
<Section header="Movie library">
<Text
label="Name of the library"
settingKey="settings-plex-movie_library"
></Text>
<Check
label="Set the movie as recently added after downloading the subtitles"
settingKey="settings-plex-set_added"
label="Mark the movie as recently added after downloading subtitles"
settingKey="settings-plex-set_movie_added"
></Check>
<Check
label="Scan library for new files after downloading subtitles"
settingKey="settings-plex-update_movie_library"
></Check>
<Message>Can be helpful for remote media files</Message>
</Section>
<Section header="Series library">
<Text
label="Name of the library"
settingKey="settings-plex-series_library"
></Text>
<Check
label="Mark the episode as recently added after downloading subtitles"
settingKey="settings-plex-set_episode_added"
></Check>
<Check
label="Scan library for new files after downloading subtitles"
settingKey="settings-plex-update_series_library"
></Check>
<Message>Can be helpful for remote media files</Message>
</Section>
</CollapseBox>
</Layout>
Expand Down
6 changes: 5 additions & 1 deletion frontend/src/types/settings.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -178,8 +178,12 @@ declare namespace Settings {
port: number;
apikey?: string;
ssl?: boolean;
set_added?: boolean;
set_movie_added?: boolean;
set_episode_added?: boolean;
movie_library?: string;
series_library?: string;
update_movie_library?: boolean;
update_series_library?: boolean;
}

interface Anticaptcha {
Expand Down

0 comments on commit 31400c8

Please sign in to comment.