232 lines
7.7 KiB
Python
232 lines
7.7 KiB
Python
# coding=utf-8
|
|
import datetime
|
|
import StringIO
|
|
import glob
|
|
import os
|
|
import urlparse
|
|
|
|
from zipfile import ZipFile, ZIP_DEFLATED
|
|
|
|
from subzero.lib.io import FileIO
|
|
from subzero.constants import PREFIX, PLUGIN_IDENTIFIER
|
|
from menu_helpers import SubFolderObjectContainer, debounce, set_refresh_menu_state, ZipObject
|
|
from main import fatality
|
|
from support.helpers import timestamp, pad_title
|
|
from support.config import config
|
|
from support.lib import Plex
|
|
from support.storage import reset_storage, log_storage
|
|
from support.background import scheduler
|
|
|
|
|
|
@route(PREFIX + '/advanced')
|
|
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(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(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 DispatchRestart():
|
|
Thread.CreateTimer(1.0, Restart)
|
|
|
|
|
|
@route(PREFIX + '/advanced/restart/trigger')
|
|
@debounce
|
|
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())
|
|
|
|
|
|
@route(PREFIX + '/advanced/restart/execute')
|
|
def Restart():
|
|
Plex[":/plugins"].restart(PLUGIN_IDENTIFIER)
|
|
|
|
|
|
@route(PREFIX + '/storage/reset', sure=bool)
|
|
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
|
|
)
|
|
|
|
|
|
@route(PREFIX + '/storage/log')
|
|
def LogStorage(key, randomize=None):
|
|
log_storage(key)
|
|
return AdvancedMenu(
|
|
randomize=timestamp(),
|
|
header='Success',
|
|
message='Information Storage (%s) logged' % key
|
|
)
|
|
|
|
|
|
@route(PREFIX + '/triggerbetter')
|
|
def TriggerBetterSubtitles(randomize=None):
|
|
scheduler.dispatch_task("FindBetterSubtitles")
|
|
return AdvancedMenu(
|
|
randomize=timestamp(),
|
|
header='Success',
|
|
message='FindBetterSubtitles triggered'
|
|
)
|
|
|
|
|
|
@route(PREFIX + '/triggermaintenance')
|
|
def TriggerStorageMaintenance(randomize=None):
|
|
scheduler.dispatch_task("SubtitleStorageMaintenance")
|
|
return AdvancedMenu(
|
|
randomize=timestamp(),
|
|
header='Success',
|
|
message='SubtitleStorageMaintenance triggered'
|
|
)
|
|
|
|
|
|
@route(PREFIX + '/get_logs_link')
|
|
def GetLogsLink():
|
|
# try getting the link base via the request in context, first, otherwise use the public ip
|
|
req_headers = Core.sandbox.context.request.headers
|
|
|
|
if "Origin" in req_headers:
|
|
link_base = req_headers["Origin"]
|
|
Log.Debug("Using origin-based link_base")
|
|
|
|
elif "Referer" in req_headers:
|
|
parsed = urlparse.urlparse(req_headers["Referer"])
|
|
link_base = "%s://%s:%s" % (parsed.scheme, parsed.hostname, parsed.port)
|
|
Log.Debug("Using referer-based link_base")
|
|
|
|
else:
|
|
ip = Core.networking.http_request("http://www.plexapp.com/ip.php", cacheTime=7200).content.strip()
|
|
link_base = "https://%s:32400" % ip
|
|
Log.Debug("Using ip-based fallback link_base")
|
|
|
|
logs_link = "%s%s?X-Plex-Token=%s" % (link_base, PREFIX + '/logs', config.universal_plex_token)
|
|
oc = ObjectContainer(title2="Download Logs", no_cache=True, no_history=True,
|
|
header="Copy this link and open this in your browser, please",
|
|
message=logs_link)
|
|
return oc
|
|
|
|
|
|
@route(PREFIX + '/logs')
|
|
def DownloadLogs():
|
|
buff = StringIO.StringIO()
|
|
zip_archive = ZipFile(buff, mode='w', compression=ZIP_DEFLATED)
|
|
|
|
logs = sorted(glob.glob(config.plugin_log_path + '*')) + [config.server_log_path]
|
|
for path in logs:
|
|
data = StringIO.StringIO()
|
|
data.write(FileIO.read(path))
|
|
zip_archive.writestr(os.path.basename(path), data.getvalue())
|
|
|
|
zip_archive.close()
|
|
|
|
return ZipObject(buff.getvalue())
|
|
|
|
|
|
@route(PREFIX + '/invalidatecache')
|
|
def InvalidateCache(randomize=None):
|
|
from subliminal.cache import region
|
|
region.invalidate()
|
|
return AdvancedMenu(
|
|
randomize=timestamp(),
|
|
header='Success',
|
|
message='Cache invalidated'
|
|
)
|
|
|
|
|
|
@route(PREFIX + '/pin')
|
|
def PinMenu(pin="", randomize=None, success_go_to="channel"):
|
|
oc = ObjectContainer(title2="Enter PIN number %s" % (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
|
|
|
|
|
|
@route(PREFIX + '/pin_lock')
|
|
def ClearPin(randomize=None):
|
|
Dict["pin_correct_time"] = None
|
|
config.locked = True
|
|
return fatality(force_title="Menu locked", header=" ", no_history=True)
|