mirror of
https://github.com/SickGear/SickGear.git
synced 2024-11-15 01:15:05 +00:00
Change optionally add disk free space in response to three Web API endpoints.
Change increase API version number to 15. Add actually use mount points to get disk free space. Add optional "freespace" parameter to endpoints: sg.getrootdirs, sg.addrootdir, sg.deleterootdir Change update help of affected endpoints. Fix explicitly save rootdirs after adding or deleting via Web API.
This commit is contained in:
parent
40badef803
commit
e239b81a18
4 changed files with 93 additions and 45 deletions
|
@ -9,6 +9,12 @@
|
||||||
* Change codebase cleanups
|
* Change codebase cleanups
|
||||||
* Change improve perf by using generators with `any`
|
* Change improve perf by using generators with `any`
|
||||||
* Change deprecate processEpisode used by nzbToMedia to advise how to configure API instead
|
* Change deprecate processEpisode used by nzbToMedia to advise how to configure API instead
|
||||||
|
* Change optionally add disk free space in response to three Web API endpoints
|
||||||
|
* Change increase API version number to 15
|
||||||
|
* Add actually use mount points to get disk free space
|
||||||
|
* Add optional "freespace" parameter to endpoints: sg.getrootdirs, sg.addrootdir, sg.deleterootdir
|
||||||
|
* Change update help of affected endpoints
|
||||||
|
* Fix explicitly save rootdirs after adding or deleting via Web API
|
||||||
|
|
||||||
|
|
||||||
[develop changelog]
|
[develop changelog]
|
||||||
|
|
|
@ -70,11 +70,11 @@ addList("Command", "Help", "?cmd=help", "sg.functions-list", "","", "default");
|
||||||
addOption("sg.functions-list", "$k", "&subject=$k", "", "", "#echo ('sb', 'sg')['sg' in $k]#")
|
addOption("sg.functions-list", "$k", "&subject=$k", "", "", "#echo ('sb', 'sg')['sg' in $k]#")
|
||||||
#end for
|
#end for
|
||||||
addList("Command", "SickBeard.AddRootDir", "?cmd=sb.addrootdir", "sb.addrootdir");
|
addList("Command", "SickBeard.AddRootDir", "?cmd=sb.addrootdir", "sb.addrootdir");
|
||||||
addList("Command", "SickGear.AddRootDir", "?cmd=sg.addrootdir", "sb.addrootdir");
|
addList("Command", "SickGear.AddRootDir", "?cmd=sg.addrootdir", "sg.addrootdir");
|
||||||
addOption("Command", "SickBeard.CheckScheduler", "?cmd=sb.checkscheduler");
|
addOption("Command", "SickBeard.CheckScheduler", "?cmd=sb.checkscheduler");
|
||||||
addOption("Command", "SickGear.CheckScheduler", "?cmd=sg.checkscheduler");
|
addOption("Command", "SickGear.CheckScheduler", "?cmd=sg.checkscheduler");
|
||||||
addList("Command", "SickBeard.DeleteRootDir", "?cmd=sb.deleterootdir", "sb.deleterootdir");
|
addList("Command", "SickBeard.DeleteRootDir", "?cmd=sb.deleterootdir", "sb.deleterootdir");
|
||||||
addList("Command", "SickGear.DeleteRootDir", "?cmd=sg.deleterootdir", "sb.deleterootdir");
|
addList("Command", "SickGear.DeleteRootDir", "?cmd=sg.deleterootdir", "sg.deleterootdir");
|
||||||
addOption("Command", "SickBeard.ForceSearch", "?cmd=sb.forcesearch");
|
addOption("Command", "SickBeard.ForceSearch", "?cmd=sb.forcesearch");
|
||||||
addList("Command", "SickGear.ForceSearch", "?cmd=sg.forcesearch", "sg.forcesearch");
|
addList("Command", "SickGear.ForceSearch", "?cmd=sg.forcesearch", "sg.forcesearch");
|
||||||
addOption("Command", "SickGear.SearchQueue", "?cmd=sg.searchqueue");
|
addOption("Command", "SickGear.SearchQueue", "?cmd=sg.searchqueue");
|
||||||
|
@ -88,7 +88,7 @@ addList("Command", "SickGear.GetIndexers", "?cmd=sg.getindexers", "listindexers"
|
||||||
addList("Command", "SickGear.GetIndexerIcon", "?cmd=sg.getindexericon", "getindexericon");
|
addList("Command", "SickGear.GetIndexerIcon", "?cmd=sg.getindexericon", "getindexericon");
|
||||||
addList("Command", "SickGear.GetNetworkIcon", "?cmd=sg.getnetworkicon", "getnetworkicon");
|
addList("Command", "SickGear.GetNetworkIcon", "?cmd=sg.getnetworkicon", "getnetworkicon");
|
||||||
addOption("Command", "SickBeard.GetRootDirs", "?cmd=sb.getrootdirs");
|
addOption("Command", "SickBeard.GetRootDirs", "?cmd=sb.getrootdirs");
|
||||||
addOption("Command", "SickGear.GetRootDirs", "?cmd=sg.getrootdirs");
|
addList("Command", "SickGear.GetRootDirs", "?cmd=sg.getrootdirs", "sg.addfreespace");
|
||||||
addList("Command", "SickBeard.PauseBacklog", "?cmd=sb.pausebacklog", "sb.pausebacklog");
|
addList("Command", "SickBeard.PauseBacklog", "?cmd=sb.pausebacklog", "sb.pausebacklog");
|
||||||
addList("Command", "SickGear.PauseBacklog", "?cmd=sg.pausebacklog", "sb.pausebacklog");
|
addList("Command", "SickGear.PauseBacklog", "?cmd=sg.pausebacklog", "sb.pausebacklog");
|
||||||
addOption("Command", "SickBeard.Ping", "?cmd=sb.ping");
|
addOption("Command", "SickBeard.Ping", "?cmd=sb.ping");
|
||||||
|
@ -621,10 +621,26 @@ addOption("sb.addrootdir-opt", "Optional Param", "", 1);
|
||||||
addOption("sb.addrootdir-opt", "Default", "&default=1");
|
addOption("sb.addrootdir-opt", "Default", "&default=1");
|
||||||
addOption("sb.addrootdir-opt", "Not Default", "&default=0");
|
addOption("sb.addrootdir-opt", "Not Default", "&default=0");
|
||||||
|
|
||||||
addOption("sb.deleterootdir", "C:\\Temp", "&location=C:\\Temp", "", 1);
|
addList("sg.addrootdir", "C:\\Temp", "&location=C:\\Temp", "sg.addrootdir-opt");
|
||||||
|
addList("sg.addrootdir", "/usr/bin", "&location=/usr/bin/", "sg.addrootdir-opt");
|
||||||
|
addList("sg.addrootdir", "S:\\Invalid_Location", "&location=S:\\Invalid_Location", "sg.addrootdir-opt");
|
||||||
|
|
||||||
|
addList("sg.addrootdir-opt", "Optional Param", "", "sg.addfreespace");
|
||||||
|
addList("sg.addrootdir-opt", "Default", "&default=1", "sg.addfreespace");
|
||||||
|
addList("sg.addrootdir-opt", "Not Default", "&default=0", "sg.addfreespace");
|
||||||
|
|
||||||
|
addOption("sb.deleterootdir", "C:\\Temp", "&location=C:\\Temp", 1);
|
||||||
addOption("sb.deleterootdir", "/usr/bin", "&location=/usr/bin/");
|
addOption("sb.deleterootdir", "/usr/bin", "&location=/usr/bin/");
|
||||||
addOption("sb.deleterootdir", "S:\\Invalid_Location", "&location=S:\\Invalid_Location");
|
addOption("sb.deleterootdir", "S:\\Invalid_Location", "&location=S:\\Invalid_Location");
|
||||||
|
|
||||||
|
addList("sg.deleterootdir", "C:\\Temp", "&location=C:\\Temp", "sg.addfreespace");
|
||||||
|
addList("sg.deleterootdir", "/usr/bin", "&location=/usr/bin/", "sg.addfreespace");
|
||||||
|
addList("sg.deleterootdir", "S:\\Invalid_Location", "&location=S:\\Invalid_Location", "sg.addfreespace");
|
||||||
|
|
||||||
|
addOption("sg.addfreespace", "Optional Param", "", 1)
|
||||||
|
addOption("sg.addfreespace", "incl Freespace", "&freespace=1")
|
||||||
|
addOption("sg.addfreespace", "excl Freespace", "&freespace=0")
|
||||||
|
|
||||||
#for $cur_show_obj in $sortedShowList:
|
#for $cur_show_obj in $sortedShowList:
|
||||||
addList("show.pause", "$cur_show_obj.name", "&indexerid=$cur_show_obj.prodid", "show.pause-opt");
|
addList("show.pause", "$cur_show_obj.name", "&indexerid=$cur_show_obj.prodid", "show.pause-opt");
|
||||||
#end for
|
#end for
|
||||||
|
|
|
@ -1412,6 +1412,19 @@ def is_link(filepath):
|
||||||
return os.path.islink(filepath)
|
return os.path.islink(filepath)
|
||||||
|
|
||||||
|
|
||||||
|
def find_mount_point(path):
|
||||||
|
# type: (AnyStr) -> AnyStr
|
||||||
|
"""
|
||||||
|
returns the mount point for the given path
|
||||||
|
:param path: path to find the mount point
|
||||||
|
:return: mount point for path
|
||||||
|
"""
|
||||||
|
path = os.path.realpath(os.path.abspath(path))
|
||||||
|
while not os.path.ismount(path):
|
||||||
|
path = os.path.dirname(path)
|
||||||
|
return path
|
||||||
|
|
||||||
|
|
||||||
def df():
|
def df():
|
||||||
"""
|
"""
|
||||||
Return disk free space at known parent locations
|
Return disk free space at known parent locations
|
||||||
|
@ -1424,17 +1437,9 @@ def df():
|
||||||
if sickgear.ROOT_DIRS and sickgear.DISPLAY_FREESPACE:
|
if sickgear.ROOT_DIRS and sickgear.DISPLAY_FREESPACE:
|
||||||
targets = []
|
targets = []
|
||||||
for path in sickgear.ROOT_DIRS.split('|')[1:]:
|
for path in sickgear.ROOT_DIRS.split('|')[1:]:
|
||||||
location_parts = os.path.splitdrive(path)
|
target = find_mount_point(path)
|
||||||
target = location_parts[0]
|
|
||||||
if 'win32' == sys.platform:
|
|
||||||
if not re.match('(?i)[a-z]:(?:\\\\)?$', target):
|
|
||||||
# simple drive letter not found, fallback to full path
|
|
||||||
target = path
|
|
||||||
min_output = False
|
|
||||||
elif sys.platform.startswith(('linux', 'darwin', 'sunos5')) or 'bsd' in sys.platform:
|
|
||||||
target = path
|
|
||||||
min_output = False
|
|
||||||
if target and target not in targets:
|
if target and target not in targets:
|
||||||
|
min_output = False
|
||||||
targets += [target]
|
targets += [target]
|
||||||
free = freespace(path)
|
free = freespace(path)
|
||||||
if None is not free:
|
if None is not free:
|
||||||
|
|
|
@ -43,7 +43,7 @@ from . import classes, db, helpers, history, image_cache, logger, network_timezo
|
||||||
from .common import ARCHIVED, DOWNLOADED, FAILED, IGNORED, SKIPPED, SNATCHED, SNATCHED_ANY, SNATCHED_BEST, \
|
from .common import ARCHIVED, DOWNLOADED, FAILED, IGNORED, SKIPPED, SNATCHED, SNATCHED_ANY, SNATCHED_BEST, \
|
||||||
SNATCHED_PROPER, UNAIRED, UNKNOWN, WANTED, Quality, qualityPresetStrings, statusStrings
|
SNATCHED_PROPER, UNAIRED, UNKNOWN, WANTED, Quality, qualityPresetStrings, statusStrings
|
||||||
from .name_parser.parser import NameParser
|
from .name_parser.parser import NameParser
|
||||||
from .helpers import starify
|
from .helpers import df, find_mount_point, starify
|
||||||
from .indexers import indexer_api, indexer_config
|
from .indexers import indexer_api, indexer_config
|
||||||
from .indexers.indexer_config import *
|
from .indexers.indexer_config import *
|
||||||
from lib.tvinfo_base.exceptions import *
|
from lib.tvinfo_base.exceptions import *
|
||||||
|
@ -150,7 +150,7 @@ else:
|
||||||
|
|
||||||
class Api(webserve.BaseHandler):
|
class Api(webserve.BaseHandler):
|
||||||
""" api class that returns json results """
|
""" api class that returns json results """
|
||||||
version = 14 # use an int since float-point is unpredictable
|
version = 15 # use an int since float-point is unpredictable
|
||||||
|
|
||||||
def check_xsrf_cookie(self):
|
def check_xsrf_cookie(self):
|
||||||
pass
|
pass
|
||||||
|
@ -801,38 +801,45 @@ def _getQualityMap():
|
||||||
return quality_map_inversed
|
return quality_map_inversed
|
||||||
|
|
||||||
|
|
||||||
def _getRootDirs():
|
def _get_root_dirs(get_freespace=False):
|
||||||
if "" == sickgear.ROOT_DIRS:
|
# type: (bool) -> List[Dict]
|
||||||
return {}
|
"""
|
||||||
|
|
||||||
|
:param get_freespace: include disk free space info in response
|
||||||
|
"""
|
||||||
|
dir_list = []
|
||||||
|
if not sickgear.ROOT_DIRS:
|
||||||
|
return dir_list
|
||||||
|
|
||||||
rootDir = {}
|
|
||||||
root_dirs = sickgear.ROOT_DIRS.split('|')
|
root_dirs = sickgear.ROOT_DIRS.split('|')
|
||||||
default_index = int(sickgear.ROOT_DIRS.split('|')[0])
|
default_index = int(root_dirs.pop(0))
|
||||||
|
|
||||||
rootDir["default_index"] = int(sickgear.ROOT_DIRS.split('|')[0])
|
|
||||||
# remove default_index value from list (this fixes the offset)
|
|
||||||
root_dirs.pop(0)
|
|
||||||
|
|
||||||
if len(root_dirs) < default_index:
|
if len(root_dirs) < default_index:
|
||||||
return {}
|
return dir_list
|
||||||
|
|
||||||
# clean up the list - replace %xx escapes by their single-character equivalent
|
# clean up the list - replace %xx escapes by their single-character equivalent
|
||||||
root_dirs = [unquote_plus(x) for x in root_dirs]
|
root_dirs = [unquote_plus(x) for x in root_dirs]
|
||||||
|
|
||||||
default_dir = root_dirs[default_index]
|
default_dir = root_dirs[default_index]
|
||||||
|
|
||||||
dir_list = []
|
if root_dirs and get_freespace:
|
||||||
for root_dir in root_dirs:
|
diskfree, _ = df()
|
||||||
valid = 1
|
|
||||||
|
for cur_root_dir in root_dirs:
|
||||||
try:
|
try:
|
||||||
os.listdir(root_dir)
|
os.listdir(cur_root_dir)
|
||||||
|
valid = 1
|
||||||
except (BaseException, Exception):
|
except (BaseException, Exception):
|
||||||
valid = 0
|
valid = 0
|
||||||
default = 0
|
|
||||||
if root_dir is default_dir:
|
|
||||||
default = 1
|
|
||||||
|
|
||||||
dir_list.append({'valid': valid, 'location': root_dir, 'default': default})
|
new_entry = {'valid': valid, 'location': cur_root_dir, 'default': int(cur_root_dir is default_dir)}
|
||||||
|
|
||||||
|
if get_freespace:
|
||||||
|
# noinspection PyUnboundLocalVariable
|
||||||
|
new_entry.update({'free_space': next((space for disk, space in diskfree or []
|
||||||
|
if disk == find_mount_point(cur_root_dir)), '')})
|
||||||
|
|
||||||
|
dir_list.append(new_entry)
|
||||||
|
|
||||||
return dir_list
|
return dir_list
|
||||||
|
|
||||||
|
@ -1975,7 +1982,8 @@ class CMD_SickGearAddRootDir(ApiCall):
|
||||||
_help = {"desc": "add a user configured parent directory",
|
_help = {"desc": "add a user configured parent directory",
|
||||||
"requiredParameters": {"location": {"desc": "the full path to root (parent) directory"}
|
"requiredParameters": {"location": {"desc": "the full path to root (parent) directory"}
|
||||||
},
|
},
|
||||||
"optionalParameters": {"default": {"desc": "make the location passed the default root (parent) directory"}
|
"optionalParameters": {"default": {"desc": "make the location passed the default root (parent) directory"},
|
||||||
|
"freespace": {"desc": "include free space of paths in response"}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1984,6 +1992,7 @@ class CMD_SickGearAddRootDir(ApiCall):
|
||||||
self.location, args = self.check_params(args, kwargs, "location", None, True, "string", [])
|
self.location, args = self.check_params(args, kwargs, "location", None, True, "string", [])
|
||||||
# optional
|
# optional
|
||||||
self.default, args = self.check_params(args, kwargs, "default", 0, False, "bool", [])
|
self.default, args = self.check_params(args, kwargs, "default", 0, False, "bool", [])
|
||||||
|
self.freespace, args = self.check_params(args, kwargs, "freespace", 0, False, "bool", [])
|
||||||
# super, missing, help
|
# super, missing, help
|
||||||
ApiCall.__init__(self, handler, args, kwargs)
|
ApiCall.__init__(self, handler, args, kwargs)
|
||||||
|
|
||||||
|
@ -2026,7 +2035,9 @@ class CMD_SickGearAddRootDir(ApiCall):
|
||||||
root_dirs_new = '|'.join([text_type(x) for x in root_dirs_new])
|
root_dirs_new = '|'.join([text_type(x) for x in root_dirs_new])
|
||||||
|
|
||||||
sickgear.ROOT_DIRS = root_dirs_new
|
sickgear.ROOT_DIRS = root_dirs_new
|
||||||
return _responds(RESULT_SUCCESS, _getRootDirs(), msg="Root directories updated")
|
sickgear.save_config()
|
||||||
|
return _responds(RESULT_SUCCESS, _get_root_dirs(not self.sickbeard_call and self.freespace),
|
||||||
|
msg="Root directories updated")
|
||||||
|
|
||||||
|
|
||||||
class CMD_SickBeardAddRootDir(CMD_SickGearAddRootDir):
|
class CMD_SickBeardAddRootDir(CMD_SickGearAddRootDir):
|
||||||
|
@ -2084,20 +2095,24 @@ class CMD_SickBeardCheckScheduler(CMD_SickGearCheckScheduler):
|
||||||
|
|
||||||
class CMD_SickGearDeleteRootDir(ApiCall):
|
class CMD_SickGearDeleteRootDir(ApiCall):
|
||||||
_help = {"desc": "delete a user configured parent directory",
|
_help = {"desc": "delete a user configured parent directory",
|
||||||
"requiredParameters": {"location": {"desc": "the full path to root (parent) directory"}}
|
"requiredParameters": {"location": {"desc": "the full path to root (parent) directory"}},
|
||||||
|
"optionalParameters": {"freespace": {"desc": "include free space of paths in response"}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self, handler, args, kwargs):
|
def __init__(self, handler, args, kwargs):
|
||||||
# required
|
# required
|
||||||
self.location, args = self.check_params(args, kwargs, "location", None, True, "string", [])
|
self.location, args = self.check_params(args, kwargs, "location", None, True, "string", [])
|
||||||
# optional
|
# optional
|
||||||
|
self.freespace, args = self.check_params(args, kwargs, "freespace", 0, False, "bool", [])
|
||||||
# super, missing, help
|
# super, missing, help
|
||||||
ApiCall.__init__(self, handler, args, kwargs)
|
ApiCall.__init__(self, handler, args, kwargs)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
""" delete a user configured parent directory """
|
""" delete a user configured parent directory """
|
||||||
if sickgear.ROOT_DIRS == "":
|
if sickgear.ROOT_DIRS == "":
|
||||||
return _responds(RESULT_FAILURE, _getRootDirs(), msg="No root directories detected")
|
return _responds(RESULT_FAILURE, _get_root_dirs(not self.sickbeard_call and self.freespace),
|
||||||
|
msg="No root directories detected")
|
||||||
|
|
||||||
newIndex = 0
|
newIndex = 0
|
||||||
root_dirs_new = []
|
root_dirs_new = []
|
||||||
|
@ -2124,8 +2139,10 @@ class CMD_SickGearDeleteRootDir(ApiCall):
|
||||||
root_dirs_new = "|".join([text_type(x) for x in root_dirs_new])
|
root_dirs_new = "|".join([text_type(x) for x in root_dirs_new])
|
||||||
|
|
||||||
sickgear.ROOT_DIRS = root_dirs_new
|
sickgear.ROOT_DIRS = root_dirs_new
|
||||||
|
sickgear.save_config()
|
||||||
# what if the root dir was not found?
|
# what if the root dir was not found?
|
||||||
return _responds(RESULT_SUCCESS, _getRootDirs(), msg="Root directory deleted")
|
return _responds(RESULT_SUCCESS, _get_root_dirs(not self.sickbeard_call and self.freespace),
|
||||||
|
msg="Root directory deleted")
|
||||||
|
|
||||||
|
|
||||||
class CMD_SickBeardDeleteRootDir(CMD_SickGearDeleteRootDir):
|
class CMD_SickBeardDeleteRootDir(CMD_SickGearDeleteRootDir):
|
||||||
|
@ -2374,18 +2391,22 @@ class CMD_SickGearGetqualityStrings(ApiCall):
|
||||||
|
|
||||||
|
|
||||||
class CMD_SickGearGetRootDirs(ApiCall):
|
class CMD_SickGearGetRootDirs(ApiCall):
|
||||||
_help = {"desc": "get list of user configured parent directories"}
|
_help = {"desc": "get list of user configured parent directories",
|
||||||
|
"optionalParameters": {"freespace": {"desc": "include free space of paths in response"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
def __init__(self, handler, args, kwargs):
|
def __init__(self, handler, args, kwargs):
|
||||||
# required
|
# required
|
||||||
# optional
|
# optional
|
||||||
|
self.freespace, args = self.check_params(args, kwargs, "freespace", 0, False, "bool", [])
|
||||||
# super, missing, help
|
# super, missing, help
|
||||||
ApiCall.__init__(self, handler, args, kwargs)
|
ApiCall.__init__(self, handler, args, kwargs)
|
||||||
|
|
||||||
def run(self):
|
def run(self):
|
||||||
""" get list of user configured parent directories """
|
""" get list of user configured parent directories """
|
||||||
|
|
||||||
return _responds(RESULT_SUCCESS, _getRootDirs())
|
return _responds(RESULT_SUCCESS, _get_root_dirs(not self.sickbeard_call and self.freespace))
|
||||||
|
|
||||||
|
|
||||||
class CMD_SickBeardGetRootDirs(CMD_SickGearGetRootDirs):
|
class CMD_SickBeardGetRootDirs(CMD_SickGearGetRootDirs):
|
||||||
|
|
Loading…
Reference in a new issue