def SubtitleShiftModMenu(unit=None, **kwargs): if unit not in POSSIBLE_UNITS_D: raise NotImplementedError kwargs.pop("randomize") oc = SubFolderObjectContainer(title2=kwargs["title"], replace_parent=True) oc.add(DirectoryObject( key=Callback(SubtitleShiftModUnitMenu, randomize=timestamp(), **kwargs), title=_("< Back to unit selection") )) rng = [] if unit == "h": rng = list(reversed(range(-10, 0))) + list(reversed(range(1, 11))) elif unit in ("m", "s"): rng = list(reversed(range(-15, 0))) + list(reversed(range(1, 16))) elif unit == "ms": rng = list(reversed(range(-900, 0, 100))) + list(reversed(range(100, 1000, 100))) for i in rng: if i == 0: continue mod_ident = SubtitleModifications.get_mod_signature("shift_offset", **{unit: i}) oc.add(DirectoryObject( key=Callback(SubtitleSetMods, mods=mod_ident, mode="add", randomize=timestamp(), **kwargs), title="%s %s" % (("%s" if i < 0 else "+%s") % i, unit) )) return oc
def PinMenu(pin="", randomize=None, success_go_to="channel"): oc = ObjectContainer( title2=_("Enter PIN number ") + str(len(pin) + 1), no_cache=True, no_history=True, skip_pin_lock=True) if pin == config.pin: Dict["pin_correct_time"] = datetime.datetime.now() config.locked = False if success_go_to == "channel": return fatality( force_title=_("PIN correct"), header=_("PIN correct"), no_history=True) elif success_go_to == "advanced": return AdvancedMenu(randomize=timestamp()) for i in range(10): oc.add(DirectoryObject( key=Callback( PinMenu, randomize=timestamp(), pin=pin + str(i), success_go_to=success_go_to), title=pad_title(str(i)), )) oc.add(DirectoryObject( key=Callback( PinMenu, randomize=timestamp(), success_go_to=success_go_to), title=pad_title(_("Reset")), )) return oc
def AdvancedMenu(randomize=None, header=None, message=None): oc = ObjectContainer(header=header or "Internal stuff, pay attention!", message=message, no_cache=True, no_history=True, title2="Advanced") oc.add(DirectoryObject( key=Callback(TriggerRestart), title=pad_title("Restart the plugin") )) oc.add(DirectoryObject( key=Callback(RefreshToken, randomize=timestamp()), title=pad_title("Re-request the API token from plex.tv") )) oc.add(DirectoryObject( key=Callback(LogStorage, key="tasks", randomize=timestamp()), title=pad_title("Log the plugin's scheduled tasks state storage") )) oc.add(DirectoryObject( key=Callback(LogStorage, key="subs", randomize=timestamp()), title=pad_title("Log the plugin's internal subtitle information storage") )) oc.add(DirectoryObject( key=Callback(ResetStorage, key="tasks", randomize=timestamp()), title=pad_title("Reset the plugin's scheduled tasks state storage") )) oc.add(DirectoryObject( key=Callback(ResetStorage, key="subs", randomize=timestamp()), title=pad_title("Reset the plugin's internal subtitle information storage") )) return oc
def ResetStorage(key, randomize=None, sure=False): if not sure: oc = SubFolderObjectContainer( no_history=True, title1=_("Reset subtitle storage"), title2=_("Are you sure?")) oc.add(DirectoryObject( key=Callback( ResetStorage, key=key, sure=True, randomize=timestamp()), title=pad_title(_("Are you really sure?")), )) return oc reset_storage(key) if key == "tasks": # reinitialize the scheduler scheduler.init_storage() scheduler.setup_tasks() return AdvancedMenu( randomize=timestamp(), header=_("Success"), message=_("Information Storage (%s) reset", key) )
def fatality(randomize=None, header=None, message=None, only_refresh=False): """ subzero main menu """ oc = ObjectContainer(header=header, message=message, no_cache=True, no_history=True) if not config.plex_api_working: oc.add(DirectoryObject( key=Callback(fatality, randomize=timestamp()), title=pad_title("PMS API ERROR"), summary=lib_unaccessible_error )) return oc if not only_refresh: oc.add(DirectoryObject( key=Callback(OnDeckMenu), title=pad_title("Subtitles for 'On Deck' items"), summary="Shows the current on deck items and allows you to individually (force-) refresh their metadata/subtitles." )) oc.add(DirectoryObject( key=Callback(RecentlyAddedMenu), title="Subtitles for 'Recently Added' items (max-age: %s)" % Prefs["scheduler.item_is_recent_age"], summary="Shows the recently added items, honoring the configured 'Item age to be considered recent'-setting (%s) and allowing you to individually (force-) refresh their metadata/subtitles." % Prefs["scheduler.item_is_recent_age"] )) task_name = "searchAllRecentlyAddedMissing" task = scheduler.task(task_name) if task.ready_for_display: task_state = "Running: %s/%s (%s%%)" % (len(task.items_done), len(task.items_searching), task.percentage) else: task_state = "Last scheduler run: %s; Next scheduled run: %s; Last runtime: %s" % (scheduler.last_run(task_name) or "never", scheduler.next_run(task_name) or "never", str(task.last_run_time).split(".")[0]) oc.add(DirectoryObject( key=Callback(RefreshMissing, randomize=timestamp()), title="Search for missing subtitles (in recently-added items, max-age: %s)" % Prefs["scheduler.item_is_recent_age"], summary="Automatically run periodically by the scheduler, if configured. %s" % task_state )) oc.add(DirectoryObject( key=Callback(fatality, randomize=timestamp()), title=pad_title("Refresh"), summary="Refreshes the current view" )) if not only_refresh: oc.add(DirectoryObject( key=Callback(AdvancedMenu, randomize=timestamp()), title=pad_title("Advanced functions"), summary="Use at your own risk" )) return oc
def ListEmbeddedSubsForItemMenu(**kwargs): rating_key = kwargs["rating_key"] part_id = kwargs["part_id"] title = kwargs["title"] kwargs.pop("randomize") oc = SubFolderObjectContainer(title2=title, replace_parent=True) oc.add(DirectoryObject( key=Callback(ItemDetailsMenu, rating_key=kwargs["rating_key"], item_title=kwargs["item_title"], base_title=kwargs["base_title"], title=kwargs["item_title"], randomize=timestamp()), title=_("< Back to %s", kwargs["title"]), thumb=default_thumb )) plex_item = get_item(rating_key) part = get_part(plex_item, part_id) if part: for stream_data in get_embedded_subtitle_streams(part, skip_duplicate_unknown=False): language = stream_data["language"] is_unknown = stream_data["is_unknown"] stream = stream_data["stream"] is_forced = stream_data["is_forced"] if language: oc.add(DirectoryObject( key=Callback(TriggerExtractEmbeddedSubForItemMenu, randomize=timestamp(), stream_index=str(stream.index), language=language, with_mods=True, **kwargs), title=_(u"Extract stream %(stream_index)s, %(language)s%(unknown_state)s%(forced_state)s" u"%(stream_title)s with default mods", stream_index=stream.index, language=display_language(language), unknown_state=_(" (unknown)") if is_unknown else "", forced_state=_(" (forced)") if is_forced else "", stream_title=" (\"%s\")" % stream.title if stream.title else ""), )) oc.add(DirectoryObject( key=Callback(TriggerExtractEmbeddedSubForItemMenu, randomize=timestamp(), stream_index=str(stream.index), language=language, **kwargs), title=_(u"Extract stream %(stream_index)s, %(language)s%(unknown_state)s%(forced_state)s" u"%(stream_title)s", stream_index=stream.index, language=display_language(language), unknown_state=_(" (unknown)") if is_unknown else "", forced_state=_(" (forced)") if is_forced else "", stream_title=" (\"%s\")" % stream.title if stream.title else ""), )) return oc
def ResetStorage(key, randomize=None, sure=False): if not sure: oc = ObjectContainer(no_history=True, title1="Reset subtitle storage", title2="Are you sure?") oc.add(DirectoryObject( key=Callback(ResetStorage, key=key, sure=True, randomize=timestamp()), title=pad_title("Are you really sure?") )) return oc resetStorage(key) return AdvancedMenu( randomize=timestamp(), header='Success', message='Subtitle Information Storage reset' )
def TriggerCacheMaintenance(randomize=None): scheduler.dispatch_task("CacheMaintenance") return AdvancedMenu( randomize=timestamp(), header=_("Success"), message=_("TriggerCacheMaintenance triggered") )
def TriggerStorageMigration(randomize=None): scheduler.dispatch_task("MigrateSubtitleStorage") return AdvancedMenu( randomize=timestamp(), header=_("Success"), message=_("MigrateSubtitleStorage triggered") )
def TriggerBetterSubtitles(randomize=None): scheduler.dispatch_task("FindBetterSubtitles") return AdvancedMenu( randomize=timestamp(), header=_("Success"), message=_("FindBetterSubtitles triggered") )
def LogStorage(key, randomize=None): log_storage(key) return AdvancedMenu( randomize=timestamp(), header=_("Success"), message=_("Information Storage (%s) logged", key) )
def LogStorage(key, randomize=None): log_storage(key) return AdvancedMenu( randomize=timestamp(), header='Success', message='Information Storage (%s) logged' % key )
def SelectStoredSubForItemMenu(**kwargs): rating_key = kwargs["rating_key"] part_id = kwargs["part_id"] language = Language.fromietf(kwargs["language"]) item_type = kwargs["item_type"] sub_key = tuple(kwargs.pop("sub_key").split("__")) plex_item = get_item(rating_key) storage = get_subtitle_storage() stored_subs = storage.load(plex_item.rating_key) subtitles = stored_subs.get_all(part_id, language) subtitle = subtitles[sub_key] save_stored_sub(subtitle, rating_key, part_id, language, item_type, plex_item=plex_item, storage=storage, stored_subs=stored_subs) stored_subs.set_current(part_id, language, sub_key) storage.save(stored_subs) storage.destroy() kwa = { "header": _("Success"), "message": _("Subtitle saved to disk"), "title": kwargs["title"], "item_title": kwargs["item_title"], "base_title": kwargs.get("base_title") } # fixme: return to SubtitleOptionsMenu properly? (needs recomputation of current_data return ItemDetailsMenu(rating_key, randomize=timestamp(), **kwa)
def ReApplyMods(randomize=None): Thread.CreateTimer(1.0, apply_default_mods, reapply_current=True) return AdvancedMenu( randomize=timestamp(), header=_("Success"), message=_("This may take some time ...") )
def ResetProviderThrottle(randomize=None): Dict["provider_throttle"] = {} Dict.Save() return AdvancedMenu( randomize=timestamp(), header=_("Success"), message=_("Provider throttles reset") )
def SubtitleShiftModUnitMenu(**kwargs): oc = SubFolderObjectContainer(title2=kwargs["title"], replace_parent=True) kwargs.pop("randomize") oc.add(DirectoryObject( key=Callback(SubtitleModificationsMenu, randomize=timestamp(), **kwargs), title=_("< Back to subtitle modifications") )) for unit, title in POSSIBLE_UNITS: oc.add(DirectoryObject( key=Callback(SubtitleShiftModMenu, unit=unit, randomize=timestamp(), **kwargs), title=_("Adjust by %(time_and_unit)s", time_and_unit=title) )) return oc
def AdvancedMenu(randomize=None, header=None, message=None): oc = ObjectContainer(header=header or "Internal stuff, pay attention!", message=message, no_cache=True, no_history=True, replace_parent=True, title2="Advanced") oc.add(DirectoryObject( key=Callback(TriggerRestart, randomize=timestamp()), title=pad_title("Restart the plugin"), )) oc.add(DirectoryObject( key=Callback(LogStorage, key="tasks", randomize=timestamp()), title=pad_title("Log the plugin's scheduled tasks state storage"), )) oc.add(DirectoryObject( key=Callback(LogStorage, key="subs", randomize=timestamp()), title=pad_title("Log the plugin's internal subtitle information storage"), )) oc.add(DirectoryObject( key=Callback(LogStorage, key="ignore", randomize=timestamp()), title=pad_title("Log the plugin's internal ignorelist storage"), )) oc.add(DirectoryObject( key=Callback(ResetStorage, key="tasks", randomize=timestamp()), title=pad_title("Reset the plugin's scheduled tasks state storage"), )) oc.add(DirectoryObject( key=Callback(ResetStorage, key="subs", randomize=timestamp()), title=pad_title("Reset the plugin's internal subtitle information storage"), )) oc.add(DirectoryObject( key=Callback(ResetStorage, key="ignore", randomize=timestamp()), title=pad_title("Reset the plugin's internal ignorelist storage"), )) return oc
def RefreshItem(rating_key=None, came_from="/recent", item_title=None, force=False): assert rating_key set_refresh_menu_state("Triggering %sRefresh for %s" % ("Force-" if force else "", item_title)) Thread.Create(refreshItem, rating_key=rating_key, force=force) return fatality( randomize=timestamp(), header="%s of item %s triggered" % ("Refresh" if not force else "Forced-refresh", rating_key), replace_parent=True, )
def RefreshItem(rating_key=None, came_from="/recent", item_title=None, force=False, refresh_kind=None, previous_rating_key=None, timeout=8000, randomize=None, trigger=True): assert rating_key header = " " if trigger: set_refresh_menu_state(u"Triggering %sRefresh for %s" % ("Force-" if force else "", item_title)) Thread.Create(refresh_item, rating_key=rating_key, force=force, refresh_kind=refresh_kind, parent_rating_key=previous_rating_key, timeout=int(timeout)) header = u"%s of item %s triggered" % ("Refresh" if not force else "Forced-refresh", rating_key) return fatality(randomize=timestamp(), header=header, replace_parent=True)
def SkipFindBetterSubtitles(randomize=None): task = scheduler.task("FindBetterSubtitles") task.last_run = datetime.datetime.now() return AdvancedMenu( randomize=timestamp(), header=_("Success"), message=_("FindBetterSubtitles skipped") )
def SkipRecentlyAddedMissing(randomize=None): task = scheduler.task("SearchAllRecentlyAddedMissing") task.last_run = datetime.datetime.now() return AdvancedMenu( randomize=timestamp(), header=_("Success"), message=_("SearchAllRecentlyAddedMissing skipped") )
def TriggerRestart(randomize=None): set_refresh_menu_state(_("Restarting the plugin")) DispatchRestart() return fatality( header=_("Restart triggered, please wait about 5 seconds"), force_title=" ", only_refresh=True, replace_parent=True, no_history=True, randomize=timestamp())
def SubtitleColorModMenu(**kwargs): kwargs.pop("randomize") color_mod = SubtitleModifications.get_mod_class("color") oc = SubFolderObjectContainer(title2=kwargs["title"], replace_parent=True) oc.add(DirectoryObject( key=Callback(SubtitleModificationsMenu, randomize=timestamp(), **kwargs), title=_("< Back to subtitle modification menu") )) for color, code in color_mod.colors.iteritems(): mod_ident = SubtitleModifications.get_mod_signature("color", **{"name": color}) oc.add(DirectoryObject( key=Callback(SubtitleSetMods, mods=mod_ident, mode="add", randomize=timestamp(), **kwargs), title="%s (%s)" % (color, code) )) return oc
def InvalidateCache(randomize=None): from subliminal.cache import region if config.new_style_cache: region.backend.clear() else: region.invalidate() return AdvancedMenu( randomize=timestamp(), header=_("Success"), message=_("Cache invalidated") )
def SubtitleReapplyMods(**kwargs): rating_key = kwargs["rating_key"] part_id = kwargs["part_id"] lang_a2 = kwargs["language"] item_type = kwargs["item_type"] language = Language.fromietf(lang_a2) set_mods_for_part(rating_key, part_id, language, item_type, [], mode="add") kwargs.pop("randomize") return SubtitleModificationsMenu(randomize=timestamp(), **kwargs)
def __init__(self, *args, **kwargs): super(SubFolderObjectContainer, self).__init__(*args, **kwargs) from interface.menu import fatality from support.helpers import pad_title, timestamp self.add(DirectoryObject( key=Callback(fatality, force_title=" ", randomize=timestamp()), title=pad_title(_("<< Back to home")), summary=_("Current state: %s; Last state: %s", (Dict["current_refresh_state"] or _("Idle")) if "current_refresh_state" in Dict else _("Idle"), (Dict["last_refresh_state"] or _("None")) if "last_refresh_state" in Dict else _("None") ) ))
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], ignore_all=True, skip_hashing=True) video, plex_part = scanned_parts.items()[0] target_fps = plex_part.fps for fps in ["23.980", "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=_("%(from_fps)s fps -> %(to_fps)s fps (%(slower_or_faster_indicator)s)", from_fps=fps, to_fps=target_fps, slower_or_faster_indicator=indicator) )) return oc
def ManageBlacklistMenu(**kwargs): oc = SubFolderObjectContainer(title2=unicode(kwargs["title"]), replace_parent=True) rating_key = kwargs["rating_key"] part_id = kwargs["part_id"] language = kwargs["language"] remove_sub_key = kwargs.pop("remove_sub_key", None) current_data = unicode(kwargs["current_data"]) current_sub, stored_subs, storage = get_current_sub(rating_key, part_id, language) current_bl, subs = stored_subs.get_blacklist(part_id, language) if remove_sub_key: remove_sub_key = tuple(remove_sub_key.split("__")) stored_subs.blacklist(part_id, language, remove_sub_key, add=False) storage.save(stored_subs) Log.Info("Removed %s from blacklist", remove_sub_key) kwargs.pop("randomize") oc.add(DirectoryObject( key=Callback(ItemDetailsMenu, rating_key=kwargs["rating_key"], item_title=kwargs["item_title"], title=kwargs["title"], randomize=timestamp()), title=_(u"< Back to %s", kwargs["title"]), summary=current_data, thumb=default_thumb )) def sorter(pair): # thanks RestrictedModule parser for messing with lambda (x, y) return pair[1]["date_added"] for sub_key, data in sorted(current_bl.iteritems(), key=sorter, reverse=True): provider_name, subtitle_id = sub_key title = _(u"%(provider_name)s, %(subtitle_id)s (added: %(date_added)s, %(mode)s), Language: %(language)s, " u"Score: %(score)i, Storage: %(storage_type)s", provider_name=_(provider_name), subtitle_id=subtitle_id, date_added=df(data["date_added"]), mode=_(current_sub.get_mode_verbose(data["mode"])), language=display_language(Language.fromietf(language)), score=data["score"], storage_type=data["storage_type"]) oc.add(DirectoryObject( key=Callback(ManageBlacklistMenu, remove_sub_key="__".join(sub_key), randomize=timestamp(), **kwargs), title=title, summary=_(u"Remove subtitle from blacklist") )) storage.destroy() return oc
def SubtitleOptionsMenu(**kwargs): oc = SubFolderObjectContainer(title2=unicode(kwargs["title"]), replace_parent=True, header=kwargs.get("header"), message=kwargs.get("message")) rating_key = kwargs["rating_key"] part_id = kwargs["part_id"] language = kwargs["language"] current_data = unicode(kwargs["current_data"]) current_sub, stored_subs, storage = get_current_sub(rating_key, part_id, language) subs_count = stored_subs.count(part_id, language) kwargs.pop("randomize") oc.add(DirectoryObject( key=Callback(ItemDetailsMenu, rating_key=kwargs["rating_key"], item_title=kwargs["item_title"], title=kwargs["title"], randomize=timestamp()), title=_(u"< Back to %s", kwargs["title"]), summary=current_data, thumb=default_thumb )) if subs_count: oc.add(DirectoryObject( key=Callback(ListStoredSubsForItemMenu, randomize=timestamp(), **kwargs), title=_(u"Select active %(language)s subtitle", language=kwargs["language_name"]), summary=_(u"%(count)d subtitles in storage", count=subs_count) )) oc.add(DirectoryObject( key=Callback(ListAvailableSubsForItemMenu, randomize=timestamp(), **kwargs), title=_(u"List available %(language)s subtitles", language=kwargs["language_name"]), summary=current_data )) if current_sub: oc.add(DirectoryObject( key=Callback(SubtitleModificationsMenu, randomize=timestamp(), **kwargs), title=_(u"Modify current %(language)s subtitle", language=kwargs["language_name"]), summary=_(u"Currently applied mods: %(mod_list)s", mod_list=(", ".join(current_sub.mods) if current_sub.mods else "none")) )) if current_sub.provider_name != "embedded": oc.add(DirectoryObject( key=Callback(BlacklistSubtitleMenu, randomize=timestamp(), **kwargs), title=_(u"Blacklist current %(language)s subtitle and search for a new one", language=kwargs["language_name"]), summary=current_data )) current_bl, subs = stored_subs.get_blacklist(part_id, language) if current_bl: oc.add(DirectoryObject( key=Callback(ManageBlacklistMenu, randomize=timestamp(), **kwargs), title=_(u"Manage blacklist (%(amount)s contained)", amount=len(current_bl)), summary=_(u"Inspect currently blacklisted subtitles") )) storage.destroy() return oc
def RecentMissingSubtitlesMenu(force=False, randomize=None): title = _("Items with missing subtitles") oc = SubFolderObjectContainer(title2=title, no_cache=True, no_history=True) running = scheduler.is_task_running("MissingSubtitles") task_data = scheduler.get_task_data("MissingSubtitles") missing_items = task_data["missing_subtitles"] if task_data else None if ((missing_items is None) or force) and not running: scheduler.dispatch_task("MissingSubtitles") running = True if not running: oc.add(DirectoryObject( key=Callback(RecentMissingSubtitlesMenu, force=True, randomize=timestamp()), title=_(u"Find recent items with missing subtitles"), thumb=default_thumb )) else: oc.add(DirectoryObject( key=Callback(RecentMissingSubtitlesMenu, force=False, randomize=timestamp()), title=_(u"Updating, refresh here ..."), thumb=default_thumb )) if missing_items is not None: for added_at, item_id, item_title, item, missing_languages in missing_items: oc.add(DirectoryObject( key=Callback(ItemDetailsMenu, title=title + " > " + item_title, item_title=item_title, rating_key=item_id), title=item_title, summary=_("Missing: %s", ", ".join(display_language(l) for l in missing_languages)), thumb=get_item_thumb(item) or default_thumb )) return oc
def SubtitleModificationsMenu(**kwargs): rating_key = kwargs["rating_key"] part_id = kwargs["part_id"] language = kwargs["language"] current_sub, stored_subs, storage = get_current_sub( rating_key, part_id, language) kwargs.pop("randomize") current_mods = current_sub.mods or [] oc = SubFolderObjectContainer(title2=kwargs["title"], replace_parent=True) from interface.item_details import SubtitleOptionsMenu oc.add( DirectoryObject(key=Callback(SubtitleOptionsMenu, randomize=timestamp(), **kwargs), title=u"< Back to subtitle options for: %s" % kwargs["title"], summary=kwargs["current_data"], thumb=default_thumb)) for identifier, mod in mod_registry.mods.iteritems(): if mod.advanced: continue if mod.exclusive and identifier in current_mods: continue oc.add( DirectoryObject(key=Callback(SubtitleSetMods, mods=identifier, mode="add", randomize=timestamp(), **kwargs), title=pad_title(mod.description), summary=mod.long_description or "")) fps_mod = SubtitleModifications.get_mod_class("change_FPS") oc.add( DirectoryObject(key=Callback(SubtitleFPSModMenu, randomize=timestamp(), **kwargs), title=pad_title(fps_mod.description), summary=fps_mod.long_description or "")) shift_mod = SubtitleModifications.get_mod_class("shift_offset") oc.add( DirectoryObject(key=Callback(SubtitleShiftModUnitMenu, randomize=timestamp(), **kwargs), title=pad_title(shift_mod.description), summary=shift_mod.long_description or "")) color_mod = SubtitleModifications.get_mod_class("color") oc.add( DirectoryObject(key=Callback(SubtitleColorModMenu, randomize=timestamp(), **kwargs), title=pad_title(color_mod.description), summary=color_mod.long_description or "")) if current_mods: oc.add( DirectoryObject( key=Callback(SubtitleSetMods, mods=None, mode="remove_last", randomize=timestamp(), **kwargs), title=pad_title("Remove last applied mod (%s)" % current_mods[-1]), summary=u"Currently applied mods: %s" % (", ".join(current_mods) if current_mods else "none"))) oc.add( DirectoryObject(key=Callback(SubtitleListMods, randomize=timestamp(), **kwargs), title=pad_title("Manage applied mods"), summary=u"Currently applied mods: %s" % (", ".join(current_mods)))) oc.add( DirectoryObject(key=Callback(SubtitleSetMods, mods=None, mode="clear", randomize=timestamp(), **kwargs), title=pad_title("Restore original version"), summary=u"Currently applied mods: %s" % (", ".join(current_mods) if current_mods else "none"))) 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 %s embedded subtitles" % 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 %s embedded subtitles" % 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 %s, possibly searching for missing and picking up new subtitles on disk" % 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 fatality(randomize=None, force_title=None, header=None, message=None, only_refresh=False, no_history=False, replace_parent=False): """ subzero main menu """ from interface.advanced import PinMenu, ClearPin, AdvancedMenu from interface.menu import RefreshMissing, IgnoreListMenu, HistoryMenu title = config.full_version # force_title if force_title is not None else config.full_version oc = ObjectContainer(title1=title, title2=title, header=unicode(header) if header else title, message=message, no_history=no_history, replace_parent=replace_parent, no_cache=True) # always re-check permissions config.refresh_permissions_status() # always re-check enabled sections config.refresh_enabled_sections() if config.lock_menu and not config.pin_correct: oc.add( DirectoryObject( key=Callback(PinMenu, randomize=timestamp()), title=pad_title(_("Enter PIN")), summary= _("The owner has restricted the access to this menu. Please enter the correct pin" ), )) return oc if not config.permissions_ok and config.missing_permissions: if not isinstance(config.missing_permissions, list): oc.add( DirectoryObject( key=Callback(fatality, randomize=timestamp()), title=pad_title(_("Insufficient permissions")), summary=config.missing_permissions, )) else: for title, path in config.missing_permissions: oc.add( DirectoryObject( key=Callback(fatality, randomize=timestamp()), title=pad_title(_("Insufficient permissions")), summary= _("Insufficient permissions on library %(title)s, folder: %(path)s", title=title, path=path), )) return oc if not config.enabled_sections: oc.add( DirectoryObject( key=Callback(fatality, randomize=timestamp()), title=pad_title(_("I'm not enabled!")), summary= _("Please enable me for some of your libraries in your server settings; currently I do nothing" ), )) return oc if not only_refresh: if Dict["current_refresh_state"]: oc.add( DirectoryObject( key=Callback(fatality, force_title=" ", randomize=timestamp()), title=pad_title(_("Working ... refresh here")), summary=_("Current state: %s; Last state: %s", (Dict["current_refresh_state"] or _("Idle")) if "current_refresh_state" in Dict else _("Idle"), (Dict["last_refresh_state"] or _("None")) if "last_refresh_state" in Dict else _("None")))) oc.add( DirectoryObject( key=Callback(OnDeckMenu), title=_("On-deck items"), summary= _("Shows the current on deck items and allows you to individually (force-) refresh their metadata/subtitles." ), thumb=R("icon-ondeck.jpg"))) if "last_played_items" in Dict and Dict["last_played_items"]: oc.add( DirectoryObject( key=Callback(RecentlyPlayedMenu), title=pad_title(_("Recently played items")), summary=_( "Shows the %s recently played items and allows you to individually (force-) refresh their metadata/subtitles.", config.store_recently_played_amount), thumb=R("icon-played.jpg"))) oc.add( DirectoryObject( key=Callback(RecentlyAddedMenu), title=_("Recently-added items"), summary=_("Shows the recently added items per section."), thumb=R("icon-added.jpg"))) oc.add( DirectoryObject( key=Callback(RecentMissingSubtitlesMenu, randomize=timestamp()), title=_("Show recently added items with missing subtitles"), summary= _("Lists items with missing subtitles. Click on Find recent items with missing subs to update list" ), thumb=R("icon-missing.jpg"))) oc.add( DirectoryObject( key=Callback(SectionsMenu), title=_("Browse all items"), summary= _("Go through your whole library and manage your ignore list. You can also (force-) refresh the metadata/subtitles of individual items." ), thumb=R("icon-browse.jpg"))) task_name = "SearchAllRecentlyAddedMissing" task = scheduler.task(task_name) if task.ready_for_display: task_state = _( "Running: %(items_done)s/%(items_searching)s (%(percentage)s%%)", items_done=task.items_done, items_searching=task.items_searching, percentage=task.percentage) else: lr = scheduler.last_run(task_name) nr = scheduler.next_run(task_name) task_state = _( "Last run: %s; Next scheduled run: %s; Last runtime: %s", df(scheduler.last_run(task_name)) if lr else "never", df(scheduler.next_run(task_name)) if nr else "never", str(task.last_run_time).split(".")[0]) oc.add( DirectoryObject( key=Callback(RefreshMissing, randomize=timestamp()), title=_( "Search for missing subtitles (in recently-added items, max-age: %s)", Prefs["scheduler.item_is_recent_age"]), summary=_( "Automatically run periodically by the scheduler, if configured. %s", task_state), thumb=R("icon-search.jpg"))) oc.add( DirectoryObject( key=Callback(IgnoreListMenu), title=_("Display ignore list (%(ignored_count)d)", ignored_count=len(ignore_list)), summary= _("Show the current ignore list (mainly used for the automatic tasks)" ), thumb=R("icon-ignore.jpg"))) oc.add( DirectoryObject(key=Callback(HistoryMenu), title=_("History"), summary=_("Show the last %i downloaded subtitles", int(Prefs["history_size"])), thumb=R("icon-history.jpg"))) oc.add( DirectoryObject( key=Callback(fatality, force_title=" ", randomize=timestamp()), title=pad_title(_("Refresh")), summary=_("Current state: %s; Last state: %s", (Dict["current_refresh_state"] or _("Idle")) if "current_refresh_state" in Dict else _("Idle"), (Dict["last_refresh_state"] or _("None")) if "last_refresh_state" in Dict else _("None")), thumb=R("icon-refresh.jpg"))) # add re-lock after pin unlock if config.pin: oc.add( DirectoryObject(key=Callback(ClearPin, randomize=timestamp()), title=pad_title(_("Re-lock menu(s)")), summary=_("Enabled the PIN again for menu(s)"))) if not only_refresh: if "provider_throttle" in Dict and Dict["provider_throttle"].keys(): summary_data = [] for provider, data in Dict["provider_throttle"].iteritems(): reason, until, desc = data summary_data.append( unicode( _("%(throttled_provider)s until %(until_date)s (%(reason)s)", throttled_provider=provider, until_date=until.strftime("%y/%m/%d %H:%M"), reason=reason))) oc.add( DirectoryObject( key=Callback(fatality, force_title=" ", randomize=timestamp()), title=pad_title( _("Throttled providers: %s", ", ".join(Dict["provider_throttle"].keys()))), summary=", ".join(summary_data), thumb=R("icon-throttled.jpg"))) oc.add( DirectoryObject(key=Callback(AdvancedMenu), title=pad_title(_("Advanced functions")), summary=_("Use at your own risk"), thumb=R("icon-advanced.jpg"))) return oc
def TriggerStorageMaintenance(randomize=None): scheduler.dispatch_task("SubtitleStorageMaintenance") return AdvancedMenu(randomize=timestamp(), header='Success', message='SubtitleStorageMaintenance triggered')
def AdvancedMenu(randomize=None, header=None, message=None): oc = SubFolderObjectContainer(header=header or "Internal stuff, pay attention!", message=message, no_cache=True, no_history=True, replace_parent=False, title2="Advanced") if config.lock_advanced_menu and not config.pin_correct: oc.add( DirectoryObject( key=Callback(PinMenu, randomize=timestamp(), success_go_to="advanced"), title=pad_title("Enter PIN"), summary= "The owner has restricted the access to this menu. Please enter the correct pin", )) return oc oc.add( DirectoryObject( key=Callback(TriggerRestart, randomize=timestamp()), title=pad_title("Restart the plugin"), )) oc.add( DirectoryObject( key=Callback(GetLogsLink), title= "Get my logs (copy the appearing link and open it in your browser, please)", summary= "Copy the appearing link and open it in your browser, please", )) oc.add( DirectoryObject( key=Callback(TriggerBetterSubtitles, randomize=timestamp()), title=pad_title("Trigger find better subtitles"), )) oc.add( DirectoryObject( key=Callback(TriggerStorageMaintenance, randomize=timestamp()), title=pad_title("Trigger subtitle storage maintenance"), )) oc.add( DirectoryObject( key=Callback(TriggerStorageMigration, randomize=timestamp()), title=pad_title("Trigger subtitle storage migration (expensive)"), )) oc.add( DirectoryObject( key=Callback(ApplyDefaultMods, randomize=timestamp()), title=pad_title( "Apply configured default subtitle mods to all (active) stored subtitles" ), )) oc.add( DirectoryObject( key=Callback(ReApplyMods, randomize=timestamp()), title=pad_title("Re-Apply mods of all stored subtitles"), )) oc.add( DirectoryObject( key=Callback(LogStorage, key="tasks", randomize=timestamp()), title=pad_title("Log the plugin's scheduled tasks state storage"), )) oc.add( DirectoryObject( key=Callback(LogStorage, key="ignore", randomize=timestamp()), title=pad_title("Log the plugin's internal ignorelist storage"), )) oc.add( DirectoryObject( key=Callback(LogStorage, key=None, randomize=timestamp()), title=pad_title("Log the plugin's complete state storage"), )) oc.add( DirectoryObject( key=Callback(ResetStorage, key="tasks", randomize=timestamp()), title=pad_title( "Reset the plugin's scheduled tasks state storage"), )) oc.add( DirectoryObject( key=Callback(ResetStorage, key="ignore", randomize=timestamp()), title=pad_title("Reset the plugin's internal ignorelist storage"), )) oc.add( DirectoryObject( key=Callback(InvalidateCache, randomize=timestamp()), title=pad_title( "Invalidate Sub-Zero metadata caches (subliminal)"), )) return oc
def ListAvailableSubsForItemMenu(rating_key=None, part_id=None, title=None, item_title=None, filename=None, item_type="episode", language=None, language_name=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) current_data = unicode(current_data) if current_data else None 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) plex_part = None if not config.low_impact_mode: scanned_parts = scan_videos([metadata], 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( unicode( _(u"by %(release_group)s", release_group=video.release_group))) video_display_data = " ".join(video_display_data) else: video_display_data = metadata["filename"] current_display = (_(u"Current: %(provider_name)s (%(score)s) ", provider_name=current_provider, score=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 %(language)s subs (%(video_data)s)", language=get_language(language).name, video_data=video_display_data), summary=_(u"%(current_info)sFilename: %(filename)s", current_info=current_display, filename=filename), thumb=default_thumb)) if search_results == "found_none": oc.add( DirectoryObject(key=Callback(ListAvailableSubsForItemMenu, rating_key=rating_key, item_title=item_title, language=language, filename=filename, current_data=current_data, force=True, 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"No subtitles found"), summary=_( u"%(current_info)sFilename: %(filename)s", current_info=current_display, filename=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 %(language)s subs (%(video_data)s), refresh here ...", language=display_language(get_language(language)), video_data=video_display_data), summary=_(u"%(current_info)sFilename: %(filename)s", current_info=current_display, filename=filename), thumb=default_thumb)) if not search_results or search_results == "found_none": return oc current_sub, stored_subs, storage = get_current_sub( rating_key, part_id, language) current_bl, subs = stored_subs.get_blacklist(part_id, language) seen = [] for subtitle in search_results: if subtitle.id in seen: continue bl_addon = "" if (str(subtitle.provider_name), str(subtitle.id)) in current_bl: bl_addon = "Blacklisted " wrong_fps_addon = "" if subtitle.wrong_fps: if plex_part: wrong_fps_addon = _( " (wrong FPS, sub: %(subtitle_fps)s, media: %(media_fps)s)", subtitle_fps=subtitle.fps, media_fps=plex_part.fps) else: wrong_fps_addon = _( " (wrong FPS, sub: %(subtitle_fps)s, media: unknown, low impact mode)", subtitle_fps=subtitle.fps) 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"%(blacklisted_state)s%(current_state)s: %(provider_name)s, score: %(score)s%(wrong_fps_state)s", blacklisted_state=bl_addon, current_state=_("Available") if current_id != subtitle.id else _("Current"), provider_name=subtitle.provider_name, score=subtitle.score, wrong_fps_state=wrong_fps_addon), summary=_(u"Release: %(release_info)s, Matches: %(matches)s", release_info=subtitle.release_info, matches=", ".join(subtitle.matches)), thumb=default_thumb)) seen.append(subtitle.id) return oc
def LogStorage(key, randomize=None): log_storage(key) return AdvancedMenu(randomize=timestamp(), header='Success', message='Information Storage (%s) logged' % key)
def fatality(randomize=None, header=None, message=None, only_refresh=False): """ subzero main menu """ oc = ObjectContainer(header=header, message=message, no_cache=True, no_history=True) if not config.plex_api_working: oc.add( DirectoryObject(key=Callback(fatality, randomize=timestamp()), title=pad_title("PMS API ERROR"), summary=lib_unaccessible_error)) return oc if not only_refresh: oc.add( DirectoryObject( key=Callback(OnDeckMenu), title=pad_title("Subtitles for 'On Deck' items"), summary= "Shows the current on deck items and allows you to individually (force-) refresh their metadata/subtitles." )) oc.add( DirectoryObject( key=Callback(RecentlyAddedMenu), title="Subtitles for 'Recently Added' items (max-age: %s)" % Prefs["scheduler.item_is_recent_age"], summary= "Shows the recently added items, honoring the configured 'Item age to be considered recent'-setting (%s) and allowing you to individually (force-) refresh their metadata/subtitles." % Prefs["scheduler.item_is_recent_age"])) task_name = "searchAllRecentlyAddedMissing" task = scheduler.task(task_name) if task.ready_for_display: task_state = "Running: %s/%s (%s%%)" % (len( task.items_done), len(task.items_searching), task.percentage) else: task_state = "Last scheduler run: %s; Next scheduled run: %s; Last runtime: %s" % ( scheduler.last_run(task_name) or "never", scheduler.next_run(task_name) or "never", str(task.last_run_time).split(".")[0]) oc.add( DirectoryObject( key=Callback(RefreshMissing, randomize=timestamp()), title= "Search for missing subtitles (in recently-added items, max-age: %s)" % Prefs["scheduler.item_is_recent_age"], summary= "Automatically run periodically by the scheduler, if configured. %s" % task_state)) oc.add( DirectoryObject(key=Callback(fatality, randomize=timestamp()), title=pad_title("Refresh"), summary="Refreshes the current view")) if not only_refresh: oc.add( DirectoryObject(key=Callback(AdvancedMenu, randomize=timestamp()), title=pad_title("Advanced functions"), summary="Use at your own risk")) return oc
def ItemDetailsMenu(rating_key, title=None, base_title=None, item_title=None, randomize=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) 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 # 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 part_index_addon = "" part_summary_addon = "" if has_multiple_parts: part_index_addon = u"File %s: " % part_index part_summary_addon = "%s " % filename 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, 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=lang.name, 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"%sActions for %s subtitle" % (part_index_addon, lang.name), 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=lang.name, 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, lang.name), summary=summary)) add_ignore_options(oc, "videos", title=item_title, rating_key=rating_key, callback_menu=IgnoreMenu) subtitle_storage.destroy() return oc
def RefreshItem(rating_key=None, came_from="/recent", item_title=None, force=False): assert rating_key set_refresh_menu_state("Triggering %sRefresh for %s" % ("Force-" if force else "", item_title)) Thread.Create(refreshItem, rating_key=rating_key, force=force) return fatality(randomize=timestamp(), header="%s of item %s triggered" % ("Refresh" if not force else "Forced-refresh", rating_key), replace_parent=True)
def fatality(randomize=None, force_title=None, header=None, message=None, only_refresh=False, no_history=False, replace_parent=False): """ subzero main menu """ title = force_title if force_title is not None else config.full_version oc = ObjectContainer(title1=title, title2=None, header=unicode(header) if header else header, message=message, no_history=no_history, replace_parent=replace_parent) if not config.plex_api_working: oc.add(DirectoryObject( key=Callback(fatality, randomize=timestamp()), title=pad_title("PMS API ERROR"), summary=lib_unaccessible_error )) return oc if not only_refresh: oc.add(DirectoryObject( key=Callback(OnDeckMenu), title=pad_title("On Deck items"), summary="Shows the current on deck items and allows you to individually (force-) refresh their metadata/subtitles." )) oc.add(DirectoryObject( key=Callback(RecentlyAddedMenu), title="Items with missing subtitles", summary="Shows the items honoring the configured 'Item age to be considered recent'-setting (%s)" " and allowing you to individually (force-) refresh their metadata/subtitles. " % Prefs["scheduler.item_is_recent_age"] )) oc.add(DirectoryObject( key=Callback(SectionsMenu), title="Browse all items", summary="Go through your whole library and manage your ignore list. You can also " "(force-) refresh the metadata/subtitles of individual items." )) task_name = "searchAllRecentlyAddedMissing" task = scheduler.task(task_name) if task.ready_for_display: task_state = "Running: %s/%s (%s%%)" % (len(task.items_done), len(task.items_searching), task.percentage) else: task_state = "Last scheduler run: %s; Next scheduled run: %s; Last runtime: %s" % (scheduler.last_run(task_name) or "never", scheduler.next_run(task_name) or "never", str(task.last_run_time).split(".")[0]) oc.add(DirectoryObject( key=Callback(RefreshMissing), title="Search for missing subtitles (in recently-added items, max-age: %s)" % Prefs["scheduler.item_is_recent_age"], summary="Automatically run periodically by the scheduler, if configured. %s" % task_state )) oc.add(DirectoryObject( key=Callback(IgnoreListMenu), title="Display ignore list (%d)" % len(ignore_list), summary="Show the current ignore list (mainly used for the automatic tasks)" )) oc.add(DirectoryObject( key=Callback(fatality, force_title=" ", randomize=timestamp()), title=pad_title("Refresh"), summary="Current state: %s; Last state: %s" % ( (Dict["current_refresh_state"] or "Idle") if "current_refresh_state" in Dict else "Idle", (Dict["last_refresh_state"] or "None") if "last_refresh_state" in Dict else "None" ) )) if not only_refresh: oc.add(DirectoryObject( key=Callback(AdvancedMenu), title=pad_title("Advanced functions"), summary="Use at your own risk" )) return oc
def ReApplyMods(randomize=None): Thread.CreateTimer(1.0, apply_default_mods, reapply_current=True) return AdvancedMenu(randomize=timestamp(), header='Success', message='This may take some time ...')
def InvalidateCache(randomize=None): from subliminal.cache import region region.invalidate() return AdvancedMenu(randomize=timestamp(), header='Success', message='Cache invalidated')
def MetadataMenu(rating_key, title=None, base_title=None, display_items=False, previous_item_type=None, previous_rating_key=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) current_kind = get_item_kind_from_rating_key(rating_key) if display_items: timeout = 30 # add back to series for season if current_kind == "season": timeout = 360 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": timeout = 1800 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 should_display_ignore(items, previous=previous_item_type): add_ignore_options(oc, "series", title=item_title, rating_key=rating_key, callback_menu=IgnoreMenu) # 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 %s, possibly searching for missing and picking up new subtitles on disk" % 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 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, 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) 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"%(part_summary)sEmbedded subtitles (%(languages)s)", part_summary=part_index_addon, languages=", ".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 RefreshItem(rating_key=None, came_from="/recent", force=False): assert rating_key Thread.Create(refreshItem, rating_key=rating_key, force=force) return fatality(randomize=timestamp(), header="%s of item %s triggered" % ("Refresh" if not force else "Forced-refresh", rating_key))
def SubtitleOptionsMenu(**kwargs): oc = SubFolderObjectContainer(title2=unicode(kwargs["title"]), replace_parent=True, header=kwargs.get("header"), message=kwargs.get("message")) rating_key = kwargs["rating_key"] part_id = kwargs["part_id"] language = kwargs["language"] current_data = unicode(kwargs["current_data"]) current_sub, stored_subs, storage = get_current_sub( rating_key, part_id, language) subs_count = stored_subs.count(part_id, language) kwargs.pop("randomize") oc.add( DirectoryObject(key=Callback(ItemDetailsMenu, rating_key=kwargs["rating_key"], item_title=kwargs["item_title"], title=kwargs["title"], randomize=timestamp()), title=_(u"< Back to %s", kwargs["title"]), summary=current_data, thumb=default_thumb)) if subs_count: oc.add( DirectoryObject(key=Callback(ListStoredSubsForItemMenu, randomize=timestamp(), **kwargs), title=_(u"Select active %(language)s subtitle", language=kwargs["language_name"]), summary=_(u"%(count)d subtitles in storage", count=subs_count))) oc.add( DirectoryObject(key=Callback(ListAvailableSubsForItemMenu, randomize=timestamp(), **kwargs), title=_(u"List available %(language)s subtitles", language=kwargs["language_name"]), summary=current_data)) if current_sub: oc.add( DirectoryObject(key=Callback(SubtitleModificationsMenu, randomize=timestamp(), **kwargs), title=_(u"Modify current %(language)s subtitle", language=kwargs["language_name"]), summary=_( u"Currently applied mods: %(mod_list)s", mod_list=(", ".join(current_sub.mods) if current_sub.mods else "none")))) if current_sub.provider_name != "embedded": oc.add( DirectoryObject( key=Callback(BlacklistSubtitleMenu, randomize=timestamp(), **kwargs), title= _(u"Blacklist current %(language)s subtitle and search for a new one", language=kwargs["language_name"]), summary=current_data)) current_bl, subs = stored_subs.get_blacklist(part_id, language) if current_bl: oc.add( DirectoryObject( key=Callback(ManageBlacklistMenu, randomize=timestamp(), **kwargs), title=_(u"Manage blacklist (%(amount)s contained)", amount=len(current_bl)), summary=_(u"Inspect currently blacklisted subtitles"))) storage.destroy() return oc
def fatality(randomize=None, force_title=None, header=None, message=None, only_refresh=False, no_history=False, replace_parent=False): """ subzero main menu """ title = config.full_version#force_title if force_title is not None else config.full_version oc = ObjectContainer(title1=title, title2=title, header=unicode(header) if header else title, message=message, no_history=no_history, replace_parent=replace_parent, no_cache=True) # always re-check permissions config.refresh_permissions_status() # always re-check enabled sections config.refresh_enabled_sections() if config.lock_menu and not config.pin_correct: oc.add(DirectoryObject( key=Callback(PinMenu, randomize=timestamp()), title=pad_title("Enter PIN"), summary="The owner has restricted the access to this menu. Please enter the correct pin", )) return oc if not config.permissions_ok and config.missing_permissions: for title, path in config.missing_permissions: oc.add(DirectoryObject( key=Callback(fatality, randomize=timestamp()), title=pad_title("Insufficient permissions"), summary="Insufficient permissions on library %s, folder: %s" % (title, path), )) return oc if not config.enabled_sections: oc.add(DirectoryObject( key=Callback(fatality, randomize=timestamp()), title=pad_title("I'm not enabled!"), summary="Please enable me for some of your libraries in your server settings; currently I do nothing", )) return oc if not only_refresh: if Dict["current_refresh_state"]: oc.add(DirectoryObject( key=Callback(fatality, force_title=" ", randomize=timestamp()), title=pad_title("Working ... refresh here"), summary="Current state: %s; Last state: %s" % ( (Dict["current_refresh_state"] or "Idle") if "current_refresh_state" in Dict else "Idle", (Dict["last_refresh_state"] or "None") if "last_refresh_state" in Dict else "None" ) )) oc.add(DirectoryObject( key=Callback(OnDeckMenu), title="On Deck items", summary="Shows the current on deck items and allows you to individually (force-) refresh their metadata/" "subtitles." )) oc.add(DirectoryObject( key=Callback(RecentlyAddedMenu), title="Recently Added items", summary="Shows the recently added items per section." )) oc.add(DirectoryObject( key=Callback(RecentMissingSubtitlesMenu, randomize=timestamp()), title="Items with missing subtitles", summary="Shows the items honoring the configured 'Item age to be considered recent'-setting (%s)" " and allowing you to individually (force-) refresh their metadata/subtitles. " % Prefs["scheduler.item_is_recent_age"] )) oc.add(DirectoryObject( key=Callback(SectionsMenu), title="Browse all items", summary="Go through your whole library and manage your ignore list. You can also " "(force-) refresh the metadata/subtitles of individual items." )) task_name = "SearchAllRecentlyAddedMissing" task = scheduler.task(task_name) if task.ready_for_display: task_state = "Running: %s/%s (%s%%)" % (len(task.items_done), len(task.items_searching), task.percentage) else: task_state = "Last scheduler run: %s; Next scheduled run: %s; Last runtime: %s" % (df(scheduler.last_run(task_name)) or "never", df(scheduler.next_run(task_name)) or "never", str(task.last_run_time).split(".")[0]) oc.add(DirectoryObject( key=Callback(RefreshMissing, randomize=timestamp()), title="Search for missing subtitles (in recently-added items, max-age: %s)" % Prefs["scheduler.item_is_recent_age"], summary="Automatically run periodically by the scheduler, if configured. %s" % task_state )) oc.add(DirectoryObject( key=Callback(IgnoreListMenu), title="Display ignore list (%d)" % len(ignore_list), summary="Show the current ignore list (mainly used for the automatic tasks)" )) oc.add(DirectoryObject( key=Callback(HistoryMenu), title="History", summary="Show the last %i downloaded subtitles" % int(Prefs["history_size"]) )) oc.add(DirectoryObject( key=Callback(fatality, force_title=" ", randomize=timestamp()), title=pad_title("Refresh"), summary="Current state: %s; Last state: %s" % ( (Dict["current_refresh_state"] or "Idle") if "current_refresh_state" in Dict else "Idle", (Dict["last_refresh_state"] or "None") if "last_refresh_state" in Dict else "None" ) )) # add re-lock after pin unlock if config.pin: oc.add(DirectoryObject( key=Callback(ClearPin, randomize=timestamp()), title=pad_title("Re-lock menu(s)"), summary="Enabled the PIN again for menu(s)" )) if not only_refresh: oc.add(DirectoryObject( key=Callback(AdvancedMenu), title=pad_title("Advanced functions"), summary="Use at your own risk" )) return oc
def ListEmbeddedSubsForItemMenu(**kwargs): rating_key = kwargs["rating_key"] part_id = kwargs["part_id"] title = kwargs["title"] kwargs.pop("randomize") oc = SubFolderObjectContainer(title2=title, replace_parent=True) oc.add( DirectoryObject(key=Callback(ItemDetailsMenu, rating_key=kwargs["rating_key"], item_title=kwargs["item_title"], base_title=kwargs["base_title"], title=kwargs["item_title"], randomize=timestamp()), title=_("< Back to %s", kwargs["title"]), thumb=default_thumb)) plex_item = get_item(rating_key) part = get_part(plex_item, part_id) if part: for stream_data in get_embedded_subtitle_streams( part, skip_duplicate_unknown=False): language = stream_data["language"] is_unknown = stream_data["is_unknown"] stream = stream_data["stream"] is_forced = stream_data["is_forced"] if language: oc.add( DirectoryObject( key=Callback(TriggerExtractEmbeddedSubForItemMenu, randomize=timestamp(), stream_index=str(stream.index), language=language, with_mods=True, **kwargs), title=_( u"Extract stream %(stream_index)s, %(language)s%(unknown_state)s%(forced_state)s" u"%(stream_title)s with default mods", stream_index=stream.index, language=display_language(language), unknown_state=_(" (unknown)") if is_unknown else "", forced_state=_(" (forced)") if is_forced else "", stream_title=" (\"%s\")" % stream.title if stream.title else ""), )) oc.add( DirectoryObject( key=Callback(TriggerExtractEmbeddedSubForItemMenu, randomize=timestamp(), stream_index=str(stream.index), language=language, **kwargs), title=_( u"Extract stream %(stream_index)s, %(language)s%(unknown_state)s%(forced_state)s" u"%(stream_title)s", stream_index=stream.index, language=display_language(language), unknown_state=_(" (unknown)") if is_unknown else "", forced_state=_(" (forced)") if is_forced else "", stream_title=" (\"%s\")" % stream.title if stream.title else ""), )) return oc
def ItemDetailsMenu(rating_key, title=None, base_title=None, item_title=None, randomize=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: """ title = unicode(base_title) + " > " + unicode(title) if base_title else unicode(title) item = get_item(rating_key) current_kind = get_item_kind_from_rating_key(rating_key) timeout = 30 oc = SubFolderObjectContainer(title2=title, replace_parent=True) 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"Auto-search: %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) # get the plex item plex_item = list(Plex["library"].metadata(rating_key))[0] # get current media info for that item media = plex_item.media # look for subtitles for all available media parts and all of their languages for part in media.parts: filename = os.path.basename(part.file) part_id = str(part.id) # iterate through all configured languages for lang in config.lang_list: lang_a2 = lang.alpha2 # ietf lang? if cast_bool(Prefs["subtitles.language.ietf"]) and "-" in lang_a2: lang_a2 = lang_a2.split("-")[0] # get corresponding stored subtitle data for that media part (physical media item), for language current_sub = stored_subs.get_any(part_id, lang_a2) current_sub_id = None current_sub_provider_name = None summary = u"No current subtitle in storage" 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"Current subtitle: %s (added: %s, %s), Language: %s, Score: %i, Storage: %s" % \ (current_sub.provider_name, df(current_sub.date_added), current_sub.mode_verbose, lang, current_sub.score, current_sub.storage_type) oc.add(DirectoryObject( key=Callback(ListAvailableSubsForItemMenu, rating_key=rating_key, part_id=part_id, title=title, item_title=item_title, 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"List %s subtitles" % lang.name, summary=summary )) add_ignore_options(oc, "videos", title=item_title, rating_key=rating_key, callback_menu=IgnoreMenu) return oc
def TriggerBetterSubtitles(randomize=None): scheduler.dispatch_task("FindBetterSubtitles") return AdvancedMenu(randomize=timestamp(), header='Success', message='FindBetterSubtitles triggered')
def ResetProviderThrottle(randomize=None): Dict["provider_throttle"] = {} Dict.Save() return AdvancedMenu(randomize=timestamp(), header=_("Success"), message=_("Provider throttles reset"))
def TriggerStorageMigration(randomize=None): scheduler.dispatch_task("MigrateSubtitleStorage") return AdvancedMenu(randomize=timestamp(), header='Success', message='MigrateSubtitleStorage triggered')
def TriggerCacheMaintenance(randomize=None): scheduler.dispatch_task("CacheMaintenance") return AdvancedMenu(randomize=timestamp(), header=_("Success"), message=_("TriggerCacheMaintenance triggered"))
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
def LogStorage(key, randomize=None): log_storage(key) return AdvancedMenu(randomize=timestamp(), header=_("Success"), message=_("Information Storage (%s) logged", key))
def ApplyDefaultMods(randomize=None): Thread.CreateTimer(1.0, apply_default_mods) return AdvancedMenu(randomize=timestamp(), header=_("Success"), message=_("This may take some time ..."))
def AdvancedMenu(randomize=None, header=None, message=None): oc = SubFolderObjectContainer(header=header or "Internal stuff, pay attention!", message=message, no_cache=True, no_history=True, replace_parent=False, title2="Advanced") if config.lock_advanced_menu and not config.pin_correct: oc.add(DirectoryObject( key=Callback(PinMenu, randomize=timestamp(), success_go_to="advanced"), title=pad_title("Enter PIN"), summary="The owner has restricted the access to this menu. Please enter the correct pin", )) return oc oc.add(DirectoryObject( key=Callback(TriggerRestart, randomize=timestamp()), title=pad_title("Restart the plugin"), )) oc.add(DirectoryObject( key=Callback(TriggerBetterSubtitles, randomize=timestamp()), title=pad_title("Trigger find better subtitles"), )) oc.add(DirectoryObject( key=Callback(LogStorage, key="tasks", randomize=timestamp()), title=pad_title("Log the plugin's scheduled tasks state storage"), )) oc.add(DirectoryObject( key=Callback(LogStorage, key="subs", randomize=timestamp()), title=pad_title("Log the plugin's internal subtitle information storage"), )) oc.add(DirectoryObject( key=Callback(LogStorage, key="ignore", randomize=timestamp()), title=pad_title("Log the plugin's internal ignorelist storage"), )) oc.add(DirectoryObject( key=Callback(LogStorage, key="history", randomize=timestamp()), title=pad_title("Log the plugin's internal history storage"), )) oc.add(DirectoryObject( key=Callback(ResetStorage, key="tasks", randomize=timestamp()), title=pad_title("Reset the plugin's scheduled tasks state storage"), )) oc.add(DirectoryObject( key=Callback(ResetStorage, key="subs", randomize=timestamp()), title=pad_title("Reset the plugin's internal subtitle information storage"), )) oc.add(DirectoryObject( key=Callback(ResetStorage, key="ignore", randomize=timestamp()), title=pad_title("Reset the plugin's internal ignorelist storage"), )) oc.add(DirectoryObject( key=Callback(ResetStorage, key="history", randomize=timestamp()), title=pad_title("Reset the plugin's internal history storage"), )) return oc
def main_menu_fallback(): key = get_lookup_key(ROUTE_REGISTRY["fatality"], [], {}) Dict["last_menu_item"] = key add_to_menu_history(key) return ROUTE_REGISTRY["fatality"](randomize=timestamp())
def TriggerRestart(randomize=None): set_refresh_menu_state("Restarting the plugin") DispatchRestart() return fatality(header="Restart triggered, please wait about 5 seconds", force_title=" ", only_refresh=True, replace_parent=True, no_history=True, randomize=timestamp())