优化变量
This commit is contained in:
parent
9088677f94
commit
115bf2a3e2
168
main.py
168
main.py
@ -4,7 +4,7 @@ from functools import wraps
|
|||||||
import logging
|
import logging
|
||||||
import threading
|
import threading
|
||||||
import colorlog
|
import colorlog
|
||||||
from pikpakFs import VirtFsNode, DirNode, FileNode, PKVirtFs
|
from pikpakFs import VirtFsNode, DirNode, FileNode, PKVirtFs, IsDir, IsFile
|
||||||
import os
|
import os
|
||||||
|
|
||||||
def RunSyncInLoop(loop):
|
def RunSyncInLoop(loop):
|
||||||
@ -30,7 +30,6 @@ def ProvideDecoratorSelfArgs(decorator, argsProvider):
|
|||||||
namespace = args[0]
|
namespace = args[0]
|
||||||
return decorator(argsProvider(namespace))(func)(*args, **kwargs)
|
return decorator(argsProvider(namespace))(func)(*args, **kwargs)
|
||||||
return decorated
|
return decorated
|
||||||
|
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
class PikpakConsole(cmd2.Cmd):
|
class PikpakConsole(cmd2.Cmd):
|
||||||
@ -39,7 +38,7 @@ class PikpakConsole(cmd2.Cmd):
|
|||||||
|
|
||||||
RunSync = ProvideDecoratorSelfArgs(RunSyncInLoop, LoopProvider)
|
RunSync = ProvideDecoratorSelfArgs(RunSyncInLoop, LoopProvider)
|
||||||
|
|
||||||
def _SetupLogging(self):
|
def _setup_logging(self):
|
||||||
formatter = colorlog.ColoredFormatter(
|
formatter = colorlog.ColoredFormatter(
|
||||||
"%(log_color)s%(asctime)s - %(levelname)s - %(name)s - %(message)s",
|
"%(log_color)s%(asctime)s - %(levelname)s - %(name)s - %(message)s",
|
||||||
datefmt='%Y-%m-%d %H:%M:%S',
|
datefmt='%Y-%m-%d %H:%M:%S',
|
||||||
@ -52,20 +51,12 @@ class PikpakConsole(cmd2.Cmd):
|
|||||||
'CRITICAL': 'red,bg_white',
|
'CRITICAL': 'red,bg_white',
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
handler = logging.StreamHandler()
|
handler = logging.StreamHandler()
|
||||||
handler.setFormatter(formatter)
|
handler.setFormatter(formatter)
|
||||||
|
|
||||||
logger = logging.getLogger()
|
logger = logging.getLogger()
|
||||||
logger.addHandler(handler)
|
logger.addHandler(handler)
|
||||||
|
|
||||||
logger.setLevel(logging.INFO)
|
logger.setLevel(logging.INFO)
|
||||||
|
|
||||||
def __init__(self):
|
|
||||||
super().__init__()
|
|
||||||
self._SetupLogging()
|
|
||||||
self.client = PKVirtFs("token.json", proxy="http://127.0.0.1:7897")
|
|
||||||
|
|
||||||
def IOWorker(self, loop):
|
def IOWorker(self, loop):
|
||||||
self.terminal_lock.acquire() # 我看cmdloop是这么做的,所以我也这么做
|
self.terminal_lock.acquire() # 我看cmdloop是这么做的,所以我也这么做
|
||||||
asyncio.set_event_loop(loop)
|
asyncio.set_event_loop(loop)
|
||||||
@ -86,6 +77,66 @@ class PikpakConsole(cmd2.Cmd):
|
|||||||
future = asyncio.run_coroutine_threadsafe(PrintOuput(output), self.ioLoop)
|
future = asyncio.run_coroutine_threadsafe(PrintOuput(output), self.ioLoop)
|
||||||
await asyncio.wrap_future(future)
|
await asyncio.wrap_future(future)
|
||||||
|
|
||||||
|
def ParserProvider(self):
|
||||||
|
return cmd2.Cmd2ArgumentParser()
|
||||||
|
|
||||||
|
def AddPathParser(parserProvider):
|
||||||
|
def PathParserProvider(self):
|
||||||
|
parser = parserProvider(self)
|
||||||
|
parser.add_argument("path", help="path", default="", nargs="?", type=RunSyncInLoop(self.loop)(self.client.PathToNode))
|
||||||
|
return parser
|
||||||
|
return PathParserProvider
|
||||||
|
|
||||||
|
def AddFatherAndSonParser(parserProvider):
|
||||||
|
def PathParserProvider(self):
|
||||||
|
parser = parserProvider(self)
|
||||||
|
parser.add_argument("path", help="path", default="", nargs="?", type=RunSyncInLoop(self.loop)(self.client.PathToFatherNodeAndNodeName))
|
||||||
|
return parser
|
||||||
|
return PathParserProvider
|
||||||
|
|
||||||
|
def AddUrlParser(parserProvider):
|
||||||
|
def PathParserProvider(self):
|
||||||
|
parser = parserProvider(self)
|
||||||
|
parser.add_argument("url", help="url")
|
||||||
|
return parser
|
||||||
|
return PathParserProvider
|
||||||
|
|
||||||
|
def AddUsernamePasswordParser(parserProvider):
|
||||||
|
def PathParserProvider(self):
|
||||||
|
parser = parserProvider(self)
|
||||||
|
parser.add_argument("username", help="username", nargs="?")
|
||||||
|
parser.add_argument("password", help="password", nargs="?")
|
||||||
|
return parser
|
||||||
|
return PathParserProvider
|
||||||
|
|
||||||
|
async def PathCompleter(self, text, line, begidx, endidx, filterFiles):
|
||||||
|
father, sonName = await self.client.PathToFatherNodeAndNodeName(text)
|
||||||
|
if not IsDir(father):
|
||||||
|
return []
|
||||||
|
matches = []
|
||||||
|
matchesNode = []
|
||||||
|
for childId in father.childrenId:
|
||||||
|
child = self.client.GetNodeById(childId)
|
||||||
|
if filterFiles and IsFile(child):
|
||||||
|
continue
|
||||||
|
if child.name.startswith(sonName):
|
||||||
|
self.display_matches.append(child.name)
|
||||||
|
if sonName == "":
|
||||||
|
matches.append(text + child.name)
|
||||||
|
elif text.endswith(sonName):
|
||||||
|
matches.append(text[:text.rfind(sonName)] + child.name)
|
||||||
|
matchesNode.append(child)
|
||||||
|
if len(matchesNode) == 1 and IsDir(matchesNode[0]):
|
||||||
|
matches[0] += "/"
|
||||||
|
self.allow_appended_space = False
|
||||||
|
self.allow_closing_quote = False
|
||||||
|
return matches
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__()
|
||||||
|
self._setup_logging()
|
||||||
|
self.client = PKVirtFs("token.json", proxy="http://127.0.0.1:7897")
|
||||||
|
|
||||||
async def Run(self):
|
async def Run(self):
|
||||||
# 1. 设置忽略SIGINT
|
# 1. 设置忽略SIGINT
|
||||||
import signal
|
import signal
|
||||||
@ -121,6 +172,8 @@ class PikpakConsole(cmd2.Cmd):
|
|||||||
self.ioLoop.call_soon_threadsafe(self.ioLoop.stop)
|
self.ioLoop.call_soon_threadsafe(self.ioLoop.stop)
|
||||||
thread.join()
|
thread.join()
|
||||||
|
|
||||||
|
# commands #
|
||||||
|
|
||||||
def do_debug(self, args):
|
def do_debug(self, args):
|
||||||
"""
|
"""
|
||||||
Enable debug mode
|
Enable debug mode
|
||||||
@ -135,12 +188,8 @@ class PikpakConsole(cmd2.Cmd):
|
|||||||
logging.getLogger().setLevel(logging.INFO)
|
logging.getLogger().setLevel(logging.INFO)
|
||||||
logging.info("Debug mode disabled")
|
logging.info("Debug mode disabled")
|
||||||
|
|
||||||
login_parser = cmd2.Cmd2ArgumentParser()
|
|
||||||
login_parser.add_argument("username", help="username", nargs="?")
|
|
||||||
login_parser.add_argument("password", help="password", nargs="?")
|
|
||||||
|
|
||||||
@RunSync
|
@RunSync
|
||||||
@cmd2.with_argparser(login_parser)
|
@ProvideDecoratorSelfArgs(cmd2.with_argparser, AddUsernamePasswordParser(ParserProvider))
|
||||||
async def do_login(self, args):
|
async def do_login(self, args):
|
||||||
"""
|
"""
|
||||||
Login to pikpak
|
Login to pikpak
|
||||||
@ -148,44 +197,6 @@ class PikpakConsole(cmd2.Cmd):
|
|||||||
await self.client.Login(args.username, args.password)
|
await self.client.Login(args.username, args.password)
|
||||||
await self.aoutput("Logged in successfully")
|
await self.aoutput("Logged in successfully")
|
||||||
|
|
||||||
def ParserProvider(self):
|
|
||||||
return cmd2.Cmd2ArgumentParser()
|
|
||||||
|
|
||||||
def AddPathParser(parserProvider):
|
|
||||||
def PathParserProvider(self):
|
|
||||||
parser = parserProvider(self)
|
|
||||||
parser.add_argument("path", help="path", default="", nargs="?", type=RunSyncInLoop(self.loop)(self.client.PathToNode))
|
|
||||||
return parser
|
|
||||||
return PathParserProvider
|
|
||||||
|
|
||||||
|
|
||||||
async def PathCompleter(self, text, line, begidx, endidx, filterFiles):
|
|
||||||
father, sonName = await self.client.PathToFatherNodeAndNodeName(text)
|
|
||||||
fatherDir = self.client.ToDir(father)
|
|
||||||
if fatherDir is None:
|
|
||||||
return []
|
|
||||||
|
|
||||||
matches = []
|
|
||||||
matchesNode = []
|
|
||||||
for childId in fatherDir.childrenId:
|
|
||||||
node = self.client.nodes[childId]
|
|
||||||
if filterFiles and isinstance(node, FileNode):
|
|
||||||
continue
|
|
||||||
if node.name.startswith(sonName):
|
|
||||||
self.display_matches.append(node.name)
|
|
||||||
if sonName == "":
|
|
||||||
matches.append(text + node.name)
|
|
||||||
elif text.endswith(sonName):
|
|
||||||
matches.append(text[:text.rfind(sonName)] + node.name)
|
|
||||||
matchesNode.append(node)
|
|
||||||
|
|
||||||
if len(matchesNode) == 1 and self.client.ToDir(matchesNode[0]) is not None:
|
|
||||||
matches[0] += "/"
|
|
||||||
self.allow_appended_space = False
|
|
||||||
self.allow_closing_quote = False
|
|
||||||
|
|
||||||
return matches
|
|
||||||
|
|
||||||
@RunSync
|
@RunSync
|
||||||
async def complete_ls(self, text, line, begidx, endidx):
|
async def complete_ls(self, text, line, begidx, endidx):
|
||||||
return await self.PathCompleter(text, line, begidx, endidx, filterFiles = False)
|
return await self.PathCompleter(text, line, begidx, endidx, filterFiles = False)
|
||||||
@ -196,13 +207,14 @@ class PikpakConsole(cmd2.Cmd):
|
|||||||
"""
|
"""
|
||||||
List files in a directory
|
List files in a directory
|
||||||
"""
|
"""
|
||||||
if isinstance(args.path, DirNode):
|
node = args.path
|
||||||
for childId in args.path.childrenId:
|
if IsDir(node):
|
||||||
node = self.client.nodes[childId]
|
for childId in node.childrenId:
|
||||||
await self.aoutput(node.name)
|
child = self.client.GetNodeById(childId)
|
||||||
elif isinstance(args.path, FileNode):
|
await self.aoutput(child.name)
|
||||||
await self.client.UpdateDownloadUrl(args.path)
|
elif IsFile(node):
|
||||||
await self.aoutput(f"{args.path.name}: {args.path.url}")
|
await self.client.Refresh(node)
|
||||||
|
await self.aoutput(f"{node.name}: {node.url}")
|
||||||
else:
|
else:
|
||||||
await self.aoutput("Invalid path")
|
await self.aoutput("Invalid path")
|
||||||
|
|
||||||
@ -216,10 +228,11 @@ class PikpakConsole(cmd2.Cmd):
|
|||||||
"""
|
"""
|
||||||
Change directory
|
Change directory
|
||||||
"""
|
"""
|
||||||
if self.client.ToDir(args.path) is None:
|
node = args.path
|
||||||
|
if not IsDir(node):
|
||||||
await self.aoutput("Invalid directory")
|
await self.aoutput("Invalid directory")
|
||||||
return
|
return
|
||||||
self.client.currentLocation = args.path
|
self.client.currentLocation = node
|
||||||
|
|
||||||
@RunSync
|
@RunSync
|
||||||
async def do_cwd(self, args):
|
async def do_cwd(self, args):
|
||||||
@ -250,13 +263,6 @@ class PikpakConsole(cmd2.Cmd):
|
|||||||
async def complete_mkdir(self, text, line, begidx, endidx):
|
async def complete_mkdir(self, text, line, begidx, endidx):
|
||||||
return await self.PathCompleter(text, line, begidx, endidx, filterFiles = True)
|
return await self.PathCompleter(text, line, begidx, endidx, filterFiles = True)
|
||||||
|
|
||||||
def AddFatherAndSonParser(parserProvider):
|
|
||||||
def PathParserProvider(self):
|
|
||||||
parser = parserProvider(self)
|
|
||||||
parser.add_argument("path", help="path", default="", nargs="?", type=RunSyncInLoop(self.loop)(self.client.PathToFatherNodeAndNodeName))
|
|
||||||
return parser
|
|
||||||
return PathParserProvider
|
|
||||||
|
|
||||||
@RunSync
|
@RunSync
|
||||||
@ProvideDecoratorSelfArgs(cmd2.with_argparser, AddFatherAndSonParser(ParserProvider))
|
@ProvideDecoratorSelfArgs(cmd2.with_argparser, AddFatherAndSonParser(ParserProvider))
|
||||||
async def do_mkdir(self, args):
|
async def do_mkdir(self, args):
|
||||||
@ -264,23 +270,14 @@ class PikpakConsole(cmd2.Cmd):
|
|||||||
Create a directory
|
Create a directory
|
||||||
"""
|
"""
|
||||||
father, sonName = args.path
|
father, sonName = args.path
|
||||||
fatherDir = self.client.ToDir(father)
|
if not IsDir(father) or sonName == "" or sonName == None:
|
||||||
if fatherDir == None or sonName == "" or sonName == None:
|
|
||||||
await self.aoutput("Invalid path")
|
await self.aoutput("Invalid path")
|
||||||
return
|
return
|
||||||
childNode = self.client.FindChildInDirByName(fatherDir, sonName)
|
child = self.client.FindChildInDirByName(father, sonName)
|
||||||
if childNode is not None:
|
if child is not None:
|
||||||
await self.aoutput("Path already exists")
|
await self.aoutput("Path already exists")
|
||||||
return
|
return
|
||||||
for i in range(1, 10):
|
await self.client.MakeDir(father, sonName)
|
||||||
await self.client.MakeDir(fatherDir, sonName + str(i))
|
|
||||||
|
|
||||||
def AddUrlParser(parserProvider):
|
|
||||||
def PathParserProvider(self):
|
|
||||||
parser = parserProvider(self)
|
|
||||||
parser.add_argument("url", help="url")
|
|
||||||
return parser
|
|
||||||
return PathParserProvider
|
|
||||||
|
|
||||||
@RunSync
|
@RunSync
|
||||||
@ProvideDecoratorSelfArgs(cmd2.with_argparser, AddPathParser(AddUrlParser(ParserProvider)))
|
@ProvideDecoratorSelfArgs(cmd2.with_argparser, AddPathParser(AddUrlParser(ParserProvider)))
|
||||||
@ -288,10 +285,11 @@ class PikpakConsole(cmd2.Cmd):
|
|||||||
"""
|
"""
|
||||||
Download a file
|
Download a file
|
||||||
"""
|
"""
|
||||||
if self.client.ToDir(args.path) is None:
|
node = args.path
|
||||||
|
if not IsDir(node):
|
||||||
await self.aoutput("Invalid directory")
|
await self.aoutput("Invalid directory")
|
||||||
return
|
return
|
||||||
await self.client.Download(args.url, args.path)
|
await self.client.Download(args.url, node)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
147
pikpakFs.py
147
pikpakFs.py
@ -42,6 +42,12 @@ class FileNode(VirtFsNode):
|
|||||||
super().__init__(id, name, fatherId)
|
super().__init__(id, name, fatherId)
|
||||||
self.url : str = None
|
self.url : str = None
|
||||||
|
|
||||||
|
def IsDir(node : VirtFsNode) -> bool:
|
||||||
|
return isinstance(node, DirNode)
|
||||||
|
|
||||||
|
def IsFile(node : VirtFsNode) -> bool:
|
||||||
|
return isinstance(node, FileNode)
|
||||||
|
|
||||||
class PikpakToken:
|
class PikpakToken:
|
||||||
def __init__(self, username, password, access_token, refresh_token, user_id):
|
def __init__(self, username, password, access_token, refresh_token, user_id):
|
||||||
self.username = username
|
self.username = username
|
||||||
@ -67,16 +73,16 @@ class PKVirtFs:
|
|||||||
self.loginCachePath = loginCachePath
|
self.loginCachePath = loginCachePath
|
||||||
self.proxyConfig = proxy
|
self.proxyConfig = proxy
|
||||||
self.client : PikPakApi = None
|
self.client : PikPakApi = None
|
||||||
self.__TryLoginFromCache()
|
self._try_login_from_cache()
|
||||||
|
|
||||||
def __InitClientByToken(self, token : PikpakToken):
|
def _init_client_by_token(self, token : PikpakToken):
|
||||||
self.__InitClientByUsernamePassword(token.username, token.password)
|
self._init_client_by_username_and_password(token.username, token.password)
|
||||||
self.client.access_token = token.access_token
|
self.client.access_token = token.access_token
|
||||||
self.client.refresh_token = token.refresh_token
|
self.client.refresh_token = token.refresh_token
|
||||||
self.client.user_id = token.user_id
|
self.client.user_id = token.user_id
|
||||||
self.client.encode_token()
|
self.client.encode_token()
|
||||||
|
|
||||||
def __InitClientByUsernamePassword(self, username : str, password : str):
|
def _init_client_by_username_and_password(self, username : str, password : str):
|
||||||
httpx_client_args = None
|
httpx_client_args = None
|
||||||
if self.proxyConfig != None:
|
if self.proxyConfig != None:
|
||||||
httpx_client_args = {
|
httpx_client_args = {
|
||||||
@ -89,7 +95,7 @@ class PKVirtFs:
|
|||||||
password = password,
|
password = password,
|
||||||
httpx_client_args=httpx_client_args)
|
httpx_client_args=httpx_client_args)
|
||||||
|
|
||||||
def __TryLoginFromCache(self):
|
def _try_login_from_cache(self):
|
||||||
if self.loginCachePath is None:
|
if self.loginCachePath is None:
|
||||||
return
|
return
|
||||||
if not os.path.exists(self.loginCachePath):
|
if not os.path.exists(self.loginCachePath):
|
||||||
@ -97,10 +103,10 @@ class PKVirtFs:
|
|||||||
with open(self.loginCachePath, 'r', encoding='utf-8') as file:
|
with open(self.loginCachePath, 'r', encoding='utf-8') as file:
|
||||||
content = file.read()
|
content = file.read()
|
||||||
token = PikpakToken.from_json(content)
|
token = PikpakToken.from_json(content)
|
||||||
self.__InitClientByToken(token)
|
self._init_client_by_token(token)
|
||||||
logging.info("successfully load login info from cache")
|
logging.info("successfully load login info from cache")
|
||||||
|
|
||||||
def __DumpLoginInfo(self):
|
def _dump_login_info(self):
|
||||||
if self.loginCachePath is None:
|
if self.loginCachePath is None:
|
||||||
return
|
return
|
||||||
with open(self.loginCachePath, 'w', encoding='utf-8') as file:
|
with open(self.loginCachePath, 'w', encoding='utf-8') as file:
|
||||||
@ -108,31 +114,26 @@ class PKVirtFs:
|
|||||||
file.write(token.to_json())
|
file.write(token.to_json())
|
||||||
logging.info("successfully dump login info to cache")
|
logging.info("successfully dump login info to cache")
|
||||||
|
|
||||||
def __IsAncestorsOf(self, nodeA : VirtFsNode, nodeB : VirtFsNode) -> bool:
|
def _is_ancestors_of(self, nodeA : VirtFsNode, nodeB : VirtFsNode) -> bool:
|
||||||
if nodeB is nodeA:
|
if nodeB is nodeA:
|
||||||
return False
|
return False
|
||||||
if nodeA is self.root:
|
if nodeA is self.root:
|
||||||
return True
|
return True
|
||||||
while nodeB.fatherId != None:
|
while nodeB.fatherId != self.root.id:
|
||||||
nodeB = self.nodes[nodeB.fatherId]
|
nodeB = self.nodes[nodeB.fatherId]
|
||||||
if nodeB is nodeA:
|
if nodeB is nodeA:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def ToDir(self, node : VirtFsNode) -> DirNode:
|
def GetNodeById(self, id : str) -> VirtFsNode:
|
||||||
if isinstance(node, DirNode):
|
if id == self.root.id:
|
||||||
return node
|
return self.root
|
||||||
return None
|
return self.nodes[id]
|
||||||
|
|
||||||
def ToFile(self, node : VirtFsNode) -> FileNode:
|
|
||||||
if isinstance(node, FileNode):
|
|
||||||
return node
|
|
||||||
return None
|
|
||||||
|
|
||||||
def GetFatherNode(self, node : VirtFsNode) -> VirtFsNode:
|
def GetFatherNode(self, node : VirtFsNode) -> VirtFsNode:
|
||||||
if node is self.root or node.fatherId == self.root.id:
|
if node is self.root:
|
||||||
return self.root
|
return self.root
|
||||||
return self.nodes[node.fatherId]
|
return self.GetNodeById(node.fatherId)
|
||||||
|
|
||||||
def FindChildInDirByName(self, dir : DirNode, name : str):
|
def FindChildInDirByName(self, dir : DirNode, name : str):
|
||||||
if dir is self.root and name == "":
|
if dir is self.root and name == "":
|
||||||
@ -143,39 +144,46 @@ class PKVirtFs:
|
|||||||
return node
|
return node
|
||||||
return None
|
return None
|
||||||
|
|
||||||
async def RefreshDirectory(self, dirNode : DirNode):
|
async def Refresh(self, node : VirtFsNode):
|
||||||
next_page_token = None
|
if node.lastUpdate != None:
|
||||||
nodes = []
|
return
|
||||||
while True:
|
|
||||||
dirInfo = await self.client.file_list(parent_id = dirNode.id, next_page_token=next_page_token)
|
|
||||||
next_page_token = dirInfo["next_page_token"]
|
|
||||||
currentPageNodes = dirInfo["files"]
|
|
||||||
nodes.extend(currentPageNodes)
|
|
||||||
if next_page_token is None or next_page_token == "":
|
|
||||||
break
|
|
||||||
dirNode.childrenId.clear()
|
|
||||||
|
|
||||||
for node in nodes:
|
if IsDir(node):
|
||||||
child : VirtFsNode = None
|
next_page_token = None
|
||||||
id = node["id"]
|
childrenInfo = []
|
||||||
name = node["name"]
|
while True:
|
||||||
fatherId = dirNode.id
|
dirInfo = await self.client.file_list(parent_id = node.id, next_page_token=next_page_token)
|
||||||
if id in self.nodes:
|
next_page_token = dirInfo["next_page_token"]
|
||||||
child = self.nodes[id]
|
currentPageNodes = dirInfo["files"]
|
||||||
else:
|
childrenInfo.extend(currentPageNodes)
|
||||||
child = DirNode(id, name, fatherId) if node["kind"].endswith("folder") else FileNode(id, name, fatherId)
|
if next_page_token is None or next_page_token == "":
|
||||||
self.nodes[id] = child
|
break
|
||||||
child.name = name
|
node.childrenId.clear()
|
||||||
child.fatherId = fatherId
|
|
||||||
dirNode.childrenId.append(id)
|
for childInfo in childrenInfo:
|
||||||
dirNode.lastUpdate = datetime.now()
|
child : VirtFsNode = None
|
||||||
|
id = childInfo["id"]
|
||||||
|
name = childInfo["name"]
|
||||||
|
fatherId = node.id
|
||||||
|
if id in self.nodes:
|
||||||
|
child = self.nodes[id]
|
||||||
|
else:
|
||||||
|
child = DirNode(id, name, fatherId) if childInfo["kind"].endswith("folder") else FileNode(id, name, fatherId)
|
||||||
|
self.nodes[id] = child
|
||||||
|
child.name = name
|
||||||
|
child.fatherId = fatherId
|
||||||
|
node.childrenId.append(id)
|
||||||
|
elif IsFile(node):
|
||||||
|
result = await self.client.get_download_url(node.id)
|
||||||
|
node.url = result["web_content_link"]
|
||||||
|
|
||||||
|
node.lastUpdate = datetime.now()
|
||||||
|
|
||||||
async def PathToNode(self, pathStr : str) -> VirtFsNode:
|
async def PathToNode(self, pathStr : str) -> VirtFsNode:
|
||||||
father, sonName = await self.PathToFatherNodeAndNodeName(pathStr)
|
father, sonName = await self.PathToFatherNodeAndNodeName(pathStr)
|
||||||
if sonName == "":
|
if sonName == "":
|
||||||
return father
|
return father
|
||||||
fatherDir = self.ToDir(father)
|
if not IsDir(father):
|
||||||
if fatherDir is None:
|
|
||||||
return None
|
return None
|
||||||
return self.FindChildInDirByName(father, sonName)
|
return self.FindChildInDirByName(father, sonName)
|
||||||
|
|
||||||
@ -193,21 +201,18 @@ class PKVirtFs:
|
|||||||
current = self.GetFatherNode(current)
|
current = self.GetFatherNode(current)
|
||||||
continue
|
continue
|
||||||
father = current
|
father = current
|
||||||
currentDir = self.ToDir(current)
|
if not IsDir(current):
|
||||||
if currentDir is None:
|
|
||||||
current = None
|
current = None
|
||||||
continue
|
continue
|
||||||
if currentDir.lastUpdate is None:
|
await self.Refresh(current)
|
||||||
await self.RefreshDirectory(currentDir)
|
|
||||||
if spot == ".":
|
if spot == ".":
|
||||||
continue
|
continue
|
||||||
sonName = spot
|
sonName = spot
|
||||||
current = self.FindChildInDirByName(currentDir, spot)
|
current = self.FindChildInDirByName(current, spot)
|
||||||
|
|
||||||
if current != None:
|
if current != None:
|
||||||
currentDir = self.ToDir(current)
|
if IsDir(current):
|
||||||
if currentDir != None and currentDir.lastUpdate is None:
|
await self.Refresh(current)
|
||||||
await self.RefreshDirectory(currentDir)
|
|
||||||
father = self.GetFatherNode(current)
|
father = self.GetFatherNode(current)
|
||||||
sonName = current.name
|
sonName = current.name
|
||||||
|
|
||||||
@ -218,19 +223,13 @@ class PKVirtFs:
|
|||||||
return "/"
|
return "/"
|
||||||
spots : list[str] = []
|
spots : list[str] = []
|
||||||
current = node
|
current = node
|
||||||
while current.id != None:
|
while current is not self.root:
|
||||||
spots.append(current.name)
|
spots.append(current.name)
|
||||||
if current.fatherId is None:
|
current = self.GetFatherNode(current)
|
||||||
break
|
|
||||||
current = self.nodes[current.fatherId]
|
|
||||||
spots.append("")
|
spots.append("")
|
||||||
return "/".join(reversed(spots))
|
return "/".join(reversed(spots))
|
||||||
|
|
||||||
async def MakeDir(self, node : DirNode, name : str) -> DirNode:
|
# commands #
|
||||||
await self.client.create_folder(name, node.id)
|
|
||||||
await self.RefreshDirectory(node)
|
|
||||||
return self.ToDir(self.FindChildInDirByName(node, name))
|
|
||||||
|
|
||||||
async def Login(self, username : str = None, password : str = None) -> None:
|
async def Login(self, username : str = None, password : str = None) -> None:
|
||||||
if self.client != None and username is None and password is None:
|
if self.client != None and username is None and password is None:
|
||||||
username = self.client.username
|
username = self.client.username
|
||||||
@ -239,28 +238,26 @@ class PKVirtFs:
|
|||||||
if username == None and password == None:
|
if username == None and password == None:
|
||||||
raise Exception("Username and password are required")
|
raise Exception("Username and password are required")
|
||||||
|
|
||||||
self.__InitClientByUsernamePassword(username, password)
|
self._init_client_by_username_and_password(username, password)
|
||||||
await self.client.login()
|
await self.client.login()
|
||||||
self.__DumpLoginInfo()
|
self._dump_login_info()
|
||||||
|
|
||||||
async def UpdateDownloadUrl(self, file : FileNode) -> None:
|
async def MakeDir(self, node : DirNode, name : str) -> DirNode:
|
||||||
result = await self.client.get_download_url(file.id)
|
await self.client.create_folder(name, node.id)
|
||||||
file.url = result["web_content_link"]
|
await self.Refresh(node)
|
||||||
|
return self.FindChildInDirByName(node, name)
|
||||||
|
|
||||||
async def Download(self, url : str, dirNode : DirNode) -> None :
|
async def Download(self, url : str, dirNode : DirNode) -> None :
|
||||||
# 默认创建在当前目录下
|
# 默认创建在当前目录下
|
||||||
# todo: 完善离线下载task相关
|
# todo: 完善离线下载task相关
|
||||||
if dirNode is None:
|
|
||||||
dirNode = self.currentLocation
|
|
||||||
await self.client.offline_download(url, dirNode.id)
|
await self.client.offline_download(url, dirNode.id)
|
||||||
|
|
||||||
async def Delete(self, node : VirtFsNode) -> None:
|
async def Delete(self, node : VirtFsNode) -> None:
|
||||||
father = self.GetFatherNode(node)
|
father = self.GetFatherNode(node)
|
||||||
fatherDir = self.ToDir(father)
|
if not IsDir(father):
|
||||||
if fatherDir is None:
|
|
||||||
raise Exception('Failed to locate')
|
raise Exception('Failed to locate')
|
||||||
if self.currentLocation is node or self.__IsAncestorsOf(node, self.currentLocation):
|
if self.currentLocation is node or self._is_ancestors_of(node, self.currentLocation):
|
||||||
raise Exception('Delete self or ancestor is not allowed')
|
raise Exception('Delete self or ancestor is not allowed')
|
||||||
|
|
||||||
await self.client.delete_to_trash([node.id])
|
await self.client.delete_to_trash([node.id])
|
||||||
await self.RefreshDirectory(fatherDir)
|
await self.Refresh(father)
|
Loading…
x
Reference in New Issue
Block a user