Beispiel #1
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)
        providers = config.get_providers(media_type="series" if item_type == "episode" else "movies")
        scanned_parts = scan_videos([metadata], ignore_all=True, providers=providers)
        video, plex_part = scanned_parts.items()[0]

        pre_download_hook(subtitle)

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

        post_download_hook(subtitle)

        # may be redundant
        subtitle.pack_data = None

        download_successful = False

        if subtitle.content:
            try:
                save_subtitles(scanned_parts, {video: [subtitle]}, mode=mode, mods=config.default_mods)
                if mode == "m":
                    Log.Debug(u"%s: Manually downloaded subtitle for: %s", self.name, rating_key)
                    track_usage("Subtitle", "manual", "download", 1)
                elif mode == "b":
                    Log.Debug(u"%s: Downloaded better subtitle for: %s", self.name, rating_key)
                    track_usage("Subtitle", "better", "download", 1)
                download_successful = True
                refresh_item(rating_key)

            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)
                    history.destroy()

                    # clear missing subtitles menu data
                    if not scheduler.is_task_running("MissingSubtitles"):
                        scheduler.clear_task_data("MissingSubtitles")
        else:
            set_refresh_menu_state(u"%s: Subtitle download failed (%s)" % (self.name, rating_key))
        return download_successful
Beispiel #2
0
def Start():
    HTTP.CacheTime = 0
    HTTP.Headers['User-agent'] = OS_PLEX_USERAGENT

    config.init_cache()

    # clear expired intents
    intent = get_intent()
    intent.cleanup()

    #Locale.DefaultLocale = "de"

    # clear expired menu history items
    now = datetime.datetime.now()
    if "menu_history" in Dict:
        for key, timeout in Dict["menu_history"].copy().items():
            if now > timeout:
                try:
                    del Dict["menu_history"][key]
                except:
                    pass

    # run migrations
    if "subs" in Dict or "history" in Dict:
        Thread.Create(dispatch_migrate)

    # clear old task data
    scheduler.clear_task_data()

    # init defaults; perhaps not the best idea to use ValidatePrefs here, but we'll see
    ValidatePrefs()
    Log.Debug(config.full_version)

    if not config.permissions_ok:
        Log.Error("Insufficient permissions on library folders:")
        for title, path in config.missing_permissions:
            Log.Error("Insufficient permissions on library %s, folder: %s" %
                      (title, path))

    # run task scheduler
    scheduler.run()

    # bind activities
    if config.enable_channel:
        Thread.Create(activity.start)

    if "anon_id" not in Dict:
        Dict["anon_id"] = get_identifier()

    # track usage
    if cast_bool(Prefs["track_usage"]):
        if "first_use" not in Dict:
            Dict["first_use"] = datetime.datetime.utcnow()
            Dict.Save()
            track_usage("General", "plugin", "first_start", config.version)
        track_usage("General", "plugin", "start", config.version)
Beispiel #3
0
def Start():
    HTTP.CacheTime = 0
    HTTP.Headers['User-agent'] = OS_PLEX_USERAGENT

    config.init_cache()

    # clear expired intents
    intent = get_intent()
    intent.cleanup()

    #Locale.DefaultLocale = "de"

    # clear expired menu history items
    now = datetime.datetime.now()
    if "menu_history" in Dict:
        for key, timeout in Dict["menu_history"].copy().items():
            if now > timeout:
                try:
                    del Dict["menu_history"][key]
                except:
                    pass

    # run migrations
    if "subs" in Dict or "history" in Dict:
        Thread.Create(dispatch_migrate)

    # clear old task data
    scheduler.clear_task_data()

    # init defaults; perhaps not the best idea to use ValidatePrefs here, but we'll see
    ValidatePrefs()
    Log.Debug(config.full_version)

    if not config.permissions_ok:
        Log.Error("Insufficient permissions on library folders:")
        for title, path in config.missing_permissions:
            Log.Error("Insufficient permissions on library %s, folder: %s" % (title, path))

    # run task scheduler
    scheduler.run()

    # bind activities
    if config.enable_channel:
        Thread.Create(activity.start)

    if "anon_id" not in Dict:
        Dict["anon_id"] = get_identifier()

    # track usage
    if cast_bool(Prefs["track_usage"]):
        if "first_use" not in Dict:
            Dict["first_use"] = datetime.datetime.utcnow()
            Dict.Save()
            track_usage("General", "plugin", "first_start", config.version)
        track_usage("General", "plugin", "start", config.version)
Beispiel #4
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
Beispiel #5
0
def Start():
    HTTP.CacheTime = 0
    HTTP.Headers['User-agent'] = OS_PLEX_USERAGENT

    # configured cache to be in memory as per https://github.com/Diaoul/subliminal/issues/303
    subliminal.region.configure('dogpile.cache.memory')

    # clear expired intents
    intent = get_intent()
    intent.cleanup()

    # clear expired menu history items
    now = datetime.datetime.now()
    if "menu_history" in Dict:
        for key, timeout in Dict["menu_history"].items():
            if now > timeout:
                del Dict["menu_history"][key]

    # run migrations
    if "subs" in Dict or "history" in Dict:
        Thread.Create(dispatch_migrate)

    # clear old task data
    scheduler.clear_task_data()

    # init defaults; perhaps not the best idea to use ValidatePrefs here, but we'll see
    ValidatePrefs()
    Log.Debug(config.full_version)

    if not config.permissions_ok:
        Log.Error("Insufficient permissions on library folders:")
        for title, path in config.missing_permissions:
            Log.Error("Insufficient permissions on library %s, folder: %s" %
                      (title, path))

    # run task scheduler
    scheduler.run()

    # bind activities
    Thread.Create(activity.start)

    if "anon_id" not in Dict:
        Dict["anon_id"] = get_identifier()

    # track usage
    if cast_bool(Prefs["track_usage"]):
        if "first_use" not in Dict:
            Dict["first_use"] = datetime.datetime.utcnow()
            Dict.Save()
            track_usage("General", "plugin", "first_start", config.version)
        track_usage("General", "plugin", "start", config.version)
Beispiel #6
0
    def run(self):
        super(AvailableSubsForItem, self).run()
        self.running = True
        track_usage("Subtitle", "manual", "list", 1)
        subs = self.list_subtitles(self.rating_key,
                                   self.item_type,
                                   self.part_id,
                                   self.language,
                                   skip_wrong_fps=False)
        if not subs:
            self.data = "found_none"
            return

        # we can't have nasty unpicklable stuff like ZipFile, BytesIO etc in self.data
        self.data = [s.make_picklable() for s in subs]
Beispiel #7
0
    def run(self):
        super(AvailableSubsForItem, self).run()
        self.running = True
        try:
            track_usage("Subtitle", "manual", "list", 1)
        except:
            Log.Error("Something went wrong with track_usage: %s", traceback.format_exc())

        Log.Debug("Listing available subtitles for: %s", self.rating_key)
        subs = self.list_subtitles(self.rating_key, self.item_type, self.part_id, self.language, skip_wrong_fps=False)
        if not subs:
            self.data = "found_none"
            return

        # we can't have nasty unpicklable stuff like ZipFile, BytesIO etc in self.data
        self.data = [s.make_picklable() for s in subs]
Beispiel #8
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()
Beispiel #9
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())
        series_providers = config.get_providers(media_type="series")
        movie_providers = config.get_providers(media_type="movies")

        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_files = subtitle_storage.get_recent_files(
            age_days=max_search_days)

        self.items_searching = len(recent_files)

        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)

        def skip_item():
            self.items_searching = self.items_searching - 1
            self.percentage = int(
                self.items_done * 100 /
                self.items_searching) if self.items_searching > 0 else 100

        # search for subtitles in viable items
        try:
            for fn in recent_files:
                stored_subs = subtitle_storage.load(filename=fn)
                if not stored_subs:
                    Log.Debug("Skipping item %s because storage is empty", fn)
                    skip_item()
                    continue

                video_id = stored_subs.video_id

                # added_date <= max_search_days?
                if stored_subs.added_at + datetime.timedelta(
                        days=max_search_days) <= now:
                    Log.Debug("Skipping item %s because it's too old",
                              video_id)
                    skip_item()
                    continue

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

                parts = []
                plex_item = get_item(video_id)

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

                if not is_wanted(video_id, item=plex_item):
                    skip_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",
                              self.name, get_item_title(plex_item))
                    scanned_parts = scan_videos([metadata],
                                                providers=providers)

                    downloaded_subtitles = download_best_subtitles(
                        scanned_parts,
                        min_score=min_score,
                        providers=providers)
                    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:
                            scanned_parts = None
                            try:
                                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"],
                                                thumb=video.plexapi_metadata[
                                                    "super_thumb"],
                                                subtitle=subtitle,
                                                mode="a")

                                    downloaded_subtitles = None
                            except:
                                Log.Error(u"%s: DEBUG HIT: %s", self.name,
                                          traceback.format_exc())

                        Log.Debug(u"%s: Waiting %s seconds before continuing",
                                  self.name, self.PROVIDER_SLACK)
                        Thread.Sleep(self.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 self.items_searching > 0 else 100

                stored_subs = None

                if downloads_per_video:
                    Log.Debug(
                        u"%s: Subtitles have been downloaded, "
                        u"waiting %s seconds before continuing", self.name,
                        self.DL_PROVIDER_SLACK)
                    Thread.Sleep(self.DL_PROVIDER_SLACK)
                else:
                    if hit_providers:
                        Log.Debug(u"%s: Waiting %s seconds before continuing",
                                  self.name, self.PROVIDER_SLACK)
                        Thread.Sleep(self.PROVIDER_SLACK)
        finally:
            subtitle_storage.destroy()
            history.destroy()

        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)
Beispiel #10
0
    def update(self, metadata, media, lang):
        if not config.enable_agent:
            Log.Debug("Skipping Sub-Zero agent(s)")
            return

        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, ...}
            providers = config.get_providers(media_type=self.agent_type)
            try:
                scanned_video_part_map = scan_videos(videos,
                                                     providers=providers)
            except IOError, e:
                Log.Exception(
                    "Permission error, please check your folder/file permissions. Exiting."
                )
                if cast_bool(Prefs["check_permissions"]):
                    config.permissions_ok = False
                    config.missing_permissions = e.message
                return

            # auto extract embedded
            if config.embedded_auto_extract:
                if config.plex_transcoder:
                    agent_extract_embedded(scanned_video_part_map)
                else:
                    Log.Warning(
                        "Plex Transcoder not found, can't auto extract")

            # clear missing subtitles menu data
            if not scheduler.is_task_running("MissingSubtitles"):
                scheduler.clear_task_data("MissingSubtitles")

            downloaded_subtitles = None

            # debounce for self.debounce seconds
            now = datetime.datetime.now()
            if "last_call" in Dict:
                last_call = Dict["last_call"]
                if last_call + datetime.timedelta(seconds=self.debounce) > now:
                    wait = self.debounce - (now - last_call).seconds
                    if wait >= 1:
                        Log.Debug("Waiting %s seconds until continuing", wait)
                        Thread.Sleep(wait)

            # downloaded_subtitles = {subliminal.Video: [subtitle, subtitle, ...]}
            try:
                downloaded_subtitles = download_best_subtitles(
                    scanned_video_part_map,
                    min_score=use_score,
                    throttle_time=self.debounce,
                    providers=providers)
            except:
                Log.Exception(
                    "Something went wrong when downloading subtitles")

            if downloaded_subtitles is not None:
                Dict["last_call"] = datetime.datetime.now()

            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_successful = False
                try:
                    save_successful = save_subtitles(scanned_video_part_map,
                                                     downloaded_subtitles,
                                                     mods=config.default_mods)
                except:
                    Log.Exception("Something went wrong when saving subtitles")

                track_usage("Subtitle", "refreshed", "download", 1)

                # store SZ meta info even if download wasn't successful
                if not save_successful:
                    self.store_blank_subtitle_metadata(scanned_video_part_map)

                else:
                    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)
                            history.destroy()
            else:
                # store SZ meta info even if we've downloaded none
                self.store_blank_subtitle_metadata(scanned_video_part_map)

            update_local_media(metadata, media, media_type=self.agent_type)
Beispiel #11
0
 def run(self):
     super(AvailableSubsForItem, self).run()
     self.running = True
     track_usage("Subtitle", "manual", "list", 1)
     self.data = self.list_subtitles(self.rating_key, self.item_type,
                                     self.part_id, self.language)
Beispiel #12
0
    def update(self, metadata, media, lang):
        if not config.enable_agent:
            Log.Debug("Skipping Sub-Zero agent(s)")
            return

        Log.Debug("Sub-Zero %s, %s update called" % (config.version, self.agent_type))

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

        intent = get_intent()

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

            # media ignored?
            ignore_parts_cleanup = []
            videos = []
            for video in all_videos:
                if not is_wanted(video["id"], item=video["item"]):
                    Log.Debug(u'Skipping "%s"' % video["filename"])
                    ignore_parts_cleanup.append(video["path"])
                    continue
                videos.append(video)

            # find local media
            update_local_media(all_videos, ignore_parts_cleanup=ignore_parts_cleanup)

            if not videos:
                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, ...}
            providers = config.get_providers(media_type=self.agent_type)
            try:
                scanned_video_part_map = scan_videos(videos, providers=providers)
            except IOError, e:
                Log.Exception("Permission error, please check your folder/file permissions. Exiting.")
                if cast_bool(Prefs["check_permissions"]):
                    config.permissions_ok = False
                    config.missing_permissions = e.message
                return

            # auto extract embedded
            if config.embedded_auto_extract:
                if config.plex_transcoder:
                    agent_extract_embedded(scanned_video_part_map)
                else:
                    Log.Warn("Plex Transcoder not found, can't auto extract")

            # clear missing subtitles menu data
            if not scheduler.is_task_running("MissingSubtitles"):
                scheduler.clear_task_data("MissingSubtitles")

            downloaded_subtitles = None

            # debounce for self.debounce seconds
            now = datetime.datetime.now()
            if "last_call" in Dict:
                last_call = Dict["last_call"]
                if last_call + datetime.timedelta(seconds=self.debounce) > now:
                    wait = self.debounce - (now - last_call).seconds
                    if wait >= 1:
                        Log.Debug("Waiting %s seconds until continuing", wait)
                        Thread.Sleep(wait)

            # downloaded_subtitles = {subliminal.Video: [subtitle, subtitle, ...]}
            try:
                downloaded_subtitles = download_best_subtitles(scanned_video_part_map, min_score=use_score,
                                                               throttle_time=self.debounce, providers=providers)
            except:
                Log.Exception("Something went wrong when downloading subtitles")

            if downloaded_subtitles is not None:
                Dict["last_call"] = datetime.datetime.now()

            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_successful = False
                try:
                    save_successful = save_subtitles(scanned_video_part_map, downloaded_subtitles,
                                                     mods=config.default_mods)
                except:
                    Log.Exception("Something went wrong when saving subtitles")

                track_usage("Subtitle", "refreshed", "download", 1)

                # store SZ meta info even if download wasn't successful
                if not save_successful:
                    self.store_blank_subtitle_metadata(scanned_video_part_map)

                else:
                    for video, video_subtitles in downloaded_subtitles.items():
                        # store item(s) in history
                        for subtitle in video_subtitles:
                            history = get_history()
                            item_title = get_title_for_video_metadata(video.plexapi_metadata, add_section_title=False)
                            history.add(item_title, video.id, section_title=video.plexapi_metadata["section"],
                                        thumb=video.plexapi_metadata["super_thumb"],
                                        subtitle=subtitle)
                            history.destroy()
            else:
                # store SZ meta info even if we've downloaded none
                self.store_blank_subtitle_metadata(scanned_video_part_map)

            update_local_media(videos)