调整完毕
This commit is contained in:
parent
2aa4d0870b
commit
72ecb98c56
@ -221,12 +221,14 @@ class PikPakFileSystem:
|
|||||||
|
|
||||||
return father, sonName
|
return father, sonName
|
||||||
|
|
||||||
async def _node_to_path(self, node : NodeBase) -> str:
|
async def _node_to_path(self, node : NodeBase, root : NodeBase = None) -> str:
|
||||||
if node is self._root:
|
if root is None:
|
||||||
|
root = self._root
|
||||||
|
if node is root:
|
||||||
return "/"
|
return "/"
|
||||||
spots : list[str] = []
|
spots : list[str] = []
|
||||||
current = node
|
current = node
|
||||||
while current is not self._root:
|
while current is not root:
|
||||||
spots.append(current.name)
|
spots.append(current.name)
|
||||||
current = await self._get_father_node(current)
|
current = await self._get_father_node(current)
|
||||||
spots.append("")
|
spots.append("")
|
||||||
@ -307,18 +309,20 @@ class PikPakFileSystem:
|
|||||||
async def GetCwd(self) -> str:
|
async def GetCwd(self) -> str:
|
||||||
return await self._node_to_path(self._cwd)
|
return await self._node_to_path(self._cwd)
|
||||||
|
|
||||||
async def GetNodeIdByPath(self, path : str) -> str:
|
async def GetChildren(self, node : NodeBase) -> list[NodeBase]:
|
||||||
|
if not isinstance(node, DirNode):
|
||||||
|
return []
|
||||||
|
await self._refresh(node)
|
||||||
|
return [await self._get_node_by_id(child_id) for child_id in node.children_id]
|
||||||
|
|
||||||
|
async def PathToNode(self, path : str) -> NodeBase:
|
||||||
node = await self._path_to_node(path)
|
node = await self._path_to_node(path)
|
||||||
if node is None:
|
if node is None:
|
||||||
return None
|
return None
|
||||||
return node.id
|
return node
|
||||||
|
|
||||||
async def IfExists(self, path : str) -> bool:
|
async def NodeToPath(self, from_node : NodeBase, to_node : NodeBase) -> str:
|
||||||
return await self._path_to_node(path) is not None
|
return await self._node_to_path(to_node, from_node)
|
||||||
|
|
||||||
async def ToFullPath(self, path : str) -> str:
|
|
||||||
node = await self._path_to_node(path)
|
|
||||||
return await self._node_to_path(node)
|
|
||||||
|
|
||||||
async def RemoteDownload(self, torrent : str, remote_base_path : str) -> tuple[str, str]:
|
async def RemoteDownload(self, torrent : str, remote_base_path : str) -> tuple[str, str]:
|
||||||
node = await self._path_to_node(remote_base_path)
|
node = await self._path_to_node(remote_base_path)
|
||||||
@ -328,25 +332,19 @@ class PikPakFileSystem:
|
|||||||
async def QueryTaskStatus(self, task_id : str, node_id : str) -> DownloadStatus:
|
async def QueryTaskStatus(self, task_id : str, node_id : str) -> DownloadStatus:
|
||||||
return await self._pikpak_client.get_task_status(task_id, node_id)
|
return await self._pikpak_client.get_task_status(task_id, node_id)
|
||||||
|
|
||||||
async def UpdateDirectory(self, path : str, son_id : str) -> str:
|
async def UpdateNode(self, node_id : str) -> NodeBase:
|
||||||
await self._path_to_node(path)
|
node : NodeBase = await self._get_node_by_id(node_id)
|
||||||
son_info = await self._pikpak_client.offline_file_info(son_id)
|
if node is None:
|
||||||
kind = son_info["kind"]
|
info = await self._pikpak_client.offline_file_info(node_id)
|
||||||
parent_id = son_info["parent_id"]
|
kind = info["kind"]
|
||||||
name = son_info["name"]
|
parent_id = info["parent_id"]
|
||||||
son : NodeBase = None
|
name = info["name"]
|
||||||
if kind.endswith("folder"):
|
if kind.endswith("folder"):
|
||||||
son = DirNode(son_id, name, parent_id)
|
node = DirNode(node_id, name, parent_id)
|
||||||
else:
|
else:
|
||||||
son = FileNode(son_id, name, parent_id)
|
node = FileNode(node_id, name, parent_id)
|
||||||
await self._add_node(son)
|
await self._add_node(node)
|
||||||
return await self._node_to_path(son)
|
node.lastUpdate = None
|
||||||
|
return node
|
||||||
async def JoinPath(self, father : str, son : str) -> str:
|
|
||||||
father_node = await self._path_to_node(father)
|
|
||||||
son_node = await self._find_child_in_dir_by_name(father_node, son)
|
|
||||||
if son_node is None:
|
|
||||||
raise Exception("Son not found")
|
|
||||||
return await self._node_to_path(son_node)
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
@ -3,7 +3,7 @@ from typing import Awaitable, Callable, Dict
|
|||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
import shortuuid
|
import shortuuid
|
||||||
from PikPakFileSystem import PikPakFileSystem
|
from PikPakFileSystem import PikPakFileSystem, FileNode, DirNode
|
||||||
from pikpakapi import DownloadStatus
|
from pikpakapi import DownloadStatus
|
||||||
import random
|
import random
|
||||||
|
|
||||||
@ -49,11 +49,11 @@ class TorrentTask(TaskBase):
|
|||||||
super().__init__(self)
|
super().__init__(self)
|
||||||
self.torrent_status : TorrentTaskStatus = TorrentTaskStatus.PENDING
|
self.torrent_status : TorrentTaskStatus = TorrentTaskStatus.PENDING
|
||||||
self.torrent : str = torrent
|
self.torrent : str = torrent
|
||||||
self.remote_full_path : str = None
|
|
||||||
self.remote_base_path : str = None
|
|
||||||
self.info : str = ""
|
self.info : str = ""
|
||||||
|
self.name : str = ""
|
||||||
|
|
||||||
# 和PikPak交互需要的信息
|
# 和PikPak交互需要的信息
|
||||||
|
self.remote_base_path : str = None
|
||||||
self.node_id : str = None
|
self.node_id : str = None
|
||||||
self.task_id : str = None
|
self.task_id : str = None
|
||||||
|
|
||||||
@ -62,9 +62,10 @@ class FileDownloadTask(TaskBase):
|
|||||||
TAG = "FileDownloadTask"
|
TAG = "FileDownloadTask"
|
||||||
MAX_CONCURRENT_NUMBER = 5
|
MAX_CONCURRENT_NUMBER = 5
|
||||||
|
|
||||||
def __init__(self, remote_path : str, owner_id : str):
|
def __init__(self, node_id : str, remote_path : str, owner_id : str):
|
||||||
super().__init__(self)
|
super().__init__(self)
|
||||||
self.file_download_status : FileDownloadTaskStatus = FileDownloadTaskStatus.PENDING
|
self.file_download_status : FileDownloadTaskStatus = FileDownloadTaskStatus.PENDING
|
||||||
|
self.node_id : str = node_id
|
||||||
self.remote_path : str = remote_path
|
self.remote_path : str = remote_path
|
||||||
self.owner_id : str = owner_id
|
self.owner_id : str = owner_id
|
||||||
|
|
||||||
@ -141,25 +142,28 @@ class TaskManager:
|
|||||||
await asyncio.sleep(wait_seconds)
|
await asyncio.sleep(wait_seconds)
|
||||||
wait_seconds = wait_seconds * 1.5
|
wait_seconds = wait_seconds * 1.5
|
||||||
|
|
||||||
task.remote_full_path = await self.client.UpdateDirectory(task.remote_base_path, task.node_id)
|
|
||||||
task.torrent_status = TorrentTaskStatus.LOCAL_DOWNLOADING
|
task.torrent_status = TorrentTaskStatus.LOCAL_DOWNLOADING
|
||||||
|
|
||||||
async def _on_torrent_local_downloading(self, task : TorrentTask):
|
async def _on_torrent_local_downloading(self, task : TorrentTask):
|
||||||
path = task.remote_full_path
|
node = await self.client.UpdateNode(task.node_id)
|
||||||
|
task.name = node.name
|
||||||
|
task.node_id = node.id
|
||||||
|
|
||||||
if not await self.client.IsDir(path):
|
if isinstance(node, FileNode):
|
||||||
await self._init_file_download_task(path, task.id)
|
await self._init_file_download_task(task.node_id, task.name, task.id)
|
||||||
else:
|
elif isinstance(node, DirNode):
|
||||||
# 使用广度优先遍历
|
# 使用广度优先遍历
|
||||||
queue : list[str] = [path]
|
queue : list[str] = [node]
|
||||||
while len(queue) > 0:
|
while len(queue) > 0:
|
||||||
current_path = queue.pop(0)
|
current = queue.pop(0)
|
||||||
for child_name in await self.client.GetChildrenNames(current_path, False):
|
for child in await self.client.GetChildren(current):
|
||||||
child_path = await self.client.JoinPath(current_path, child_name)
|
if isinstance(child, DirNode):
|
||||||
if await self.client.IsDir(child_path):
|
queue.append(child)
|
||||||
queue.append(child_path)
|
if isinstance(child, FileNode):
|
||||||
|
child_path = task.name + await self.client.NodeToPath(node, child)
|
||||||
|
await self._init_file_download_task(child.id, child_path, task.id)
|
||||||
else:
|
else:
|
||||||
await self._init_file_download_task(child_path, task.id)
|
raise Exception("unknown node type")
|
||||||
|
|
||||||
# 开始等待下载任务完成
|
# 开始等待下载任务完成
|
||||||
while True:
|
while True:
|
||||||
@ -214,22 +218,21 @@ class TaskManager:
|
|||||||
|
|
||||||
|
|
||||||
#region 文件下载部分
|
#region 文件下载部分
|
||||||
async def _init_file_download_task(self, remote_path : str, owner_id : str) -> str:
|
async def _init_file_download_task(self, node_id : str, remote_path : str, owner_id : str) -> str:
|
||||||
queue = await self._get_file_download_queue(owner_id)
|
queue = await self._get_file_download_queue(owner_id)
|
||||||
for task in queue:
|
for task in queue:
|
||||||
if not isinstance(task, FileDownloadTask):
|
if not isinstance(task, FileDownloadTask):
|
||||||
continue
|
continue
|
||||||
if task.remote_path == remote_path:
|
if task.node_id == node_id:
|
||||||
if task.status in {TaskStatus.PAUSED, TaskStatus.ERROR}:
|
if task.status in {TaskStatus.PAUSED, TaskStatus.ERROR}:
|
||||||
task.status = TaskStatus.PENDING
|
task.status = TaskStatus.PENDING
|
||||||
return task.id
|
return task.id
|
||||||
task = FileDownloadTask(remote_path, owner_id)
|
task = FileDownloadTask(node_id, remote_path, owner_id)
|
||||||
task.handler = self._file_download_task_handler
|
task.handler = self._file_download_task_handler
|
||||||
await self._append_task(task)
|
await self._append_task(task)
|
||||||
return task.id
|
return task.id
|
||||||
|
|
||||||
async def _file_download_task_handler(self, task : FileDownloadTask):
|
async def _file_download_task_handler(self, task : FileDownloadTask):
|
||||||
await asyncio.sleep(30)
|
|
||||||
if random.randint(1, 5) == 2:
|
if random.randint(1, 5) == 2:
|
||||||
raise asyncio.CancelledError()
|
raise asyncio.CancelledError()
|
||||||
if random.randint(1, 5) == 3:
|
if random.randint(1, 5) == 3:
|
||||||
@ -260,17 +263,19 @@ class TaskManager:
|
|||||||
await self._append_task(task)
|
await self._append_task(task)
|
||||||
return task.id
|
return task.id
|
||||||
|
|
||||||
async def PullRemote(self, remote_full_path : str) -> str:
|
async def PullRemote(self, path : str) -> str:
|
||||||
if not await self.client.IfExists(remote_full_path):
|
target = await self.client.PathToNode(path)
|
||||||
|
if target is None:
|
||||||
raise Exception("target not found")
|
raise Exception("target not found")
|
||||||
queue = await self._get_torrent_queue()
|
queue = await self._get_torrent_queue()
|
||||||
for task in queue:
|
for task in queue:
|
||||||
if not isinstance(task, TorrentTask):
|
if not isinstance(task, TorrentTask):
|
||||||
continue
|
continue
|
||||||
if task.remote_full_path == remote_full_path:
|
if task.node_id == target.id:
|
||||||
return task.id
|
return task.id
|
||||||
task = TorrentTask(None)
|
task = TorrentTask(None)
|
||||||
task.remote_full_path = remote_full_path
|
task.name = target.name
|
||||||
|
task.node_id = target.id
|
||||||
task.handler = self._torrent_task_handler
|
task.handler = self._torrent_task_handler
|
||||||
task.torrent_status = TorrentTaskStatus.LOCAL_DOWNLOADING
|
task.torrent_status = TorrentTaskStatus.LOCAL_DOWNLOADING
|
||||||
await self._append_task(task)
|
await self._append_task(task)
|
||||||
|
12
main.py
12
main.py
@ -166,10 +166,10 @@ class App(cmd2.Cmd):
|
|||||||
await Client.Login(args.username, args.password)
|
await Client.Login(args.username, args.password)
|
||||||
await self.print("Logged in successfully")
|
await self.print("Logged in successfully")
|
||||||
|
|
||||||
async def _path_completer(self, text, line, begidx, endidx, ignoreFiles):
|
async def _path_completer(self, text, line, begidx, endidx, ignore_files):
|
||||||
father_path, son_name = await Client.SplitPath(text)
|
father_path, son_name = await Client.SplitPath(text)
|
||||||
children_names = await Client.GetChildrenNames(father_path, ignoreFiles)
|
children_names = await Client.GetChildrenNames(father_path, ignore_files)
|
||||||
matches = []
|
matches : list[str] = []
|
||||||
for child_name in children_names:
|
for child_name in children_names:
|
||||||
if child_name.startswith(son_name):
|
if child_name.startswith(son_name):
|
||||||
self.display_matches.append(child_name)
|
self.display_matches.append(child_name)
|
||||||
@ -177,8 +177,8 @@ class App(cmd2.Cmd):
|
|||||||
matches.append(text + child_name)
|
matches.append(text + child_name)
|
||||||
elif text.endswith(son_name):
|
elif text.endswith(son_name):
|
||||||
matches.append(text[:text.rfind(son_name)] + child_name)
|
matches.append(text[:text.rfind(son_name)] + child_name)
|
||||||
if len(matches) == 1 and await Client.IsDir(father_path + matches[0]):
|
if len(matches) == 1 and await Client.IsDir(matches[0]):
|
||||||
if matches[0] == son_name:
|
if matches[0].endswith(son_name):
|
||||||
matches[0] += "/"
|
matches[0] += "/"
|
||||||
self.allow_appended_space = False
|
self.allow_appended_space = False
|
||||||
self.allow_closing_quote = False
|
self.allow_closing_quote = False
|
||||||
@ -278,7 +278,7 @@ class App(cmd2.Cmd):
|
|||||||
"""
|
"""
|
||||||
Pull a file or directory
|
Pull a file or directory
|
||||||
"""
|
"""
|
||||||
task_id = await self.task_manager.PullRemote(await Client.ToFullPath(args.target))
|
task_id = await self.task_manager.PullRemote(args.target)
|
||||||
await self.print(f"Task {task_id} created")
|
await self.print(f"Task {task_id} created")
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user