aboutsummaryrefslogtreecommitdiffhomepage
path: root/custom_libs/subzero/video.py
blob: 0a06240f66d7d62ceb4136fc0475481c5ea9ae73 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
# coding=utf-8

from __future__ import absolute_import
import logging
import os

from babelfish.exceptions import LanguageError
from subzero.language import Language, language_from_stream
from subliminal_patch import scan_video, refine, search_external_subtitles
import six

logger = logging.getLogger(__name__)


def has_external_subtitle(part_id, stored_subs, language):
    stored_sub = stored_subs.get_any(part_id, language)
    if stored_sub and stored_sub.storage_type == "filesystem":
        return True


def set_existing_languages(video, video_info, external_subtitles=False, embedded_subtitles=False, known_embedded=None,
                           stored_subs=None, languages=None, only_one=False, known_metadata_subs=None,
                           match_strictness="strict"):
    logger.debug(u"Determining existing subtitles for %s", video.name)

    external_langs_found = set()
    # scan for external subtitles
    if known_metadata_subs:
        # existing metadata subtitles
        external_langs_found = known_metadata_subs

    external_langs_found.update(set(search_external_subtitles(video.name, languages=languages,
                                                              only_one=only_one,
                                                              match_strictness=match_strictness).values()))

    # found external subtitles should be considered?
    if external_subtitles:
        # |= is update, thanks plex
        video.subtitle_languages.update(external_langs_found)
        video.external_subtitle_languages.update(external_langs_found)

    else:
        # did we already download subtitles for this?
        if stored_subs and external_langs_found:
            for lang in external_langs_found:
                if has_external_subtitle(video_info["plex_part"].id, stored_subs, lang):
                    logger.info("Not re-downloading subtitle for language %s, it already exists on the filesystem",
                                lang)
                    video.subtitle_languages.add(lang)

    # add known embedded subtitles
    if embedded_subtitles and known_embedded:
        # mp4 and stuff, check burned in
        for language in known_embedded:
            logger.debug('Found embedded subtitle %r', language)
            video.subtitle_languages.add(language)


def parse_video(fn, hints, skip_hashing=False, dry_run=False, providers=None, hash_from=None):
    logger.debug("Parsing video: %s, hints: %s", os.path.basename(fn), hints)
    return scan_video(fn, hints=hints, dont_use_actual_file=dry_run, providers=providers,
                      skip_hashing=skip_hashing, hash_from=hash_from)


def refine_video(video, no_refining=False, refiner_settings=None):
    refiner_settings = refiner_settings or {}
    video_info = video.plexapi_metadata
    hints = video.hints

    if no_refining:
        logger.debug("Taking parse_video shortcut")
        return video

    # refiners
    refine_kwargs = {
        "episode_refiners": ['sz_tvdb', 'sz_omdb',],
        "movie_refiners": ['sz_omdb',],
        "embedded_subtitles": False,
    }
    refine_kwargs.update(refiner_settings)

    if "filebot" in refiner_settings:
        # filebot always comes first
        refine_kwargs["episode_refiners"].insert(0, "filebot")
        refine_kwargs["movie_refiners"].insert(0, "filebot")

    if "symlinks" in refiner_settings:
        refine_kwargs["episode_refiners"].insert(0, "symlinks")
        refine_kwargs["movie_refiners"].insert(0, "symlinks")

    if "file_info_file" in refiner_settings:
        # file_info_file always comes first
        refine_kwargs["episode_refiners"].insert(0, "file_info_file")
        refine_kwargs["movie_refiners"].insert(0, "file_info_file")

    if "sonarr" in refiner_settings:
        # drone always comes last
        refine_kwargs["episode_refiners"].append("drone")

    if "radarr" in refiner_settings:
        refine_kwargs["movie_refiners"].append("drone")

    # our own metadata refiner :)
    if "stream" in video_info:
        for key, value in six.iteritems(video_info["stream"]):
            if hasattr(video, key) and not getattr(video, key):
                logger.info(u"Adding stream %s info: %s", key, value)
                setattr(video, key, value)

    plex_title = video_info.get("original_title") or video_info.get("title")
    if hints["type"] == "episode":
        plex_title = video_info.get("original_title") or video_info.get("series")

    year = video_info.get("year")
    if not video.year and year:
        logger.info(u"Adding PMS year info: %s", year)
        video.year = year

    refine(video, **refine_kwargs)
    logger.info(u"Using filename: %s", video.original_name)

    if hints["type"] == "movie" and not video.imdb_id:
        if plex_title:
            logger.info(u"Adding PMS title/original_title info: %s", plex_title)
            old_title = video.title
            video.title = plex_title.replace(" - ", " ").replace(" -", " ").replace("- ", " ")

            # re-refine with new info
            logger.info(u"Re-refining with movie title: '%s' instead of '%s'", plex_title, old_title)
            refine(video, **refine_kwargs)

            video.alternative_titles.append(old_title)

        # still no match? add our own data
        if not video.imdb_id:
            video.imdb_id = video_info.get("imdb_id")
            if video.imdb_id:
                logger.info(u"Adding PMS imdb_id info: %s", video.imdb_id)

    elif hints["type"] == "movie" and plex_title:
        pt = plex_title.replace(" - ", " ").replace(" -", " ").replace("- ", " ")
        if pt != video.title:
            video.alternative_titles.append(pt)

    if hints["type"] == "episode":
        video.season = video_info.get("season", video.season)
        video.episode = video_info.get("episode", video.episode)
        if not video.series_tvdb_id and not video.tvdb_id and plex_title:
            # add our title
            logger.info(u"Adding PMS title/original_title info: %s", plex_title)
            old_title = video.series
            video.series = plex_title

            # re-refine with new info
            logger.info(u"Re-refining with series title: '%s' instead of '%s'", plex_title, old_title)
            refine(video, **refine_kwargs)

            video.alternative_series.append(old_title)

        elif plex_title and video.series != plex_title:
            video.alternative_series.append(plex_title)

        # still no match? add our own data
        if not video.series_tvdb_id or not video.tvdb_id:
            logger.info(u"Adding PMS year info: %s", video_info.get("year"))
            video.year = video_info.get("year")

        if not video.series_tvdb_id and video_info.get("series_tvdb_id"):
            logger.info(u"Adding PMS series_tvdb_id info: %s", video_info.get("series_tvdb_id"))
            video.series_tvdb_id = video_info.get("series_tvdb_id")

        if not video.tvdb_id and video_info.get("tvdb_id"):
            logger.info(u"Adding PMS tvdb_id info: %s", video_info.get("tvdb_id"))
            video.tvdb_id = video_info.get("tvdb_id")

    # did it match?
    if (hints["type"] == "episode" and not video.series_tvdb_id and not video.tvdb_id) \
            or (hints["type"] == "movie" and not video.imdb_id):
        logger.warning("Couldn't find corresponding series/movie in online databases, continuing")

    # guess special
    if hints["type"] == "episode":
        if video.season == 0 or video.episode == 0:
            video.is_special = True
        else:
            # check parent folder name
            if os.path.dirname(video.name).split(os.path.sep)[-1].lower() in ("specials", "season 00"):
                video.is_special = True

    return video