bazarr/bazarr/api/movies/history.py

171 lines
7.0 KiB
Python

# coding=utf-8
import operator
import pretty
import ast
from flask_restx import Resource, Namespace, reqparse, fields
from functools import reduce
from app.database import TableMovies, TableHistoryMovie, TableBlacklistMovie, database, select, func
from subtitles.upgrade import get_upgradable_movies_subtitles, _language_still_desired
from api.swaggerui import subtitles_language_model
from api.utils import authenticate, postprocess
api_ns_movies_history = Namespace('Movies History', description='List movies history events')
@api_ns_movies_history.route('movies/history')
class MoviesHistory(Resource):
get_request_parser = reqparse.RequestParser()
get_request_parser.add_argument('start', type=int, required=False, default=0, help='Paging start integer')
get_request_parser.add_argument('length', type=int, required=False, default=-1, help='Paging length integer')
get_request_parser.add_argument('radarrid', type=int, required=False, help='Movie ID')
get_language_model = api_ns_movies_history.model('subtitles_language_model', subtitles_language_model)
data_model = api_ns_movies_history.model('history_movies_data_model', {
'action': fields.Integer(),
'title': fields.String(),
'timestamp': fields.String(),
'description': fields.String(),
'radarrId': fields.Integer(),
'monitored': fields.Boolean(),
'path': fields.String(),
'language': fields.Nested(get_language_model),
'tags': fields.List(fields.String),
'score': fields.String(),
'subs_id': fields.String(),
'provider': fields.String(),
'subtitles_path': fields.String(),
'upgradable': fields.Boolean(),
'parsed_timestamp': fields.String(),
'blacklisted': fields.Boolean(),
'matches': fields.List(fields.String),
'dont_matches': fields.List(fields.String),
})
get_response_model = api_ns_movies_history.model('MovieHistoryGetResponse', {
'data': fields.Nested(data_model),
'total': fields.Integer(),
})
@authenticate
@api_ns_movies_history.marshal_with(get_response_model, code=200)
@api_ns_movies_history.response(401, 'Not Authenticated')
@api_ns_movies_history.doc(parser=get_request_parser)
def get(self):
"""List movies history events"""
args = self.get_request_parser.parse_args()
start = args.get('start')
length = args.get('length')
radarrid = args.get('radarrid')
upgradable_movies_not_perfect = get_upgradable_movies_subtitles()
blacklisted_subtitles = select(TableBlacklistMovie.provider,
TableBlacklistMovie.subs_id) \
.subquery()
query_conditions = [(TableMovies.title.is_not(None))]
if radarrid:
query_conditions.append((TableMovies.radarrId == radarrid))
stmt = select(TableHistoryMovie.id,
TableHistoryMovie.action,
TableMovies.title,
TableHistoryMovie.timestamp,
TableHistoryMovie.description,
TableHistoryMovie.radarrId,
TableMovies.monitored,
TableMovies.path,
TableHistoryMovie.language,
TableMovies.tags,
TableHistoryMovie.score,
TableHistoryMovie.subs_id,
TableHistoryMovie.provider,
TableHistoryMovie.subtitles_path,
TableHistoryMovie.video_path,
TableHistoryMovie.matched,
TableHistoryMovie.not_matched,
TableMovies.profileId,
TableMovies.subtitles.label('external_subtitles'),
upgradable_movies_not_perfect.c.id.label('upgradable'),
blacklisted_subtitles.c.subs_id.label('blacklisted')) \
.select_from(TableHistoryMovie) \
.join(TableMovies) \
.join(upgradable_movies_not_perfect, onclause=TableHistoryMovie.id == upgradable_movies_not_perfect.c.id,
isouter=True) \
.join(blacklisted_subtitles, onclause=TableHistoryMovie.subs_id == blacklisted_subtitles.c.subs_id,
isouter=True) \
.where(reduce(operator.and_, query_conditions)) \
.order_by(TableHistoryMovie.timestamp.desc())
if length > 0:
stmt = stmt.limit(length).offset(start)
movie_history = [{
'id': x.id,
'action': x.action,
'title': x.title,
'timestamp': x.timestamp,
'description': x.description,
'radarrId': x.radarrId,
'monitored': x.monitored,
'path': x.path,
'language': x.language,
'tags': x.tags,
'score': x.score,
'subs_id': x.subs_id,
'provider': x.provider,
'subtitles_path': x.subtitles_path,
'video_path': x.video_path,
'matches': x.matched,
'dont_matches': x.not_matched,
'external_subtitles': [y[1] for y in ast.literal_eval(x.external_subtitles) if y[1]],
'upgradable': bool(x.upgradable) if _language_still_desired(x.language, x.profileId) else False,
'blacklisted': bool(x.blacklisted),
} for x in database.execute(stmt).all()]
for item in movie_history:
original_video_path = item['path']
original_subtitle_path = item['subtitles_path']
item.update(postprocess(item))
# Mark not upgradable if score or if video/subtitles file doesn't exist anymore
if item['upgradable']:
if original_subtitle_path not in item['external_subtitles'] or \
not item['video_path'] == original_video_path:
item.update({"upgradable": False})
del item['path']
del item['video_path']
del item['external_subtitles']
if item['score']:
item['score'] = str(round((int(item['score']) * 100 / 120), 2)) + "%"
# Make timestamp pretty
if item['timestamp']:
item["parsed_timestamp"] = item['timestamp'].strftime('%x %X')
item['timestamp'] = pretty.date(item["timestamp"])
# Parse matches and dont_matches
if item['matches']:
item.update({'matches': ast.literal_eval(item['matches'])})
else:
item.update({'matches': []})
if item['dont_matches']:
item.update({'dont_matches': ast.literal_eval(item['dont_matches'])})
else:
item.update({'dont_matches': []})
count = database.execute(
select(func.count())
.select_from(TableHistoryMovie)
.join(TableMovies)
.where(TableMovies.title.is_not(None))) \
.scalar()
return {'data': movie_history, 'total': count}