2022-01-03 03:59:30 +00:00
|
|
|
# coding=utf-8
|
|
|
|
# fmt: off
|
|
|
|
|
|
|
|
import logging
|
|
|
|
import operator
|
2023-07-26 23:34:49 +00:00
|
|
|
import ast
|
|
|
|
|
2022-01-03 03:59:30 +00:00
|
|
|
from datetime import datetime, timedelta
|
2023-02-17 16:14:37 +00:00
|
|
|
from functools import reduce
|
2023-07-26 23:34:49 +00:00
|
|
|
from sqlalchemy import and_
|
2022-01-03 03:59:30 +00:00
|
|
|
|
2022-05-01 12:00:20 +00:00
|
|
|
from app.config import settings
|
|
|
|
from app.database import get_exclusion_clause, get_audio_profile_languages, TableShows, TableEpisodes, TableMovies, \
|
2023-07-26 23:34:49 +00:00
|
|
|
TableHistory, TableHistoryMovie, database, select, func, get_profiles_list
|
2022-05-01 12:00:20 +00:00
|
|
|
from app.event_handler import show_progress, hide_progress
|
2023-02-17 16:14:37 +00:00
|
|
|
from app.get_providers import get_providers
|
|
|
|
from app.notifier import send_notifications, send_notifications_movie
|
|
|
|
from radarr.history import history_log_movie
|
|
|
|
from sonarr.history import history_log
|
|
|
|
from subtitles.indexer.movies import store_subtitles_movie
|
|
|
|
from subtitles.indexer.series import store_subtitles
|
|
|
|
from utilities.path_mappings import path_mappings
|
2022-01-03 03:59:30 +00:00
|
|
|
from .download import generate_subtitles
|
|
|
|
|
|
|
|
|
|
|
|
def upgrade_subtitles():
|
2023-10-14 13:56:21 +00:00
|
|
|
use_sonarr = settings.general.use_sonarr
|
|
|
|
use_radarr = settings.general.use_radarr
|
2022-01-03 03:59:30 +00:00
|
|
|
|
2023-02-23 16:18:57 +00:00
|
|
|
if use_sonarr:
|
|
|
|
episodes_to_upgrade = get_upgradable_episode_subtitles()
|
2023-07-26 23:34:49 +00:00
|
|
|
episodes_data = [{
|
|
|
|
'id': x.id,
|
|
|
|
'seriesTitle': x.seriesTitle,
|
|
|
|
'season': x.season,
|
|
|
|
'episode': x.episode,
|
|
|
|
'title': x.title,
|
|
|
|
'language': x.language,
|
|
|
|
'audio_language': x.audio_language,
|
|
|
|
'video_path': x.video_path,
|
|
|
|
'sceneName': x.sceneName,
|
|
|
|
'score': x.score,
|
|
|
|
'sonarrEpisodeId': x.sonarrEpisodeId,
|
|
|
|
'sonarrSeriesId': x.sonarrSeriesId,
|
|
|
|
'subtitles_path': x.subtitles_path,
|
|
|
|
'path': x.path,
|
|
|
|
'external_subtitles': [y[1] for y in ast.literal_eval(x.external_subtitles) if y[1]],
|
|
|
|
'upgradable': bool(x.upgradable),
|
|
|
|
} for x in database.execute(
|
|
|
|
select(TableHistory.id,
|
|
|
|
TableShows.title.label('seriesTitle'),
|
|
|
|
TableEpisodes.season,
|
|
|
|
TableEpisodes.episode,
|
|
|
|
TableEpisodes.title,
|
|
|
|
TableHistory.language,
|
|
|
|
TableEpisodes.audio_language,
|
|
|
|
TableHistory.video_path,
|
|
|
|
TableEpisodes.sceneName,
|
|
|
|
TableHistory.score,
|
|
|
|
TableHistory.sonarrEpisodeId,
|
|
|
|
TableHistory.sonarrSeriesId,
|
|
|
|
TableHistory.subtitles_path,
|
|
|
|
TableEpisodes.path,
|
|
|
|
TableShows.profileId,
|
|
|
|
TableEpisodes.subtitles.label('external_subtitles'),
|
|
|
|
episodes_to_upgrade.c.id.label('upgradable'))
|
|
|
|
.select_from(TableHistory)
|
|
|
|
.join(TableShows, onclause=TableHistory.sonarrSeriesId == TableShows.sonarrSeriesId)
|
|
|
|
.join(TableEpisodes, onclause=TableHistory.sonarrEpisodeId == TableEpisodes.sonarrEpisodeId)
|
|
|
|
.join(episodes_to_upgrade, onclause=TableHistory.id == episodes_to_upgrade.c.id, isouter=True)
|
|
|
|
.where(episodes_to_upgrade.c.id.is_not(None)))
|
|
|
|
.all() if _language_still_desired(x.language, x.profileId)]
|
|
|
|
|
|
|
|
for item in episodes_data:
|
|
|
|
if item['upgradable']:
|
|
|
|
if item['subtitles_path'] not in item['external_subtitles'] or \
|
|
|
|
not item['video_path'] == item['path']:
|
|
|
|
item.update({"upgradable": False})
|
|
|
|
|
|
|
|
del item['path']
|
|
|
|
del item['external_subtitles']
|
|
|
|
|
|
|
|
count_episode_to_upgrade = len(episodes_data)
|
|
|
|
|
|
|
|
for i, episode in enumerate(episodes_data):
|
2022-01-03 03:59:30 +00:00
|
|
|
providers_list = get_providers()
|
|
|
|
|
|
|
|
show_progress(id='upgrade_episodes_progress',
|
|
|
|
header='Upgrading episodes subtitles...',
|
2023-10-18 03:24:26 +00:00
|
|
|
name=f'{episode["seriesTitle"]} - S{episode["season"]:02d}E{episode["episode"]:02d} - {episode["title"]}',
|
2022-01-03 03:59:30 +00:00
|
|
|
value=i,
|
|
|
|
count=count_episode_to_upgrade)
|
|
|
|
|
|
|
|
if not providers_list:
|
|
|
|
logging.info("BAZARR All providers are throttled")
|
|
|
|
return
|
2023-02-23 16:18:57 +00:00
|
|
|
|
|
|
|
language, is_forced, is_hi = parse_language_string(episode['language'])
|
2022-01-03 03:59:30 +00:00
|
|
|
|
2023-01-29 21:44:56 +00:00
|
|
|
audio_language_list = get_audio_profile_languages(episode['audio_language'])
|
2022-01-03 03:59:30 +00:00
|
|
|
if len(audio_language_list) > 0:
|
|
|
|
audio_language = audio_language_list[0]['name']
|
|
|
|
else:
|
|
|
|
audio_language = 'None'
|
|
|
|
|
|
|
|
result = list(generate_subtitles(path_mappings.path_replace(episode['video_path']),
|
|
|
|
[(language, is_hi, is_forced)],
|
|
|
|
audio_language,
|
2023-01-29 21:44:56 +00:00
|
|
|
str(episode['sceneName']),
|
2022-01-19 12:58:31 +00:00
|
|
|
episode['seriesTitle'],
|
2022-01-03 03:59:30 +00:00
|
|
|
'series',
|
|
|
|
forced_minimum_score=int(episode['score']),
|
|
|
|
is_upgrade=True))
|
|
|
|
|
|
|
|
if result:
|
2023-10-08 13:20:46 +00:00
|
|
|
if isinstance(result, list) and len(result):
|
|
|
|
result = result[0]
|
|
|
|
if isinstance(result, tuple) and len(result):
|
|
|
|
result = result[0]
|
2022-01-03 03:59:30 +00:00
|
|
|
store_subtitles(episode['video_path'], path_mappings.path_replace(episode['video_path']))
|
2023-02-23 16:18:57 +00:00
|
|
|
history_log(3, episode['sonarrSeriesId'], episode['sonarrEpisodeId'], result)
|
|
|
|
send_notifications(episode['sonarrSeriesId'], episode['sonarrEpisodeId'], result.message)
|
2022-01-03 03:59:30 +00:00
|
|
|
|
|
|
|
hide_progress(id='upgrade_episodes_progress')
|
|
|
|
|
2023-02-23 16:18:57 +00:00
|
|
|
if use_radarr:
|
|
|
|
movies_to_upgrade = get_upgradable_movies_subtitles()
|
2023-07-26 23:34:49 +00:00
|
|
|
movies_data = [{
|
|
|
|
'title': x.title,
|
|
|
|
'language': x.language,
|
|
|
|
'audio_language': x.audio_language,
|
|
|
|
'video_path': x.video_path,
|
|
|
|
'sceneName': x.sceneName,
|
|
|
|
'score': x.score,
|
|
|
|
'radarrId': x.radarrId,
|
|
|
|
'path': x.path,
|
|
|
|
'subtitles_path': x.subtitles_path,
|
|
|
|
'external_subtitles': [y[1] for y in ast.literal_eval(x.external_subtitles) if y[1]],
|
|
|
|
'upgradable': bool(x.upgradable),
|
|
|
|
} for x in database.execute(
|
|
|
|
select(TableMovies.title,
|
|
|
|
TableHistoryMovie.language,
|
|
|
|
TableMovies.audio_language,
|
|
|
|
TableHistoryMovie.video_path,
|
|
|
|
TableMovies.sceneName,
|
|
|
|
TableHistoryMovie.score,
|
|
|
|
TableHistoryMovie.radarrId,
|
|
|
|
TableHistoryMovie.subtitles_path,
|
|
|
|
TableMovies.path,
|
|
|
|
TableMovies.profileId,
|
|
|
|
TableMovies.subtitles.label('external_subtitles'),
|
|
|
|
movies_to_upgrade.c.id.label('upgradable'))
|
|
|
|
.select_from(TableHistoryMovie)
|
|
|
|
.join(TableMovies, onclause=TableHistoryMovie.radarrId == TableMovies.radarrId)
|
|
|
|
.join(movies_to_upgrade, onclause=TableHistoryMovie.id == movies_to_upgrade.c.id, isouter=True)
|
|
|
|
.where(movies_to_upgrade.c.id.is_not(None)))
|
|
|
|
.all() if _language_still_desired(x.language, x.profileId)]
|
|
|
|
|
|
|
|
for item in movies_data:
|
|
|
|
if item['upgradable']:
|
|
|
|
if item['subtitles_path'] not in item['external_subtitles'] or \
|
|
|
|
not item['video_path'] == item['path']:
|
|
|
|
item.update({"upgradable": False})
|
|
|
|
|
|
|
|
del item['path']
|
|
|
|
del item['external_subtitles']
|
|
|
|
|
|
|
|
count_movie_to_upgrade = len(movies_data)
|
|
|
|
|
|
|
|
for i, movie in enumerate(movies_data):
|
2022-01-03 03:59:30 +00:00
|
|
|
providers_list = get_providers()
|
|
|
|
|
|
|
|
show_progress(id='upgrade_movies_progress',
|
|
|
|
header='Upgrading movies subtitles...',
|
|
|
|
name=movie['title'],
|
|
|
|
value=i,
|
|
|
|
count=count_movie_to_upgrade)
|
|
|
|
|
|
|
|
if not providers_list:
|
|
|
|
logging.info("BAZARR All providers are throttled")
|
|
|
|
return
|
2023-02-23 16:18:57 +00:00
|
|
|
|
|
|
|
language, is_forced, is_hi = parse_language_string(movie['language'])
|
2022-01-03 03:59:30 +00:00
|
|
|
|
2023-01-29 21:44:56 +00:00
|
|
|
audio_language_list = get_audio_profile_languages(movie['audio_language'])
|
2022-01-03 03:59:30 +00:00
|
|
|
if len(audio_language_list) > 0:
|
|
|
|
audio_language = audio_language_list[0]['name']
|
|
|
|
else:
|
|
|
|
audio_language = 'None'
|
|
|
|
|
|
|
|
result = list(generate_subtitles(path_mappings.path_replace_movie(movie['video_path']),
|
|
|
|
[(language, is_hi, is_forced)],
|
|
|
|
audio_language,
|
|
|
|
str(movie['sceneName']),
|
|
|
|
movie['title'],
|
|
|
|
'movie',
|
|
|
|
forced_minimum_score=int(movie['score']),
|
|
|
|
is_upgrade=True))
|
|
|
|
if result:
|
2023-10-08 13:20:46 +00:00
|
|
|
if isinstance(result, list) and len(result):
|
|
|
|
result = result[0]
|
|
|
|
if isinstance(result, tuple) and len(result):
|
|
|
|
result = result[0]
|
2022-01-03 03:59:30 +00:00
|
|
|
store_subtitles_movie(movie['video_path'],
|
|
|
|
path_mappings.path_replace_movie(movie['video_path']))
|
2023-02-23 16:18:57 +00:00
|
|
|
history_log_movie(3, movie['radarrId'], result)
|
|
|
|
send_notifications_movie(movie['radarrId'], result.message)
|
2022-01-03 03:59:30 +00:00
|
|
|
|
|
|
|
hide_progress(id='upgrade_movies_progress')
|
|
|
|
|
|
|
|
logging.info('BAZARR Finished searching for Subtitles to upgrade. Check History for more information.')
|
2023-02-23 16:18:57 +00:00
|
|
|
|
|
|
|
|
|
|
|
def get_queries_condition_parameters():
|
|
|
|
days_to_upgrade_subs = settings.general.days_to_upgrade_subs
|
|
|
|
minimum_timestamp = (datetime.now() - timedelta(days=int(days_to_upgrade_subs)))
|
|
|
|
|
2023-10-14 13:56:21 +00:00
|
|
|
if settings.general.upgrade_manual:
|
2023-02-23 16:18:57 +00:00
|
|
|
query_actions = [1, 2, 3, 4, 6]
|
|
|
|
else:
|
|
|
|
query_actions = [1, 3]
|
|
|
|
|
|
|
|
return [minimum_timestamp, query_actions]
|
|
|
|
|
|
|
|
|
|
|
|
def parse_language_string(language_string):
|
|
|
|
if language_string.endswith('forced'):
|
|
|
|
language = language_string.split(':')[0]
|
|
|
|
is_forced = "True"
|
|
|
|
is_hi = "False"
|
|
|
|
elif language_string.endswith('hi'):
|
|
|
|
language = language_string.split(':')[0]
|
|
|
|
is_forced = "False"
|
|
|
|
is_hi = "True"
|
|
|
|
else:
|
|
|
|
language = language_string.split(':')[0]
|
|
|
|
is_forced = "False"
|
|
|
|
is_hi = "False"
|
|
|
|
|
|
|
|
return [language, is_forced, is_hi]
|
|
|
|
|
|
|
|
|
|
|
|
def get_upgradable_episode_subtitles():
|
2023-10-14 13:56:21 +00:00
|
|
|
if not settings.general.upgrade_subs:
|
2023-08-04 14:18:48 +00:00
|
|
|
# return an empty set of rows
|
|
|
|
return select(TableHistory.id) \
|
|
|
|
.where(TableHistory.id.is_(None)) \
|
|
|
|
.subquery()
|
2023-07-03 22:28:29 +00:00
|
|
|
|
2023-07-26 23:34:49 +00:00
|
|
|
max_id_timestamp = select(TableHistory.video_path,
|
|
|
|
TableHistory.language,
|
|
|
|
func.max(TableHistory.timestamp).label('timestamp')) \
|
|
|
|
.group_by(TableHistory.video_path, TableHistory.language) \
|
|
|
|
.distinct() \
|
|
|
|
.subquery()
|
|
|
|
|
2023-02-23 16:18:57 +00:00
|
|
|
minimum_timestamp, query_actions = get_queries_condition_parameters()
|
|
|
|
|
2023-07-26 23:34:49 +00:00
|
|
|
upgradable_episodes_conditions = [(TableHistory.action.in_(query_actions)),
|
2023-02-23 16:18:57 +00:00
|
|
|
(TableHistory.timestamp > minimum_timestamp),
|
2023-07-26 23:34:49 +00:00
|
|
|
TableHistory.score.is_not(None),
|
|
|
|
(TableHistory.score < 357)]
|
2023-02-23 16:18:57 +00:00
|
|
|
upgradable_episodes_conditions += get_exclusion_clause('series')
|
2023-07-26 23:34:49 +00:00
|
|
|
return select(TableHistory.id)\
|
|
|
|
.select_from(TableHistory) \
|
|
|
|
.join(max_id_timestamp, onclause=and_(TableHistory.video_path == max_id_timestamp.c.video_path,
|
|
|
|
TableHistory.language == max_id_timestamp.c.language,
|
|
|
|
max_id_timestamp.c.timestamp == TableHistory.timestamp)) \
|
|
|
|
.join(TableShows, onclause=TableHistory.sonarrSeriesId == TableShows.sonarrSeriesId) \
|
|
|
|
.join(TableEpisodes, onclause=TableHistory.sonarrEpisodeId == TableEpisodes.sonarrEpisodeId) \
|
2023-02-23 16:18:57 +00:00
|
|
|
.where(reduce(operator.and_, upgradable_episodes_conditions)) \
|
2023-07-26 23:34:49 +00:00
|
|
|
.order_by(TableHistory.timestamp.desc())\
|
|
|
|
.subquery()
|
2023-02-23 16:18:57 +00:00
|
|
|
|
|
|
|
|
|
|
|
def get_upgradable_movies_subtitles():
|
2023-10-14 13:56:21 +00:00
|
|
|
if not settings.general.upgrade_subs:
|
2023-08-04 14:18:48 +00:00
|
|
|
# return an empty set of rows
|
|
|
|
return select(TableHistoryMovie.id) \
|
|
|
|
.where(TableHistoryMovie.id.is_(None)) \
|
|
|
|
.subquery()
|
2023-07-03 22:28:29 +00:00
|
|
|
|
2023-07-26 23:34:49 +00:00
|
|
|
max_id_timestamp = select(TableHistoryMovie.video_path,
|
|
|
|
TableHistoryMovie.language,
|
|
|
|
func.max(TableHistoryMovie.timestamp).label('timestamp')) \
|
|
|
|
.group_by(TableHistoryMovie.video_path, TableHistoryMovie.language) \
|
|
|
|
.distinct() \
|
|
|
|
.subquery()
|
|
|
|
|
2023-02-23 16:18:57 +00:00
|
|
|
minimum_timestamp, query_actions = get_queries_condition_parameters()
|
|
|
|
|
2023-07-26 23:34:49 +00:00
|
|
|
upgradable_movies_conditions = [(TableHistoryMovie.action.in_(query_actions)),
|
2023-02-23 16:18:57 +00:00
|
|
|
(TableHistoryMovie.timestamp > minimum_timestamp),
|
2023-07-26 23:34:49 +00:00
|
|
|
TableHistoryMovie.score.is_not(None),
|
|
|
|
(TableHistoryMovie.score < 117)]
|
2023-02-23 16:18:57 +00:00
|
|
|
upgradable_movies_conditions += get_exclusion_clause('movie')
|
2023-07-26 23:34:49 +00:00
|
|
|
return select(TableHistoryMovie.id) \
|
|
|
|
.select_from(TableHistoryMovie) \
|
|
|
|
.join(max_id_timestamp, onclause=and_(TableHistoryMovie.video_path == max_id_timestamp.c.video_path,
|
|
|
|
TableHistoryMovie.language == max_id_timestamp.c.language,
|
|
|
|
max_id_timestamp.c.timestamp == TableHistoryMovie.timestamp)) \
|
|
|
|
.join(TableMovies, onclause=TableHistoryMovie.radarrId == TableMovies.radarrId) \
|
2023-02-23 16:18:57 +00:00
|
|
|
.where(reduce(operator.and_, upgradable_movies_conditions)) \
|
|
|
|
.order_by(TableHistoryMovie.timestamp.desc()) \
|
2023-07-26 23:34:49 +00:00
|
|
|
.subquery()
|
2023-06-15 16:06:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
def _language_still_desired(language, profile_id):
|
|
|
|
if not profile_id:
|
|
|
|
return False
|
|
|
|
|
|
|
|
profile = get_profiles_list(profile_id)
|
|
|
|
if profile and language in _language_from_items(profile['items']):
|
|
|
|
return True
|
|
|
|
else:
|
|
|
|
return False
|
|
|
|
|
|
|
|
|
|
|
|
def _language_from_items(items):
|
|
|
|
results = []
|
|
|
|
for item in items:
|
|
|
|
if item['forced'] == 'True':
|
2023-10-18 03:24:26 +00:00
|
|
|
results.append(f'{item["language"]}:forced')
|
2023-06-15 16:06:18 +00:00
|
|
|
elif item['hi'] == 'True':
|
2023-10-18 03:24:26 +00:00
|
|
|
results.append(f'{item["language"]}:hi')
|
2023-06-15 16:06:18 +00:00
|
|
|
else:
|
|
|
|
results.append(item['language'])
|
2023-10-18 03:24:26 +00:00
|
|
|
results.append(f'{item["language"]}:hi')
|
2023-06-15 16:06:18 +00:00
|
|
|
return results
|