mirror of
https://github.com/morpheus65535/bazarr.git
synced 2025-06-27 17:09:34 -04:00
Added scan Plex library option for new files after downloading subtitles
This commit is contained in:
parent
fe7b224916
commit
31400c8957
5 changed files with 120 additions and 27 deletions
|
@ -221,7 +221,11 @@ validators = [
|
||||||
Validator('plex.ssl', must_exist=True, default=False, is_type_of=bool),
|
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.apikey', must_exist=True, default='', is_type_of=str),
|
||||||
Validator('plex.movie_library', 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
|
# proxy section
|
||||||
Validator('proxy.type', must_exist=True, default=None, is_type_of=(NoneType, str),
|
Validator('proxy.type', must_exist=True, default=None, is_type_of=(NoneType, str),
|
||||||
|
|
|
@ -6,22 +6,76 @@ import logging
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
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:
|
try:
|
||||||
if settings.plex.ssl:
|
protocol = "https://" if settings.plex.ssl else "http://"
|
||||||
protocol_plex = "https://"
|
baseurl = f"{protocol}{settings.plex.ip}:{settings.plex.port}"
|
||||||
else:
|
return PlexServer(baseurl, settings.plex.apikey)
|
||||||
protocol_plex = "http://"
|
except Exception as e:
|
||||||
|
logger.error(f"Failed to connect to Plex server: {e}")
|
||||||
|
raise
|
||||||
|
|
||||||
baseurl = f'{protocol_plex}{settings.plex.ip}:{settings.plex.port}'
|
|
||||||
token = settings.plex.apikey
|
def update_added_date(video, added_date: str) -> None:
|
||||||
plex = PlexServer(baseurl, token)
|
"""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:
|
||||||
|
plex = get_plex_server()
|
||||||
library = plex.library.section(settings.plex.movie_library)
|
library = plex.library.section(settings.plex.movie_library)
|
||||||
video = library.getGuid(guid=movie_metadata.imdbId)
|
video = library.getGuid(guid=movie_metadata.imdbId)
|
||||||
# Get the current date and time in the desired format
|
current_date = datetime.now().strftime(DATETIME_FORMAT)
|
||||||
current_date = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
|
update_added_date(video, current_date)
|
||||||
updates = {"addedAt.value": current_date}
|
|
||||||
video.edit(**updates)
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"A Plex error occurred: {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"Error in plex_update_library: {e}")
|
|
@ -7,11 +7,11 @@ from app.config import settings, sync_checker as _defaul_sync_checker
|
||||||
from utilities.path_mappings import path_mappings
|
from utilities.path_mappings import path_mappings
|
||||||
from utilities.post_processing import pp_replace, set_chmod
|
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 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 utilities.analytics import event_tracker
|
||||||
from radarr.notify import notify_radarr
|
from radarr.notify import notify_radarr
|
||||||
from sonarr.notify import notify_sonarr
|
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 app.event_handler import event_stream
|
||||||
|
|
||||||
from .utils import _get_download_code3
|
from .utils import _get_download_code3
|
||||||
|
@ -77,8 +77,10 @@ def process_subtitle(subtitle, media_type, audio_language, path, max_score, is_u
|
||||||
|
|
||||||
if media_type == 'series':
|
if media_type == 'series':
|
||||||
episode_metadata = database.execute(
|
episode_metadata = database.execute(
|
||||||
select(TableEpisodes.sonarrSeriesId, TableEpisodes.sonarrEpisodeId)
|
select(TableShows.imdbId, TableEpisodes.sonarrSeriesId, TableEpisodes.sonarrEpisodeId,
|
||||||
.where(TableEpisodes.path == path_mappings.path_replace_reverse(path)))\
|
TableEpisodes.season, TableEpisodes.episode)
|
||||||
|
.join(TableShows)\
|
||||||
|
.where(TableEpisodes.path == path_mappings.path_replace_reverse(path)))\
|
||||||
.first()
|
.first()
|
||||||
if not episode_metadata:
|
if not episode_metadata:
|
||||||
return
|
return
|
||||||
|
@ -97,7 +99,7 @@ def process_subtitle(subtitle, media_type, audio_language, path, max_score, is_u
|
||||||
else:
|
else:
|
||||||
movie_metadata = database.execute(
|
movie_metadata = database.execute(
|
||||||
select(TableMovies.radarrId, TableMovies.imdbId)
|
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()
|
.first()
|
||||||
if not movie_metadata:
|
if not movie_metadata:
|
||||||
return
|
return
|
||||||
|
@ -116,7 +118,8 @@ def process_subtitle(subtitle, media_type, audio_language, path, max_score, is_u
|
||||||
if use_postprocessing is True:
|
if use_postprocessing is True:
|
||||||
command = pp_replace(postprocessing_cmd, path, downloaded_path, downloaded_language, downloaded_language_code2,
|
command = pp_replace(postprocessing_cmd, path, downloaded_path, downloaded_language, downloaded_language_code2,
|
||||||
downloaded_language_code3, audio_language, audio_language_code2, audio_language_code3,
|
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':
|
if media_type == 'series':
|
||||||
use_pp_threshold = settings.general.use_postprocessing_threshold
|
use_pp_threshold = settings.general.use_postprocessing_threshold
|
||||||
|
@ -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='series', action='update', payload=episode_metadata.sonarrSeriesId)
|
||||||
event_stream(type='episode-wanted', action='delete',
|
event_stream(type='episode-wanted', action='delete',
|
||||||
payload=episode_metadata.sonarrEpisodeId)
|
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:
|
else:
|
||||||
reversed_path = path_mappings.path_replace_reverse_movie(path)
|
reversed_path = path_mappings.path_replace_reverse_movie(path)
|
||||||
reversed_subtitles_path = path_mappings.path_replace_reverse_movie(downloaded_path)
|
reversed_subtitles_path = path_mappings.path_replace_reverse_movie(downloaded_path)
|
||||||
notify_radarr(movie_metadata.radarrId)
|
notify_radarr(movie_metadata.radarrId)
|
||||||
event_stream(type='movie-wanted', action='delete', payload=movie_metadata.radarrId)
|
event_stream(type='movie-wanted', action='delete', payload=movie_metadata.radarrId)
|
||||||
if settings.plex.set_added is True:
|
if settings.general.use_plex is True:
|
||||||
plex_set_added_date_now(movie_metadata)
|
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)
|
event_tracker.track_subtitles(provider=downloaded_provider, action=action, language=downloaded_language)
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ import { plexEnabledKey } from "@/pages/Settings/keys";
|
||||||
const SettingsPlexView: FunctionComponent = () => {
|
const SettingsPlexView: FunctionComponent = () => {
|
||||||
return (
|
return (
|
||||||
<Layout name="Interface">
|
<Layout name="Interface">
|
||||||
<Section header="Use Plex integration">
|
<Section header="Use Plex operations">
|
||||||
<Check label="Enabled" settingKey={plexEnabledKey}></Check>
|
<Check label="Enabled" settingKey={plexEnabledKey}></Check>
|
||||||
</Section>
|
</Section>
|
||||||
<CollapseBox settingKey={plexEnabledKey}>
|
<CollapseBox settingKey={plexEnabledKey}>
|
||||||
|
@ -28,15 +28,35 @@ const SettingsPlexView: FunctionComponent = () => {
|
||||||
<Text label="API Token" settingKey="settings-plex-apikey"></Text>
|
<Text label="API Token" settingKey="settings-plex-apikey"></Text>
|
||||||
<Check label="SSL" settingKey="settings-plex-ssl"></Check>
|
<Check label="SSL" settingKey="settings-plex-ssl"></Check>
|
||||||
</Section>
|
</Section>
|
||||||
<Section header="Movie editing">
|
<Section header="Movie library">
|
||||||
<Text
|
<Text
|
||||||
label="Name of the library"
|
label="Name of the library"
|
||||||
settingKey="settings-plex-movie_library"
|
settingKey="settings-plex-movie_library"
|
||||||
></Text>
|
></Text>
|
||||||
<Check
|
<Check
|
||||||
label="Set the movie as recently added after downloading the subtitles"
|
label="Mark the movie as recently added after downloading subtitles"
|
||||||
settingKey="settings-plex-set_added"
|
settingKey="settings-plex-set_movie_added"
|
||||||
></Check>
|
></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>
|
</Section>
|
||||||
</CollapseBox>
|
</CollapseBox>
|
||||||
</Layout>
|
</Layout>
|
||||||
|
|
6
frontend/src/types/settings.d.ts
vendored
6
frontend/src/types/settings.d.ts
vendored
|
@ -178,8 +178,12 @@ declare namespace Settings {
|
||||||
port: number;
|
port: number;
|
||||||
apikey?: string;
|
apikey?: string;
|
||||||
ssl?: boolean;
|
ssl?: boolean;
|
||||||
set_added?: boolean;
|
set_movie_added?: boolean;
|
||||||
|
set_episode_added?: boolean;
|
||||||
movie_library?: string;
|
movie_library?: string;
|
||||||
|
series_library?: string;
|
||||||
|
update_movie_library?: boolean;
|
||||||
|
update_series_library?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Anticaptcha {
|
interface Anticaptcha {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue