Ejemplo n.º 1
0
    def list_subtitles(self, rating_key, item_type, part_id, language):
        metadata = get_plex_metadata(rating_key, part_id, item_type)

        if item_type == "episode":
            min_score = 66
        else:
            min_score = 23

        scanned_parts = scan_videos(
            [metadata],
            kind="series" if item_type == "episode" else "movie",
            ignore_all=True)
        if not scanned_parts:
            Log.Error("Couldn't list available subtitles for %s", rating_key)
            return

        video, plex_part = scanned_parts.items()[0]
        config.init_subliminal_patches()

        available_subs = list_all_subtitles(
            scanned_parts, {Language.fromietf(language)},
            providers=config.providers,
            provider_configs=config.provider_settings)

        use_hearing_impaired = Prefs['subtitles.search.hearingImpaired'] in (
            "prefer", "force HI")

        # sort subtitles by score
        unsorted_subtitles = []
        for s in available_subs[video]:
            Log.Debug("Starting score computation for %s", s)
            try:
                matches = s.get_matches(video,
                                        hearing_impaired=use_hearing_impaired)
            except AttributeError:
                Log.Error("Match computation failed for %s: %s", s,
                          traceback.format_exc())
                continue

            unsorted_subtitles.append((s, compute_score(matches,
                                                        video), matches))
        scored_subtitles = sorted(unsorted_subtitles,
                                  key=operator.itemgetter(1),
                                  reverse=True)

        subtitles = []
        for subtitle, score, matches in scored_subtitles:
            # check score
            if score < min_score:
                Log.Info('Score %d is below min_score (%d)', score, min_score)
                continue
            subtitle.score = score
            subtitle.matches = matches
            subtitle.part_id = part_id
            subtitle.item_type = item_type
            subtitles.append(subtitle)
        return subtitles
Ejemplo n.º 2
0
    def download_subtitle(self, subtitle, rating_key, mode="m"):
        from interface.menu_helpers import set_refresh_menu_state

        item_type = subtitle.item_type
        part_id = subtitle.part_id
        metadata = get_plex_metadata(rating_key, part_id, item_type)
        scanned_parts = scan_videos(
            [metadata],
            kind="series" if item_type == "episode" else "movie",
            ignore_all=True)
        video, plex_part = scanned_parts.items()[0]

        # downloaded_subtitles = {subliminal.Video: [subtitle, subtitle, ...]}
        download_subtitles([subtitle],
                           providers=config.providers,
                           provider_configs=config.provider_settings,
                           pool_class=config.provider_pool)
        download_successful = False

        if subtitle.content:
            try:
                save_subtitles(scanned_parts, {video: [subtitle]},
                               mode=mode,
                               mods=config.default_mods)
                Log.Debug(u"%s: Manually downloaded subtitle for: %s",
                          self.name, rating_key)
                download_successful = True
                refresh_item(rating_key)
                track_usage("Subtitle", "manual", "download", 1)
            except:
                Log.Error(
                    u"%s: Something went wrong when downloading specific subtitle: %s",
                    self.name, traceback.format_exc())
            finally:
                set_refresh_menu_state(None)

                if download_successful:
                    # store item in history
                    from support.history import get_history
                    item_title = get_title_for_video_metadata(
                        metadata, add_section_title=False)
                    history = get_history()
                    history.add(
                        item_title,
                        video.id,
                        section_title=video.plexapi_metadata["section"],
                        subtitle=subtitle,
                        mode=mode)
        else:
            set_refresh_menu_state(u"%s: Subtitle download failed (%s)",
                                   self.name, rating_key)
        return download_successful
Ejemplo n.º 3
0
def SubtitleFPSModMenu(**kwargs):
    rating_key = kwargs["rating_key"]
    part_id = kwargs["part_id"]
    item_type = kwargs["item_type"]

    kwargs.pop("randomize")

    oc = SubFolderObjectContainer(title2=kwargs["title"], replace_parent=True)

    oc.add(
        DirectoryObject(key=Callback(SubtitleModificationsMenu,
                                     randomize=timestamp(),
                                     **kwargs),
                        title="< Back to subtitle modification menu"))

    metadata = get_plex_metadata(rating_key, part_id, item_type)
    scanned_parts = scan_videos(
        [metadata],
        kind="series" if item_type == "episode" else "movie",
        ignore_all=True)
    video, plex_part = scanned_parts.items()[0]

    target_fps = plex_part.fps

    for fps in [
            "23.976", "24.000", "25.000", "29.970", "30.000", "50.000",
            "59.940", "60.000"
    ]:
        if float(fps) == float(target_fps):
            continue

        if float(fps) > float(target_fps):
            indicator = "subs constantly getting faster"
        else:
            indicator = "subs constantly getting slower"

        mod_ident = SubtitleModifications.get_mod_signature(
            "change_FPS", **{
                "from": fps,
                "to": target_fps
            })
        oc.add(
            DirectoryObject(key=Callback(SubtitleSetMods,
                                         mods=mod_ident,
                                         mode="add",
                                         randomize=timestamp(),
                                         **kwargs),
                            title="%s fps -> %s fps (%s)" %
                            (fps, target_fps, indicator)))

    return oc
Ejemplo n.º 4
0
    def update(self, metadata, media, lang):
        Log.Debug("Sub-Zero %s, %s update called" %
                  (config.version, self.agent_type))
        intent = get_intent()

        if not media:
            Log.Error(
                "Called with empty media, something is really wrong with your setup!"
            )
            return

        item_ids = []
        try:
            config.init_subliminal_patches()
            videos = media_to_videos(media, kind=self.agent_type)

            # find local media
            update_local_media(metadata, media, media_type=self.agent_type)

            # media ignored?
            use_any_parts = False
            for video in videos:
                if is_ignored(video["id"]):
                    Log.Debug(u"Ignoring %s" % video)
                    continue
                use_any_parts = True

            if not use_any_parts:
                Log.Debug(u"Nothing to do.")
                return

            try:
                use_score = int(Prefs[self.score_prefs_key].strip())
            except ValueError:
                Log.Error(
                    "Please only put numbers into the scores setting. Exiting")
                return

            set_refresh_menu_state(media, media_type=self.agent_type)

            # scanned_video_part_map = {subliminal.Video: plex_part, ...}
            scanned_video_part_map = scan_videos(videos, kind=self.agent_type)

            downloaded_subtitles = None
            if not config.enable_agent:
                Log.Debug("Skipping Sub-Zero agent(s)")

            else:
                # downloaded_subtitles = {subliminal.Video: [subtitle, subtitle, ...]}
                downloaded_subtitles = download_best_subtitles(
                    scanned_video_part_map, min_score=use_score)
                item_ids = get_media_item_ids(media, kind=self.agent_type)

            downloaded_any = False
            if downloaded_subtitles:
                downloaded_any = any(downloaded_subtitles.values())

            if downloaded_any:
                save_subtitles(scanned_video_part_map,
                               downloaded_subtitles,
                               mods=config.default_mods)
                track_usage("Subtitle", "refreshed", "download", 1)

                for video, video_subtitles in downloaded_subtitles.items():
                    # store item(s) in history
                    for subtitle in video_subtitles:
                        item_title = get_title_for_video_metadata(
                            video.plexapi_metadata, add_section_title=False)
                        history = get_history()
                        history.add(
                            item_title,
                            video.id,
                            section_title=video.plexapi_metadata["section"],
                            subtitle=subtitle)
            else:
                # store subtitle info even if we've downloaded none
                store_subtitle_info(
                    scanned_video_part_map,
                    dict((k, []) for k in scanned_video_part_map.keys()),
                    None,
                    mode="a")

            update_local_media(metadata, media, media_type=self.agent_type)

        finally:
            # update the menu state
            set_refresh_menu_state(None)

            # notify any running tasks about our finished update
            for item_id in item_ids:
                #scheduler.signal("updated_metadata", item_id)

                # resolve existing intent for that id
                intent.resolve("force", item_id)

            Dict.Save()
Ejemplo n.º 5
0
    def run(self):
        super(SearchAllRecentlyAddedMissing, self).run()

        self.running = True
        self.prepare()

        from support.history import get_history
        history = get_history()

        now = datetime.datetime.now()
        min_score_series = int(
            Prefs["subtitles.search.minimumTVScore2"].strip())
        min_score_movies = int(
            Prefs["subtitles.search.minimumMovieScore2"].strip())

        is_recent_str = Prefs["scheduler.item_is_recent_age"]
        num, ident = is_recent_str.split()

        max_search_days = 0
        if ident == "days":
            max_search_days = int(num)
        elif ident == "weeks":
            max_search_days = int(num) * 7

        subtitle_storage = get_subtitle_storage()
        recent_sub_fns = subtitle_storage.get_recent_files(
            age_days=max_search_days)
        viable_items = {}

        # determine viable items
        for fn in recent_sub_fns:
            # added_date <= max_search_days?
            stored_subs = subtitle_storage.load(filename=fn)
            if not stored_subs:
                continue

            if stored_subs.added_at + datetime.timedelta(
                    days=max_search_days) <= now:
                continue

            viable_items[fn] = stored_subs

        subtitle_storage.destroy()

        self.items_searching = len(viable_items)

        download_count = 0
        videos_with_downloads = 0

        config.init_subliminal_patches()

        Log.Info(u"%s: Searching for subtitles for %s items", self.name,
                 self.items_searching)

        # search for subtitles in viable items
        for fn, stored_subs in viable_items.iteritems():
            video_id = stored_subs.video_id

            if stored_subs.item_type == "episode":
                min_score = min_score_series
            else:
                min_score = min_score_movies

            parts = []
            plex_item = get_item(video_id)

            if not plex_item:
                Log.Info(u"%s: Item %s unknown, skipping", self.name, video_id)
                continue

            if is_ignored(video_id, item=plex_item):
                continue

            for media in plex_item.media:
                parts += media.parts

            downloads_per_video = 0
            hit_providers = False
            for part in parts:
                part_id = part.id

                try:
                    metadata = get_plex_metadata(video_id, part_id,
                                                 stored_subs.item_type)
                except PartUnknownException:
                    Log.Info(u"%s: Part %s:%s unknown, skipping", self.name,
                             video_id, part_id)
                    continue

                if not metadata:
                    Log.Info(u"%s: Part %s:%s unknown, skipping", self.name,
                             video_id, part_id)
                    continue

                Log.Debug(u"%s: Looking for missing subtitles: %s:%s",
                          self.name, video_id, part_id)
                scanned_parts = scan_videos(
                    [metadata],
                    kind="series"
                    if stored_subs.item_type == "episode" else "movie")

                downloaded_subtitles = download_best_subtitles(
                    scanned_parts, min_score=min_score)
                hit_providers = downloaded_subtitles is not None
                download_successful = False

                if downloaded_subtitles:
                    downloaded_any = any(downloaded_subtitles.values())
                    if not downloaded_any:
                        continue

                    try:
                        save_subtitles(scanned_parts,
                                       downloaded_subtitles,
                                       mode="a",
                                       mods=config.default_mods)
                        Log.Debug(
                            u"%s: Downloaded subtitle for item with missing subs: %s",
                            self.name, video_id)
                        download_successful = True
                        refresh_item(video_id)
                        track_usage("Subtitle", "manual", "download", 1)
                    except:
                        Log.Error(
                            u"%s: Something went wrong when downloading specific subtitle: %s",
                            self.name, traceback.format_exc())
                    finally:
                        item_title = get_title_for_video_metadata(
                            metadata, add_section_title=False)
                        if download_successful:
                            # store item in history
                            for video, video_subtitles in downloaded_subtitles.items(
                            ):
                                if not video_subtitles:
                                    continue

                                for subtitle in video_subtitles:
                                    downloads_per_video += 1
                                    history.add(
                                        item_title,
                                        video.id,
                                        section_title=metadata["section"],
                                        subtitle=subtitle,
                                        mode="a")

                    Log.Debug(u"%s: Waiting %s seconds before continuing",
                              self.name, PROVIDER_SLACK)
                    time.sleep(PROVIDER_SLACK)

            download_count += downloads_per_video

            if downloads_per_video:
                videos_with_downloads += 1

            self.items_done = self.items_done + 1
            self.percentage = int(self.items_done * 100 / self.items_searching)

            if downloads_per_video:
                Log.Debug(
                    u"%s: Subtitles have been downloaded, "
                    u"waiting %s seconds before continuing", self.name,
                    DL_PROVIDER_SLACK)
                time.sleep(DL_PROVIDER_SLACK)
            else:
                if hit_providers:
                    Log.Debug(u"%s: Waiting %s seconds before continuing",
                              self.name, PROVIDER_SLACK)
                    time.sleep(PROVIDER_SLACK)

        if download_count:
            Log.Debug(
                u"%s: done. Missing subtitles found for %s/%s items (%s subs downloaded)",
                self.name, videos_with_downloads, self.items_searching,
                download_count)
        else:
            Log.Debug(u"%s: done. No subtitles found for %s items", self.name,
                      self.items_searching)
Ejemplo n.º 6
0
def ListAvailableSubsForItemMenu(rating_key=None,
                                 part_id=None,
                                 title=None,
                                 item_title=None,
                                 filename=None,
                                 item_type="episode",
                                 language=None,
                                 force=False,
                                 current_id=None,
                                 current_data=None,
                                 current_provider=None,
                                 current_score=None,
                                 randomize=None):
    assert rating_key, part_id

    running = scheduler.is_task_running("AvailableSubsForItem")
    search_results = get_item_task_data("AvailableSubsForItem", rating_key,
                                        language)

    if (search_results is None or force) and not running:
        scheduler.dispatch_task("AvailableSubsForItem",
                                rating_key=rating_key,
                                item_type=item_type,
                                part_id=part_id,
                                language=language)
        running = True

    oc = SubFolderObjectContainer(title2=unicode(title), replace_parent=True)
    oc.add(
        DirectoryObject(key=Callback(ItemDetailsMenu,
                                     rating_key=rating_key,
                                     item_title=item_title,
                                     title=title,
                                     randomize=timestamp()),
                        title=u"Back to: %s" % title,
                        summary=current_data,
                        thumb=default_thumb))

    metadata = get_plex_metadata(rating_key, part_id, item_type)
    scanned_parts = scan_videos(
        [metadata],
        kind="series" if item_type == "episode" else "movie",
        ignore_all=True)

    if not scanned_parts:
        Log.Error("Couldn't list available subtitles for %s", rating_key)
        return oc

    video, plex_part = scanned_parts.items()[0]

    video_display_data = [video.format] if video.format else []
    if video.release_group:
        video_display_data.append(u"by %s" % video.release_group)
    video_display_data = " ".join(video_display_data)

    current_display = (u"Current: %s (%s) " % (current_provider, current_score)
                       if current_provider else "")
    if not running:
        oc.add(
            DirectoryObject(key=Callback(ListAvailableSubsForItemMenu,
                                         rating_key=rating_key,
                                         item_title=item_title,
                                         language=language,
                                         filename=filename,
                                         part_id=part_id,
                                         title=title,
                                         current_id=current_id,
                                         force=True,
                                         current_provider=current_provider,
                                         current_score=current_score,
                                         current_data=current_data,
                                         item_type=item_type,
                                         randomize=timestamp()),
                            title=u"Search for %s subs (%s)" %
                            (get_language(language).name, video_display_data),
                            summary=u"%sFilename: %s" %
                            (current_display, filename),
                            thumb=default_thumb))
    else:
        oc.add(
            DirectoryObject(
                key=Callback(ListAvailableSubsForItemMenu,
                             rating_key=rating_key,
                             item_title=item_title,
                             language=language,
                             filename=filename,
                             current_data=current_data,
                             part_id=part_id,
                             title=title,
                             current_id=current_id,
                             item_type=item_type,
                             current_provider=current_provider,
                             current_score=current_score,
                             randomize=timestamp()),
                title=u"Searching for %s subs (%s), refresh here ..." %
                (get_language(language).name, video_display_data),
                summary=u"%sFilename: %s" % (current_display, filename),
                thumb=default_thumb))

    if not search_results:
        return oc

    for subtitle in search_results:
        oc.add(
            DirectoryObject(
                key=Callback(TriggerDownloadSubtitle,
                             rating_key=rating_key,
                             randomize=timestamp(),
                             item_title=item_title,
                             subtitle_id=str(subtitle.id),
                             language=language),
                title=u"%s: %s, score: %s" %
                ("Available" if current_id != subtitle.id else "Current",
                 subtitle.provider_name, subtitle.score),
                summary=u"Release: %s, Matches: %s" %
                (subtitle.release_info, ", ".join(subtitle.matches)),
                thumb=default_thumb))

    return oc
Ejemplo n.º 7
0
def set_mods_for_part(rating_key, part_id, language, item_type, mods, mode="add"):
    from support.plex_media import get_plex_metadata, scan_videos
    from support.storage import save_subtitles

    current_sub, stored_subs, storage = get_current_sub(rating_key, part_id, language)
    if mode == "add":
        for mod in mods:
            identifier, args = SubtitleModifications.parse_identifier(mod)
            mod_class = SubtitleModifications.get_mod_class(identifier)

            if identifier not in mod_registry.mods_available:
                raise NotImplementedError("Mod unknown or not registered")

            # clean exclusive mods
            if mod_class.exclusive and current_sub.mods:
                for current_mod in current_sub.mods[:]:
                    if current_mod.startswith(identifier):
                        current_sub.mods.remove(current_mod)
                        Log.Info("Removing superseded mod %s" % current_mod)

            current_sub.add_mod(mod)
    elif mode == "clear":
        current_sub.add_mod(None)
    elif mode == "remove":
        for mod in mods:
            current_sub.mods.remove(mod)

    elif mode == "remove_last":
        if current_sub.mods:
            current_sub.mods.pop()
    else:
        raise NotImplementedError("Wrong mode given")
    storage.save(stored_subs)

    try:
        metadata = get_plex_metadata(rating_key, part_id, item_type)
    except PartUnknownException:
        return

    scanned_parts = scan_videos([metadata], kind="series" if item_type == "episode" else "movie", ignore_all=True,
                                no_refining=True)
    video, plex_part = scanned_parts.items()[0]

    subtitle = ModifiedSubtitle(language, mods=current_sub.mods)
    subtitle.content = current_sub.content
    if current_sub.encoding:
        # thanks plex
        setattr(subtitle, "_guessed_encoding", current_sub.encoding)

        if current_sub.encoding != "utf-8":
            subtitle.set_encoding("utf-8")
            current_sub.content = subtitle.content
            current_sub.encoding = "utf-8"
            storage.save(stored_subs)

    storage.destroy()

    subtitle.plex_media_fps = plex_part.fps
    subtitle.page_link = "modify subtitles with: %s" % (", ".join(current_sub.mods) if current_sub.mods else "none")
    subtitle.language = language
    subtitle.id = current_sub.id

    try:
        save_subtitles(scanned_parts, {video: [subtitle]}, mode="m", bare_save=True)
        Log.Debug("Modified %s subtitle for: %s:%s with: %s", language.name, rating_key, part_id,
                  ", ".join(current_sub.mods) if current_sub.mods else "none")
    except:
        Log.Error("Something went wrong when modifying subtitle: %s", traceback.format_exc())