1# coding=utf-8
2
3import datetime
4import os
5import operator
6import pretty
7
8from flask import request, jsonify
9from flask_restful import Resource
10from functools import reduce
11from peewee import fn
12from datetime import timedelta
13
14from database import get_exclusion_clause, TableEpisodes, TableShows, TableHistory, TableBlacklist
15from ..utils import authenticate, postprocessEpisode
16from config import settings
17from helper import path_mappings
18
19
20class EpisodesHistory(Resource):
21    @authenticate
22    def get(self):
23        start = request.args.get('start') or 0
24        length = request.args.get('length') or -1
25        episodeid = request.args.get('episodeid')
26
27        upgradable_episodes_not_perfect = []
28        if settings.general.getboolean('upgrade_subs'):
29            days_to_upgrade_subs = settings.general.days_to_upgrade_subs
30            minimum_timestamp = ((datetime.datetime.now() - timedelta(days=int(days_to_upgrade_subs))) -
31                                 datetime.datetime(1970, 1, 1)).total_seconds()
32
33            if settings.general.getboolean('upgrade_manual'):
34                query_actions = [1, 2, 3, 6]
35            else:
36                query_actions = [1, 3]
37
38            upgradable_episodes_conditions = [(TableHistory.action.in_(query_actions)),
39                                              (TableHistory.timestamp > minimum_timestamp),
40                                              (TableHistory.score is not None)]
41            upgradable_episodes_conditions += get_exclusion_clause('series')
42            upgradable_episodes = TableHistory.select(TableHistory.video_path,
43                                                      fn.MAX(TableHistory.timestamp).alias('timestamp'),
44                                                      TableHistory.score,
45                                                      TableShows.tags,
46                                                      TableEpisodes.monitored,
47                                                      TableShows.seriesType)\
48                .join(TableEpisodes, on=(TableHistory.sonarrEpisodeId == TableEpisodes.sonarrEpisodeId))\
49                .join(TableShows, on=(TableHistory.sonarrSeriesId == TableShows.sonarrSeriesId))\
50                .where(reduce(operator.and_, upgradable_episodes_conditions))\
51                .group_by(TableHistory.video_path)\
52                .dicts()
53            upgradable_episodes = list(upgradable_episodes)
54            for upgradable_episode in upgradable_episodes:
55                if upgradable_episode['timestamp'] > minimum_timestamp:
56                    try:
57                        int(upgradable_episode['score'])
58                    except ValueError:
59                        pass
60                    else:
61                        if int(upgradable_episode['score']) < 360:
62                            upgradable_episodes_not_perfect.append(upgradable_episode)
63
64        query_conditions = [(TableEpisodes.title is not None)]
65        if episodeid:
66            query_conditions.append((TableEpisodes.sonarrEpisodeId == episodeid))
67        query_condition = reduce(operator.and_, query_conditions)
68        episode_history = TableHistory.select(TableHistory.id,
69                                              TableShows.title.alias('seriesTitle'),
70                                              TableEpisodes.monitored,
71                                              TableEpisodes.season.concat('x').concat(TableEpisodes.episode).alias('episode_number'),
72                                              TableEpisodes.title.alias('episodeTitle'),
73                                              TableHistory.timestamp,
74                                              TableHistory.subs_id,
75                                              TableHistory.description,
76                                              TableHistory.sonarrSeriesId,
77                                              TableEpisodes.path,
78                                              TableHistory.language,
79                                              TableHistory.score,
80                                              TableShows.tags,
81                                              TableHistory.action,
82                                              TableHistory.subtitles_path,
83                                              TableHistory.sonarrEpisodeId,
84                                              TableHistory.provider,
85                                              TableShows.seriesType)\
86            .join(TableShows, on=(TableHistory.sonarrSeriesId == TableShows.sonarrSeriesId))\
87            .join(TableEpisodes, on=(TableHistory.sonarrEpisodeId == TableEpisodes.sonarrEpisodeId))\
88            .where(query_condition)\
89            .order_by(TableHistory.timestamp.desc())\
90            .limit(length)\
91            .offset(start)\
92            .dicts()
93        episode_history = list(episode_history)
94
95        blacklist_db = TableBlacklist.select(TableBlacklist.provider, TableBlacklist.subs_id).dicts()
96        blacklist_db = list(blacklist_db)
97
98        for item in episode_history:
99            # Mark episode as upgradable or not
100            item.update({"upgradable": False})
101            if {"video_path": str(item['path']), "timestamp": float(item['timestamp']), "score": str(item['score']),
102                "tags": str(item['tags']), "monitored": str(item['monitored']),
103                "seriesType": str(item['seriesType'])} in upgradable_episodes_not_perfect:
104                if os.path.isfile(path_mappings.path_replace(item['subtitles_path'])):
105                    item.update({"upgradable": True})
106
107            del item['path']
108
109            postprocessEpisode(item)
110
111            if item['score']:
112                item['score'] = str(round((int(item['score']) * 100 / 360), 2)) + "%"
113
114            # Make timestamp pretty
115            if item['timestamp']:
116                item["raw_timestamp"] = int(item['timestamp'])
117                item["parsed_timestamp"] = datetime.datetime.fromtimestamp(int(item['timestamp'])).strftime('%x %X')
118                item['timestamp'] = pretty.date(item["raw_timestamp"])
119
120            # Check if subtitles is blacklisted
121            item.update({"blacklisted": False})
122            if item['action'] not in [0, 4, 5]:
123                for blacklisted_item in blacklist_db:
124                    if blacklisted_item['provider'] == item['provider'] and \
125                            blacklisted_item['subs_id'] == item['subs_id']:
126                        item.update({"blacklisted": True})
127                        break
128
129        count = TableHistory.select()\
130            .join(TableEpisodes, on=(TableHistory.sonarrEpisodeId == TableEpisodes.sonarrEpisodeId))\
131            .where(TableEpisodes.title is not None).count()
132
133        return jsonify(data=episode_history, total=count)
134