Merge fixes for API.

autonomous
morpheus65535 3 years ago
parent dc86c0076d
commit 2420344604

@ -22,7 +22,7 @@ class Badges(Resource):
missing_episodes = TableEpisodes.select(TableShows.tags,
TableShows.seriesType,
TableEpisodes.monitored)\
.join(TableShows, on=(TableEpisodes.sonarrSeriesId == TableShows.sonarrSeriesId))\
.join(TableShows)\
.where(reduce(operator.and_, episodes_conditions))\
.count()

@ -9,7 +9,6 @@ from flask_restful import Resource
from database import TableEpisodes, TableShows, TableBlacklist
from ..utils import authenticate, postprocessEpisode
from utils import blacklist_log, delete_subtitles, blacklist_delete_all, blacklist_delete
from helper import path_mappings
from get_subtitle import episode_download_subtitles
from event_handler import event_stream
@ -26,13 +25,13 @@ class EpisodesBlacklist(Resource):
data = TableBlacklist.select(TableShows.title.alias('seriesTitle'),
TableEpisodes.season.concat('x').concat(TableEpisodes.episode).alias('episode_number'),
TableEpisodes.title.alias('episodeTitle'),
TableEpisodes.sonarrSeriesId,
TableEpisodes.seriesId,
TableBlacklist.provider,
TableBlacklist.subs_id,
TableBlacklist.language,
TableBlacklist.timestamp)\
.join(TableEpisodes, on=(TableBlacklist.sonarr_episode_id == TableEpisodes.sonarrEpisodeId))\
.join(TableShows, on=(TableBlacklist.sonarr_series_id == TableShows.sonarrSeriesId))\
.join(TableEpisodes)\
.join(TableShows)\
.order_by(TableBlacklist.timestamp.desc())\
.limit(length)\
.offset(start)\
@ -50,22 +49,22 @@ class EpisodesBlacklist(Resource):
@authenticate
def post(self):
sonarr_series_id = int(request.args.get('seriesid'))
sonarr_episode_id = int(request.args.get('episodeid'))
series_id = int(request.args.get('seriesid'))
episode_id = int(request.args.get('episodeid'))
provider = request.form.get('provider')
subs_id = request.form.get('subs_id')
language = request.form.get('language')
episodeInfo = TableEpisodes.select(TableEpisodes.path)\
.where(TableEpisodes.sonarrEpisodeId == sonarr_episode_id)\
.where(TableEpisodes.episodeId == episode_id)\
.dicts()\
.get()
media_path = episodeInfo['path']
subtitles_path = request.form.get('subtitles_path')
blacklist_log(sonarr_series_id=sonarr_series_id,
sonarr_episode_id=sonarr_episode_id,
blacklist_log(series_id=series_id,
episode_id=episode_id,
provider=provider,
subs_id=subs_id,
language=language)
@ -73,11 +72,11 @@ class EpisodesBlacklist(Resource):
language=language,
forced=False,
hi=False,
media_path=path_mappings.path_replace(media_path),
media_path=media_path,
subtitles_path=subtitles_path,
sonarr_series_id=sonarr_series_id,
sonarr_episode_id=sonarr_episode_id)
episode_download_subtitles(sonarr_episode_id)
series_id=series_id,
episode_id=episode_id)
episode_download_subtitles(episode_id)
event_stream(type='episode-history')
return '', 200

@ -5,6 +5,7 @@ from flask_restful import Resource
from database import TableEpisodes
from ..utils import authenticate, postprocessEpisode
from event_handler import event_stream
class Episodes(Resource):
@ -14,10 +15,10 @@ class Episodes(Resource):
episodeId = request.args.getlist('episodeid[]')
if len(episodeId) > 0:
result = TableEpisodes.select().where(TableEpisodes.sonarrEpisodeId.in_(episodeId)).dicts()
result = TableEpisodes.select().where(TableEpisodes.episodeId.in_(episodeId)).dicts()
elif len(seriesId) > 0:
result = TableEpisodes.select()\
.where(TableEpisodes.sonarrSeriesId.in_(seriesId))\
.where(TableEpisodes.seriesId.in_(seriesId))\
.order_by(TableEpisodes.season.desc(), TableEpisodes.episode.desc())\
.dicts()
else:
@ -28,3 +29,29 @@ class Episodes(Resource):
postprocessEpisode(item)
return jsonify(data=result)
@authenticate
def patch(self):
episodeid = request.form.get('episodeid')
action = request.form.get('action')
value = request.form.get('value')
if action == "monitored":
if value == 'false':
new_monitored_value = 'True'
else:
new_monitored_value = 'False'
# update episode monitored status
TableEpisodes.update({
TableEpisodes.monitored: new_monitored_value
}) \
.where(TableEpisodes.episodeId == episodeid) \
.execute()
event_stream(type='episode', payload=episodeid)
event_stream(type='badges')
event_stream(type='episode-wanted', payload=episodeid)
return '', 204
return '', 400

@ -8,7 +8,6 @@ from subliminal_patch.core import SUBTITLE_EXTENSIONS
from database import TableEpisodes, get_audio_profile_languages
from ..utils import authenticate
from helper import path_mappings
from get_providers import get_providers, get_providers_auth
from get_subtitle import download_subtitle, manual_upload_subtitle
from utils import history_log, delete_subtitles
@ -24,21 +23,17 @@ from config import settings
class EpisodesSubtitles(Resource):
@authenticate
def patch(self):
sonarrSeriesId = request.args.get('seriesid')
sonarrEpisodeId = request.args.get('episodeid')
seriesId = request.args.get('seriesid')
episodeId = request.args.get('episodeid')
episodeInfo = TableEpisodes.select(TableEpisodes.title,
TableEpisodes.path,
TableEpisodes.scene_name,
TableEpisodes.audio_language)\
.where(TableEpisodes.sonarrEpisodeId == sonarrEpisodeId)\
.where(TableEpisodes.episodeId == episodeId)\
.dicts()\
.get()
title = episodeInfo['title']
episodePath = path_mappings.path_replace(episodeInfo['path'])
sceneName = episodeInfo['scene_name']
audio_language = episodeInfo['audio_language']
if sceneName is None: sceneName = "None"
episodePath = episodeInfo['path']
language = request.form.get('language')
hi = request.form.get('hi').capitalize()
@ -47,7 +42,7 @@ class EpisodesSubtitles(Resource):
providers_list = get_providers()
providers_auth = get_providers_auth()
audio_language_list = get_audio_profile_languages(episode_id=sonarrEpisodeId)
audio_language_list = get_audio_profile_languages(episode_id=episodeId)
if len(audio_language_list) > 0:
audio_language = audio_language_list[0]['name']
else:
@ -55,7 +50,7 @@ class EpisodesSubtitles(Resource):
try:
result = download_subtitle(episodePath, language, audio_language, hi, forced, providers_list,
providers_auth, sceneName, title, 'series')
providers_auth, title, 'series')
if result is not None:
message = result[0]
path = result[1]
@ -70,12 +65,12 @@ class EpisodesSubtitles(Resource):
score = result[4]
subs_id = result[6]
subs_path = result[7]
history_log(1, sonarrSeriesId, sonarrEpisodeId, message, path, language_code, provider, score, subs_id,
history_log(1, seriesId, episodeId, message, path, language_code, provider, score, subs_id,
subs_path)
send_notifications(sonarrSeriesId, sonarrEpisodeId, message)
store_subtitles(path, episodePath)
send_notifications(seriesId, episodeId, message)
store_subtitles(episodePath)
else:
event_stream(type='episode', payload=sonarrEpisodeId)
event_stream(type='episode', payload=episodeId)
except OSError:
pass
@ -84,21 +79,18 @@ class EpisodesSubtitles(Resource):
@authenticate
def post(self):
sonarrSeriesId = request.args.get('seriesid')
sonarrEpisodeId = request.args.get('episodeid')
seriesId = request.args.get('seriesid')
episodeId = request.args.get('episodeid')
episodeInfo = TableEpisodes.select(TableEpisodes.title,
TableEpisodes.path,
TableEpisodes.scene_name,
TableEpisodes.audio_language)\
.where(TableEpisodes.sonarrEpisodeId == sonarrEpisodeId)\
.where(TableEpisodes.episodeId == episodeId)\
.dicts()\
.get()
title = episodeInfo['title']
episodePath = path_mappings.path_replace(episodeInfo['path'])
sceneName = episodeInfo['scene_name']
episodePath = episodeInfo['path']
audio_language = episodeInfo['audio_language']
if sceneName is None: sceneName = "None"
language = request.form.get('language')
forced = True if request.form.get('forced') == 'true' else False
@ -116,7 +108,6 @@ class EpisodesSubtitles(Resource):
forced=forced,
hi=hi,
title=title,
scene_name=sceneName,
media_type='series',
subtitle=subFile,
audio_language=audio_language)
@ -133,11 +124,11 @@ class EpisodesSubtitles(Resource):
language_code = language
provider = "manual"
score = 360
history_log(4, sonarrSeriesId, sonarrEpisodeId, message, path, language_code, provider, score,
history_log(4, seriesId, episodeId, message, path, language_code, provider, score,
subtitles_path=subs_path)
if not settings.general.getboolean('dont_notify_manual_actions'):
send_notifications(sonarrSeriesId, sonarrEpisodeId, message)
store_subtitles(path, episodePath)
send_notifications(seriesId, episodeId, message)
store_subtitles(episodePath)
except OSError:
pass
@ -146,32 +137,29 @@ class EpisodesSubtitles(Resource):
@authenticate
def delete(self):
sonarrSeriesId = request.args.get('seriesid')
sonarrEpisodeId = request.args.get('episodeid')
seriesId = request.args.get('seriesid')
episodeId = request.args.get('episodeid')
episodeInfo = TableEpisodes.select(TableEpisodes.title,
TableEpisodes.path,
TableEpisodes.scene_name,
TableEpisodes.audio_language)\
.where(TableEpisodes.sonarrEpisodeId == sonarrEpisodeId)\
.where(TableEpisodes.episodeId == episodeId)\
.dicts()\
.get()
episodePath = path_mappings.path_replace(episodeInfo['path'])
episodePath = episodeInfo['path']
language = request.form.get('language')
forced = request.form.get('forced')
hi = request.form.get('hi')
subtitlesPath = request.form.get('path')
subtitlesPath = path_mappings.path_replace_reverse(subtitlesPath)
delete_subtitles(media_type='series',
language=language,
forced=forced,
hi=hi,
media_path=episodePath,
subtitles_path=subtitlesPath,
sonarr_series_id=sonarrSeriesId,
sonarr_episode_id=sonarrEpisodeId)
series_id=seriesId,
episode_id=episodeId)
return '', 204

@ -14,7 +14,6 @@ from datetime import timedelta
from database import get_exclusion_clause, TableEpisodes, TableShows, TableHistory, TableBlacklist
from ..utils import authenticate, postprocessEpisode
from config import settings
from helper import path_mappings
class EpisodesHistory(Resource):
@ -27,7 +26,7 @@ class EpisodesHistory(Resource):
upgradable_episodes_not_perfect = []
if settings.general.getboolean('upgrade_subs'):
days_to_upgrade_subs = settings.general.days_to_upgrade_subs
minimum_timestamp = ((datetime.datetime.now() - timedelta(days=int(days_to_upgrade_subs))) -
minimum_timestamp = ((datetime.datetime.now() - datetime.timedelta(days=int(days_to_upgrade_subs))) -
datetime.datetime(1970, 1, 1)).total_seconds()
if settings.general.getboolean('upgrade_manual'):
@ -45,8 +44,8 @@ class EpisodesHistory(Resource):
TableShows.tags,
TableEpisodes.monitored,
TableShows.seriesType)\
.join(TableEpisodes, on=(TableHistory.sonarrEpisodeId == TableEpisodes.sonarrEpisodeId))\
.join(TableShows, on=(TableHistory.sonarrSeriesId == TableShows.sonarrSeriesId))\
.join(TableEpisodes)\
.join(TableShows)\
.where(reduce(operator.and_, upgradable_episodes_conditions))\
.group_by(TableHistory.video_path)\
.dicts()
@ -63,7 +62,7 @@ class EpisodesHistory(Resource):
query_conditions = [(TableEpisodes.title is not None)]
if episodeid:
query_conditions.append((TableEpisodes.sonarrEpisodeId == episodeid))
query_conditions.append((TableEpisodes.episodeId == episodeid))
query_condition = reduce(operator.and_, query_conditions)
episode_history = TableHistory.select(TableHistory.id,
TableShows.title.alias('seriesTitle'),
@ -73,18 +72,18 @@ class EpisodesHistory(Resource):
TableHistory.timestamp,
TableHistory.subs_id,
TableHistory.description,
TableHistory.sonarrSeriesId,
TableHistory.seriesId,
TableEpisodes.path,
TableHistory.language,
TableHistory.score,
TableShows.tags,
TableHistory.action,
TableHistory.subtitles_path,
TableHistory.sonarrEpisodeId,
TableHistory.episodeId,
TableHistory.provider,
TableShows.seriesType)\
.join(TableShows, on=(TableHistory.sonarrSeriesId == TableShows.sonarrSeriesId))\
.join(TableEpisodes, on=(TableHistory.sonarrEpisodeId == TableEpisodes.sonarrEpisodeId))\
.join(TableShows)\
.join(TableEpisodes)\
.where(query_condition)\
.order_by(TableHistory.timestamp.desc())\
.limit(length)\
@ -98,13 +97,18 @@ class EpisodesHistory(Resource):
for item in episode_history:
# Mark episode as upgradable or not
item.update({"upgradable": False})
if {"video_path": str(item['path']), "timestamp": float(item['timestamp']), "score": str(item['score']),
"tags": str(item['tags']), "monitored": str(item['monitored']),
"seriesType": str(item['seriesType'])} in upgradable_episodes_not_perfect:
if os.path.isfile(path_mappings.path_replace(item['subtitles_path'])):
if {
"video_path": str(item["path"]),
"timestamp": float(item["timestamp"]),
"score": str(item["score"]),
"tags": str(item["tags"]),
"monitored": str(item["monitored"]),
"seriesType": str(item["seriesType"]),
} in upgradable_episodes_not_perfect:
if os.path.isfile(item["subtitles_path"]):
item.update({"upgradable": True})
del item['path']
del item["path"]
postprocessEpisode(item)
@ -127,7 +131,7 @@ class EpisodesHistory(Resource):
break
count = TableHistory.select()\
.join(TableEpisodes, on=(TableHistory.sonarrEpisodeId == TableEpisodes.sonarrEpisodeId))\
.join(TableEpisodes)\
.where(TableEpisodes.title is not None).count()
return jsonify(data=episode_history, total=count)

@ -18,7 +18,7 @@ class EpisodesWanted(Resource):
wanted_conditions = [(TableEpisodes.missing_subtitles != '[]')]
if len(episodeid) > 0:
wanted_conditions.append((TableEpisodes.sonarrEpisodeId in episodeid))
wanted_conditions.append((TableEpisodes.episodeId in episodeid))
wanted_conditions += get_exclusion_clause('series')
wanted_condition = reduce(operator.and_, wanted_conditions)
@ -28,13 +28,12 @@ class EpisodesWanted(Resource):
TableEpisodes.season.concat('x').concat(TableEpisodes.episode).alias('episode_number'),
TableEpisodes.title.alias('episodeTitle'),
TableEpisodes.missing_subtitles,
TableEpisodes.sonarrSeriesId,
TableEpisodes.sonarrEpisodeId,
TableEpisodes.scene_name.alias('sceneName'),
TableEpisodes.seriesId,
TableEpisodes.episodeId,
TableShows.tags,
TableEpisodes.failedAttempts,
TableShows.seriesType)\
.join(TableShows, on=(TableEpisodes.sonarrSeriesId == TableShows.sonarrSeriesId))\
.join(TableShows)\
.where(wanted_condition)\
.dicts()
else:
@ -45,15 +44,14 @@ class EpisodesWanted(Resource):
TableEpisodes.season.concat('x').concat(TableEpisodes.episode).alias('episode_number'),
TableEpisodes.title.alias('episodeTitle'),
TableEpisodes.missing_subtitles,
TableEpisodes.sonarrSeriesId,
TableEpisodes.sonarrEpisodeId,
TableEpisodes.scene_name.alias('sceneName'),
TableEpisodes.seriesId,
TableEpisodes.episodeId,
TableShows.tags,
TableEpisodes.failedAttempts,
TableShows.seriesType)\
.join(TableShows, on=(TableEpisodes.sonarrSeriesId == TableShows.sonarrSeriesId))\
.join(TableShows)\
.where(wanted_condition)\
.order_by(TableEpisodes.rowid.desc())\
.order_by(TableEpisodes.episodeId.desc())\
.limit(length)\
.offset(start)\
.dicts()
@ -67,7 +65,7 @@ class EpisodesWanted(Resource):
count = TableEpisodes.select(TableShows.tags,
TableShows.seriesType,
TableEpisodes.monitored)\
.join(TableShows, on=(TableEpisodes.sonarrSeriesId == TableShows.sonarrSeriesId))\
.join(TableShows)\
.where(reduce(operator.and_, count_conditions))\
.count()

@ -4,13 +4,9 @@ from flask import Blueprint
from flask_restful import Api
from .files import BrowseBazarrFS
from .files_sonarr import BrowseSonarrFS
from .files_radarr import BrowseRadarrFS
api_bp_files = Blueprint('api_files', __name__)
api = Api(api_bp_files)
api.add_resource(BrowseBazarrFS, '/files')
api.add_resource(BrowseSonarrFS, '/files/sonarr')
api.add_resource(BrowseRadarrFS, '/files/radarr')

@ -1,24 +0,0 @@
# coding=utf-8
from flask import request, jsonify
from flask_restful import Resource
from filesystem import browse_radarr_filesystem
from ..utils import authenticate
class BrowseRadarrFS(Resource):
@authenticate
def get(self):
path = request.args.get('path') or ''
data = []
try:
result = browse_radarr_filesystem(path)
if result is None:
raise ValueError
except Exception:
return jsonify([])
for item in result['directories']:
data.append({'name': item['name'], 'children': True, 'path': item['path']})
return jsonify(data)

@ -1,24 +0,0 @@
# coding=utf-8
from flask import request, jsonify
from flask_restful import Resource
from filesystem import browse_sonarr_filesystem
from ..utils import authenticate
class BrowseSonarrFS(Resource):
@authenticate
def get(self):
path = request.args.get('path') or ''
data = []
try:
result = browse_sonarr_filesystem(path)
if result is None:
raise ValueError
except Exception:
return jsonify([])
for item in result['directories']:
data.append({'name': item['name'], 'children': True, 'path': item['path']})
return jsonify(data)

@ -71,8 +71,7 @@ class HistoryStats(Resource):
.dicts()
data_movies = list(data_movies)
for dt in rrule.rrule(rrule.DAILY,
dtstart=datetime.datetime.now() - datetime.timedelta(seconds=delay),
for dt in rrule.rrule(rrule.DAILY, dtstart=datetime.datetime.now() - datetime.timedelta(seconds=delay),
until=datetime.datetime.now()):
if not any(d['date'] == dt.strftime('%Y-%m-%d') for d in data_series):
data_series.append({'date': dt.strftime('%Y-%m-%d'), 'count': 0})

@ -8,6 +8,11 @@ from .movies_subtitles import MoviesSubtitles
from .history import MoviesHistory
from .wanted import MoviesWanted
from .blacklist import MoviesBlacklist
from .rootfolders import MoviesRootfolders
from .directories import MoviesDirectories
from .lookup import MoviesLookup
from .add import MoviesAdd
from .modify import MoviesModify
api_bp_movies = Blueprint('api_movies', __name__)
@ -18,3 +23,8 @@ api.add_resource(MoviesWanted, '/movies/wanted')
api.add_resource(MoviesSubtitles, '/movies/subtitles')
api.add_resource(MoviesHistory, '/movies/history')
api.add_resource(MoviesBlacklist, '/movies/blacklist')
api.add_resource(MoviesRootfolders, '/movies/rootfolders')
api.add_resource(MoviesDirectories, '/movies/directories')
api.add_resource(MoviesLookup, '/movies/lookup')
api.add_resource(MoviesAdd, '/movies/add')
api.add_resource(MoviesModify, '/movies/modify')

@ -0,0 +1,27 @@
# coding=utf-8
from flask import request
from flask_restful import Resource
from ..utils import authenticate
from indexer.movies.local.movies_indexer import get_movies_metadata
from database import TableMovies
from list_subtitles import store_subtitles_movie
class MoviesAdd(Resource):
@authenticate
def post(self):
# add a new movie to database
tmdbId = request.args.get('tmdbid')
rootdir_id = request.args.get('rootdir_id')
directory = request.args.get('directory')
movies_metadata = get_movies_metadata(tmdbid=tmdbId, root_dir_id=rootdir_id, dir_name=directory)
if movies_metadata and movies_metadata['path']:
try:
result = TableMovies.insert(movies_metadata).execute()
except Exception:
pass
else:
if result:
store_subtitles_movie(movies_metadata['path'])

@ -9,7 +9,6 @@ from flask_restful import Resource
from database import TableMovies, TableBlacklistMovie
from ..utils import authenticate, postprocessMovie
from utils import blacklist_log_movie, delete_subtitles, blacklist_delete_all_movie, blacklist_delete_movie
from helper import path_mappings
from get_subtitle import movies_download_subtitles
from event_handler import event_stream
@ -24,12 +23,12 @@ class MoviesBlacklist(Resource):
length = request.args.get('length') or -1
data = TableBlacklistMovie.select(TableMovies.title,
TableMovies.radarrId,
TableMovies.movieId,
TableBlacklistMovie.provider,
TableBlacklistMovie.subs_id,
TableBlacklistMovie.language,
TableBlacklistMovie.timestamp)\
.join(TableMovies, on=(TableBlacklistMovie.radarr_id == TableMovies.radarrId))\
.join(TableMovies)\
.order_by(TableBlacklistMovie.timestamp.desc())\
.limit(length)\
.offset(start)\
@ -47,7 +46,7 @@ class MoviesBlacklist(Resource):
@authenticate
def post(self):
radarr_id = int(request.args.get('radarrid'))
movie_id = int(request.args.get('movieid'))
provider = request.form.get('provider')
subs_id = request.form.get('subs_id')
language = request.form.get('language')
@ -55,12 +54,12 @@ class MoviesBlacklist(Resource):
forced = False
hi = False
data = TableMovies.select(TableMovies.path).where(TableMovies.radarrId == radarr_id).dicts().get()
data = TableMovies.select(TableMovies.path).where(TableMovies.movieId == movie_id).dicts().get()
media_path = data['path']
subtitles_path = request.form.get('subtitles_path')
blacklist_log_movie(radarr_id=radarr_id,
blacklist_log_movie(movie_id=movie_id,
provider=provider,
subs_id=subs_id,
language=language)
@ -68,10 +67,10 @@ class MoviesBlacklist(Resource):
language=language,
forced=forced,
hi=hi,
media_path=path_mappings.path_replace_movie(media_path),
media_path=media_path,
subtitles_path=subtitles_path,
radarr_id=radarr_id)
movies_download_subtitles(radarr_id)
movie_id=movie_id)
movies_download_subtitles(movie_id)
event_stream(type='movie-history')
return '', 200

@ -0,0 +1,15 @@
# coding=utf-8
from flask import request, jsonify
from flask_restful import Resource
from ..utils import authenticate
from indexer.movies.local.movies_indexer import list_movies_directories
class MoviesDirectories(Resource):
@authenticate
def get(self):
# list movies directories inside a specific root folder
root_folder_id = request.args.get('id')
return jsonify(data=list_movies_directories(root_dir=root_folder_id))

@ -14,7 +14,6 @@ from datetime import timedelta
from database import get_exclusion_clause, TableMovies, TableHistoryMovie, TableBlacklistMovie
from ..utils import authenticate, postprocessMovie
from config import settings
from helper import path_mappings
class MoviesHistory(Resource):
@ -22,13 +21,13 @@ class MoviesHistory(Resource):
def get(self):
start = request.args.get('start') or 0
length = request.args.get('length') or -1
radarrid = request.args.get('radarrid')
movieid = request.args.get('movieid')
upgradable_movies = []
upgradable_movies_not_perfect = []
if settings.general.getboolean('upgrade_subs'):
days_to_upgrade_subs = settings.general.days_to_upgrade_subs
minimum_timestamp = ((datetime.datetime.now() - timedelta(days=int(days_to_upgrade_subs))) -
minimum_timestamp = ((datetime.datetime.now() - datetime.timedelta(days=int(days_to_upgrade_subs))) -
datetime.datetime(1970, 1, 1)).total_seconds()
if settings.general.getboolean('upgrade_manual'):
@ -45,7 +44,7 @@ class MoviesHistory(Resource):
TableHistoryMovie.score,
TableMovies.tags,
TableMovies.monitored)\
.join(TableMovies, on=(TableHistoryMovie.radarrId == TableMovies.radarrId))\
.join(TableMovies)\
.where(reduce(operator.and_, upgradable_movies_conditions))\
.group_by(TableHistoryMovie.video_path)\
.dicts()
@ -62,8 +61,8 @@ class MoviesHistory(Resource):
upgradable_movies_not_perfect.append(upgradable_movie)
query_conditions = [(TableMovies.title is not None)]
if radarrid:
query_conditions.append((TableMovies.radarrId == radarrid))
if movieid:
query_conditions.append((TableMovies.movieId == movieid))
query_condition = reduce(operator.and_, query_conditions)
movie_history = TableHistoryMovie.select(TableHistoryMovie.id,
@ -71,7 +70,7 @@ class MoviesHistory(Resource):
TableMovies.title,
TableHistoryMovie.timestamp,
TableHistoryMovie.description,
TableHistoryMovie.radarrId,
TableHistoryMovie.movieId,
TableMovies.monitored,
TableHistoryMovie.video_path.alias('path'),
TableHistoryMovie.language,
@ -80,7 +79,7 @@ class MoviesHistory(Resource):
TableHistoryMovie.subs_id,
TableHistoryMovie.provider,
TableHistoryMovie.subtitles_path)\
.join(TableMovies, on=(TableHistoryMovie.radarrId == TableMovies.radarrId))\
.join(TableMovies)\
.where(query_condition)\
.order_by(TableHistoryMovie.timestamp.desc())\
.limit(length)\
@ -94,12 +93,17 @@ class MoviesHistory(Resource):
for item in movie_history:
# Mark movies as upgradable or not
item.update({"upgradable": False})
if {"video_path": str(item['path']), "timestamp": float(item['timestamp']), "score": str(item['score']),
"tags": str(item['tags']), "monitored": str(item['monitored'])} in upgradable_movies_not_perfect:
if os.path.isfile(path_mappings.path_replace_movie(item['subtitles_path'])):
if {
"video_path": str(item["path"]),
"timestamp": float(item["timestamp"]),
"score": str(item["score"]),
"tags": str(item["tags"]),
"monitored": str(item["monitored"]),
} in upgradable_movies_not_perfect:
if os.path.isfile(item["subtitles_path"]):
item.update({"upgradable": True})
del item['path']
del item["path"]
postprocessMovie(item)
@ -116,13 +120,13 @@ class MoviesHistory(Resource):
item.update({"blacklisted": False})
if item['action'] not in [0, 4, 5]:
for blacklisted_item in blacklist_db:
if blacklisted_item['provider'] == item['provider'] and blacklisted_item['subs_id'] == item[
'subs_id']:
if blacklisted_item['provider'] == item['provider'] and \
blacklisted_item['subs_id'] == item['subs_id']:
item.update({"blacklisted": True})
break
count = TableHistoryMovie.select()\
.join(TableMovies, on=(TableHistoryMovie.radarrId == TableMovies.radarrId))\
.join(TableMovies)\
.where(TableMovies.title is not None)\
.count()

@ -0,0 +1,16 @@
# coding=utf-8
from flask import request, jsonify
from flask_restful import Resource
from ..utils import authenticate
from indexer.movies.local.movies_indexer import get_movies_match
class MoviesLookup(Resource):
@authenticate
def get(self):
# return possible matches from TMDB for a specific movie directory
dir_name = request.args.get('dir_name')
matches = get_movies_match(directory=dir_name)
return jsonify(data=matches)

@ -0,0 +1,13 @@
# coding=utf-8
# from flask import request, jsonify
from flask_restful import Resource
from ..utils import authenticate
class MoviesModify(Resource):
@authenticate
def patch(self):
# modify an existing movie in database
pass

@ -15,13 +15,13 @@ class Movies(Resource):
def get(self):
start = request.args.get('start') or 0
length = request.args.get('length') or -1
radarrId = request.args.getlist('radarrid[]')
movieId = request.args.getlist('movieid[]')
count = TableMovies.select().count()
if len(radarrId) != 0:
if len(movieId) != 0:
result = TableMovies.select()\
.where(TableMovies.radarrId.in_(radarrId))\
.where(TableMovies.movieId.in_(movieId))\
.order_by(TableMovies.sortTitle)\
.dicts()
else:
@ -34,12 +34,14 @@ class Movies(Resource):
@authenticate
def post(self):
radarrIdList = request.form.getlist('radarrid')
movieIdList = request.form.getlist('movieid')
profileIdList = request.form.getlist('profileid')
monitoredList = request.form.getlist('monitored')
for idx in range(len(radarrIdList)):
radarrId = radarrIdList[idx]
for idx in range(len(movieIdList)):
movieId = movieIdList[idx]
profileId = profileIdList[idx]
monitored = monitoredList[idx]
if profileId in None_Keys:
profileId = None
@ -50,31 +52,56 @@ class Movies(Resource):
return '', 400
TableMovies.update({
TableMovies.profileId: profileId
TableMovies.profileId: profileId,
TableMovies.monitored: monitored
})\
.where(TableMovies.radarrId == radarrId)\
.where(TableMovies.movieId == movieId)\
.execute()
list_missing_subtitles_movies(no=radarrId, send_event=False)
list_missing_subtitles_movies(no=movieId, send_event=False)
event_stream(type='movie', payload=radarrId)
event_stream(type='movie-wanted', payload=radarrId)
event_stream(type='movie', payload=movieId)
event_stream(type='movie-wanted', payload=movieId)
event_stream(type='badges')
return '', 204
@authenticate
def patch(self):
radarrid = request.form.get('radarrid')
movieid = request.form.get('movieid')
action = request.form.get('action')
if action == "scan-disk":
movies_scan_subtitles(radarrid)
value = request.form.get('value')
tmdbid = request.form.get('tmdbid')
if tmdbid:
TableMovies.update({TableMovies.tmdbId: tmdbid}).where(TableMovies.movieId == movieid).execute()
event_stream(type='movie', payload=movieid)
movies_scan_subtitles(movieid)
return '', 204
elif action == "refresh":
movies_scan_subtitles(movieid)
return '', 204
elif action == "search-missing":
movies_download_subtitles(radarrid)
movies_download_subtitles(movieid)
return '', 204
elif action == "search-wanted":
wanted_search_missing_subtitles_movies()
return '', 204
elif action == "monitored":
if value == 'false':
new_monitored_value = 'True'
else:
new_monitored_value = 'False'
TableMovies.update({
TableMovies.monitored: new_monitored_value
}) \
.where(TableMovies.movieId == movieid) \
.execute()
event_stream(type='movie', payload=movieid)
event_stream(type='badges')
event_stream(type='movie-wanted')
return '', 204
return '', 400

@ -8,7 +8,6 @@ from subliminal_patch.core import SUBTITLE_EXTENSIONS
from database import TableMovies, get_audio_profile_languages
from ..utils import authenticate
from helper import path_mappings
from get_providers import get_providers, get_providers_auth
from get_subtitle import download_subtitle, manual_upload_subtitle
from utils import history_log_movie, delete_subtitles
@ -25,19 +24,16 @@ class MoviesSubtitles(Resource):
@authenticate
def patch(self):
# Download
radarrId = request.args.get('radarrid')
movieId = request.args.get('movieid')
movieInfo = TableMovies.select(TableMovies.title,
TableMovies.path,
TableMovies.sceneName,
TableMovies.audio_language)\
.where(TableMovies.radarrId == radarrId)\
.where(TableMovies.movieId == movieId)\
.dicts()\
.get()
moviePath = path_mappings.path_replace_movie(movieInfo['path'])
sceneName = movieInfo['sceneName']
if sceneName is None: sceneName = 'None'
moviePath = movieInfo['path']
title = movieInfo['title']
audio_language = movieInfo['audio_language']
@ -49,7 +45,7 @@ class MoviesSubtitles(Resource):
providers_list = get_providers()
providers_auth = get_providers_auth()
audio_language_list = get_audio_profile_languages(movie_id=radarrId)
audio_language_list = get_audio_profile_languages(movie_id=movieId)
if len(audio_language_list) > 0:
audio_language = audio_language_list[0]['name']
else:
@ -57,7 +53,7 @@ class MoviesSubtitles(Resource):
try:
result = download_subtitle(moviePath, language, audio_language, hi, forced, providers_list,
providers_auth, sceneName, title, 'movie')
providers_auth, title, 'movie')
if result is not None:
message = result[0]
path = result[1]
@ -72,11 +68,11 @@ class MoviesSubtitles(Resource):
score = result[4]
subs_id = result[6]
subs_path = result[7]
history_log_movie(1, radarrId, message, path, language_code, provider, score, subs_id, subs_path)
send_notifications_movie(radarrId, message)
store_subtitles_movie(path, moviePath)
history_log_movie(1, movieId, message, path, language_code, provider, score, subs_id, subs_path)
send_notifications_movie(movieId, message)
store_subtitles_movie(moviePath)
else:
event_stream(type='movie', payload=radarrId)
event_stream(type='movie', payload=movieId)
except OSError:
pass
@ -86,18 +82,15 @@ class MoviesSubtitles(Resource):
def post(self):
# Upload
# TODO: Support Multiply Upload
radarrId = request.args.get('radarrid')
movieId = request.args.get('movieid')
movieInfo = TableMovies.select(TableMovies.title,
TableMovies.path,
TableMovies.sceneName,
TableMovies.audio_language) \
.where(TableMovies.radarrId == radarrId) \
.where(TableMovies.movieId == movieId) \
.dicts() \
.get()
moviePath = path_mappings.path_replace_movie(movieInfo['path'])
sceneName = movieInfo['sceneName']
if sceneName is None: sceneName = 'None'
moviePath = movieInfo['path']
title = movieInfo['title']
audioLanguage = movieInfo['audio_language']
@ -118,7 +111,6 @@ class MoviesSubtitles(Resource):
forced=forced,
hi=hi,
title=title,
scene_name=sceneName,
media_type='movie',
subtitle=subFile,
audio_language=audioLanguage)
@ -135,10 +127,10 @@ class MoviesSubtitles(Resource):
language_code = language
provider = "manual"
score = 120
history_log_movie(4, radarrId, message, path, language_code, provider, score, subtitles_path=subs_path)
history_log_movie(4, movieId, message, path, language_code, provider, score, subtitles_path=subs_path)
if not settings.general.getboolean('dont_notify_manual_actions'):
send_notifications_movie(radarrId, message)
store_subtitles_movie(path, moviePath)
send_notifications_movie(movieId, message)
store_subtitles_movie(moviePath)
except OSError:
pass
@ -147,28 +139,26 @@ class MoviesSubtitles(Resource):
@authenticate
def delete(self):
# Delete
radarrId = request.args.get('radarrid')
movieId = request.args.get('movieid')
movieInfo = TableMovies.select(TableMovies.path) \
.where(TableMovies.radarrId == radarrId) \
.where(TableMovies.movieId == movieId) \
.dicts() \
.get()
moviePath = path_mappings.path_replace_movie(movieInfo['path'])
moviePath = movieInfo['path']
language = request.form.get('language')
forced = request.form.get('forced')
hi = request.form.get('hi')
subtitlesPath = request.form.get('path')
subtitlesPath = path_mappings.path_replace_reverse_movie(subtitlesPath)
result = delete_subtitles(media_type='movie',
language=language,
forced=forced,
hi=hi,
media_path=moviePath,
subtitles_path=subtitlesPath,
radarr_id=radarrId)
movie_id=movieId)
if result:
return '', 202
else:

@ -0,0 +1,27 @@
# coding=utf-8
from flask import request, jsonify
from flask_restful import Resource
from ..utils import authenticate
from database import TableMoviesRootfolder
class MoviesRootfolders(Resource):
@authenticate
def get(self):
# list existing movies root folders
root_folders = TableMoviesRootfolder.select().dicts()
root_folders = list(root_folders)
return jsonify(data=root_folders)
@authenticate
def post(self):
# add a new movies root folder
path = request.form.get('path')
result = TableMoviesRootfolder.insert({
TableMoviesRootfolder.path: path,
TableMoviesRootfolder.accessible: 1, # TODO: test it instead of assuming it's accessible
TableMoviesRootfolder.error: ''
}).execute()
return jsonify(data=list(TableMoviesRootfolder.select().where(TableMoviesRootfolder.rootId == result).dicts()))

@ -14,19 +14,18 @@ from ..utils import authenticate, postprocessMovie
class MoviesWanted(Resource):
@authenticate
def get(self):
radarrid = request.args.getlist("radarrid[]")
movieid = request.args.getlist("movieid[]")
wanted_conditions = [(TableMovies.missing_subtitles != '[]')]
if len(radarrid) > 0:
wanted_conditions.append((TableMovies.radarrId.in_(radarrid)))
if len(movieid) > 0:
wanted_conditions.append((TableMovies.movieId.in_(movieid)))
wanted_conditions += get_exclusion_clause('movie')
wanted_condition = reduce(operator.and_, wanted_conditions)
if len(radarrid) > 0:
if len(movieid) > 0:
result = TableMovies.select(TableMovies.title,
TableMovies.missing_subtitles,
TableMovies.radarrId,
TableMovies.sceneName,
TableMovies.movieId,
TableMovies.failedAttempts,
TableMovies.tags,
TableMovies.monitored)\
@ -37,13 +36,12 @@ class MoviesWanted(Resource):
length = request.args.get('length') or -1
result = TableMovies.select(TableMovies.title,
TableMovies.missing_subtitles,
TableMovies.radarrId,
TableMovies.sceneName,
TableMovies.movieId,
TableMovies.failedAttempts,
TableMovies.tags,
TableMovies.monitored)\
.where(wanted_condition)\
.order_by(TableMovies.rowid.desc())\
.order_by(TableMovies.movieId.desc())\
.limit(length)\
.offset(start)\
.dicts()

@ -15,10 +15,10 @@ class Providers(Resource):
history = request.args.get('history')
if history and history not in False_Keys:
providers = list(TableHistory.select(TableHistory.provider)
.where(TableHistory.provider != None and TableHistory.provider != "manual")
.where(TableHistory.provider is not None and TableHistory.provider != "manual")
.dicts())
providers += list(TableHistoryMovie.select(TableHistoryMovie.provider)
.where(TableHistoryMovie.provider != None and TableHistoryMovie.provider != "manual")
.where(TableHistoryMovie.provider is not None and TableHistoryMovie.provider != "manual")
.dicts())
providers_list = list(set([x['provider'] for x in providers]))
providers_dicts = []

@ -4,7 +4,6 @@ from flask import request, jsonify
from flask_restful import Resource
from database import TableEpisodes, TableShows, get_audio_profile_languages
from helper import path_mappings
from get_providers import get_providers, get_providers_auth
from get_subtitle import manual_search, manual_download_subtitle
from utils import history_log
@ -19,27 +18,23 @@ class ProviderEpisodes(Resource):
@authenticate
def get(self):
# Manual Search
sonarrEpisodeId = request.args.get('episodeid')
episodeId = request.args.get('episodeid')
episodeInfo = TableEpisodes.select(TableEpisodes.title,
TableEpisodes.path,
TableEpisodes.scene_name,
TableShows.profileId) \
.join(TableShows, on=(TableEpisodes.sonarrSeriesId == TableShows.sonarrSeriesId))\
.where(TableEpisodes.sonarrEpisodeId == sonarrEpisodeId) \
.join(TableShows) \
.where(TableEpisodes.episodeId == episodeId) \
.dicts() \
.get()
title = episodeInfo['title']
episodePath = path_mappings.path_replace(episodeInfo['path'])
sceneName = episodeInfo['scene_name']
episodePath = episodeInfo['path']
profileId = episodeInfo['profileId']
if sceneName is None: sceneName = "None"
providers_list = get_providers()
providers_auth = get_providers_auth()
data = manual_search(episodePath, profileId, providers_list, providers_auth, sceneName, title,
'series')
data = manual_search(episodePath, profileId, providers_list, providers_auth, title, 'series')
if not data:
data = []
return jsonify(data=data)
@ -47,19 +42,16 @@ class ProviderEpisodes(Resource):
@authenticate
def post(self):
# Manual Download
sonarrSeriesId = request.args.get('seriesid')
sonarrEpisodeId = request.args.get('episodeid')
seriesId = request.args.get('seriesid')
episodeId = request.args.get('episodeid')
episodeInfo = TableEpisodes.select(TableEpisodes.title,
TableEpisodes.path,
TableEpisodes.scene_name) \
.where(TableEpisodes.sonarrEpisodeId == sonarrEpisodeId) \
TableEpisodes.path) \
.where(TableEpisodes.episodeId == episodeId) \
.dicts() \
.get()
title = episodeInfo['title']
episodePath = path_mappings.path_replace(episodeInfo['path'])
sceneName = episodeInfo['scene_name']
if sceneName is None: sceneName = "None"
episodePath = episodeInfo['path']
language = request.form.get('language')
hi = request.form.get('hi').capitalize()
@ -68,7 +60,7 @@ class ProviderEpisodes(Resource):
subtitle = request.form.get('subtitle')
providers_auth = get_providers_auth()
audio_language_list = get_audio_profile_languages(episode_id=sonarrEpisodeId)
audio_language_list = get_audio_profile_languages(episode_id=episodeId)
if len(audio_language_list) > 0:
audio_language = audio_language_list[0]['name']
else:
@ -76,7 +68,7 @@ class ProviderEpisodes(Resource):
try:
result = manual_download_subtitle(episodePath, language, audio_language, hi, forced, subtitle,
selected_provider, providers_auth, sceneName, title, 'series')
selected_provider, providers_auth, title, 'series')
if result is not None:
message = result[0]
path = result[1]
@ -91,11 +83,10 @@ class ProviderEpisodes(Resource):
score = result[4]
subs_id = result[6]
subs_path = result[7]
history_log(2, sonarrSeriesId, sonarrEpisodeId, message, path, language_code, provider, score, subs_id,
subs_path)
history_log(2, seriesId, episodeId, message, path, language_code, provider, score, subs_id, subs_path)
if not settings.general.getboolean('dont_notify_manual_actions'):
send_notifications(sonarrSeriesId, sonarrEpisodeId, message)
store_subtitles(path, episodePath)
send_notifications(seriesId, episodeId, message)
store_subtitles(episodePath)
return result, 201
except OSError:
pass

@ -4,7 +4,6 @@ from flask import request, jsonify
from flask_restful import Resource
from database import TableMovies, get_audio_profile_languages
from helper import path_mappings
from get_providers import get_providers, get_providers_auth
from get_subtitle import manual_search, manual_download_subtitle
from utils import history_log_movie
@ -19,26 +18,22 @@ class ProviderMovies(Resource):
@authenticate
def get(self):
# Manual Search
radarrId = request.args.get('radarrid')
movieId = request.args.get('movieid')
movieInfo = TableMovies.select(TableMovies.title,
TableMovies.path,
TableMovies.sceneName,
TableMovies.profileId) \
.where(TableMovies.radarrId == radarrId) \
.where(TableMovies.movieId == movieId) \
.dicts() \
.get()
title = movieInfo['title']
moviePath = path_mappings.path_replace_movie(movieInfo['path'])
sceneName = movieInfo['sceneName']
moviePath = movieInfo['path']
profileId = movieInfo['profileId']
if sceneName is None: sceneName = "None"
providers_list = get_providers()
providers_auth = get_providers_auth()
data = manual_search(moviePath, profileId, providers_list, providers_auth, sceneName, title,
'movie')
data = manual_search(moviePath, profileId, providers_list, providers_auth, title, 'movie')
if not data:
data = []
return jsonify(data=data)
@ -46,19 +41,16 @@ class ProviderMovies(Resource):
@authenticate
def post(self):
# Manual Download
radarrId = request.args.get('radarrid')
movieId = request.args.get('movieid')
movieInfo = TableMovies.select(TableMovies.title,
TableMovies.path,
TableMovies.sceneName,
TableMovies.audio_language) \
.where(TableMovies.radarrId == radarrId) \
.where(TableMovies.movieId == movieId) \
.dicts() \
.get()
title = movieInfo['title']
moviePath = path_mappings.path_replace_movie(movieInfo['path'])
sceneName = movieInfo['sceneName']
if sceneName is None: sceneName = "None"
moviePath = movieInfo['path']
audio_language = movieInfo['audio_language']
language = request.form.get('language')
@ -69,7 +61,7 @@ class ProviderMovies(Resource):
providers_auth = get_providers_auth()
audio_language_list = get_audio_profile_languages(movie_id=radarrId)
audio_language_list = get_audio_profile_languages(movie_id=movieId)
if len(audio_language_list) > 0:
audio_language = audio_language_list[0]['name']
else:
@ -77,7 +69,7 @@ class ProviderMovies(Resource):
try:
result = manual_download_subtitle(moviePath, language, audio_language, hi, forced, subtitle,
selected_provider, providers_auth, sceneName, title, 'movie')
selected_provider, providers_auth, title, 'movie')
if result is not None:
message = result[0]
path = result[1]
@ -92,10 +84,10 @@ class ProviderMovies(Resource):
score = result[4]
subs_id = result[6]
subs_path = result[7]
history_log_movie(2, radarrId, message, path, language_code, provider, score, subs_id, subs_path)
history_log_movie(2, movieId, message, path, language_code, provider, score, subs_id, subs_path)
if not settings.general.getboolean('dont_notify_manual_actions'):
send_notifications_movie(radarrId, message)
store_subtitles_movie(path, moviePath)
send_notifications_movie(movieId, message)
store_subtitles_movie(moviePath)
except OSError:
pass

@ -4,9 +4,19 @@ from flask import Blueprint
from flask_restful import Api
from .series import Series
from .rootfolders import SeriesRootfolders
from .directories import SeriesDirectories
from .lookup import SeriesLookup
from .add import SeriesAdd
from .modify import SeriesModify
api_bp_series = Blueprint('api_series', __name__)
api = Api(api_bp_series)
api.add_resource(Series, '/series')
api.add_resource(SeriesRootfolders, '/series/rootfolders')
api.add_resource(SeriesDirectories, '/series/directories')
api.add_resource(SeriesLookup, '/series/lookup')
api.add_resource(SeriesAdd, '/series/add')
api.add_resource(SeriesModify, '/series/modify')

@ -0,0 +1,27 @@
# coding=utf-8
from flask import request
from flask_restful import Resource
from ..utils import authenticate
from indexer.series.local.series_indexer import get_series_metadata
from database import TableShows
from list_subtitles import store_subtitles
class SeriesAdd(Resource):
@authenticate
def post(self):
# add a new series to database
tmdbId = request.args.get('tmdbid')
rootdir_id = request.args.get('rootdir_id')
directory = request.args.get('directory')
series_metadata = get_series_metadata(tmdbid=tmdbId, root_dir_id=rootdir_id, dir_name=directory)
if series_metadata and series_metadata['path']:
try:
result = TableShows.insert(series_metadata).execute()
except Exception:
pass
else:
if result:
store_subtitles(series_metadata['path'])

@ -0,0 +1,15 @@
# coding=utf-8
from flask import request, jsonify
from flask_restful import Resource
from ..utils import authenticate
from indexer.series.local.series_indexer import list_series_directories
class SeriesDirectories(Resource):
@authenticate
def get(self):
# list series directories inside a specific root folder
root_folder_id = request.args.get('id')
return jsonify(data=list_series_directories(root_dir=root_folder_id))

@ -0,0 +1,16 @@
# coding=utf-8
from flask import request, jsonify
from flask_restful import Resource
from ..utils import authenticate
from indexer.series.local.series_indexer import get_series_match
class SeriesLookup(Resource):
@authenticate
def get(self):
# return possible matches from TMDB for a specific series directory
dir_name = request.args.get('dir_name')
matches = get_series_match(directory=dir_name)
return jsonify(data=matches)

@ -0,0 +1,12 @@
# coding=utf-8
from flask_restful import Resource
from ..utils import authenticate
class SeriesModify(Resource):
@authenticate
def patch(self):
# modify an existing series in database
pass

@ -0,0 +1,27 @@
# coding=utf-8
from flask import request, jsonify
from flask_restful import Resource
from ..utils import authenticate
from database import TableShowsRootfolder
class SeriesRootfolders(Resource):
@authenticate
def get(self):
# list existing series root folders
root_folders = TableShowsRootfolder.select().dicts()
root_folders = list(root_folders)
return jsonify(data=root_folders)
@authenticate
def post(self):
# add a new series root folder
path = request.form.get('path')
result = TableShowsRootfolder.insert({
TableShowsRootfolder.path: path,
TableShowsRootfolder.accessible: 1, # TODO: test it instead of assuming it's accessible
TableShowsRootfolder.error: ''
}).execute()
return jsonify(data=list(TableShowsRootfolder.select().where(TableShowsRootfolder.rootId == result).dicts()))

@ -24,7 +24,7 @@ class Series(Resource):
if len(seriesId) != 0:
result = TableShows.select() \
.where(TableShows.sonarrSeriesId.in_(seriesId)) \
.where(TableShows.seriesId.in_(seriesId)) \
.order_by(TableShows.sortTitle).dicts()
else:
result = TableShows.select().order_by(TableShows.sortTitle).limit(length).offset(start).dicts()
@ -35,14 +35,14 @@ class Series(Resource):
postprocessSeries(item)
# Add missing subtitles episode count
episodes_missing_conditions = [(TableEpisodes.sonarrSeriesId == item['sonarrSeriesId']),
episodes_missing_conditions = [(TableEpisodes.seriesId == item['seriesId']),
(TableEpisodes.missing_subtitles != '[]')]
episodes_missing_conditions += get_exclusion_clause('series')
episodeMissingCount = TableEpisodes.select(TableShows.tags,
TableEpisodes.monitored,
TableShows.seriesType) \
.join(TableShows, on=(TableEpisodes.sonarrSeriesId == TableShows.sonarrSeriesId)) \
.join(TableShows) \
.where(reduce(operator.and_, episodes_missing_conditions)) \
.count()
item.update({"episodeMissingCount": episodeMissingCount})
@ -51,8 +51,8 @@ class Series(Resource):
episodeFileCount = TableEpisodes.select(TableShows.tags,
TableEpisodes.monitored,
TableShows.seriesType) \
.join(TableShows, on=(TableEpisodes.sonarrSeriesId == TableShows.sonarrSeriesId)) \
.where(TableEpisodes.sonarrSeriesId == item['sonarrSeriesId']) \
.join(TableShows) \
.where(TableEpisodes.seriesId == item['seriesId']) \
.count()
item.update({"episodeFileCount": episodeFileCount})
@ -62,10 +62,12 @@ class Series(Resource):
def post(self):
seriesIdList = request.form.getlist('seriesid')
profileIdList = request.form.getlist('profileid')
monitoredList = request.form.getlist('monitored')
for idx in range(len(seriesIdList)):
seriesId = seriesIdList[idx]
profileId = profileIdList[idx]
monitored = monitoredList[idx]
if profileId in None_Keys:
profileId = None
@ -76,9 +78,16 @@ class Series(Resource):
return '', 400
TableShows.update({
TableShows.profileId: profileId
TableShows.profileId: profileId,
TableShows.monitored: monitored
}) \
.where(TableShows.sonarrSeriesId == seriesId) \
.where(TableShows.seriesId == seriesId) \
.execute()
TableEpisodes.update({
TableEpisodes.monitored: monitored
}) \
.where(TableEpisodes.seriesId == seriesId) \
.execute()
list_missing_subtitles(no=seriesId, send_event=False)
@ -86,12 +95,13 @@ class Series(Resource):
event_stream(type='series', payload=seriesId)
episode_id_list = TableEpisodes \
.select(TableEpisodes.sonarrEpisodeId) \
.where(TableEpisodes.sonarrSeriesId == seriesId) \
.select(TableEpisodes.episodeId) \
.where(TableEpisodes.seriesId == seriesId) \
.dicts()
for item in episode_id_list:
event_stream(type='episode-wanted', payload=item['sonarrEpisodeId'])
event_stream(type='episode', payload=item['episodeId'])
event_stream(type='episode-wanted', payload=item['episodeId'])
event_stream(type='badges')
@ -101,7 +111,15 @@ class Series(Resource):
def patch(self):
seriesid = request.form.get('seriesid')
action = request.form.get('action')
if action == "scan-disk":
value = request.form.get('value')
tmdbid = request.form.get('tmdbid')
if tmdbid:
TableShows.update({TableShows.tmdbId: tmdbid}).where(TableShows.seriesId == seriesid).execute()
event_stream(type='series', payload=seriesid)
series_scan_subtitles(seriesid)
return '', 204
elif action == "refresh":
series_scan_subtitles(seriesid)
return '', 204
elif action == "search-missing":
@ -110,5 +128,36 @@ class Series(Resource):
elif action == "search-wanted":
wanted_search_missing_subtitles_series()
return '', 204
elif action == "monitored":
if value == 'false':
new_monitored_value = 'True'
else:
new_monitored_value = 'False'
# update series monitored status
TableShows.update({
TableShows.monitored: new_monitored_value
}) \
.where(TableShows.seriesId == seriesid) \
.execute()
event_stream(type='series', payload=seriesid)
# update each series episode monitored status
series_episodes = TableEpisodes.select(TableEpisodes.episodeId) \
.where(TableEpisodes.seriesId == seriesid) \
.dicts()
TableEpisodes.update({
TableEpisodes.monitored: new_monitored_value
}) \
.where(TableEpisodes.seriesId == seriesid) \
.execute()
for episodeid in series_episodes:
event_stream(type='badges')
event_stream(type='episode-wanted', payload=episodeid['episodeId'])
return '', 204
return '', 400

@ -7,7 +7,6 @@ from flask import request
from flask_restful import Resource
from database import TableEpisodes, TableMovies
from helper import path_mappings
from ..utils import authenticate
from subsyncer import subsync
from utils import translate_subtitles_file, subtitles_apply_mods
@ -26,25 +25,23 @@ class Subtitles(Resource):
id = request.form.get('id')
if media_type == 'episode':
subtitles_path = path_mappings.path_replace(subtitles_path)
metadata = TableEpisodes.select(TableEpisodes.path, TableEpisodes.sonarrSeriesId)\
.where(TableEpisodes.sonarrEpisodeId == id)\
metadata = TableEpisodes.select(TableEpisodes.path, TableEpisodes.seriesId) \
.where(TableEpisodes.episodeId == id) \
.dicts()\
.get()
video_path = path_mappings.path_replace(metadata['path'])
video_path = metadata['path']
else:
subtitles_path = path_mappings.path_replace_movie(subtitles_path)
metadata = TableMovies.select(TableMovies.path).where(TableMovies.radarrId == id).dicts().get()
video_path = path_mappings.path_replace_movie(metadata['path'])
metadata = TableMovies.select(TableMovies.path).where(TableMovies.movieId == id).dicts().get()
video_path = metadata['path']
if action == 'sync':
if media_type == 'episode':
subsync.sync(video_path=video_path, srt_path=subtitles_path,
srt_lang=language, media_type='series', sonarr_series_id=metadata['sonarrSeriesId'],
sonarr_episode_id=int(id))
srt_lang=language, media_type='series', series_id=metadata['seriesId'],
episode_id = int(id))
else:
subsync.sync(video_path=video_path, srt_path=subtitles_path,
srt_lang=language, media_type='movies', radarr_id=id)
srt_lang=language, media_type='movies', movie_id=id)
elif action == 'translate':
dest_language = language
forced = True if request.form.get('forced') == 'true' else False
@ -54,9 +51,9 @@ class Subtitles(Resource):
forced=forced, hi=hi)
if result:
if media_type == 'episode':
store_subtitles(path_mappings.path_replace_reverse(video_path), video_path)
store_subtitles(video_path)
else:
store_subtitles_movie(path_mappings.path_replace_reverse_movie(video_path), video_path)
store_subtitles_movie(video_path)
return '', 200
else:
return '', 404

@ -16,12 +16,12 @@ class Languages(Resource):
history = request.args.get('history')
if history and history not in False_Keys:
languages = list(TableHistory.select(TableHistory.language)
.where(TableHistory.language != None)
.where(TableHistory.language is not None)
.dicts())
languages += list(TableHistoryMovie.select(TableHistoryMovie.language)
.where(TableHistoryMovie.language != None)
.where(TableHistoryMovie.language is not None)
.dicts())
languages_list = list(set([l['language'].split(':')[0] for l in languages]))
languages_list = list(set([lang['language'].split(':')[0] for lang in languages]))
languages_dicts = []
for language in languages_list:
code2 = None
@ -40,7 +40,7 @@ class Languages(Resource):
# Compatibility: Use false temporarily
'enabled': False
})
except:
except Exception:
continue
return jsonify(sorted(languages_dicts, key=itemgetter('name')))

@ -15,10 +15,10 @@ class Searches(Resource):
search_list = []
if query:
if settings.general.getboolean('use_sonarr'):
if settings.general.getboolean('use_series'):
# Get matching series
series = TableShows.select(TableShows.title,
TableShows.sonarrSeriesId,
TableShows.seriesId,
TableShows.year)\
.where(TableShows.title.contains(query))\
.order_by(TableShows.title)\
@ -26,10 +26,10 @@ class Searches(Resource):
series = list(series)
search_list += series
if settings.general.getboolean('use_radarr'):
if settings.general.getboolean('use_movies'):
# Get matching movies
movies = TableMovies.select(TableMovies.title,
TableMovies.radarrId,
TableMovies.movieId,
TableMovies.year) \
.where(TableMovies.title.contains(query)) \
.order_by(TableMovies.title) \

@ -83,9 +83,9 @@ class SystemSettings(Resource):
update_profile_id_list()
event_stream("languages")
if settings.general.getboolean('use_sonarr'):
if settings.general.getboolean('use_series'):
scheduler.add_job(list_missing_subtitles, kwargs={'send_event': False})
if settings.general.getboolean('use_radarr'):
if settings.general.getboolean('use_movies'):
scheduler.add_job(list_missing_subtitles_movies, kwargs={'send_event': False})
# Update Notification

@ -7,7 +7,6 @@ from flask import jsonify
from flask_restful import Resource
from ..utils import authenticate
from utils import get_sonarr_info, get_radarr_info
from get_args import args
from init import startTime
@ -17,8 +16,6 @@ class SystemStatus(Resource):
def get(self):
system_status = {}
system_status.update({'bazarr_version': os.environ["BAZARR_VERSION"]})
system_status.update({'sonarr_version': get_sonarr_info.version()})
system_status.update({'radarr_version': get_radarr_info.version()})
system_status.update({'operating_system': platform.platform()})
system_status.update({'python_version': platform.python_version()})
system_status.update({'bazarr_directory': os.path.dirname(os.path.dirname(__file__))})

@ -6,10 +6,9 @@ from functools import wraps
from flask import request, abort
from operator import itemgetter
from config import settings, base_url
from config import settings
from get_languages import language_from_alpha2, alpha3_from_alpha2
from database import get_audio_profile_languages, get_desired_languages
from helper import path_mappings
None_Keys = ['null', 'undefined', '', None]
@ -74,7 +73,7 @@ def postprocessSeries(item):
postprocess(item)
# Parse audio language
if 'audio_language' in item and item['audio_language'] is not None:
item['audio_language'] = get_audio_profile_languages(series_id=item['sonarrSeriesId'])
item['audio_language'] = get_audio_profile_languages(series_id=item['seriesId'])
if 'alternateTitles' in item:
if item['alternateTitles'] is None:
@ -87,23 +86,11 @@ def postprocessSeries(item):
if 'seriesType' in item and item['seriesType'] is not None:
item['seriesType'] = item['seriesType'].capitalize()
if 'path' in item:
item['path'] = path_mappings.path_replace(item['path'])
# map poster and fanart to server proxy
if 'poster' in item:
poster = item['poster']
item['poster'] = f"{base_url}/images/series{poster}" if poster else None
if 'fanart' in item:
fanart = item['fanart']
item['fanart'] = f"{base_url}/images/series{fanart}" if fanart else None
def postprocessEpisode(item):
postprocess(item)
if 'audio_language' in item and item['audio_language'] is not None:
item['audio_language'] = get_audio_profile_languages(episode_id=item['sonarrEpisodeId'])
item['audio_language'] = get_audio_profile_languages(episode_id=item['episodeId'])
if 'subtitles' in item:
if item['subtitles'] is None:
@ -117,7 +104,7 @@ def postprocessEpisode(item):
sub = {"name": language_from_alpha2(subtitle[0]),
"code2": subtitle[0],
"code3": alpha3_from_alpha2(subtitle[0]),
"path": path_mappings.path_replace(subs[1]),
"path": subs[1],
"forced": False,
"hi": False}
if len(subtitle) > 1:
@ -147,21 +134,13 @@ def postprocessEpisode(item):
"hi": True if subtitle[1] == 'hi' else False
})
if 'scene_name' in item:
item["sceneName"] = item["scene_name"]
del item["scene_name"]
if 'path' in item and item['path']:
# Provide mapped path
item['path'] = path_mappings.path_replace(item['path'])
# TODO: Move
def postprocessMovie(item):
postprocess(item)
# Parse audio language
if 'audio_language' in item and item['audio_language'] is not None:
item['audio_language'] = get_audio_profile_languages(movie_id=item['radarrId'])
item['audio_language'] = get_audio_profile_languages(movie_id=item['movieId'])
# Parse alternate titles
if 'alternativeTitles' in item:
@ -183,7 +162,7 @@ def postprocessMovie(item):
item['subtitles'] = ast.literal_eval(item['subtitles'])
for i, subs in enumerate(item['subtitles']):
language = subs[0].split(':')
item['subtitles'][i] = {"path": path_mappings.path_replace_movie(subs[1]),
item['subtitles'][i] = {"path": subs[1],
"name": language_from_alpha2(language[0]),
"code2": language[0],
"code3": alpha3_from_alpha2(language[0]),
@ -219,21 +198,3 @@ def postprocessMovie(item):
"forced": True if language[1] == 'forced' else False,
"hi": True if language[1] == 'hi' else False
})
# Provide mapped path
if 'path' in item:
if item['path']:
item['path'] = path_mappings.path_replace_movie(item['path'])
if 'subtitles_path' in item:
# Provide mapped subtitles path
item['subtitles_path'] = path_mappings.path_replace_movie(item['subtitles_path'])
# map poster and fanart to server proxy
if 'poster' in item:
poster = item['poster']
item['poster'] = f"{base_url}/images/movies{poster}" if poster else None
if 'fanart' in item:
fanart = item['fanart']
item['fanart'] = f"{base_url}/images/movies{fanart}" if fanart else None

@ -47,30 +47,30 @@ class WebHooksPlex(Resource):
headers={"User-Agent": os.environ["SZ_USER_AGENT"]})
soup = bso(r.content, "html.parser")
series_imdb_id = soup.find('a', {'class': re.compile(r'SeriesParentLink__ParentTextLink')})['href'].split('/')[2]
except:
except Exception:
return '', 404
else:
sonarrEpisodeId = TableEpisodes.select(TableEpisodes.sonarrEpisodeId) \
.join(TableShows, on=(TableEpisodes.sonarrSeriesId == TableShows.sonarrSeriesId)) \
episodeId = TableEpisodes.select(TableEpisodes.episodeId) \
.join(TableShows) \
.where(TableShows.imdbId == series_imdb_id,
TableEpisodes.season == season,
TableEpisodes.episode == episode) \
.dicts() \
.get()
if sonarrEpisodeId:
episode_download_subtitles(no=sonarrEpisodeId['sonarrEpisodeId'], send_progress=True)
if episodeId:
episode_download_subtitles(no=episodeId['episodeId'], send_progress=True)
else:
try:
movie_imdb_id = [x['imdb'] for x in ids if 'imdb' in x][0]
except:
except Exception:
return '', 404
else:
radarrId = TableMovies.select(TableMovies.radarrId)\
movieId = TableMovies.select(TableMovies.movieId)\
.where(TableMovies.imdbId == movie_imdb_id)\
.dicts()\
.get()
if radarrId:
movies_download_subtitles(no=radarrId['radarrId'])
if movieId:
movies_download_subtitles(no=movieId['movieId'])
return '', 200

Loading…
Cancel
Save