def BlacklistAllPartsSubtitleMenu(**kwargs): rating_key = kwargs.get("rating_key") language = kwargs.get("language") if language: language = Language.fromietf(language) item = get_item(rating_key) if not item: return item_title = get_item_title(item) subtitle_storage = get_subtitle_storage() stored_subs = subtitle_storage.load_or_new(item) for part_id, languages in stored_subs.parts.iteritems(): sub_dict = languages if language: key = str(language) if key not in sub_dict: continue sub_dict = {key: sub_dict[key]} for language, subs in sub_dict.iteritems(): if "current" in subs: stored_subs.blacklist(part_id, language, subs["current"]) Log.Info("Added %s to blacklist", subs["current"]) subtitle_storage.save(stored_subs) subtitle_storage.destroy() return RefreshItem(rating_key=rating_key, item_title=item_title, force=True, randomize=timestamp(), timeout=30000)
def BlacklistAllPartsSubtitleMenu(**kwargs): rating_key = kwargs.get("rating_key") language = kwargs.get("language") if language: language = Language.fromietf(language) item = get_item(rating_key) if not item: return item_title = get_item_title(item) subtitle_storage = get_subtitle_storage() stored_subs = subtitle_storage.load_or_new(item) for part_id, languages in stored_subs.parts.iteritems(): sub_dict = languages if language: key = str(language) if key not in sub_dict: continue sub_dict = {key: sub_dict[key]} for language, subs in sub_dict.iteritems(): if "current" in subs: stored_subs.blacklist(part_id, language, subs["current"]) Log.Info("Added %s to blacklist", subs["current"]) subtitle_storage.save(stored_subs) subtitle_storage.destroy() return RefreshItem(rating_key=rating_key, item_title=item_title, force=True, randomize=timestamp(), timeout=30000)
def RecentlyPlayedMenu(): base_title = _("Recently Played") oc = SubFolderObjectContainer(title2=base_title, replace_parent=True) for item in [ get_item(rating_key) for rating_key in Dict["last_played_items"] ]: if not item: continue if getattr(getattr(item, "__class__"), "__name__") not in ("Episode", "Movie"): continue item_title = get_item_title(item) oc.add( DirectoryObject(thumb=get_item_thumb(item) or default_thumb, title=item_title, key=Callback(ItemDetailsMenu, title=base_title + " > " + item.title, item_title=item.title, rating_key=item.rating_key))) return oc
def RecentlyPlayedMenu(): base_title = _("Recently Played") oc = SubFolderObjectContainer(title2=base_title, replace_parent=True) for item in [get_item(rating_key) for rating_key in Dict["last_played_items"]]: if not item: continue if getattr(getattr(item, "__class__"), "__name__") not in ("Episode", "Movie"): continue item_title = get_item_title(item) oc.add(DirectoryObject( thumb=get_item_thumb(item) or default_thumb, title=item_title, key=Callback(ItemDetailsMenu, title=base_title + " > " + item.title, item_title=item.title, rating_key=item.rating_key) )) return oc
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)
def ItemDetailsMenu(rating_key, title=None, base_title=None, item_title=None, randomize=None, header=None): """ displays the item details menu of an item that doesn't contain any deeper tree, such as a movie or an episode :param rating_key: :param title: :param base_title: :param item_title: :param randomize: :return: """ from interface.main import IgnoreMenu title = unicode(base_title) + " > " + unicode(title) if base_title else unicode(title) item = plex_item = get_item(rating_key) current_kind = get_item_kind_from_rating_key(rating_key) timeout = 30 oc = SubFolderObjectContainer(title2=title, replace_parent=True, header=header) if not item: oc.add(DirectoryObject( key=Callback(ItemDetailsMenu, rating_key=rating_key, title=title, base_title=base_title, item_title=item_title, randomize=timestamp()), title=u"Item not found: %s!" % item_title, summary="Plex didn't return any information about the item, please refresh it and come back later", thumb=default_thumb )) return oc # add back to season for episode if current_kind == "episode": from interface.menu import MetadataMenu show = get_item(item.show.rating_key) season = get_item(item.season.rating_key) oc.add(DirectoryObject( key=Callback(MetadataMenu, rating_key=season.rating_key, title=season.title, base_title=show.title, previous_item_type="show", previous_rating_key=show.rating_key, display_items=True, randomize=timestamp()), title=u"< Back to %s" % season.title, summary="Back to %s > %s" % (show.title, season.title), thumb=season.thumb or default_thumb )) oc.add(DirectoryObject( key=Callback(RefreshItem, rating_key=rating_key, item_title=item_title, randomize=timestamp(), timeout=timeout * 1000), title=u"Refresh: %s" % item_title, summary="Refreshes the %s, possibly searching for missing and picking up new subtitles on disk" % current_kind, thumb=item.thumb or default_thumb )) oc.add(DirectoryObject( key=Callback(RefreshItem, rating_key=rating_key, item_title=item_title, force=True, randomize=timestamp(), timeout=timeout * 1000), title=u"Force-find subtitles: %s" % item_title, summary="Issues a forced refresh, ignoring known subtitles and searching for new ones", thumb=item.thumb or default_thumb )) # get stored subtitle info for item id subtitle_storage = get_subtitle_storage() stored_subs = subtitle_storage.load_or_new(item) # look for subtitles for all available media parts and all of their languages has_multiple_parts = len(plex_item.media) > 1 part_index = 0 for media in plex_item.media: for part in media.parts: filename = os.path.basename(part.file) if not os.path.exists(part.file): continue part_id = str(part.id) part_index += 1 part_index_addon = "" part_summary_addon = "" if has_multiple_parts: part_index_addon = u"File %s: " % part_index part_summary_addon = "%s " % filename # iterate through all configured languages for lang in config.lang_list: # get corresponding stored subtitle data for that media part (physical media item), for language current_sub = stored_subs.get_any(part_id, lang) current_sub_id = None current_sub_provider_name = None summary = u"%sNo current subtitle in storage" % part_summary_addon current_score = None if current_sub: current_sub_id = current_sub.id current_sub_provider_name = current_sub.provider_name current_score = current_sub.score summary = u"%sCurrent subtitle: %s (added: %s, %s), Language: %s, Score: %i, Storage: %s" % \ (part_summary_addon, current_sub.provider_name, df(current_sub.date_added), current_sub.mode_verbose, display_language(lang), current_sub.score, current_sub.storage_type) oc.add(DirectoryObject( key=Callback(SubtitleOptionsMenu, rating_key=rating_key, part_id=part_id, title=title, item_title=item_title, language=lang, language_name=display_language(lang), current_id=current_sub_id, item_type=plex_item.type, filename=filename, current_data=summary, randomize=timestamp(), current_provider=current_sub_provider_name, current_score=current_score), title=u"%sManage %s subtitle" % (part_index_addon, display_language(lang)), summary=summary )) else: oc.add(DirectoryObject( key=Callback(ListAvailableSubsForItemMenu, rating_key=rating_key, part_id=part_id, title=title, item_title=item_title, language=lang, language_name=display_language(lang), current_id=current_sub_id, item_type=plex_item.type, filename=filename, current_data=summary, randomize=timestamp(), current_provider=current_sub_provider_name, current_score=current_score), title=u"%sList %s subtitles" % (part_index_addon, display_language(lang)), summary=summary )) if config.plex_transcoder: # embedded subtitles embedded_count = 0 embedded_langs = [] for stream in part.streams: # subtitle stream if stream.stream_type == 3 and not stream.stream_key and stream.codec in TEXT_SUBTITLE_EXTS: lang = get_language_from_stream(stream.language_code) if not lang and config.treat_und_as_first: lang = list(config.lang_list)[0] if lang: embedded_langs.append(lang) embedded_count += 1 if embedded_count: oc.add(DirectoryObject( key=Callback(ListEmbeddedSubsForItemMenu, rating_key=rating_key, part_id=part_id, title=title, item_type=plex_item.type, item_title=item_title, base_title=base_title, randomize=timestamp()), title=u"%sEmbedded subtitles (%s)" % (part_index_addon, ", ".join(display_language(l) for l in set(embedded_langs))), summary=u"Extract and activate embedded subtitle streams" )) ignore_title = item_title if current_kind == "episode": ignore_title = get_item_title(item) add_ignore_options(oc, "videos", title=ignore_title, rating_key=rating_key, callback_menu=IgnoreMenu) subtitle_storage.destroy() return oc
def MetadataMenu(rating_key, title=None, base_title=None, display_items=False, previous_item_type=None, previous_rating_key=None, message=None, header=None, randomize=None): """ displays the contents of a section based on whether it has a deeper tree or not (movies->movie (item) list; series->series list) :param rating_key: :param title: :param base_title: :param display_items: :param previous_item_type: :param previous_rating_key: :return: """ title = unicode(title) item_title = title title = base_title + " > " + title oc = SubFolderObjectContainer(title2=title, no_cache=True, no_history=True, header=header, message=message, view_group="full_details") current_kind = get_item_kind_from_rating_key(rating_key) if display_items: timeout = 30 show = None # add back to series for season if current_kind == "season": timeout = 720 show = get_item(previous_rating_key) oc.add(DirectoryObject( key=Callback(MetadataMenu, rating_key=show.rating_key, title=show.title, base_title=show.section.title, previous_item_type="section", display_items=True, randomize=timestamp()), title=_(u"< Back to %s", show.title), thumb=show.thumb or default_thumb )) elif current_kind == "series": # it shouldn't take more than 6 minutes to scan all of a series' files and determine the force refresh timeout = 3600 items = get_all_items(key="children", value=rating_key, base="library/metadata") kind, deeper = get_items_info(items) dig_tree(oc, items, MetadataMenu, pass_kwargs={"base_title": title, "display_items": deeper, "previous_item_type": kind, "previous_rating_key": rating_key}) # we don't know exactly where we are here, only add ignore option to series if current_kind in ("series", "season"): item = get_item(rating_key) sub_title = get_item_title(item) add_ignore_options(oc, current_kind, title=sub_title, rating_key=rating_key, callback_menu=IgnoreMenu) # mass-extract embedded if current_kind == "season" and config.plex_transcoder: for lang in config.lang_list: oc.add(DirectoryObject( key=Callback(SeasonExtractEmbedded, rating_key=rating_key, language=lang, base_title=show.section.title, display_items=display_items, item_title=item_title, title=title, previous_item_type=previous_item_type, with_mods=True, previous_rating_key=previous_rating_key, randomize=timestamp()), title=_(u"Extract missing %(language)s embedded subtitles", language=display_language(lang)), summary=_("Extracts the not yet extracted embedded subtitles of all episodes for the current " "season with all configured default modifications") )) oc.add(DirectoryObject( key=Callback(SeasonExtractEmbedded, rating_key=rating_key, language=lang, base_title=show.section.title, display_items=display_items, item_title=item_title, title=title, force=True, previous_item_type=previous_item_type, with_mods=True, previous_rating_key=previous_rating_key, randomize=timestamp()), title=_(u"Extract and activate %(language)s embedded subtitles", language=display_language(lang)), summary=_("Extracts embedded subtitles of all episodes for the current season " "with all configured default modifications") )) # add refresh oc.add(DirectoryObject( key=Callback(RefreshItem, rating_key=rating_key, item_title=title, refresh_kind=current_kind, previous_rating_key=previous_rating_key, timeout=timeout * 1000, randomize=timestamp()), title=_(u"Refresh: %s", item_title), summary=_("Refreshes %(the_movie_series_season_episode)s, possibly searching for missing and picking up " "new subtitles on disk", the_movie_series_season_episode=_(u"the %s" % current_kind)) )) oc.add(DirectoryObject( key=Callback(RefreshItem, rating_key=rating_key, item_title=title, force=True, refresh_kind=current_kind, previous_rating_key=previous_rating_key, timeout=timeout * 1000, randomize=timestamp()), title=_(u"Auto-Find subtitles: %s", item_title), summary=_("Issues a forced refresh, ignoring known subtitles and searching for new ones") )) else: return ItemDetailsMenu(rating_key=rating_key, title=title, item_title=item_title) return oc
def ItemDetailsMenu(rating_key, title=None, base_title=None, item_title=None, randomize=None, header=None, message=None): """ displays the item details menu of an item that doesn't contain any deeper tree, such as a movie or an episode :param rating_key: :param title: :param base_title: :param item_title: :param randomize: :return: """ from interface.main import InclExclMenu title = unicode(base_title) + " > " + unicode(title) if base_title else unicode(title) item = plex_item = get_item(rating_key) current_kind = get_item_kind_from_rating_key(rating_key) timeout = 30 oc = SubFolderObjectContainer( title2=title, replace_parent=True, header=header, message=message) if not item: oc.add(DirectoryObject( key=Callback( ItemDetailsMenu, rating_key=rating_key, title=title, base_title=base_title, item_title=item_title, randomize=timestamp()), title=_(u"Item not found: %s!", item_title), summary=_("Plex didn't return any information about the item, please refresh it and come back later"), thumb=default_thumb )) return oc # add back to season for episode if current_kind == "episode": from interface.menu import MetadataMenu show = get_item(item.show.rating_key) season = get_item(item.season.rating_key) oc.add(DirectoryObject( key=Callback( MetadataMenu, rating_key=season.rating_key, title=season.title, base_title=show.title, previous_item_type="show", previous_rating_key=show.rating_key, display_items=True, randomize=timestamp()), title=_(u"< Back to %s", season.title), summary=_("Back to %s > %s", show.title, season.title), thumb=season.thumb or default_thumb )) oc.add(DirectoryObject( key=Callback( RefreshItem, rating_key=rating_key, item_title=item_title, randomize=timestamp(), timeout=timeout * 1000), title=_(u"Refresh: %s", item_title), summary=_("Refreshes %(the_movie_series_season_episode)s, possibly searching for missing and picking up " "new subtitles on disk", the_movie_series_season_episode=_(u"the %s" % current_kind)), thumb=item.thumb or default_thumb )) oc.add(DirectoryObject( key=Callback(RefreshItem, rating_key=rating_key, item_title=item_title, force=True, randomize=timestamp(), timeout=timeout * 1000), title=_(u"Force-find subtitles: %(item_title)s", item_title=item_title), summary=_("Issues a forced refresh, ignoring known subtitles and searching for new ones"), thumb=item.thumb or default_thumb )) # get stored subtitle info for item id subtitle_storage = get_subtitle_storage() stored_subs = subtitle_storage.load_or_new(item) # look for subtitles for all available media parts and all of their languages has_multiple_parts = len(plex_item.media) > 1 part_index = 0 for media in plex_item.media: for part in media.parts: filename = os.path.basename(part.file) if not os.path.exists(part.file): continue part_id = str(part.id) part_index += 1 part_index_addon = u"" part_summary_addon = u"" if has_multiple_parts: part_index_addon = _(u"File %(file_part_index)s: ", file_part_index=part_index) part_summary_addon = u"%s " % filename # iterate through all configured languages for lang in config.lang_list: # get corresponding stored subtitle data for that media part (physical media item), for language current_sub = stored_subs.get_any(part_id, lang) current_sub_id = None current_sub_provider_name = None summary = _(u"%(part_summary)sNo current subtitle in storage", part_summary=part_summary_addon) current_score = None if current_sub: current_sub_id = current_sub.id current_sub_provider_name = current_sub.provider_name current_score = current_sub.score summary = _(u"%(part_summary)sCurrent subtitle: %(provider_name)s (added: %(date_added)s, " u"%(mode)s), Language: %(language)s, Score: %(score)i, Storage: %(storage_type)s", part_summary=part_summary_addon, provider_name=_(current_sub.provider_name), date_added=df(current_sub.date_added), mode=_(current_sub.mode_verbose), language=display_language(lang), score=current_sub.score, storage_type=current_sub.storage_type) oc.add(DirectoryObject( key=Callback(SubtitleOptionsMenu, rating_key=rating_key, part_id=part_id, title=title, item_title=item_title, language=lang, language_name=display_language(lang), current_id=current_sub_id, item_type=plex_item.type, filename=filename, current_data=summary, randomize=timestamp(), current_provider=current_sub_provider_name, current_score=current_score), title=_(u"%(part_summary)sManage %(language)s subtitle", part_summary=part_index_addon, language=display_language(lang)), summary=summary )) else: oc.add(DirectoryObject( key=Callback(ListAvailableSubsForItemMenu, rating_key=rating_key, part_id=part_id, title=title, item_title=item_title, language=lang, language_name=display_language(lang), current_id=current_sub_id, item_type=plex_item.type, filename=filename, current_data=summary, randomize=timestamp(), current_provider=current_sub_provider_name, current_score=current_score), title=_(u"%(part_summary)sList %(language)s subtitles", part_summary=part_index_addon, language=display_language(lang)), summary=summary )) if config.plex_transcoder: # embedded subtitles embedded_count = 0 embedded_langs = [] for stream in part.streams: # subtitle stream if stream.stream_type == 3 and not stream.stream_key and stream.codec in TEXT_SUBTITLE_EXTS: lang = get_language_from_stream(stream.language_code) is_forced = is_stream_forced(stream) if not lang and config.treat_und_as_first: lang = list(config.lang_list)[0] if lang: lang = Language.rebuild(lang, forced=is_forced) embedded_langs.append(lang) embedded_count += 1 if embedded_count: oc.add(DirectoryObject( key=Callback(ListEmbeddedSubsForItemMenu, rating_key=rating_key, part_id=part_id, title=title, item_type=plex_item.type, item_title=item_title, base_title=base_title, randomize=timestamp()), title=_(u"%(part_summary)sEmbedded subtitles (%(languages)s)", part_summary=part_index_addon, languages=", ".join(display_language(l) for l in list(OrderedDict.fromkeys(embedded_langs)))), summary=_(u"Extract embedded subtitle streams") )) ignore_title = item_title if current_kind == "episode": ignore_title = get_item_title(item) add_incl_excl_options(oc, "videos", title=ignore_title, rating_key=rating_key, callback_menu=InclExclMenu) subtitle_storage.destroy() return oc
def MetadataMenu(rating_key, title=None, base_title=None, display_items=False, previous_item_type=None, previous_rating_key=None, message=None, header=None, randomize=None): """ displays the contents of a section based on whether it has a deeper tree or not (movies->movie (item) list; series->series list) :param rating_key: :param title: :param base_title: :param display_items: :param previous_item_type: :param previous_rating_key: :return: """ title = unicode(title) item_title = title title = base_title + " > " + title oc = SubFolderObjectContainer(title2=title, no_cache=True, no_history=True, header=header, message=message, view_group="full_details") current_kind = get_item_kind_from_rating_key(rating_key) if display_items: timeout = 30 show = None # add back to series for season if current_kind == "season": timeout = 720 show = get_item(previous_rating_key) oc.add(DirectoryObject( key=Callback(MetadataMenu, rating_key=show.rating_key, title=show.title, base_title=show.section.title, previous_item_type="section", display_items=True, randomize=timestamp()), title=_(u"< Back to %s", show.title), thumb=show.thumb or default_thumb )) elif current_kind == "series": # it shouldn't take more than 6 minutes to scan all of a series' files and determine the force refresh timeout = 3600 items = get_all_items(key="children", value=rating_key, base="library/metadata") kind, deeper = get_items_info(items) dig_tree(oc, items, MetadataMenu, pass_kwargs={"base_title": title, "display_items": deeper, "previous_item_type": kind, "previous_rating_key": rating_key}) # we don't know exactly where we are here, only add ignore option to series if current_kind in ("series", "season"): item = get_item(rating_key) sub_title = get_item_title(item) add_incl_excl_options(oc, current_kind, title=sub_title, rating_key=rating_key, callback_menu=InclExclMenu) # mass-extract embedded if current_kind == "season" and config.plex_transcoder: for lang in config.lang_list: oc.add(DirectoryObject( key=Callback(SeasonExtractEmbedded, rating_key=rating_key, language=lang, base_title=show.section.title, display_items=display_items, item_title=item_title, title=title, previous_item_type=previous_item_type, with_mods=True, previous_rating_key=previous_rating_key, randomize=timestamp()), title=_(u"Extract missing %(language)s embedded subtitles", language=display_language(lang)), summary=_("Extracts the not yet extracted embedded subtitles of all episodes for the current " "season with all configured default modifications") )) oc.add(DirectoryObject( key=Callback(SeasonExtractEmbedded, rating_key=rating_key, language=lang, base_title=show.section.title, display_items=display_items, item_title=item_title, title=title, force=True, previous_item_type=previous_item_type, with_mods=True, previous_rating_key=previous_rating_key, randomize=timestamp()), title=_(u"Extract and activate %(language)s embedded subtitles", language=display_language(lang)), summary=_("Extracts embedded subtitles of all episodes for the current season " "with all configured default modifications") )) # add refresh oc.add(DirectoryObject( key=Callback(RefreshItem, rating_key=rating_key, item_title=title, refresh_kind=current_kind, previous_rating_key=previous_rating_key, timeout=timeout * 1000, randomize=timestamp()), title=_(u"Refresh: %s", item_title), summary=_("Refreshes %(the_movie_series_season_episode)s, possibly searching for missing and picking up " "new subtitles on disk", the_movie_series_season_episode=_(u"the %s" % current_kind)) )) oc.add(DirectoryObject( key=Callback(RefreshItem, rating_key=rating_key, item_title=title, force=True, refresh_kind=current_kind, previous_rating_key=previous_rating_key, timeout=timeout * 1000, randomize=timestamp()), title=_(u"Auto-Find subtitles: %s", item_title), summary=_("Issues a forced refresh, ignoring known subtitles and searching for new ones") )) else: return ItemDetailsMenu(rating_key=rating_key, title=title, item_title=item_title) return oc