p115client 0.0.5.13__py3-none-any.whl → 0.0.5.13.2__py3-none-any.whl
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/tool/download.py +20 -15
- p115client/tool/export_dir.py +7 -36
- p115client/tool/fs_files.py +13 -16
- p115client/tool/iterdir.py +123 -115
- {p115client-0.0.5.13.dist-info → p115client-0.0.5.13.2.dist-info}/METADATA +2 -2
- {p115client-0.0.5.13.dist-info → p115client-0.0.5.13.2.dist-info}/RECORD +8 -8
- {p115client-0.0.5.13.dist-info → p115client-0.0.5.13.2.dist-info}/LICENSE +0 -0
- {p115client-0.0.5.13.dist-info → p115client-0.0.5.13.2.dist-info}/WHEEL +0 -0
p115client/tool/download.py
CHANGED
@@ -872,6 +872,7 @@ def iter_subtitle_batches(
|
|
872
872
|
|
873
873
|
|
874
874
|
# TODO: 要支持 open 接口
|
875
|
+
# TODO: 后续还可用 iter_download_nodes 接口,来更快地拉取数据
|
875
876
|
@overload
|
876
877
|
def make_strm(
|
877
878
|
client: str | P115Client,
|
@@ -1220,7 +1221,6 @@ def iter_download_nodes(
|
|
1220
1221
|
if id_to_dirnode is None:
|
1221
1222
|
id_to_dirnode = ID_TO_DIRNODE_CACHE[client.user_id]
|
1222
1223
|
file_skim = client.fs_file_skim
|
1223
|
-
@as_gen_step
|
1224
1224
|
def normalize_attrs(attrs: list[dict], /):
|
1225
1225
|
if files:
|
1226
1226
|
for i, info in enumerate(attrs):
|
@@ -1231,20 +1231,6 @@ def iter_download_nodes(
|
|
1231
1231
|
"parent_id": int(info["pid"]),
|
1232
1232
|
"size": info["fs"],
|
1233
1233
|
}
|
1234
|
-
if ensure_name:
|
1235
|
-
resp = yield file_skim(
|
1236
|
-
(a["id"] for a in attrs),
|
1237
|
-
method="POST",
|
1238
|
-
async_=async_,
|
1239
|
-
**request_kwargs,
|
1240
|
-
)
|
1241
|
-
if resp.get("error") != "文件不存在":
|
1242
|
-
check_response(resp)
|
1243
|
-
nodes = {int(a["file_id"]): a for a in resp["data"]}
|
1244
|
-
for attr in attrs:
|
1245
|
-
if node := nodes.get(attr["id"]):
|
1246
|
-
attr["sha1"] = node["sha1"]
|
1247
|
-
attr["name"] = unescape_115_charref(node["file_name"])
|
1248
1234
|
else:
|
1249
1235
|
for i, info in enumerate(attrs):
|
1250
1236
|
attrs[i] = {
|
@@ -1257,6 +1243,25 @@ def iter_download_nodes(
|
|
1257
1243
|
for attr in attrs:
|
1258
1244
|
id_to_dirnode[attr["id"]] = DirNode(attr["name"], attr["parent_id"])
|
1259
1245
|
return attrs
|
1246
|
+
if files and ensure_name:
|
1247
|
+
prepare = normalize_attrs
|
1248
|
+
@as_gen_step
|
1249
|
+
def normalize_attrs(attrs: list[dict], /):
|
1250
|
+
prepare(attrs)
|
1251
|
+
resp = yield file_skim(
|
1252
|
+
(a["id"] for a in attrs),
|
1253
|
+
method="POST",
|
1254
|
+
async_=async_,
|
1255
|
+
**request_kwargs,
|
1256
|
+
)
|
1257
|
+
if resp.get("error") != "文件不存在":
|
1258
|
+
check_response(resp)
|
1259
|
+
nodes = {int(a["file_id"]): a for a in resp["data"]}
|
1260
|
+
for attr in attrs:
|
1261
|
+
if node := nodes.get(attr["id"]):
|
1262
|
+
attr["sha1"] = node["sha1"]
|
1263
|
+
attr["name"] = unescape_115_charref(node["file_name"])
|
1264
|
+
return attrs
|
1260
1265
|
get_nodes = partial(
|
1261
1266
|
method,
|
1262
1267
|
async_=async_,
|
p115client/tool/export_dir.py
CHANGED
@@ -363,8 +363,8 @@ def export_dir(
|
|
363
363
|
"""导出目录树
|
364
364
|
|
365
365
|
:param client: 115 客户端或 cookies
|
366
|
-
:param export_file_ids: 待导出的目录 id
|
367
|
-
:param target_pid: 导出到的目标目录 id
|
366
|
+
:param export_file_ids: 待导出的目录 id 或 pickcode
|
367
|
+
:param target_pid: 导出到的目标目录 id 或 pickcode
|
368
368
|
:param layer_limit: 层级深度,小于等于 0 时不限
|
369
369
|
:param async_: 是否异步
|
370
370
|
:param request_kwargs: 其它请求参数
|
@@ -373,45 +373,16 @@ def export_dir(
|
|
373
373
|
"""
|
374
374
|
if not isinstance(client, P115Client):
|
375
375
|
client = P115Client(client, check_for_relogin=True)
|
376
|
-
from .iterdir import get_id_to_path
|
377
|
-
@as_gen_step
|
378
|
-
def get_id(s: str, /):
|
379
|
-
if len(s) >= 17 and is_valid_pickcode(s):
|
380
|
-
try:
|
381
|
-
return to_id(s)
|
382
|
-
except Exception:
|
383
|
-
pass
|
384
|
-
return (yield get_id_to_path(
|
385
|
-
client,
|
386
|
-
s,
|
387
|
-
ensure_file=False,
|
388
|
-
async_=async_,
|
389
|
-
**request_kwargs,
|
390
|
-
))
|
391
376
|
def gen_step():
|
392
377
|
nonlocal export_file_ids, target_pid
|
393
378
|
if isinstance(export_file_ids, int):
|
394
379
|
pass
|
395
380
|
elif isinstance(export_file_ids, str):
|
396
|
-
|
381
|
+
if "," not in export_file_ids:
|
382
|
+
export_file_ids = to_id(export_file_ids)
|
397
383
|
else:
|
398
|
-
|
399
|
-
|
400
|
-
for cid in export_file_ids:
|
401
|
-
if isinstance(cid, str):
|
402
|
-
cid = yield get_id(cid)
|
403
|
-
add_cid(cid)
|
404
|
-
if not cids:
|
405
|
-
raise ValueError("`export_file_ids` is empty")
|
406
|
-
export_file_ids = ",".join(map(str, cids))
|
407
|
-
if isinstance(target_pid, str):
|
408
|
-
target_pid = yield get_id_to_path(
|
409
|
-
client,
|
410
|
-
target_pid,
|
411
|
-
ensure_file=False,
|
412
|
-
async_=async_,
|
413
|
-
**request_kwargs,
|
414
|
-
)
|
384
|
+
export_file_ids = ",".join(str(to_id(eid)) for eid in export_file_ids)
|
385
|
+
target_pid = to_id(target_pid)
|
415
386
|
payload = {"file_ids": export_file_ids, "target": f"U_0_{target_pid}"}
|
416
387
|
if layer_limit > 0:
|
417
388
|
payload["layer_limit"] = layer_limit
|
@@ -557,7 +528,7 @@ def export_dir_parse_iter(
|
|
557
528
|
:param client: 115 客户端或 cookies
|
558
529
|
:param export_file_ids: 待导出的目录 id、pickcode 或 路径(如果有多个,需传入可迭代对象)
|
559
530
|
:param export_id: 优先级高于 `export_file_ids`,之前提交的 `export_dir` 任务的 id,如果是 str,则视为导出的目录树文件的提取码(因此无需导出)
|
560
|
-
:param target_pid: 导出到的目标目录 id 或
|
531
|
+
:param target_pid: 导出到的目标目录 id 或 pickcode
|
561
532
|
:param layer_limit: 层级深度,小于等于 0 时不限
|
562
533
|
:param parse_iter: 解析打开的二进制文件,返回可迭代对象
|
563
534
|
:param delete: 最终删除目录树文件(如果 export_id 为 str(即提取码),则这个值不生效,必不删除)
|
p115client/tool/fs_files.py
CHANGED
@@ -115,20 +115,20 @@ def iter_fs_files(
|
|
115
115
|
"limit": first_page_size, "show_dir": 1, **payload,
|
116
116
|
}
|
117
117
|
cid = int(payload["cid"])
|
118
|
-
|
119
|
-
def get_files(payload: dict, /):
|
118
|
+
def gen_step():
|
120
119
|
nonlocal count
|
121
120
|
while True:
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
payload["limit"]
|
131
|
-
|
121
|
+
while True:
|
122
|
+
try:
|
123
|
+
resp = yield fs_files(payload, async_=async_)
|
124
|
+
check_response(resp)
|
125
|
+
except DataError:
|
126
|
+
if payload["limit"] <= 1150:
|
127
|
+
raise
|
128
|
+
payload["limit"] -= 1_000
|
129
|
+
if payload["limit"] < 1150:
|
130
|
+
payload["limit"] = 1150
|
131
|
+
continue
|
132
132
|
if cid and int(resp["path"][-1]["cid"]) != cid:
|
133
133
|
if count < 0:
|
134
134
|
raise NotADirectoryError(ENOTDIR, cid)
|
@@ -146,10 +146,7 @@ def iter_fs_files(
|
|
146
146
|
count = count_new
|
147
147
|
if callback is not None:
|
148
148
|
resp["callback"] = yield callback(resp)
|
149
|
-
|
150
|
-
def gen_step():
|
151
|
-
while True:
|
152
|
-
resp = yield get_files(payload)
|
149
|
+
break
|
153
150
|
payload["limit"] = page_size
|
154
151
|
yield Yield(resp)
|
155
152
|
payload["offset"] += len(resp["data"])
|
p115client/tool/iterdir.py
CHANGED
@@ -19,6 +19,7 @@ __all__ = [
|
|
19
19
|
]
|
20
20
|
__doc__ = "这个模块提供了一些和目录信息罗列有关的函数"
|
21
21
|
|
22
|
+
# TODO: 路径表示法,应该支持 / 和 > 开头,而不仅仅是 / 开头
|
22
23
|
# TODO: 对于路径,增加 top_id 和 relpath 字段,表示搜素目录的 id 和相对于搜索路径的相对路径
|
23
24
|
# TODO: get_id* 这类方法,应该放在 attr.py,用来获取某个 id 对应的值(根本还是 get_attr)
|
24
25
|
# TODO: 创造函数 get_id, get_parent_id, get_ancestors, get_sha1, get_pickcode, get_path 等,支持多种类型的参数,目前已有的名字太长,需要改造,甚至转为私有,另外这些函数或许可以放到另一个包中,attr.py
|
@@ -46,9 +47,9 @@ from warnings import warn
|
|
46
47
|
from asynctools import to_list
|
47
48
|
from concurrenttools import run_as_thread, taskgroup_map, threadpool_map, conmap
|
48
49
|
from iterutils import (
|
49
|
-
as_gen_step, bfs_gen, chunked, chain, chain_from_iterable, collect,
|
50
|
-
run_gen_step_iter, through, with_iter_next, map as do_map,
|
51
|
-
Yield, YieldFrom,
|
50
|
+
as_gen_step, bfs_gen, chunked, chain, chain_from_iterable, collect, foreach,
|
51
|
+
run_gen_step, run_gen_step_iter, through, with_iter_next, map as do_map,
|
52
|
+
filter as do_filter, Yield, YieldFrom,
|
52
53
|
)
|
53
54
|
from iter_collect import iter_keyed_dups, SupportsLT
|
54
55
|
from orjson import loads
|
@@ -135,6 +136,46 @@ def _overview_attr(info: Mapping, /) -> OverviewAttr:
|
|
135
136
|
return OverviewAttr(is_dir, id, pid, name, ctime, mtime)
|
136
137
|
|
137
138
|
|
139
|
+
def _update_resp_2_id_to_dirnode(
|
140
|
+
resp: dict,
|
141
|
+
id_to_dirnode: EllipsisType | MutableMapping[int, tuple[str, int] | DirNode],
|
142
|
+
/,
|
143
|
+
error: None | OSError = FileNotFoundError(ENOENT, "not found"),
|
144
|
+
) -> dict:
|
145
|
+
if "path" in resp:
|
146
|
+
if id_to_dirnode is not ...:
|
147
|
+
for info in resp["path"][1:]:
|
148
|
+
id_to_dirnode[int(info["cid"])] = DirNode(info["name"], int(info["pid"]))
|
149
|
+
else:
|
150
|
+
if not resp:
|
151
|
+
if error is None:
|
152
|
+
return resp
|
153
|
+
raise error
|
154
|
+
if "paths" not in resp:
|
155
|
+
check_response(resp)
|
156
|
+
resp = resp["data"]
|
157
|
+
if not resp:
|
158
|
+
if error is None:
|
159
|
+
return resp
|
160
|
+
raise error
|
161
|
+
if id_to_dirnode is not ...:
|
162
|
+
paths = resp["paths"]
|
163
|
+
info = paths[0]
|
164
|
+
pid = int(info["file_id"])
|
165
|
+
for info in paths[1:]:
|
166
|
+
fid = int(info["file_id"])
|
167
|
+
id_to_dirnode[fid] = DirNode(info["file_name"], pid)
|
168
|
+
pid = fid
|
169
|
+
if not resp["sha1"]:
|
170
|
+
if "file_id" in resp:
|
171
|
+
fid = int(resp["file_id"])
|
172
|
+
else:
|
173
|
+
fid = to_id(resp["pick_code"])
|
174
|
+
id_to_dirnode[fid] = DirNode(resp["file_name"], pid)
|
175
|
+
return resp
|
176
|
+
|
177
|
+
|
178
|
+
# TODO: 支持 open
|
138
179
|
@overload
|
139
180
|
def get_path_to_cid(
|
140
181
|
client: str | P115Client,
|
@@ -368,25 +409,15 @@ def get_file_count(
|
|
368
409
|
return int(resp["count"])
|
369
410
|
else:
|
370
411
|
resp = yield get_resp_of_category_get(cid)
|
371
|
-
|
372
|
-
|
373
|
-
if "paths" not in resp:
|
374
|
-
check_response(resp)
|
375
|
-
resp = resp["data"]
|
376
|
-
if not resp:
|
377
|
-
raise FileNotFoundError(ENOENT, cid)
|
378
|
-
if int(resp["file_category"]):
|
412
|
+
resp = _update_resp_2_id_to_dirnode(resp, id_to_dirnode, FileNotFoundError(ENOENT, cid))
|
413
|
+
if resp["sha1"]:
|
379
414
|
resp["cid"] = cid
|
380
415
|
raise NotADirectoryError(ENOTDIR, resp)
|
381
|
-
if id_to_dirnode is not ...:
|
382
|
-
pid = int(resp["paths"][0]["file_id"])
|
383
|
-
for info in resp["paths"][1:]:
|
384
|
-
node = DirNode(info["file_name"], pid)
|
385
|
-
id_to_dirnode[(pid := int(info["file_id"]))] = node
|
386
416
|
return int(resp["count"]) - int(resp.get("folder_count") or 0)
|
387
417
|
return run_gen_step(gen_step, async_)
|
388
418
|
|
389
419
|
|
420
|
+
# TODO: 支持 open
|
390
421
|
@overload
|
391
422
|
def get_ancestors(
|
392
423
|
client: str | P115Client,
|
@@ -544,22 +575,13 @@ def get_ancestors(
|
|
544
575
|
return ancestors
|
545
576
|
else:
|
546
577
|
resp = yield get_resp_of_category_get(fid)
|
547
|
-
|
548
|
-
raise FileNotFoundError(ENOENT, attr)
|
549
|
-
if "paths" not in resp:
|
550
|
-
check_response(resp)
|
551
|
-
resp = resp["data"]
|
552
|
-
if not resp:
|
553
|
-
raise FileNotFoundError(ENOENT, attr)
|
578
|
+
resp = _update_resp_2_id_to_dirnode(resp, id_to_dirnode)
|
554
579
|
for info in resp["paths"]:
|
555
580
|
add_ancestor({
|
556
581
|
"parent_id": pid,
|
557
582
|
"id": (pid := int(info["file_id"])),
|
558
583
|
"name": info["file_name"],
|
559
584
|
})
|
560
|
-
if id_to_dirnode is not ...:
|
561
|
-
for ans in ancestors[1:]:
|
562
|
-
id_to_dirnode[ans["id"]] = DirNode(ans["name"], ans["parent_id"])
|
563
585
|
ans = {"id": fid, "parent_id": pid, "name": resp["file_name"]}
|
564
586
|
add_ancestor(ans)
|
565
587
|
if not resp.get("sha1") and id_to_dirnode is not ...:
|
@@ -583,22 +605,13 @@ def get_ancestors(
|
|
583
605
|
id_to_dirnode[ans["id"]] = DirNode(ans["name"], ans["parent_id"])
|
584
606
|
else:
|
585
607
|
resp = yield get_resp_of_category_get(fid)
|
586
|
-
|
587
|
-
raise FileNotFoundError(ENOENT, fid)
|
588
|
-
if "paths" not in resp:
|
589
|
-
check_response(resp)
|
590
|
-
resp = resp["data"]
|
591
|
-
if not resp:
|
592
|
-
raise FileNotFoundError(ENOENT, fid)
|
608
|
+
resp = _update_resp_2_id_to_dirnode(resp, id_to_dirnode)
|
593
609
|
for info in resp["paths"]:
|
594
610
|
add_ancestor({
|
595
611
|
"parent_id": pid,
|
596
612
|
"id": (pid := int(info["file_id"])),
|
597
613
|
"name": info["file_name"],
|
598
614
|
})
|
599
|
-
if id_to_dirnode is not ...:
|
600
|
-
for ans in ancestors[1:]:
|
601
|
-
id_to_dirnode[ans["id"]] = DirNode(ans["name"], ans["parent_id"])
|
602
615
|
ans = {"id": fid, "parent_id": pid, "name": resp["file_name"]}
|
603
616
|
add_ancestor(ans)
|
604
617
|
if not resp.get("sha1") and id_to_dirnode is not ...:
|
@@ -607,6 +620,7 @@ def get_ancestors(
|
|
607
620
|
return run_gen_step(gen_step, async_)
|
608
621
|
|
609
622
|
|
623
|
+
# TODO: 支持 open
|
610
624
|
@overload
|
611
625
|
def get_ancestors_to_cid(
|
612
626
|
client: str | P115Client,
|
@@ -714,7 +728,7 @@ def get_ancestors_to_cid(
|
|
714
728
|
# TODO: 立即支持几种形式,分隔符可以是 / 和 > 或 " > "
|
715
729
|
@overload
|
716
730
|
def get_id_to_path(
|
717
|
-
client: str | P115Client,
|
731
|
+
client: str | P115Client | P115OpenClient,
|
718
732
|
path: str | Sequence[str],
|
719
733
|
parent_id: int = 0,
|
720
734
|
ensure_file: None | bool = None,
|
@@ -730,7 +744,7 @@ def get_id_to_path(
|
|
730
744
|
...
|
731
745
|
@overload
|
732
746
|
def get_id_to_path(
|
733
|
-
client: str | P115Client,
|
747
|
+
client: str | P115Client | P115OpenClient,
|
734
748
|
path: str | Sequence[str],
|
735
749
|
parent_id: int = 0,
|
736
750
|
ensure_file: None | bool = None,
|
@@ -745,7 +759,7 @@ def get_id_to_path(
|
|
745
759
|
) -> Coroutine[Any, Any, int]:
|
746
760
|
...
|
747
761
|
def get_id_to_path(
|
748
|
-
client: str | P115Client,
|
762
|
+
client: str | P115Client | P115OpenClient,
|
749
763
|
path: str | Sequence[str],
|
750
764
|
parent_id: int = 0,
|
751
765
|
ensure_file: None | bool = None,
|
@@ -785,7 +799,7 @@ def get_id_to_path(
|
|
785
799
|
id_to_dirnode = ID_TO_DIRNODE_CACHE[client.user_id]
|
786
800
|
error = FileNotFoundError(ENOENT, f"no such path: {path!r}")
|
787
801
|
def gen_step():
|
788
|
-
nonlocal ensure_file, parent_id
|
802
|
+
nonlocal ensure_file, parent_id, path
|
789
803
|
if isinstance(path, str):
|
790
804
|
if path.startswith("/"):
|
791
805
|
parent_id = 0
|
@@ -816,6 +830,11 @@ def get_id_to_path(
|
|
816
830
|
if ensure_file:
|
817
831
|
raise error
|
818
832
|
return parent_id
|
833
|
+
if not isinstance(client, P115Client) or app == "open":
|
834
|
+
path = ">" + ">".join(patht)
|
835
|
+
resp = yield client.fs_info_open(path, async_=async_, **request_kwargs)
|
836
|
+
data = _update_resp_2_id_to_dirnode(resp, id_to_dirnode)
|
837
|
+
return P115ID(data["file_id"], data, about="path", path=path)
|
819
838
|
i = 0
|
820
839
|
start_parent_id = parent_id
|
821
840
|
if not refresh and id_to_dirnode and id_to_dirnode is not ...:
|
@@ -906,12 +925,11 @@ def get_id_to_path(
|
|
906
925
|
return run_gen_step(gen_step, async_)
|
907
926
|
|
908
927
|
|
909
|
-
# TODO: 支持 open 接口
|
910
928
|
@overload
|
911
929
|
def get_id_to_sha1(
|
912
|
-
client: str | P115Client,
|
930
|
+
client: str | P115Client | P115OpenClient,
|
913
931
|
sha1: str,
|
914
|
-
app: str = "
|
932
|
+
app: str = "",
|
915
933
|
*,
|
916
934
|
async_: Literal[False] = False,
|
917
935
|
**request_kwargs,
|
@@ -919,18 +937,18 @@ def get_id_to_sha1(
|
|
919
937
|
...
|
920
938
|
@overload
|
921
939
|
def get_id_to_sha1(
|
922
|
-
client: str | P115Client,
|
940
|
+
client: str | P115Client | P115OpenClient,
|
923
941
|
sha1: str,
|
924
|
-
app: str = "
|
942
|
+
app: str = "",
|
925
943
|
*,
|
926
944
|
async_: Literal[True],
|
927
945
|
**request_kwargs,
|
928
946
|
) -> Coroutine[Any, Any, P115ID]:
|
929
947
|
...
|
930
948
|
def get_id_to_sha1(
|
931
|
-
client: str | P115Client,
|
949
|
+
client: str | P115Client | P115OpenClient,
|
932
950
|
sha1: str,
|
933
|
-
app: str = "
|
951
|
+
app: str = "",
|
934
952
|
*,
|
935
953
|
async_: Literal[False, True] = False,
|
936
954
|
**request_kwargs,
|
@@ -951,12 +969,18 @@ def get_id_to_sha1(
|
|
951
969
|
client = P115Client(client, check_for_relogin=True)
|
952
970
|
def gen_step():
|
953
971
|
file_sha1 = sha1.upper()
|
954
|
-
if app
|
972
|
+
if app == "" and isinstance(client, P115Client):
|
955
973
|
resp = yield client.fs_shasearch(sha1, async_=async_, **request_kwargs)
|
956
974
|
check_response(resp)
|
957
975
|
data = resp["data"]
|
958
976
|
else:
|
959
|
-
|
977
|
+
if not isinstance(client, P115Client) or app == "open":
|
978
|
+
search: Callable = client.fs_search_open
|
979
|
+
elif app in ("", "web", "desktop", "harmony"):
|
980
|
+
search = client.fs_search
|
981
|
+
else:
|
982
|
+
search = partial(client.fs_search_app, app=app)
|
983
|
+
resp = yield search(sha1, async_=async_, **request_kwargs)
|
960
984
|
check_response(resp)
|
961
985
|
for data in resp["data"]:
|
962
986
|
if data["sha1"] == file_sha1:
|
@@ -967,7 +991,6 @@ def get_id_to_sha1(
|
|
967
991
|
return run_gen_step(gen_step, async_)
|
968
992
|
|
969
993
|
|
970
|
-
|
971
994
|
@overload
|
972
995
|
def share_get_id_to_path(
|
973
996
|
client: str | P115Client,
|
@@ -1277,37 +1300,29 @@ def ensure_attr_path[D: dict](
|
|
1277
1300
|
ancestors = get_ancestors(pid, id_to_dirnode[pid])
|
1278
1301
|
ancestors.append(me)
|
1279
1302
|
return ancestors
|
1280
|
-
|
1281
|
-
|
1282
|
-
|
1283
|
-
|
1284
|
-
|
1285
|
-
|
1286
|
-
|
1287
|
-
|
1288
|
-
|
1289
|
-
|
1290
|
-
|
1291
|
-
|
1292
|
-
|
1293
|
-
|
1294
|
-
|
1295
|
-
|
1296
|
-
|
1297
|
-
|
1298
|
-
|
1299
|
-
|
1300
|
-
|
1301
|
-
|
1302
|
-
|
1303
|
-
id_to_dirnode[pid] = DirNode(resp["file_name"], pid)
|
1304
|
-
if not resp["sha1"]:
|
1305
|
-
id_to_dirnode[cur_id] = DirNode(resp["file_name"], pid)
|
1306
|
-
attr["path"] = get_path(attr)
|
1307
|
-
if with_ancestors:
|
1308
|
-
attr["ancestors"] = get_ancestors(id, attr)
|
1309
|
-
return attr
|
1310
|
-
return do_map(ensure_path, attrs)
|
1303
|
+
def gen_step():
|
1304
|
+
with with_iter_next(attrs) as get_next:
|
1305
|
+
while True:
|
1306
|
+
attr = yield get_next()
|
1307
|
+
id = attr["id"]
|
1308
|
+
pid = attr["parent_id"]
|
1309
|
+
while pid and pid in id_to_dirnode:
|
1310
|
+
pid = id_to_dirnode[pid][1]
|
1311
|
+
if pid and pid not in dangling_id_to_name:
|
1312
|
+
resp = yield get_info(pid, async_=async_, **request_kwargs)
|
1313
|
+
resp = _update_resp_2_id_to_dirnode(resp, id_to_dirnode, None)
|
1314
|
+
if not resp:
|
1315
|
+
dangling_id_to_name[pid] = ""
|
1316
|
+
yield Yield(attr)
|
1317
|
+
return
|
1318
|
+
info = resp["paths"][0]
|
1319
|
+
if pid := int(info["file_id"]):
|
1320
|
+
dangling_id_to_name[pid] = info["file_name"]
|
1321
|
+
attr["path"] = get_path(attr)
|
1322
|
+
if with_ancestors:
|
1323
|
+
attr["ancestors"] = get_ancestors(id, attr)
|
1324
|
+
yield Yield(attr)
|
1325
|
+
return run_gen_step_iter(gen_step, async_)
|
1311
1326
|
|
1312
1327
|
|
1313
1328
|
@overload
|
@@ -1423,7 +1438,6 @@ def ensure_attr_path_using_star_event[D: dict](
|
|
1423
1438
|
ancestors = get_ancestors(pid, id_to_dirnode[pid])
|
1424
1439
|
ancestors.append(me)
|
1425
1440
|
return ancestors
|
1426
|
-
|
1427
1441
|
def gen_step():
|
1428
1442
|
cache: Sequence[dict]
|
1429
1443
|
if id_to_dirnode:
|
@@ -1586,26 +1600,25 @@ def _iter_fs_files(
|
|
1586
1600
|
with_dirname = False
|
1587
1601
|
if with_dirname:
|
1588
1602
|
pid_to_name = {0: ""}
|
1589
|
-
def get_pid(info: dict, /):
|
1603
|
+
def get_pid(info: dict, /) -> int:
|
1590
1604
|
for key in ("parent_id", "pid", "cid"):
|
1591
1605
|
if key in info:
|
1592
1606
|
return int(info[key])
|
1593
1607
|
raise KeyError("parent_id", "pid", "cid")
|
1594
|
-
|
1608
|
+
setitem = pid_to_name.__setitem__
|
1595
1609
|
def callback(resp: dict, /):
|
1596
|
-
|
1597
|
-
|
1598
|
-
|
1610
|
+
return foreach(
|
1611
|
+
lambda info: setitem(info["file_id"], info["file_name"]),
|
1612
|
+
iter_nodes_skim(
|
1613
|
+
cast(P115Client, client),
|
1614
|
+
(
|
1615
|
+
pid for info in resp["data"]
|
1616
|
+
if (pid := get_pid(info)) and pid not in pid_to_name
|
1617
|
+
),
|
1618
|
+
async_=async_,
|
1619
|
+
**request_kwargs,
|
1620
|
+
)
|
1599
1621
|
)
|
1600
|
-
with with_iter_next(iter_nodes_skim(
|
1601
|
-
cast(P115Client, client),
|
1602
|
-
pids,
|
1603
|
-
async_=async_,
|
1604
|
-
**request_kwargs,
|
1605
|
-
)) as get_next:
|
1606
|
-
while True:
|
1607
|
-
info = yield get_next()
|
1608
|
-
pid_to_name[info["file_id"]] = info["file_name"]
|
1609
1622
|
request_kwargs["callback"] = callback
|
1610
1623
|
def gen_step():
|
1611
1624
|
if cooldown <= 0 or max_workers == 1:
|
@@ -1937,7 +1950,7 @@ def iter_dirs(
|
|
1937
1950
|
def iter_dirs_with_path(
|
1938
1951
|
client: str | P115Client,
|
1939
1952
|
cid: int | str = 0,
|
1940
|
-
with_ancestors: bool =
|
1953
|
+
with_ancestors: bool = False,
|
1941
1954
|
escape: None | bool | Callable[[str], str] = True,
|
1942
1955
|
id_to_dirnode: None | EllipsisType | MutableMapping[int, tuple[str, int] | DirNode] = None,
|
1943
1956
|
app: str = "android",
|
@@ -1951,7 +1964,7 @@ def iter_dirs_with_path(
|
|
1951
1964
|
def iter_dirs_with_path(
|
1952
1965
|
client: str | P115Client,
|
1953
1966
|
cid: int | str = 0,
|
1954
|
-
with_ancestors: bool =
|
1967
|
+
with_ancestors: bool = False,
|
1955
1968
|
escape: None | bool | Callable[[str], str] = True,
|
1956
1969
|
id_to_dirnode: None | EllipsisType | MutableMapping[int, tuple[str, int] | DirNode] = None,
|
1957
1970
|
app: str = "android",
|
@@ -1964,7 +1977,7 @@ def iter_dirs_with_path(
|
|
1964
1977
|
def iter_dirs_with_path(
|
1965
1978
|
client: str | P115Client,
|
1966
1979
|
cid: int | str = 0,
|
1967
|
-
with_ancestors: bool =
|
1980
|
+
with_ancestors: bool = False,
|
1968
1981
|
escape: None | bool | Callable[[str], str] = True,
|
1969
1982
|
id_to_dirnode: None | EllipsisType | MutableMapping[int, tuple[str, int] | DirNode] = None,
|
1970
1983
|
app: str = "android",
|
@@ -2168,7 +2181,7 @@ def iter_files_with_path(
|
|
2168
2181
|
cur: Literal[0, 1] = 0,
|
2169
2182
|
normalize_attr: None | Callable[[dict], dict] = normalize_attr,
|
2170
2183
|
escape: None | bool | Callable[[str], str] = True,
|
2171
|
-
with_ancestors: bool =
|
2184
|
+
with_ancestors: bool = False,
|
2172
2185
|
id_to_dirnode: None | EllipsisType | MutableMapping[int, tuple[str, int] | DirNode] = None,
|
2173
2186
|
path_already: bool = False,
|
2174
2187
|
raise_for_changed_count: bool = False,
|
@@ -2192,7 +2205,7 @@ def iter_files_with_path(
|
|
2192
2205
|
cur: Literal[0, 1] = 0,
|
2193
2206
|
normalize_attr: None | Callable[[dict], dict] = normalize_attr,
|
2194
2207
|
escape: None | bool | Callable[[str], str] = True,
|
2195
|
-
with_ancestors: bool =
|
2208
|
+
with_ancestors: bool = False,
|
2196
2209
|
id_to_dirnode: None | EllipsisType | MutableMapping[int, tuple[str, int] | DirNode] = None,
|
2197
2210
|
path_already: bool = False,
|
2198
2211
|
raise_for_changed_count: bool = False,
|
@@ -2215,7 +2228,7 @@ def iter_files_with_path(
|
|
2215
2228
|
cur: Literal[0, 1] = 0,
|
2216
2229
|
normalize_attr: None | Callable[[dict], dict] = normalize_attr,
|
2217
2230
|
escape: None | bool | Callable[[str], str] = True,
|
2218
|
-
with_ancestors: bool =
|
2231
|
+
with_ancestors: bool = False,
|
2219
2232
|
id_to_dirnode: None | EllipsisType | MutableMapping[int, tuple[str, int] | DirNode] = None,
|
2220
2233
|
path_already: bool = False,
|
2221
2234
|
raise_for_changed_count: bool = False,
|
@@ -2296,6 +2309,7 @@ def iter_files_with_path(
|
|
2296
2309
|
def set_path_already(*_):
|
2297
2310
|
nonlocal _path_already
|
2298
2311
|
_path_already = True
|
2312
|
+
@as_gen_step
|
2299
2313
|
def fetch_dirs(id: int | str, /):
|
2300
2314
|
if id:
|
2301
2315
|
yield through(iter_download_nodes(
|
@@ -2318,7 +2332,7 @@ def iter_files_with_path(
|
|
2318
2332
|
)) as get_next:
|
2319
2333
|
while True:
|
2320
2334
|
attr = yield get_next()
|
2321
|
-
yield
|
2335
|
+
yield fetch_dirs(attr["pickcode"])
|
2322
2336
|
if with_ancestors:
|
2323
2337
|
id_to_ancestors: dict[int, list[dict]] = {}
|
2324
2338
|
def get_ancestors(id: int, attr: dict | tuple[str, int] | DirNode, /) -> list[dict]:
|
@@ -2366,9 +2380,9 @@ def iter_files_with_path(
|
|
2366
2380
|
add_to_cache = cache.append
|
2367
2381
|
if not path_already:
|
2368
2382
|
if async_:
|
2369
|
-
task: Any = create_task(
|
2383
|
+
task: Any = create_task(fetch_dirs(cid))
|
2370
2384
|
else:
|
2371
|
-
task = run_as_thread(
|
2385
|
+
task = run_as_thread(fetch_dirs, cid)
|
2372
2386
|
task.add_done_callback(set_path_already)
|
2373
2387
|
with with_iter_next(iter_files(
|
2374
2388
|
client,
|
@@ -2417,7 +2431,7 @@ def iter_files_with_path(
|
|
2417
2431
|
def iter_files_with_path_skim(
|
2418
2432
|
client: str | P115Client,
|
2419
2433
|
cid: int | str = 0,
|
2420
|
-
with_ancestors: bool =
|
2434
|
+
with_ancestors: bool = False,
|
2421
2435
|
escape: None | bool | Callable[[str], str] = True,
|
2422
2436
|
id_to_dirnode: None | EllipsisType | MutableMapping[int, tuple[str, int] | DirNode] = None,
|
2423
2437
|
path_already: bool = False,
|
@@ -2432,7 +2446,7 @@ def iter_files_with_path_skim(
|
|
2432
2446
|
def iter_files_with_path_skim(
|
2433
2447
|
client: str | P115Client,
|
2434
2448
|
cid: int | str = 0,
|
2435
|
-
with_ancestors: bool =
|
2449
|
+
with_ancestors: bool = False,
|
2436
2450
|
escape: None | bool | Callable[[str], str] = True,
|
2437
2451
|
id_to_dirnode: None | EllipsisType | MutableMapping[int, tuple[str, int] | DirNode] = None,
|
2438
2452
|
path_already: bool = False,
|
@@ -2446,7 +2460,7 @@ def iter_files_with_path_skim(
|
|
2446
2460
|
def iter_files_with_path_skim(
|
2447
2461
|
client: str | P115Client,
|
2448
2462
|
cid: int | str = 0,
|
2449
|
-
with_ancestors: bool =
|
2463
|
+
with_ancestors: bool = False,
|
2450
2464
|
escape: None | bool | Callable[[str], str] = True,
|
2451
2465
|
id_to_dirnode: None | EllipsisType | MutableMapping[int, tuple[str, int] | DirNode] = None,
|
2452
2466
|
path_already: bool = False,
|
@@ -3047,13 +3061,7 @@ def iter_nodes_using_info(
|
|
3047
3061
|
return None
|
3048
3062
|
check_response(resp)
|
3049
3063
|
if id_to_dirnode is not ...:
|
3050
|
-
|
3051
|
-
for info in resp["paths"][1:]:
|
3052
|
-
fid = int(info["file_id"])
|
3053
|
-
id_to_dirnode[fid] = DirNode(info["file_name"], pid)
|
3054
|
-
pid = fid
|
3055
|
-
if resp["is_dir"]:
|
3056
|
-
id_to_dirnode[resp["id"]] = DirNode(resp["name"], pid)
|
3064
|
+
_update_resp_2_id_to_dirnode(resp, id_to_dirnode)
|
3057
3065
|
return resp
|
3058
3066
|
return do_filter(None, do_map(
|
3059
3067
|
project,
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: p115client
|
3
|
-
Version: 0.0.5.13
|
3
|
+
Version: 0.0.5.13.2
|
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.2)
|
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)
|
@@ -8,12 +8,12 @@ p115client/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
8
|
p115client/tool/__init__.py,sha256=IwwzbCQ7jpRoFGTQUCfGBx8zvjqjgSFs98yKpYyI46s,429
|
9
9
|
p115client/tool/attr.py,sha256=G91V71EhsqIIPkhGDnv2z6nxVq7wgl6nNPDj3AKzw1I,3079
|
10
10
|
p115client/tool/auth.py,sha256=qlRcfEjzebseiHR2dyBpOoPpxB4k8P6Tj729S2TLB1s,1672
|
11
|
-
p115client/tool/download.py,sha256=
|
11
|
+
p115client/tool/download.py,sha256=sRp0Jt9PeQjBMlMqTF-1TBR898tuYBWMLzYeR4W190A,65149
|
12
12
|
p115client/tool/edit.py,sha256=eAlINrXEAwAwliZFako5vrne_sLmxEyBr1Bk05YZsAc,17332
|
13
|
-
p115client/tool/export_dir.py,sha256=
|
14
|
-
p115client/tool/fs_files.py,sha256=
|
13
|
+
p115client/tool/export_dir.py,sha256=jPD4VP0kbJ1MW9CDgUcInSmt0aJejhn257x30Sm3hss,23557
|
14
|
+
p115client/tool/fs_files.py,sha256=4L81eiWblAgURIz8pC6_Dun3MKjWBY05qkn6jDv9qUY,15837
|
15
15
|
p115client/tool/history.py,sha256=9pgF9l8VvQkpjsVgtIzNcrUQZzLH9tt4JysBwJ4yHsk,11636
|
16
|
-
p115client/tool/iterdir.py,sha256=
|
16
|
+
p115client/tool/iterdir.py,sha256=SiFfjOuE4HMLsGfy5b3psiIlWMDjv2F5g3mK2eI7gY8,161857
|
17
17
|
p115client/tool/life.py,sha256=dfwm5jKfo0K9pIUZKpZ32oPBrlcfrezflSJyyDIbX8E,17721
|
18
18
|
p115client/tool/offline.py,sha256=6HaGkbsAAx3FPFvSr_7LZvrUw_fp3QRB2y2kVRHNgZ0,6291
|
19
19
|
p115client/tool/pool.py,sha256=PImYG4fU7retZVFDPYib9e87J3RvJvugOW1mxX9jSU0,13831
|
@@ -22,7 +22,7 @@ p115client/tool/upload.py,sha256=dpww3TGSOyjqz1EogQEJDiZ9QWERd47izZOw9mNCCiA,329
|
|
22
22
|
p115client/tool/util.py,sha256=gvA-o-TcEAR3o754Kn82Bu6yggmnAhScUCrRpMVCI50,3934
|
23
23
|
p115client/tool/xys.py,sha256=r9wzE5VgpR6ATYHM1uVZ06uIU4qqVeDyRTYU6W_N_Tc,10190
|
24
24
|
p115client/type.py,sha256=h_pGKTlz07g64Y_93ylF-fUyC8g-HiQacMhu4KOXjYA,6457
|
25
|
-
p115client-0.0.5.13.dist-info/LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
|
26
|
-
p115client-0.0.5.13.dist-info/METADATA,sha256=
|
27
|
-
p115client-0.0.5.13.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
28
|
-
p115client-0.0.5.13.dist-info/RECORD,,
|
25
|
+
p115client-0.0.5.13.2.dist-info/LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
|
26
|
+
p115client-0.0.5.13.2.dist-info/METADATA,sha256=9rvUKsIxlIaPJXTyV2pOP8yEhqRmJr4p8VHv_06tSJI,8228
|
27
|
+
p115client-0.0.5.13.2.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
28
|
+
p115client-0.0.5.13.2.dist-info/RECORD,,
|
File without changes
|
File without changes
|