p115client 0.0.5.14.2__tar.gz → 0.0.5.14.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {p115client-0.0.5.14.2 → p115client-0.0.5.14.4}/PKG-INFO +3 -3
- {p115client-0.0.5.14.2 → p115client-0.0.5.14.4}/p115client/client.py +8 -4
- {p115client-0.0.5.14.2 → p115client-0.0.5.14.4}/p115client/tool/iterdir.py +290 -11
- {p115client-0.0.5.14.2 → p115client-0.0.5.14.4}/pyproject.toml +3 -3
- {p115client-0.0.5.14.2 → p115client-0.0.5.14.4}/LICENSE +0 -0
- {p115client-0.0.5.14.2 → p115client-0.0.5.14.4}/p115client/__init__.py +0 -0
- {p115client-0.0.5.14.2 → p115client-0.0.5.14.4}/p115client/_upload.py +0 -0
- {p115client-0.0.5.14.2 → p115client-0.0.5.14.4}/p115client/const.py +0 -0
- {p115client-0.0.5.14.2 → p115client-0.0.5.14.4}/p115client/exception.py +0 -0
- {p115client-0.0.5.14.2 → p115client-0.0.5.14.4}/p115client/py.typed +0 -0
- {p115client-0.0.5.14.2 → p115client-0.0.5.14.4}/p115client/tool/__init__.py +0 -0
- {p115client-0.0.5.14.2 → p115client-0.0.5.14.4}/p115client/tool/attr.py +0 -0
- {p115client-0.0.5.14.2 → p115client-0.0.5.14.4}/p115client/tool/auth.py +0 -0
- {p115client-0.0.5.14.2 → p115client-0.0.5.14.4}/p115client/tool/download.py +0 -0
- {p115client-0.0.5.14.2 → p115client-0.0.5.14.4}/p115client/tool/edit.py +0 -0
- {p115client-0.0.5.14.2 → p115client-0.0.5.14.4}/p115client/tool/export_dir.py +0 -0
- {p115client-0.0.5.14.2 → p115client-0.0.5.14.4}/p115client/tool/fs_files.py +0 -0
- {p115client-0.0.5.14.2 → p115client-0.0.5.14.4}/p115client/tool/history.py +0 -0
- {p115client-0.0.5.14.2 → p115client-0.0.5.14.4}/p115client/tool/life.py +0 -0
- {p115client-0.0.5.14.2 → p115client-0.0.5.14.4}/p115client/tool/offline.py +0 -0
- {p115client-0.0.5.14.2 → p115client-0.0.5.14.4}/p115client/tool/pool.py +0 -0
- {p115client-0.0.5.14.2 → p115client-0.0.5.14.4}/p115client/tool/request.py +0 -0
- {p115client-0.0.5.14.2 → p115client-0.0.5.14.4}/p115client/tool/upload.py +0 -0
- {p115client-0.0.5.14.2 → p115client-0.0.5.14.4}/p115client/tool/util.py +0 -0
- {p115client-0.0.5.14.2 → p115client-0.0.5.14.4}/p115client/tool/xys.py +0 -0
- {p115client-0.0.5.14.2 → p115client-0.0.5.14.4}/p115client/type.py +0 -0
- {p115client-0.0.5.14.2 → p115client-0.0.5.14.4}/readme.md +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: p115client
|
3
|
-
Version: 0.0.5.14.
|
3
|
+
Version: 0.0.5.14.4
|
4
4
|
Summary: Python 115 webdisk client.
|
5
5
|
Home-page: https://github.com/ChenyangGao/p115client
|
6
6
|
License: MIT
|
@@ -29,7 +29,7 @@ Requires-Dist: iter_collect (>=0.0.5.1)
|
|
29
29
|
Requires-Dist: multidict
|
30
30
|
Requires-Dist: orjson
|
31
31
|
Requires-Dist: p115cipher (>=0.0.3)
|
32
|
-
Requires-Dist: p115pickcode (>=0.0.
|
32
|
+
Requires-Dist: p115pickcode (>=0.0.5)
|
33
33
|
Requires-Dist: posixpatht (>=0.0.3)
|
34
34
|
Requires-Dist: python-argtools (>=0.0.1)
|
35
35
|
Requires-Dist: python-asynctools (>=0.1.3)
|
@@ -41,7 +41,7 @@ Requires-Dist: python-filewrap (>=0.2.8)
|
|
41
41
|
Requires-Dist: python-hashtools (>=0.0.3.3)
|
42
42
|
Requires-Dist: python-http_request (>=0.0.6)
|
43
43
|
Requires-Dist: python-httpfile (>=0.0.5.2)
|
44
|
-
Requires-Dist: python-iterutils (>=0.2.5.
|
44
|
+
Requires-Dist: python-iterutils (>=0.2.5.4)
|
45
45
|
Requires-Dist: python-property (>=0.0.3)
|
46
46
|
Requires-Dist: python-startfile (>=0.0.2)
|
47
47
|
Requires-Dist: python-undefined (>=0.0.3)
|
@@ -693,7 +693,8 @@ def normalize_attr_web[D: dict[str, Any]](
|
|
693
693
|
if "te" in info:
|
694
694
|
attr["mtime"] = int(info["te"])
|
695
695
|
else:
|
696
|
-
|
696
|
+
if "pickcode" in attr:
|
697
|
+
attr["pick_code"] = attr["pickcode"]
|
697
698
|
attr["ico"] = info.get("ico", "folder" if is_dir else "")
|
698
699
|
if "te" in info:
|
699
700
|
attr["mtime"] = attr["user_utime"] = int(info["te"])
|
@@ -837,7 +838,8 @@ def normalize_attr_app[D: dict[str, Any]](
|
|
837
838
|
if "upt" in info:
|
838
839
|
attr["mtime"] = int(info["upt"])
|
839
840
|
else:
|
840
|
-
|
841
|
+
if "pickcode" in attr:
|
842
|
+
attr["pick_code"] = attr["pickcode"]
|
841
843
|
attr["ico"] = info.get("ico", "folder" if attr["is_dir"] else "")
|
842
844
|
if "thumb" in info:
|
843
845
|
thumb = info["thumb"]
|
@@ -980,7 +982,8 @@ def normalize_attr_app2[D: dict[str, Any]](
|
|
980
982
|
if "user_ptime" in info:
|
981
983
|
attr["mtime"] = int(info["user_ptime"])
|
982
984
|
else:
|
983
|
-
|
985
|
+
if "pickcode" in attr:
|
986
|
+
attr["pick_code"] = attr["pickcode"]
|
984
987
|
if is_dir:
|
985
988
|
if "thumb_url" in info:
|
986
989
|
attr["thumb"] = info["thumb_url"]
|
@@ -1620,7 +1623,7 @@ class ClientRequestMixin:
|
|
1620
1623
|
api = complete_api("/open/authorize", base_url=base_url)
|
1621
1624
|
payload = {"response_type": "code", **payload}
|
1622
1625
|
def parse(resp, content, /):
|
1623
|
-
if resp
|
1626
|
+
if get_status_code(resp) == 302:
|
1624
1627
|
return {
|
1625
1628
|
"state": True,
|
1626
1629
|
"url": resp.headers["location"],
|
@@ -2290,6 +2293,7 @@ class ClientRequestMixin:
|
|
2290
2293
|
|
2291
2294
|
:param app: 扫二维码后绑定的 `app` (或者叫 `device`)
|
2292
2295
|
:param console_qrcode: 在命令行输出二维码,否则在浏览器中打开
|
2296
|
+
:param base_url: 接口的基地址
|
2293
2297
|
:param async_: 是否异步
|
2294
2298
|
:param request_kwargs: 其它请求参数
|
2295
2299
|
|
@@ -11,27 +11,29 @@ __all__ = [
|
|
11
11
|
"ensure_attr_path", "ensure_attr_path_using_star_event",
|
12
12
|
"iterdir", "iter_stared_dirs", "iter_dirs", "iter_dirs_with_path",
|
13
13
|
"iter_files", "iter_files_with_path", "iter_files_with_path_skim",
|
14
|
-
"
|
15
|
-
"
|
16
|
-
"
|
17
|
-
"
|
18
|
-
"
|
14
|
+
"traverse_tree", "traverse_tree_with_path", "iter_nodes",
|
15
|
+
"iter_nodes_skim", "iter_nodes_by_pickcode", "iter_nodes_using_update",
|
16
|
+
"iter_nodes_using_info", "iter_nodes_using_star_event",
|
17
|
+
"iter_dir_nodes_using_star", "iter_parents", "iter_files_shortcut",
|
18
|
+
"iter_dupfiles", "iter_image_files", "search_iter", "share_iterdir",
|
19
|
+
"share_iter_files", "share_search_iter",
|
19
20
|
]
|
20
21
|
__doc__ = "这个模块提供了一些和目录信息罗列有关的函数"
|
21
22
|
|
22
|
-
# TODO: 再实现 2 个方法,利用 iter_download_nodes,一个有 path,一个没有,可以把某个目录下的所有节点都搞出来,导出时,先导出目录节点,再导出文件节点,但它们是并发执行的,然后必有字段:id, parent_id, pickcode, name, is_dir, sha1 等
|
23
23
|
# TODO: 路径表示法,应该支持 / 和 > 开头,而不仅仅是 / 开头
|
24
24
|
# TODO: get_id* 这类方法,应该放在 attr.py,用来获取某个 id 对应的值(根本还是 get_attr)
|
25
25
|
# TODO: 创造函数 get_id, get_parent_id, get_ancestors, get_sha1, get_pickcode, get_path 等,支持多种类型的参数,目前已有的名字太长,需要改造,甚至转为私有,另外这些函数或许可以放到另一个包中,attr.py
|
26
26
|
# TODO: 去除掉一些并不便利的办法,然后加上 traverse 和 walk 方法,通过递归拉取(支持深度和广度优先遍历)
|
27
27
|
# TODO: 要获取某个 id 对应的路径,可以先用 fs_file_skim 或 fs_info 看一下是不是存在,以及是不是文件,然后再选择响应最快的办法获取
|
28
28
|
|
29
|
-
from asyncio import create_task, sleep as async_sleep
|
29
|
+
from asyncio import create_task, sleep as async_sleep, Task
|
30
30
|
from collections import defaultdict
|
31
31
|
from collections.abc import (
|
32
|
-
AsyncIterable, AsyncIterator, Callable, Coroutine,
|
33
|
-
Iterator, Mapping, MutableMapping, Sequence,
|
32
|
+
AsyncIterable, AsyncIterator, Callable, Coroutine, Generator,
|
33
|
+
Iterable, Iterator, Mapping, MutableMapping, Sequence,
|
34
34
|
)
|
35
|
+
from contextlib import contextmanager
|
36
|
+
from concurrent.futures import Future
|
35
37
|
from dataclasses import dataclass
|
36
38
|
from errno import EIO, ENOENT, ENOTDIR
|
37
39
|
from functools import partial
|
@@ -183,6 +185,76 @@ def _update_resp_ancestors(
|
|
183
185
|
return resp
|
184
186
|
|
185
187
|
|
188
|
+
def _make_top_adder(
|
189
|
+
top_id: int,
|
190
|
+
id_to_dirnode: MutableMapping[int, tuple[str, int] | DirNode],
|
191
|
+
) -> Callable:
|
192
|
+
top_ancestors: list[dict]
|
193
|
+
if not top_id:
|
194
|
+
top_ancestors = [{"id": 0, "parent_id": 0, "name": ""}]
|
195
|
+
def add_top[T: MutableMapping](attr: T, /) -> T:
|
196
|
+
nonlocal top_ancestors
|
197
|
+
try:
|
198
|
+
top_ancestors
|
199
|
+
except NameError:
|
200
|
+
top_ancestors = []
|
201
|
+
add_ancestor = top_ancestors.append
|
202
|
+
tid = top_id
|
203
|
+
while tid and tid in id_to_dirnode:
|
204
|
+
name, pid = id_to_dirnode[tid]
|
205
|
+
add_ancestor({"id": tid, "parent_id": pid, "name": name})
|
206
|
+
tid = pid
|
207
|
+
if not tid:
|
208
|
+
add_ancestor({"id": 0, "parent_id": 0, "name": ""})
|
209
|
+
top_ancestors.reverse()
|
210
|
+
attr["top_id"] = top_id
|
211
|
+
attr["top_ancestors"] = top_ancestors
|
212
|
+
return attr
|
213
|
+
return add_top
|
214
|
+
|
215
|
+
|
216
|
+
@overload
|
217
|
+
@contextmanager
|
218
|
+
def cache_loading[T](
|
219
|
+
it: Iterator[T],
|
220
|
+
/,
|
221
|
+
) -> Generator[tuple[list[T], Future]]:
|
222
|
+
...
|
223
|
+
@overload
|
224
|
+
@contextmanager
|
225
|
+
def cache_loading[T](
|
226
|
+
it: AsyncIterator[T],
|
227
|
+
/,
|
228
|
+
) -> Generator[tuple[list[T], Task]]:
|
229
|
+
...
|
230
|
+
@contextmanager
|
231
|
+
def cache_loading[T](
|
232
|
+
it: Iterator[T] | AsyncIterator[T],
|
233
|
+
/,
|
234
|
+
) -> Generator[tuple[list[T], Future | Task]]:
|
235
|
+
cache: list[T] = []
|
236
|
+
add_to_cache = cache.append
|
237
|
+
running = True
|
238
|
+
if isinstance(it, AsyncIterator):
|
239
|
+
async def arunner():
|
240
|
+
async for e in it:
|
241
|
+
add_to_cache(e)
|
242
|
+
if not running:
|
243
|
+
break
|
244
|
+
task: Future | Task = create_task(arunner())
|
245
|
+
else:
|
246
|
+
def runner():
|
247
|
+
for e in it:
|
248
|
+
add_to_cache(e)
|
249
|
+
if not running:
|
250
|
+
break
|
251
|
+
task = run_as_thread(runner)
|
252
|
+
try:
|
253
|
+
yield (cache, task)
|
254
|
+
finally:
|
255
|
+
running = False
|
256
|
+
|
257
|
+
|
186
258
|
# TODO: 支持 open
|
187
259
|
@overload
|
188
260
|
def get_path_to_cid(
|
@@ -2037,7 +2109,8 @@ def iter_dirs_with_path(
|
|
2037
2109
|
async_=async_, # type: ignore
|
2038
2110
|
**request_kwargs,
|
2039
2111
|
))
|
2040
|
-
|
2112
|
+
add_top = _make_top_adder(to_id(cid), id_to_dirnode)
|
2113
|
+
return YieldFrom(do_map(add_top, ensure_attr_path(
|
2041
2114
|
client,
|
2042
2115
|
attrs,
|
2043
2116
|
with_ancestors=with_ancestors,
|
@@ -2046,7 +2119,7 @@ def iter_dirs_with_path(
|
|
2046
2119
|
app=app,
|
2047
2120
|
async_=async_,
|
2048
2121
|
**request_kwargs,
|
2049
|
-
))
|
2122
|
+
)))
|
2050
2123
|
return run_gen_step_iter(gen_step, async_)
|
2051
2124
|
|
2052
2125
|
|
@@ -2692,6 +2765,212 @@ def iter_files_with_path_skim(
|
|
2692
2765
|
return run_gen_step_iter(gen_step, async_)
|
2693
2766
|
|
2694
2767
|
|
2768
|
+
@overload
|
2769
|
+
def traverse_tree(
|
2770
|
+
client: str | P115Client,
|
2771
|
+
cid: int | str = 0,
|
2772
|
+
id_to_dirnode: None | EllipsisType | MutableMapping[int, tuple[str, int] | DirNode] = None,
|
2773
|
+
app: str = "android",
|
2774
|
+
max_workers: None | int = None,
|
2775
|
+
*,
|
2776
|
+
async_: Literal[False] = False,
|
2777
|
+
**request_kwargs,
|
2778
|
+
) -> Iterator[dict]:
|
2779
|
+
...
|
2780
|
+
@overload
|
2781
|
+
def traverse_tree(
|
2782
|
+
client: str | P115Client,
|
2783
|
+
cid: int | str = 0,
|
2784
|
+
id_to_dirnode: None | EllipsisType | MutableMapping[int, tuple[str, int] | DirNode] = None,
|
2785
|
+
app: str = "android",
|
2786
|
+
max_workers: None | int = None,
|
2787
|
+
*,
|
2788
|
+
async_: Literal[True],
|
2789
|
+
**request_kwargs,
|
2790
|
+
) -> AsyncIterator[dict]:
|
2791
|
+
...
|
2792
|
+
def traverse_tree(
|
2793
|
+
client: str | P115Client,
|
2794
|
+
cid: int | str = 0,
|
2795
|
+
id_to_dirnode: None | EllipsisType | MutableMapping[int, tuple[str, int] | DirNode] = None,
|
2796
|
+
app: str = "android",
|
2797
|
+
max_workers: None | int = None,
|
2798
|
+
*,
|
2799
|
+
async_: Literal[False, True] = False,
|
2800
|
+
**request_kwargs,
|
2801
|
+
) -> Iterator[dict] | AsyncIterator[dict]:
|
2802
|
+
"""遍历目录树,获取文件或目录节点的信息
|
2803
|
+
|
2804
|
+
:param client: 115 客户端或 cookies
|
2805
|
+
:param cid: 目录 id 或 pickcode
|
2806
|
+
:param id_to_dirnode: 字典,保存 id 到对应文件的 `DirNode(name, parent_id)` 命名元组的字典
|
2807
|
+
:param app: 使用指定 app(设备)的接口
|
2808
|
+
:param max_workers: 最大并发数,如果为 None 或 <= 0,则自动确定
|
2809
|
+
:param async_: 是否异步
|
2810
|
+
:param request_kwargs: 其它请求参数
|
2811
|
+
|
2812
|
+
:return: 迭代器,返回此目录内的文件或目录节点的信息
|
2813
|
+
"""
|
2814
|
+
if isinstance(client, str):
|
2815
|
+
client = P115Client(client, check_for_relogin=True)
|
2816
|
+
if id_to_dirnode is None:
|
2817
|
+
id_to_dirnode = ID_TO_DIRNODE_CACHE[client.user_id]
|
2818
|
+
elif id_to_dirnode is ...:
|
2819
|
+
id_to_dirnode = {}
|
2820
|
+
from .download import iter_download_nodes
|
2821
|
+
to_pickcode = client.to_pickcode
|
2822
|
+
def fulfill_dir_node(attr: dict, /) -> dict:
|
2823
|
+
attr["pickcode"] = to_pickcode(attr["id"], "fa")
|
2824
|
+
attr["size"] = 0
|
2825
|
+
attr["sha1"] = ""
|
2826
|
+
return attr
|
2827
|
+
def gen_step():
|
2828
|
+
files = iter_download_nodes(
|
2829
|
+
client,
|
2830
|
+
cid,
|
2831
|
+
files=True,
|
2832
|
+
ensure_name=True,
|
2833
|
+
id_to_dirnode=id_to_dirnode,
|
2834
|
+
app=app,
|
2835
|
+
max_workers=max_workers,
|
2836
|
+
async_=async_,
|
2837
|
+
**request_kwargs,
|
2838
|
+
)
|
2839
|
+
with cache_loading(files) as (cache, task):
|
2840
|
+
yield YieldFrom(do_map(fulfill_dir_node, iter_download_nodes(
|
2841
|
+
client,
|
2842
|
+
cid,
|
2843
|
+
files=False,
|
2844
|
+
id_to_dirnode=id_to_dirnode,
|
2845
|
+
app=app,
|
2846
|
+
max_workers=max_workers,
|
2847
|
+
async_=async_,
|
2848
|
+
**request_kwargs,
|
2849
|
+
)))
|
2850
|
+
if isinstance(task, Task):
|
2851
|
+
yield task
|
2852
|
+
else:
|
2853
|
+
task.result()
|
2854
|
+
yield YieldFrom(cache)
|
2855
|
+
yield YieldFrom(files)
|
2856
|
+
return run_gen_step_iter(gen_step, async_)
|
2857
|
+
|
2858
|
+
|
2859
|
+
@overload
|
2860
|
+
def traverse_tree_with_path(
|
2861
|
+
client: str | P115Client,
|
2862
|
+
cid: int | str = 0,
|
2863
|
+
with_ancestors: bool = False,
|
2864
|
+
escape: None | bool | Callable[[str], str] = True,
|
2865
|
+
id_to_dirnode: None | EllipsisType | MutableMapping[int, tuple[str, int] | DirNode] = None,
|
2866
|
+
app: str = "android",
|
2867
|
+
max_workers: None | int = None,
|
2868
|
+
*,
|
2869
|
+
async_: Literal[False] = False,
|
2870
|
+
**request_kwargs,
|
2871
|
+
) -> Iterator[dict]:
|
2872
|
+
...
|
2873
|
+
@overload
|
2874
|
+
def traverse_tree_with_path(
|
2875
|
+
client: str | P115Client,
|
2876
|
+
cid: int | str = 0,
|
2877
|
+
with_ancestors: bool = False,
|
2878
|
+
escape: None | bool | Callable[[str], str] = True,
|
2879
|
+
id_to_dirnode: None | EllipsisType | MutableMapping[int, tuple[str, int] | DirNode] = None,
|
2880
|
+
app: str = "android",
|
2881
|
+
max_workers: None | int = None,
|
2882
|
+
*,
|
2883
|
+
async_: Literal[True],
|
2884
|
+
**request_kwargs,
|
2885
|
+
) -> AsyncIterator[dict]:
|
2886
|
+
...
|
2887
|
+
def traverse_tree_with_path(
|
2888
|
+
client: str | P115Client,
|
2889
|
+
cid: int | str = 0,
|
2890
|
+
with_ancestors: bool = False,
|
2891
|
+
escape: None | bool | Callable[[str], str] = True,
|
2892
|
+
id_to_dirnode: None | EllipsisType | MutableMapping[int, tuple[str, int] | DirNode] = None,
|
2893
|
+
app: str = "android",
|
2894
|
+
max_workers: None | int = None,
|
2895
|
+
*,
|
2896
|
+
async_: Literal[False, True] = False,
|
2897
|
+
**request_kwargs,
|
2898
|
+
) -> Iterator[dict] | AsyncIterator[dict]:
|
2899
|
+
"""遍历目录树,获取文件或目录节点的信息(包含 "path",可选 "ancestors")
|
2900
|
+
|
2901
|
+
:param client: 115 客户端或 cookies
|
2902
|
+
:param cid: 目录 id 或 pickcode
|
2903
|
+
:param with_ancestors: 文件信息中是否要包含 "ancestors"
|
2904
|
+
:param escape: 对文件名进行转义
|
2905
|
+
|
2906
|
+
- 如果为 None,则不处理;否则,这个函数用来对文件名中某些符号进行转义,例如 "/" 等
|
2907
|
+
- 如果为 True,则使用 `posixpatht.escape`,会对文件名中 "/",或单独出现的 "." 和 ".." 用 "\\" 进行转义
|
2908
|
+
- 如果为 False,则使用 `posix_escape_name` 函数对名字进行转义,会把文件名中的 "/" 转换为 "|"
|
2909
|
+
- 如果为 Callable,则用你所提供的调用,以或者转义后的名字
|
2910
|
+
|
2911
|
+
:param id_to_dirnode: 字典,保存 id 到对应文件的 `DirNode(name, parent_id)` 命名元组的字典
|
2912
|
+
:param app: 使用指定 app(设备)的接口
|
2913
|
+
:param max_workers: 最大并发数,如果为 None 或 <= 0,则自动确定
|
2914
|
+
:param async_: 是否异步
|
2915
|
+
:param request_kwargs: 其它请求参数
|
2916
|
+
|
2917
|
+
:return: 迭代器,返回此目录内的文件或目录节点的信息
|
2918
|
+
"""
|
2919
|
+
if isinstance(client, str):
|
2920
|
+
client = P115Client(client, check_for_relogin=True)
|
2921
|
+
if id_to_dirnode is None:
|
2922
|
+
id_to_dirnode = ID_TO_DIRNODE_CACHE[client.user_id]
|
2923
|
+
elif id_to_dirnode is ...:
|
2924
|
+
id_to_dirnode = {}
|
2925
|
+
from .download import iter_download_nodes
|
2926
|
+
to_pickcode = client.to_pickcode
|
2927
|
+
def fulfill_dir_node(attr: dict, /) -> dict:
|
2928
|
+
attr["pickcode"] = to_pickcode(attr["id"], "fa")
|
2929
|
+
attr["size"] = 0
|
2930
|
+
attr["sha1"] = ""
|
2931
|
+
return attr
|
2932
|
+
def gen_step():
|
2933
|
+
files = iter_download_nodes(
|
2934
|
+
client,
|
2935
|
+
cid,
|
2936
|
+
files=True,
|
2937
|
+
ensure_name=True,
|
2938
|
+
id_to_dirnode=id_to_dirnode,
|
2939
|
+
app=app,
|
2940
|
+
max_workers=max_workers,
|
2941
|
+
async_=async_,
|
2942
|
+
**request_kwargs,
|
2943
|
+
)
|
2944
|
+
with cache_loading(files) as (cache, task):
|
2945
|
+
yield YieldFrom(do_map(fulfill_dir_node, iter_dirs_with_path(
|
2946
|
+
client,
|
2947
|
+
cid,
|
2948
|
+
with_ancestors=with_ancestors,
|
2949
|
+
escape=escape,
|
2950
|
+
id_to_dirnode=id_to_dirnode,
|
2951
|
+
app=app,
|
2952
|
+
max_workers=max_workers,
|
2953
|
+
async_=async_,
|
2954
|
+
**request_kwargs,
|
2955
|
+
)))
|
2956
|
+
if isinstance(task, Task):
|
2957
|
+
yield task
|
2958
|
+
else:
|
2959
|
+
task.result()
|
2960
|
+
add_top = _make_top_adder(to_id(cid), id_to_dirnode)
|
2961
|
+
yield YieldFrom(do_map(add_top, ensure_attr_path(
|
2962
|
+
client,
|
2963
|
+
chain(cache, files), # type: ignore
|
2964
|
+
with_ancestors=with_ancestors,
|
2965
|
+
escape=escape,
|
2966
|
+
id_to_dirnode=id_to_dirnode,
|
2967
|
+
app=app,
|
2968
|
+
async_=async_,
|
2969
|
+
**request_kwargs,
|
2970
|
+
)))
|
2971
|
+
return run_gen_step_iter(gen_step, async_)
|
2972
|
+
|
2973
|
+
|
2695
2974
|
@overload
|
2696
2975
|
def iter_nodes(
|
2697
2976
|
client: str | P115Client,
|
@@ -1,6 +1,6 @@
|
|
1
1
|
[tool.poetry]
|
2
2
|
name = "p115client"
|
3
|
-
version = "0.0.5.14.
|
3
|
+
version = "0.0.5.14.4"
|
4
4
|
description = "Python 115 webdisk client."
|
5
5
|
authors = ["ChenyangGao <wosiwujm@gmail.com>"]
|
6
6
|
license = "MIT"
|
@@ -37,7 +37,7 @@ iter_collect = ">=0.0.5.1"
|
|
37
37
|
multidict = "*"
|
38
38
|
orjson = "*"
|
39
39
|
p115cipher = ">=0.0.3"
|
40
|
-
p115pickcode = ">=0.0.
|
40
|
+
p115pickcode = ">=0.0.5"
|
41
41
|
posixpatht = ">=0.0.3"
|
42
42
|
python-argtools = ">=0.0.1"
|
43
43
|
python-asynctools = ">=0.1.3"
|
@@ -49,7 +49,7 @@ python-filewrap = ">=0.2.8"
|
|
49
49
|
python-hashtools = ">=0.0.3.3"
|
50
50
|
python-httpfile = ">=0.0.5.2"
|
51
51
|
python-http_request = ">=0.0.6"
|
52
|
-
python-iterutils = ">=0.2.5.
|
52
|
+
python-iterutils = ">=0.2.5.4"
|
53
53
|
python-property = ">=0.0.3"
|
54
54
|
python-startfile = ">=0.0.2"
|
55
55
|
python-undefined = ">=0.0.3"
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|