p115client 0.0.5.10.3__tar.gz → 0.0.5.10.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.10.3 → p115client-0.0.5.10.4}/PKG-INFO +1 -1
- {p115client-0.0.5.10.3 → p115client-0.0.5.10.4}/p115client/tool/iterdir.py +311 -167
- {p115client-0.0.5.10.3 → p115client-0.0.5.10.4}/pyproject.toml +1 -1
- {p115client-0.0.5.10.3 → p115client-0.0.5.10.4}/LICENSE +0 -0
- {p115client-0.0.5.10.3 → p115client-0.0.5.10.4}/p115client/__init__.py +0 -0
- {p115client-0.0.5.10.3 → p115client-0.0.5.10.4}/p115client/_upload.py +0 -0
- {p115client-0.0.5.10.3 → p115client-0.0.5.10.4}/p115client/client.py +0 -0
- {p115client-0.0.5.10.3 → p115client-0.0.5.10.4}/p115client/const.py +0 -0
- {p115client-0.0.5.10.3 → p115client-0.0.5.10.4}/p115client/exception.py +0 -0
- {p115client-0.0.5.10.3 → p115client-0.0.5.10.4}/p115client/py.typed +0 -0
- {p115client-0.0.5.10.3 → p115client-0.0.5.10.4}/p115client/tool/__init__.py +0 -0
- {p115client-0.0.5.10.3 → p115client-0.0.5.10.4}/p115client/tool/attr.py +0 -0
- {p115client-0.0.5.10.3 → p115client-0.0.5.10.4}/p115client/tool/download.py +0 -0
- {p115client-0.0.5.10.3 → p115client-0.0.5.10.4}/p115client/tool/edit.py +0 -0
- {p115client-0.0.5.10.3 → p115client-0.0.5.10.4}/p115client/tool/export_dir.py +0 -0
- {p115client-0.0.5.10.3 → p115client-0.0.5.10.4}/p115client/tool/fs_files.py +0 -0
- {p115client-0.0.5.10.3 → p115client-0.0.5.10.4}/p115client/tool/history.py +0 -0
- {p115client-0.0.5.10.3 → p115client-0.0.5.10.4}/p115client/tool/life.py +0 -0
- {p115client-0.0.5.10.3 → p115client-0.0.5.10.4}/p115client/tool/pool.py +0 -0
- {p115client-0.0.5.10.3 → p115client-0.0.5.10.4}/p115client/tool/request.py +0 -0
- {p115client-0.0.5.10.3 → p115client-0.0.5.10.4}/p115client/tool/upload.py +0 -0
- {p115client-0.0.5.10.3 → p115client-0.0.5.10.4}/p115client/tool/util.py +0 -0
- {p115client-0.0.5.10.3 → p115client-0.0.5.10.4}/p115client/tool/xys.py +0 -0
- {p115client-0.0.5.10.3 → p115client-0.0.5.10.4}/p115client/type.py +0 -0
- {p115client-0.0.5.10.3 → p115client-0.0.5.10.4}/readme.md +0 -0
@@ -8,8 +8,8 @@ __all__ = [
|
|
8
8
|
"iter_nodes_skim", "iter_stared_dirs_raw", "iter_stared_dirs", "ensure_attr_path",
|
9
9
|
"ensure_attr_path_by_category_get", "iterdir_raw", "iterdir", "iterdir_limited",
|
10
10
|
"iter_files_raw", "iter_files", "traverse_files", "iter_dirs", "iter_dupfiles",
|
11
|
-
"iter_image_files", "share_iterdir", "share_iter_files", "
|
12
|
-
"iter_selected_nodes_by_pickcode", "iter_selected_nodes_using_category_get",
|
11
|
+
"iter_image_files", "share_iterdir", "share_iter_files", "share_get_id_to_path",
|
12
|
+
"iter_selected_nodes", "iter_selected_nodes_by_pickcode", "iter_selected_nodes_using_category_get",
|
13
13
|
"iter_selected_nodes_using_edit", "iter_selected_nodes_using_star_event",
|
14
14
|
"iter_selected_dirs_using_star", "iter_files_with_dirname", "iter_files_with_path",
|
15
15
|
"iter_files_with_path_by_export_dir", "iter_parents_3_level", "iter_dir_nodes",
|
@@ -104,7 +104,7 @@ class OverviewAttr:
|
|
104
104
|
|
105
105
|
|
106
106
|
#: 用于缓存每个用户(根据用户 id 区别)的每个目录 id 到所对应的 (名称, 父id) 的元组的字典的字典
|
107
|
-
ID_TO_DIRNODE_CACHE: Final[defaultdict[int, dict[int, tuple[str, int] | DirNode]]] = defaultdict(dict)
|
107
|
+
ID_TO_DIRNODE_CACHE: Final[defaultdict[int | tuple[int, str], dict[int, tuple[str, int] | DirNode]]] = defaultdict(dict)
|
108
108
|
|
109
109
|
|
110
110
|
def _overview_attr(info: Mapping, /) -> OverviewAttr:
|
@@ -117,8 +117,8 @@ def _overview_attr(info: Mapping, /) -> OverviewAttr:
|
|
117
117
|
else:
|
118
118
|
id = int(info["fid"])
|
119
119
|
pid = int(info["cid"])
|
120
|
-
ctime = int(info
|
121
|
-
mtime = int(info
|
120
|
+
ctime = int(info.get("tp") or info["t"])
|
121
|
+
mtime = int(info.get("te") or info["t"])
|
122
122
|
elif "fn" in info:
|
123
123
|
is_dir = info["fc"] == "0"
|
124
124
|
name = info["fn"]
|
@@ -596,18 +596,18 @@ def get_ancestors_to_cid(
|
|
596
596
|
return run_gen_step(gen_step, async_=async_)
|
597
597
|
|
598
598
|
|
599
|
-
|
600
|
-
|
601
599
|
# TODO: 使用 search 接口以在特定目录之下搜索某个名字,以便减少风控
|
602
600
|
@overload
|
603
601
|
def get_id_to_path(
|
604
602
|
client: str | P115Client,
|
605
603
|
path: str | Sequence[str],
|
604
|
+
parent_id: int = 0,
|
606
605
|
ensure_file: None | bool = None,
|
607
606
|
is_posixpath: bool = False,
|
608
607
|
refresh: bool = False,
|
609
608
|
id_to_dirnode: None | dict[int, tuple[str, int] | DirNode] = None,
|
610
609
|
app: str = "web",
|
610
|
+
dont_use_getid: bool = False,
|
611
611
|
*,
|
612
612
|
async_: Literal[False] = False,
|
613
613
|
**request_kwargs,
|
@@ -617,11 +617,13 @@ def get_id_to_path(
|
|
617
617
|
def get_id_to_path(
|
618
618
|
client: str | P115Client,
|
619
619
|
path: str | Sequence[str],
|
620
|
+
parent_id: int = 0,
|
620
621
|
ensure_file: None | bool = None,
|
621
622
|
is_posixpath: bool = False,
|
622
623
|
refresh: bool = False,
|
623
624
|
id_to_dirnode: None | dict[int, tuple[str, int] | DirNode] = None,
|
624
625
|
app: str = "web",
|
626
|
+
dont_use_getid: bool = False,
|
625
627
|
*,
|
626
628
|
async_: Literal[True],
|
627
629
|
**request_kwargs,
|
@@ -630,11 +632,13 @@ def get_id_to_path(
|
|
630
632
|
def get_id_to_path(
|
631
633
|
client: str | P115Client,
|
632
634
|
path: str | Sequence[str],
|
635
|
+
parent_id: int = 0,
|
633
636
|
ensure_file: None | bool = None,
|
634
637
|
is_posixpath: bool = False,
|
635
638
|
refresh: bool = False,
|
636
639
|
id_to_dirnode: None | dict[int, tuple[str, int] | DirNode] = None,
|
637
640
|
app: str = "web",
|
641
|
+
dont_use_getid: bool = False,
|
638
642
|
*,
|
639
643
|
async_: Literal[False, True] = False,
|
640
644
|
**request_kwargs,
|
@@ -643,6 +647,7 @@ def get_id_to_path(
|
|
643
647
|
|
644
648
|
:param client: 115 客户端或 cookies
|
645
649
|
:param path: 路径
|
650
|
+
:param parent_id: 上级目录的 id
|
646
651
|
:param ensure_file: 是否确保为文件
|
647
652
|
|
648
653
|
- True: 必须是文件
|
@@ -653,6 +658,7 @@ def get_id_to_path(
|
|
653
658
|
:param refresh: 是否刷新。如果为 True,则会执行网络请求以查询;如果为 False,则直接从 `id_to_dirnode` 中获取
|
654
659
|
:param id_to_dirnode: 字典,保存 id 到对应文件的 `DirNode(name, parent_id)` 命名元组的字典
|
655
660
|
:param app: 使用某个 app (设备)的接口
|
661
|
+
:param dont_use_getid: 不要使用 `client.fs_dir_getid` 或 `client.fs_dir_getid_app`,以便 `id_to_dirnode` 有缓存
|
656
662
|
:param async_: 是否异步
|
657
663
|
:param request_kwargs: 其它请求参数
|
658
664
|
|
@@ -664,178 +670,124 @@ def get_id_to_path(
|
|
664
670
|
id_to_dirnode = ID_TO_DIRNODE_CACHE[client.user_id]
|
665
671
|
error = FileNotFoundError(ENOENT, f"no such path: {path!r}")
|
666
672
|
def gen_step():
|
667
|
-
nonlocal
|
668
|
-
if
|
669
|
-
|
670
|
-
|
671
|
-
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
686
|
-
if ensure_file is None and path.endswith("/"):
|
687
|
-
ensure_file = False
|
688
|
-
patht = ["", *filter(None, path.split("/"))]
|
673
|
+
nonlocal ensure_file, parent_id
|
674
|
+
if isinstance(path, str):
|
675
|
+
if path.startswith("/"):
|
676
|
+
parent_id = 0
|
677
|
+
if path in (".", "..", "/"):
|
678
|
+
if ensure_file:
|
679
|
+
raise error
|
680
|
+
return parent_id
|
681
|
+
elif path.startswith("根目录 > "):
|
682
|
+
parent_id = 0
|
683
|
+
patht = path.split(" > ")[1:]
|
684
|
+
elif is_posixpath:
|
685
|
+
if ensure_file is None and path.endswith("/"):
|
686
|
+
ensure_file = False
|
687
|
+
patht = [p for p in path.split("/") if p]
|
688
|
+
else:
|
689
|
+
if ensure_file is None and path_is_dir_form(path):
|
690
|
+
ensure_file = False
|
691
|
+
patht, _ = splits(path.lstrip("/"))
|
689
692
|
else:
|
690
|
-
if
|
691
|
-
|
692
|
-
|
693
|
-
|
693
|
+
if path and not path[0]:
|
694
|
+
parent_id = 0
|
695
|
+
patht = list(path[1:])
|
696
|
+
else:
|
697
|
+
patht = [p for p in path if p]
|
698
|
+
if not patht:
|
699
|
+
return parent_id
|
700
|
+
if not patht:
|
694
701
|
if ensure_file:
|
695
702
|
raise error
|
696
|
-
return
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
if
|
701
|
-
|
702
|
-
|
703
|
-
|
704
|
-
|
705
|
-
pid = 0
|
706
|
-
if stop > 1 and not refresh and id_to_dirnode:
|
707
|
-
if stop == 2:
|
708
|
-
if is_posixpath:
|
709
|
-
needle = (patht[1].replace("/", "|"), pid)
|
710
|
-
else:
|
711
|
-
needle = (patht[1], pid)
|
712
|
-
for k, t in id_to_dirnode.items():
|
713
|
-
if is_posixpath:
|
714
|
-
t = (t[0].replace("/", "|"), t[1])
|
715
|
-
if t == needle:
|
716
|
-
pid = k
|
717
|
-
j = 2
|
718
|
-
else:
|
719
|
-
if is_posixpath:
|
720
|
-
table = {(n.replace("/", "|"), pid): k for k, (n, pid) in id_to_dirnode.items()}
|
703
|
+
return parent_id
|
704
|
+
i = 0
|
705
|
+
start_parent_id = parent_id
|
706
|
+
if not refresh and id_to_dirnode and id_to_dirnode is not ...:
|
707
|
+
if i := len(patht) - bool(ensure_file):
|
708
|
+
obj = "|" if is_posixpath else "/"
|
709
|
+
for i in range(i):
|
710
|
+
if obj in patht[i]:
|
711
|
+
break
|
721
712
|
else:
|
722
|
-
|
723
|
-
|
724
|
-
|
725
|
-
|
726
|
-
|
727
|
-
|
728
|
-
|
729
|
-
pid = table[needle]
|
730
|
-
j += 1
|
731
|
-
except KeyError:
|
732
|
-
pass
|
733
|
-
if j >= i:
|
734
|
-
i = j
|
735
|
-
cid = pid
|
736
|
-
else:
|
737
|
-
if ensure_file and len(patht) == i:
|
738
|
-
i -= 1
|
739
|
-
if app in ("", "web", "desktop", "harmony"):
|
740
|
-
fs_dir_getid: Callable = client.fs_dir_getid
|
741
|
-
else:
|
742
|
-
fs_dir_getid = partial(client.fs_dir_getid_app, app=app)
|
743
|
-
cid = 0
|
744
|
-
while i > 1:
|
745
|
-
dirname = "/".join(patht[:i])
|
746
|
-
resp = yield fs_dir_getid(dirname, async_=async_, **request_kwargs)
|
747
|
-
if not (resp["state"] and (cid := resp["id"])):
|
748
|
-
if len(patht) == i and ensure_file is None:
|
749
|
-
ensure_file = True
|
750
|
-
i -= 1
|
751
|
-
continue
|
752
|
-
raise error
|
753
|
-
cid = int(cid)
|
754
|
-
if not refresh and cid not in id_to_dirnode:
|
755
|
-
yield get_path_to_cid(
|
756
|
-
client,
|
757
|
-
cid,
|
758
|
-
id_to_dirnode=id_to_dirnode,
|
759
|
-
app=app,
|
760
|
-
async_=async_,
|
761
|
-
**request_kwargs,
|
762
|
-
)
|
763
|
-
break
|
764
|
-
if len(patht) == i:
|
765
|
-
return cid
|
766
|
-
for name in patht[i:-1]:
|
767
|
-
if async_:
|
768
|
-
async def request():
|
769
|
-
nonlocal cid
|
770
|
-
async for info in iterdir_raw(
|
771
|
-
client,
|
772
|
-
cid,
|
773
|
-
ensure_file=False,
|
774
|
-
app=app,
|
775
|
-
id_to_dirnode=id_to_dirnode,
|
776
|
-
async_=True,
|
777
|
-
**request_kwargs,
|
778
|
-
):
|
779
|
-
attr = _overview_attr(info)
|
780
|
-
if (attr.name.replace("/", "|") if is_posixpath else attr.name) == name:
|
781
|
-
cid = attr.id
|
713
|
+
i += 1
|
714
|
+
if i:
|
715
|
+
for i in range(i):
|
716
|
+
needle = (patht[i], parent_id)
|
717
|
+
for fid, key in id_to_dirnode.items():
|
718
|
+
if needle == key:
|
719
|
+
parent_id = fid
|
782
720
|
break
|
783
721
|
else:
|
784
|
-
raise error
|
785
|
-
yield request
|
786
|
-
else:
|
787
|
-
for info in iterdir_raw(
|
788
|
-
client,
|
789
|
-
cid,
|
790
|
-
ensure_file=False,
|
791
|
-
app=app,
|
792
|
-
id_to_dirnode=id_to_dirnode,
|
793
|
-
**request_kwargs,
|
794
|
-
):
|
795
|
-
attr = _overview_attr(info)
|
796
|
-
if (attr.name.replace("/", "|") if is_posixpath else attr.name) == name:
|
797
|
-
cid = attr.id
|
798
722
|
break
|
799
723
|
else:
|
800
|
-
|
801
|
-
|
802
|
-
|
803
|
-
|
804
|
-
|
805
|
-
|
806
|
-
|
807
|
-
|
808
|
-
|
809
|
-
async_=True,
|
810
|
-
**request_kwargs,
|
811
|
-
):
|
812
|
-
attr = _overview_attr(info)
|
813
|
-
if (attr.name.replace("/", "|") if is_posixpath else attr.name) == name:
|
814
|
-
if ensure_file:
|
815
|
-
if not attr.is_dir:
|
816
|
-
return P115ID(attr.id, info, about="path")
|
817
|
-
elif attr.is_dir:
|
818
|
-
return P115ID(attr.id, info, about="path")
|
724
|
+
i += 1
|
725
|
+
if i == len(patht):
|
726
|
+
return parent_id
|
727
|
+
if not start_parent_id:
|
728
|
+
stop = 0
|
729
|
+
if j := len(patht) - bool(ensure_file):
|
730
|
+
for stop, part in enumerate(patht[:j]):
|
731
|
+
if "/" in part:
|
732
|
+
break
|
819
733
|
else:
|
820
|
-
|
821
|
-
|
822
|
-
|
823
|
-
|
734
|
+
stop += 1
|
735
|
+
if not dont_use_getid:
|
736
|
+
while stop > i:
|
737
|
+
if app in ("", "web", "desktop", "harmony"):
|
738
|
+
fs_dir_getid: Callable = client.fs_dir_getid
|
739
|
+
else:
|
740
|
+
fs_dir_getid = partial(client.fs_dir_getid_app, app=app)
|
741
|
+
dirname = "/".join(patht[:stop])
|
742
|
+
resp = yield fs_dir_getid(dirname, async_=async_, **request_kwargs)
|
743
|
+
check_response(resp)
|
744
|
+
cid = int(resp["id"])
|
745
|
+
if not cid:
|
746
|
+
if stop == len(patht) and ensure_file is None:
|
747
|
+
stop -= 1
|
748
|
+
continue
|
749
|
+
raise error
|
750
|
+
parent_id = cid
|
751
|
+
i = stop
|
752
|
+
break
|
753
|
+
if i == len(patht):
|
754
|
+
return parent_id
|
755
|
+
for name in patht[i:-1]:
|
756
|
+
if is_posixpath:
|
757
|
+
name = name.replace("/", "|")
|
758
|
+
with with_iter_next(iterdir(
|
824
759
|
client,
|
825
|
-
|
760
|
+
parent_id,
|
761
|
+
ensure_file=False,
|
826
762
|
app=app,
|
827
763
|
id_to_dirnode=id_to_dirnode,
|
764
|
+
async_=async_,
|
828
765
|
**request_kwargs,
|
829
|
-
):
|
830
|
-
|
831
|
-
|
832
|
-
|
833
|
-
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
766
|
+
)) as get_next:
|
767
|
+
found = False
|
768
|
+
while not found:
|
769
|
+
attr = yield get_next
|
770
|
+
found = (attr["name"].replace("/", "|") if is_posixpath else attr["name"]) == name
|
771
|
+
parent_id = attr["id"]
|
772
|
+
if not found:
|
773
|
+
raise error
|
774
|
+
name = patht[-1]
|
775
|
+
if is_posixpath:
|
776
|
+
name = name.replace("/", "|")
|
777
|
+
with with_iter_next(iterdir(
|
778
|
+
client,
|
779
|
+
parent_id,
|
780
|
+
app=app,
|
781
|
+
id_to_dirnode=id_to_dirnode,
|
782
|
+
async_=async_,
|
783
|
+
**request_kwargs,
|
784
|
+
)) as get_next:
|
785
|
+
while True:
|
786
|
+
attr = yield get_next
|
787
|
+
if (attr["name"].replace("/", "|") if is_posixpath else attr["name"]) == name:
|
788
|
+
if ensure_file is None or ensure_file ^ attr["is_dir"]:
|
789
|
+
return P115ID(attr["id"], attr, about="path")
|
790
|
+
raise error
|
839
791
|
return run_gen_step(gen_step, async_=async_)
|
840
792
|
|
841
793
|
|
@@ -1135,6 +1087,11 @@ def _iter_fs_files(
|
|
1135
1087
|
pid, name = int(info["cid"]), info["name"]
|
1136
1088
|
id_to_dirnode[pid] = DirNode(name, int(info["pid"]))
|
1137
1089
|
if ensure_file is None:
|
1090
|
+
if id_to_dirnode is not ...:
|
1091
|
+
for info in resp["data"]:
|
1092
|
+
attr = _overview_attr(info)
|
1093
|
+
if attr.is_dir:
|
1094
|
+
id_to_dirnode[attr.id] = DirNode(attr.name, attr.parent_id)
|
1138
1095
|
yield YieldFrom(resp["data"], identity=True)
|
1139
1096
|
else:
|
1140
1097
|
for info in resp["data"]:
|
@@ -3118,6 +3075,7 @@ def share_iterdir(
|
|
3118
3075
|
order: Literal["file_name", "file_size", "file_type", "user_utime", "user_ptime", "user_otime"] = "user_ptime",
|
3119
3076
|
asc: Literal[0, 1] = 1,
|
3120
3077
|
normalize_attr: None | Callable[[dict], dict] = normalize_attr,
|
3078
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
3121
3079
|
*,
|
3122
3080
|
async_: Literal[False] = False,
|
3123
3081
|
**request_kwargs,
|
@@ -3133,6 +3091,7 @@ def share_iterdir(
|
|
3133
3091
|
order: Literal["file_name", "file_size", "file_type", "user_utime", "user_ptime", "user_otime"] = "user_ptime",
|
3134
3092
|
asc: Literal[0, 1] = 1,
|
3135
3093
|
normalize_attr: None | Callable[[dict], dict] = normalize_attr,
|
3094
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
3136
3095
|
*,
|
3137
3096
|
async_: Literal[True],
|
3138
3097
|
**request_kwargs,
|
@@ -3147,6 +3106,7 @@ def share_iterdir(
|
|
3147
3106
|
order: Literal["file_name", "file_size", "file_type", "user_utime", "user_ptime", "user_otime"] = "user_ptime",
|
3148
3107
|
asc: Literal[0, 1] = 1,
|
3149
3108
|
normalize_attr: None | Callable[[dict], dict] = normalize_attr,
|
3109
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
3150
3110
|
*,
|
3151
3111
|
async_: Literal[False, True] = False,
|
3152
3112
|
**request_kwargs,
|
@@ -3169,6 +3129,7 @@ def share_iterdir(
|
|
3169
3129
|
|
3170
3130
|
:param asc: 升序排列。0: 否,1: 是
|
3171
3131
|
:param normalize_attr: 把数据进行转换处理,使之便于阅读
|
3132
|
+
:param id_to_dirnode: 字典,保存 id 到对应文件的 `DirNode(name, parent_id)` 命名元组的字典
|
3172
3133
|
:param async_: 是否异步
|
3173
3134
|
:param request_kwargs: 其它请求参数
|
3174
3135
|
|
@@ -3176,7 +3137,9 @@ def share_iterdir(
|
|
3176
3137
|
"""
|
3177
3138
|
if isinstance(client, str):
|
3178
3139
|
client = P115Client(client, check_for_relogin=True)
|
3179
|
-
if
|
3140
|
+
if id_to_dirnode is None:
|
3141
|
+
id_to_dirnode = ID_TO_DIRNODE_CACHE[(client.user_id, share_code)]
|
3142
|
+
if page_size <= 0:
|
3180
3143
|
page_size = 10_000
|
3181
3144
|
def gen_step():
|
3182
3145
|
nonlocal receive_code
|
@@ -3202,6 +3165,10 @@ def share_iterdir(
|
|
3202
3165
|
for attr in resp["data"]["list"]:
|
3203
3166
|
attr["share_code"] = share_code
|
3204
3167
|
attr["receive_code"] = receive_code
|
3168
|
+
if id_to_dirnode is not ...:
|
3169
|
+
oattr = _overview_attr(attr)
|
3170
|
+
if oattr.is_dir:
|
3171
|
+
id_to_dirnode[oattr.id] = DirNode(oattr.name, oattr.parent_id)
|
3205
3172
|
if normalize_attr is not None:
|
3206
3173
|
attr = normalize_attr(attr)
|
3207
3174
|
yield Yield(attr, identity=True)
|
@@ -3216,6 +3183,7 @@ def share_iter_files(
|
|
3216
3183
|
client: str | P115Client,
|
3217
3184
|
share_link: str,
|
3218
3185
|
receive_code: str = "",
|
3186
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
3219
3187
|
*,
|
3220
3188
|
async_: Literal[False] = False,
|
3221
3189
|
**request_kwargs,
|
@@ -3226,6 +3194,7 @@ def share_iter_files(
|
|
3226
3194
|
client: str | P115Client,
|
3227
3195
|
share_link: str,
|
3228
3196
|
receive_code: str = "",
|
3197
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
3229
3198
|
*,
|
3230
3199
|
async_: Literal[True],
|
3231
3200
|
**request_kwargs,
|
@@ -3235,6 +3204,7 @@ def share_iter_files(
|
|
3235
3204
|
client: str | P115Client,
|
3236
3205
|
share_link: str,
|
3237
3206
|
receive_code: str = "",
|
3207
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
3238
3208
|
*,
|
3239
3209
|
async_: Literal[False, True] = False,
|
3240
3210
|
**request_kwargs,
|
@@ -3274,6 +3244,7 @@ def share_iter_files(
|
|
3274
3244
|
if isinstance(client, str):
|
3275
3245
|
client = P115Client(client, check_for_relogin=True)
|
3276
3246
|
def gen_step():
|
3247
|
+
nonlocal id_to_dirnode
|
3277
3248
|
payload: dict = cast(dict, share_extract_payload(share_link))
|
3278
3249
|
if receive_code:
|
3279
3250
|
payload["receive_code"] = receive_code
|
@@ -3281,7 +3252,10 @@ def share_iter_files(
|
|
3281
3252
|
resp = yield client.share_info(payload["share_code"], async_=async_, **request_kwargs)
|
3282
3253
|
check_response(resp)
|
3283
3254
|
payload["receive_code"] = resp["data"]["receive_code"]
|
3255
|
+
if id_to_dirnode is None:
|
3256
|
+
id_to_dirnode = ID_TO_DIRNODE_CACHE[(client.user_id, payload["share_code"])]
|
3284
3257
|
payload["cid"] = 0
|
3258
|
+
payload["id_to_dirnode"] = id_to_dirnode
|
3285
3259
|
it = share_iterdir(client, **payload, async_=async_, **request_kwargs)
|
3286
3260
|
do_next: Callable = anext if async_ else next
|
3287
3261
|
try:
|
@@ -3307,6 +3281,176 @@ def share_iter_files(
|
|
3307
3281
|
return run_gen_step(gen_step, async_=async_)
|
3308
3282
|
|
3309
3283
|
|
3284
|
+
@overload
|
3285
|
+
def share_get_id_to_path(
|
3286
|
+
client: str | P115Client,
|
3287
|
+
share_code: str,
|
3288
|
+
receive_code: str = "",
|
3289
|
+
path: str | Sequence[str] = "",
|
3290
|
+
parent_id: int = 0,
|
3291
|
+
ensure_file: None | bool = None,
|
3292
|
+
is_posixpath: bool = False,
|
3293
|
+
refresh: bool = False,
|
3294
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
3295
|
+
*,
|
3296
|
+
async_: Literal[False] = False,
|
3297
|
+
**request_kwargs,
|
3298
|
+
) -> int:
|
3299
|
+
...
|
3300
|
+
@overload
|
3301
|
+
def share_get_id_to_path(
|
3302
|
+
client: str | P115Client,
|
3303
|
+
share_code: str,
|
3304
|
+
receive_code: str = "",
|
3305
|
+
path: str | Sequence[str] = "",
|
3306
|
+
parent_id: int = 0,
|
3307
|
+
ensure_file: None | bool = None,
|
3308
|
+
is_posixpath: bool = False,
|
3309
|
+
refresh: bool = False,
|
3310
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
3311
|
+
*,
|
3312
|
+
async_: Literal[True],
|
3313
|
+
**request_kwargs,
|
3314
|
+
) -> Coroutine[Any, Any, int]:
|
3315
|
+
...
|
3316
|
+
def share_get_id_to_path(
|
3317
|
+
client: str | P115Client,
|
3318
|
+
share_code: str,
|
3319
|
+
receive_code: str = "",
|
3320
|
+
path: str | Sequence[str] = "",
|
3321
|
+
parent_id: int = 0,
|
3322
|
+
ensure_file: None | bool = None,
|
3323
|
+
is_posixpath: bool = False,
|
3324
|
+
refresh: bool = False,
|
3325
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
3326
|
+
*,
|
3327
|
+
async_: Literal[False, True] = False,
|
3328
|
+
**request_kwargs,
|
3329
|
+
) -> int | Coroutine[Any, Any, int]:
|
3330
|
+
"""对分享链接,获取路径对应的 id
|
3331
|
+
|
3332
|
+
:param client: 115 客户端或 cookies
|
3333
|
+
:param share_code: 分享码
|
3334
|
+
:param receive_code: 密码
|
3335
|
+
:param path: 路径
|
3336
|
+
:param parent_id: 上级目录的 id
|
3337
|
+
:param ensure_file: 是否确保为文件
|
3338
|
+
|
3339
|
+
- True: 必须是文件
|
3340
|
+
- False: 必须是目录
|
3341
|
+
- None: 可以是目录或文件
|
3342
|
+
|
3343
|
+
:param is_posixpath: 使用 posixpath,会把 "/" 转换为 "|",因此解析的时候,会对 "|" 进行特别处理
|
3344
|
+
:param refresh: 是否刷新。如果为 True,则会执行网络请求以查询;如果为 False,则直接从 `id_to_dirnode` 中获取
|
3345
|
+
:param id_to_dirnode: 字典,保存 id 到对应文件的 `DirNode(name, parent_id)` 命名元组的字典
|
3346
|
+
:param async_: 是否异步
|
3347
|
+
:param request_kwargs: 其它请求参数
|
3348
|
+
|
3349
|
+
:return: 文件或目录的 id
|
3350
|
+
"""
|
3351
|
+
if isinstance(client, str):
|
3352
|
+
client = P115Client(client, check_for_relogin=True)
|
3353
|
+
if id_to_dirnode is None:
|
3354
|
+
id_to_dirnode = ID_TO_DIRNODE_CACHE[(client.user_id, share_code)]
|
3355
|
+
error = FileNotFoundError(ENOENT, f"no such path: {path!r}")
|
3356
|
+
def gen_step():
|
3357
|
+
nonlocal ensure_file, parent_id, receive_code
|
3358
|
+
if isinstance(path, str):
|
3359
|
+
if path.startswith("/"):
|
3360
|
+
parent_id = 0
|
3361
|
+
if path in (".", "..", "/"):
|
3362
|
+
if ensure_file:
|
3363
|
+
raise error
|
3364
|
+
return parent_id
|
3365
|
+
elif path.startswith("根目录 > "):
|
3366
|
+
parent_id = 0
|
3367
|
+
patht = path.split(" > ")[1:]
|
3368
|
+
elif is_posixpath:
|
3369
|
+
if ensure_file is None and path.endswith("/"):
|
3370
|
+
ensure_file = False
|
3371
|
+
patht = [p for p in path.split("/") if p]
|
3372
|
+
else:
|
3373
|
+
if ensure_file is None and path_is_dir_form(path):
|
3374
|
+
ensure_file = False
|
3375
|
+
patht, _ = splits(path.lstrip("/"))
|
3376
|
+
else:
|
3377
|
+
if path and not path[0]:
|
3378
|
+
parent_id = 0
|
3379
|
+
patht = list(path[1:])
|
3380
|
+
else:
|
3381
|
+
patht = [p for p in path if p]
|
3382
|
+
if not patht:
|
3383
|
+
return parent_id
|
3384
|
+
if not patht:
|
3385
|
+
if ensure_file:
|
3386
|
+
raise error
|
3387
|
+
return parent_id
|
3388
|
+
if not receive_code:
|
3389
|
+
resp = yield client.share_info(share_code, async_=async_, **request_kwargs)
|
3390
|
+
check_response(resp)
|
3391
|
+
receive_code = resp["data"]["receive_code"]
|
3392
|
+
i = 0
|
3393
|
+
if not refresh and id_to_dirnode and id_to_dirnode is not ...:
|
3394
|
+
if i := len(patht) - bool(ensure_file):
|
3395
|
+
obj = "|" if is_posixpath else "/"
|
3396
|
+
for i in range(i):
|
3397
|
+
if obj in patht[i]:
|
3398
|
+
break
|
3399
|
+
else:
|
3400
|
+
i += 1
|
3401
|
+
if i:
|
3402
|
+
for i in range(i):
|
3403
|
+
needle = (patht[i], parent_id)
|
3404
|
+
for fid, key in id_to_dirnode.items():
|
3405
|
+
if needle == key:
|
3406
|
+
parent_id = fid
|
3407
|
+
break
|
3408
|
+
else:
|
3409
|
+
break
|
3410
|
+
else:
|
3411
|
+
i += 1
|
3412
|
+
if i == len(patht):
|
3413
|
+
return parent_id
|
3414
|
+
for name in patht[i:-1]:
|
3415
|
+
if is_posixpath:
|
3416
|
+
name = name.replace("/", "|")
|
3417
|
+
with with_iter_next(share_iterdir(
|
3418
|
+
client,
|
3419
|
+
share_code,
|
3420
|
+
receive_code=receive_code,
|
3421
|
+
cid=parent_id,
|
3422
|
+
id_to_dirnode=id_to_dirnode,
|
3423
|
+
async_=async_,
|
3424
|
+
**request_kwargs,
|
3425
|
+
)) as get_next:
|
3426
|
+
found = False
|
3427
|
+
while not found:
|
3428
|
+
attr = yield get_next
|
3429
|
+
found = attr["is_dir"] and (attr["name"].replace("/", "|") if is_posixpath else attr["name"]) == name
|
3430
|
+
parent_id = attr["id"]
|
3431
|
+
if not found:
|
3432
|
+
raise error
|
3433
|
+
name = patht[-1]
|
3434
|
+
if is_posixpath:
|
3435
|
+
name = name.replace("/", "|")
|
3436
|
+
with with_iter_next(share_iterdir(
|
3437
|
+
client,
|
3438
|
+
share_code,
|
3439
|
+
receive_code=receive_code,
|
3440
|
+
cid=parent_id,
|
3441
|
+
id_to_dirnode=id_to_dirnode,
|
3442
|
+
async_=async_,
|
3443
|
+
**request_kwargs,
|
3444
|
+
)) as get_next:
|
3445
|
+
while True:
|
3446
|
+
attr = yield get_next
|
3447
|
+
if (attr["name"].replace("/", "|") if is_posixpath else attr["name"]) == name:
|
3448
|
+
if ensure_file is None or ensure_file ^ attr["is_dir"]:
|
3449
|
+
return P115ID(attr["id"], attr, about="path")
|
3450
|
+
raise error
|
3451
|
+
return run_gen_step(gen_step, async_=async_)
|
3452
|
+
|
3453
|
+
|
3310
3454
|
@overload
|
3311
3455
|
def iter_selected_nodes(
|
3312
3456
|
client: str | P115Client,
|
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
|