p115client 0.0.5.10.9__py3-none-any.whl → 0.0.5.11.1__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/_upload.py +8 -8
- p115client/client.py +963 -256
- p115client/tool/attr.py +1 -1
- p115client/tool/download.py +86 -69
- p115client/tool/edit.py +3 -3
- p115client/tool/export_dir.py +22 -23
- p115client/tool/fs_files.py +4 -7
- p115client/tool/history.py +5 -5
- p115client/tool/iterdir.py +87 -88
- p115client/tool/life.py +12 -12
- p115client/tool/pool.py +5 -5
- p115client/tool/upload.py +4 -4
- p115client/tool/xys.py +10 -7
- {p115client-0.0.5.10.9.dist-info → p115client-0.0.5.11.1.dist-info}/METADATA +2 -2
- p115client-0.0.5.11.1.dist-info/RECORD +26 -0
- p115client-0.0.5.10.9.dist-info/RECORD +0 -26
- {p115client-0.0.5.10.9.dist-info → p115client-0.0.5.11.1.dist-info}/LICENSE +0 -0
- {p115client-0.0.5.10.9.dist-info → p115client-0.0.5.11.1.dist-info}/WHEEL +0 -0
p115client/client.py
CHANGED
@@ -181,7 +181,7 @@ def complete_proapi(
|
|
181
181
|
) -> str:
|
182
182
|
if path and not path.startswith("/"):
|
183
183
|
path = "/" + path
|
184
|
-
if app in ("
|
184
|
+
if app in ("aps", "desktop", "open", "web"):
|
185
185
|
app = "android"
|
186
186
|
if app and not app.startswith("/"):
|
187
187
|
app = "/" + app
|
@@ -266,7 +266,7 @@ def get_default_request():
|
|
266
266
|
return _httpx_request
|
267
267
|
|
268
268
|
|
269
|
-
def parse_upload_init_response(
|
269
|
+
def parse_upload_init_response(_, content: bytes, /) -> dict:
|
270
270
|
data = ecdh_aes_decode(content, decompress=True)
|
271
271
|
if not isinstance(data, (bytes, bytearray, memoryview)):
|
272
272
|
data = memoryview(data)
|
@@ -542,6 +542,36 @@ def check_response(resp: dict | Awaitable[dict], /) -> dict | Coroutine[Any, Any
|
|
542
542
|
# {"state": 0, "errno": 40140126, "error": "access_token 校验失败(防篡改)"}
|
543
543
|
case 40140126:
|
544
544
|
raise OperationalError(errno.EINVAL, resp)
|
545
|
+
# {"state": 0, "errno": 40140127, "error": "response_type 错误"}
|
546
|
+
case 40140127:
|
547
|
+
raise OperationalError(errno.EINVAL, resp)
|
548
|
+
# {"state": 0, "errno": 40140128, "error": "redirect_uri 缺少协议"}
|
549
|
+
case 40140128:
|
550
|
+
raise OperationalError(errno.EINVAL, resp)
|
551
|
+
# {"state": 0, "errno": 40140129, "error": "redirect_uri 缺少域名"}
|
552
|
+
case 40140129:
|
553
|
+
raise OperationalError(errno.EINVAL, resp)
|
554
|
+
# {"state": 0, "errno": 40140130, "error": "没有配置重定向域名"}
|
555
|
+
case 40140130:
|
556
|
+
raise OperationalError(errno.EINVAL, resp)
|
557
|
+
# {"state": 0, "errno": 40140131, "error": "redirect_uri 非法域名"}
|
558
|
+
case 40140131:
|
559
|
+
raise OperationalError(errno.EINVAL, resp)
|
560
|
+
# {"state": 0, "errno": 40140132, "error": "grant_type 错误"}
|
561
|
+
case 40140132:
|
562
|
+
raise OperationalError(errno.EINVAL, resp)
|
563
|
+
# {"state": 0, "errno": 40140133, "error": "client_secret 验证失败"}
|
564
|
+
case 40140133:
|
565
|
+
raise OperationalError(errno.EINVAL, resp)
|
566
|
+
# {"state": 0, "errno": 40140134, "error": "授权码 code 验证失败"}
|
567
|
+
case 40140134:
|
568
|
+
raise OperationalError(errno.EINVAL, resp)
|
569
|
+
# {"state": 0, "errno": 40140135, "error": "client_id 验证失败"}
|
570
|
+
case 40140135:
|
571
|
+
raise OperationalError(errno.EINVAL, resp)
|
572
|
+
# {"state": 0, "errno": 40140136, "error": "redirect_uri 验证失败(防MITM)"}
|
573
|
+
case 40140136:
|
574
|
+
raise OperationalError(errno.EINVAL, resp)
|
545
575
|
elif "msg_code" in resp:
|
546
576
|
match resp["msg_code"]:
|
547
577
|
case 50028:
|
@@ -566,13 +596,34 @@ def check_response(resp: dict | Awaitable[dict], /) -> dict | Coroutine[Any, Any
|
|
566
596
|
raise P115OSError(errno.EIO, resp)
|
567
597
|
|
568
598
|
|
599
|
+
@overload
|
569
600
|
def normalize_attr_web(
|
570
601
|
info: Mapping,
|
571
602
|
/,
|
572
603
|
simple: bool = False,
|
573
604
|
keep_raw: bool = False,
|
574
|
-
|
605
|
+
*,
|
606
|
+
dict_cls: None = None,
|
575
607
|
) -> dict[str, Any]:
|
608
|
+
...
|
609
|
+
@overload
|
610
|
+
def normalize_attr_web[D: dict[str, Any]](
|
611
|
+
info: Mapping,
|
612
|
+
/,
|
613
|
+
simple: bool = False,
|
614
|
+
keep_raw: bool = False,
|
615
|
+
*,
|
616
|
+
dict_cls: type[D],
|
617
|
+
) -> D:
|
618
|
+
...
|
619
|
+
def normalize_attr_web[D: dict[str, Any]](
|
620
|
+
info: Mapping,
|
621
|
+
/,
|
622
|
+
simple: bool = False,
|
623
|
+
keep_raw: bool = False,
|
624
|
+
*,
|
625
|
+
dict_cls: None | type[D] = None,
|
626
|
+
) -> dict[str, Any] | D:
|
576
627
|
"""翻译 `P115Client.fs_files`、`P115Client.fs_search`、`P115Client.share_snap` 等接口响应的文件信息数据,使之便于阅读
|
577
628
|
|
578
629
|
:param info: 原始数据
|
@@ -583,10 +634,7 @@ def normalize_attr_web(
|
|
583
634
|
:return: 翻译后的 dict 类型数据
|
584
635
|
"""
|
585
636
|
if dict_cls is None:
|
586
|
-
|
587
|
-
dict_cls = dict
|
588
|
-
else:
|
589
|
-
dict_cls = AttrDict
|
637
|
+
dict_cls = cast(type[D], dict)
|
590
638
|
attr: dict[str, Any] = dict_cls()
|
591
639
|
is_directory = attr["is_dir"] = "fid" not in info
|
592
640
|
if not simple:
|
@@ -690,10 +738,10 @@ def normalize_attr_web(
|
|
690
738
|
attr["type"] = 0
|
691
739
|
elif info.get("iv") or "vdi" in info:
|
692
740
|
attr["type"] = 4
|
693
|
-
elif
|
694
|
-
attr["type"] =
|
695
|
-
elif
|
696
|
-
attr["type"] =
|
741
|
+
elif type_ := CLASS_TO_TYPE.get(attr.get("class", "")):
|
742
|
+
attr["type"] = type_
|
743
|
+
elif type_ := SUFFIX_TO_TYPE.get(splitext(attr["name"])[1].lower()):
|
744
|
+
attr["type"] = type_
|
697
745
|
else:
|
698
746
|
attr["type"] = 99
|
699
747
|
if keep_raw:
|
@@ -701,13 +749,33 @@ def normalize_attr_web(
|
|
701
749
|
return attr
|
702
750
|
|
703
751
|
|
752
|
+
@overload
|
704
753
|
def normalize_attr_app(
|
705
754
|
info: Mapping,
|
706
755
|
/,
|
707
756
|
simple: bool = False,
|
708
757
|
keep_raw: bool = False,
|
709
|
-
|
758
|
+
*,
|
759
|
+
dict_cls: None = None,
|
710
760
|
) -> dict[str, Any]:
|
761
|
+
...
|
762
|
+
@overload
|
763
|
+
def normalize_attr_app[D: dict[str, Any]](
|
764
|
+
info: Mapping,
|
765
|
+
/,
|
766
|
+
simple: bool = False,
|
767
|
+
keep_raw: bool = False,
|
768
|
+
*,
|
769
|
+
dict_cls: None | type[D] = None,
|
770
|
+
) -> D:
|
771
|
+
...
|
772
|
+
def normalize_attr_app[D: dict[str, Any]](
|
773
|
+
info: Mapping,
|
774
|
+
/,
|
775
|
+
simple: bool = False,
|
776
|
+
keep_raw: bool = False,
|
777
|
+
dict_cls: None | type[D] = None,
|
778
|
+
) -> dict[str, Any] | D:
|
711
779
|
"""翻译 `P115Client.fs_files_app` 接口响应的文件信息数据,使之便于阅读
|
712
780
|
|
713
781
|
:param info: 原始数据
|
@@ -718,10 +786,7 @@ def normalize_attr_app(
|
|
718
786
|
:return: 翻译后的 dict 类型数据
|
719
787
|
"""
|
720
788
|
if dict_cls is None:
|
721
|
-
|
722
|
-
dict_cls = dict
|
723
|
-
else:
|
724
|
-
dict_cls = AttrDict
|
789
|
+
dict_cls = cast(type[D], dict)
|
725
790
|
attr: dict[str, Any] = dict_cls()
|
726
791
|
is_directory = attr["is_dir"] = info["fc"] == "0" # fc => file_category
|
727
792
|
if not simple:
|
@@ -805,8 +870,8 @@ def normalize_attr_app(
|
|
805
870
|
attr["type"] = 3
|
806
871
|
elif info.get("isv") or "def" in info or "def2" in info or "v_img" in info:
|
807
872
|
attr["type"] = 4
|
808
|
-
elif
|
809
|
-
attr["type"] =
|
873
|
+
elif type_ := SUFFIX_TO_TYPE.get(splitext(attr["name"])[1].lower()):
|
874
|
+
attr["type"] = type_
|
810
875
|
else:
|
811
876
|
attr["type"] = 99
|
812
877
|
if keep_raw:
|
@@ -814,13 +879,33 @@ def normalize_attr_app(
|
|
814
879
|
return attr
|
815
880
|
|
816
881
|
|
882
|
+
@overload
|
817
883
|
def normalize_attr_app2(
|
818
884
|
info: Mapping,
|
819
885
|
/,
|
820
886
|
simple: bool = False,
|
821
887
|
keep_raw: bool = False,
|
822
|
-
|
888
|
+
*,
|
889
|
+
dict_cls: None = None,
|
823
890
|
) -> dict[str, Any]:
|
891
|
+
...
|
892
|
+
@overload
|
893
|
+
def normalize_attr_app2[D: dict[str, Any]](
|
894
|
+
info: Mapping,
|
895
|
+
/,
|
896
|
+
simple: bool = False,
|
897
|
+
keep_raw: bool = False,
|
898
|
+
*,
|
899
|
+
dict_cls: None | type[D] = None,
|
900
|
+
) -> D:
|
901
|
+
...
|
902
|
+
def normalize_attr_app2[D: dict[str, Any]](
|
903
|
+
info: Mapping,
|
904
|
+
/,
|
905
|
+
simple: bool = False,
|
906
|
+
keep_raw: bool = False,
|
907
|
+
dict_cls: None | type[D] = None,
|
908
|
+
) -> dict[str, Any] | D:
|
824
909
|
"""翻译 `P115Client.fs_files_app2` 接口响应的文件信息数据,使之便于阅读
|
825
910
|
|
826
911
|
:param info: 原始数据
|
@@ -831,10 +916,7 @@ def normalize_attr_app2(
|
|
831
916
|
:return: 翻译后的 dict 类型数据
|
832
917
|
"""
|
833
918
|
if dict_cls is None:
|
834
|
-
|
835
|
-
dict_cls = dict
|
836
|
-
else:
|
837
|
-
dict_cls = AttrDict
|
919
|
+
dict_cls = cast(type[D], dict)
|
838
920
|
attr: dict[str, Any] = dict_cls()
|
839
921
|
if "file_id" in info and "parent_id" in info:
|
840
922
|
if "file_category" in info:
|
@@ -940,8 +1022,8 @@ def normalize_attr_app2(
|
|
940
1022
|
attr["type"] = 3
|
941
1023
|
elif info.get("is_video") or "definition" in info or "definition2" in info or "video_img_url" in info:
|
942
1024
|
attr["type"] = 4
|
943
|
-
elif
|
944
|
-
attr["type"] =
|
1025
|
+
elif type_ := SUFFIX_TO_TYPE.get(splitext(attr["name"])[1].lower()):
|
1026
|
+
attr["type"] = type_
|
945
1027
|
else:
|
946
1028
|
attr["type"] = 99
|
947
1029
|
if keep_raw:
|
@@ -949,13 +1031,34 @@ def normalize_attr_app2(
|
|
949
1031
|
return attr
|
950
1032
|
|
951
1033
|
|
1034
|
+
@overload
|
952
1035
|
def normalize_attr(
|
953
1036
|
info: Mapping,
|
954
1037
|
/,
|
955
1038
|
simple: bool = False,
|
956
1039
|
keep_raw: bool = False,
|
957
|
-
|
1040
|
+
*,
|
1041
|
+
dict_cls: None,
|
958
1042
|
) -> dict[str, Any]:
|
1043
|
+
...
|
1044
|
+
@overload
|
1045
|
+
def normalize_attr[D: dict[str, Any]](
|
1046
|
+
info: Mapping,
|
1047
|
+
/,
|
1048
|
+
simple: bool = False,
|
1049
|
+
keep_raw: bool = False,
|
1050
|
+
*,
|
1051
|
+
dict_cls: type[D] = AttrDict, # type: ignore
|
1052
|
+
) -> D:
|
1053
|
+
...
|
1054
|
+
def normalize_attr[D: dict[str, Any]](
|
1055
|
+
info: Mapping,
|
1056
|
+
/,
|
1057
|
+
simple: bool = False,
|
1058
|
+
keep_raw: bool = False,
|
1059
|
+
*,
|
1060
|
+
dict_cls: None | type[D] = AttrDict, # type: ignore
|
1061
|
+
) -> dict[str, Any] | D:
|
959
1062
|
"""翻译获取自罗列目录、搜索、获取文件信息等接口的数据,使之便于阅读
|
960
1063
|
|
961
1064
|
:param info: 原始数据
|
@@ -973,12 +1076,32 @@ def normalize_attr(
|
|
973
1076
|
return normalize_attr_web(info, simple=simple, keep_raw=keep_raw, dict_cls=dict_cls)
|
974
1077
|
|
975
1078
|
|
1079
|
+
@overload
|
976
1080
|
def normalize_attr_simple(
|
977
1081
|
info: Mapping,
|
978
1082
|
/,
|
979
1083
|
keep_raw: bool = False,
|
1084
|
+
*,
|
1085
|
+
dict_cls: None = None,
|
980
1086
|
) -> dict[str, Any]:
|
981
|
-
|
1087
|
+
...
|
1088
|
+
@overload
|
1089
|
+
def normalize_attr_simple[D: dict[str, Any]](
|
1090
|
+
info: Mapping,
|
1091
|
+
/,
|
1092
|
+
keep_raw: bool = False,
|
1093
|
+
*,
|
1094
|
+
dict_cls: type[D],
|
1095
|
+
) -> D:
|
1096
|
+
...
|
1097
|
+
def normalize_attr_simple[D: dict[str, Any]](
|
1098
|
+
info: Mapping,
|
1099
|
+
/,
|
1100
|
+
keep_raw: bool = False,
|
1101
|
+
*,
|
1102
|
+
dict_cls: None | type[D] = None,
|
1103
|
+
) -> dict[str, Any] | D:
|
1104
|
+
return normalize_attr(info, simple=True, keep_raw=keep_raw, dict_cls=dict_cls)
|
982
1105
|
|
983
1106
|
|
984
1107
|
class IgnoreCaseDict[V](dict[str, V]):
|
@@ -2157,7 +2280,7 @@ class ClientRequestMixin:
|
|
2157
2280
|
else:
|
2158
2281
|
url = complete_api(f"/api/1.0/web/1.0/qrcode?uid={login_uid}", base_url=base_url)
|
2159
2282
|
if async_:
|
2160
|
-
yield
|
2283
|
+
yield startfile_async(url)
|
2161
2284
|
else:
|
2162
2285
|
startfile(url)
|
2163
2286
|
while True:
|
@@ -2194,7 +2317,7 @@ class ClientRequestMixin:
|
|
2194
2317
|
)
|
2195
2318
|
else:
|
2196
2319
|
return qrcode_token
|
2197
|
-
return run_gen_step(gen_step, async_=async_)
|
2320
|
+
return run_gen_step(gen_step, simple=True, async_=async_)
|
2198
2321
|
|
2199
2322
|
@overload
|
2200
2323
|
@classmethod
|
@@ -2261,7 +2384,7 @@ class ClientRequestMixin:
|
|
2261
2384
|
else:
|
2262
2385
|
url = complete_api(f"/api/1.0/web/1.0/qrcode?uid={login_uid}", base_url=base_url)
|
2263
2386
|
if async_:
|
2264
|
-
yield
|
2387
|
+
yield startfile_async(url)
|
2265
2388
|
else:
|
2266
2389
|
startfile(url)
|
2267
2390
|
while True:
|
@@ -2294,7 +2417,7 @@ class ClientRequestMixin:
|
|
2294
2417
|
async_=async_,
|
2295
2418
|
**request_kwargs,
|
2296
2419
|
)
|
2297
|
-
return run_gen_step(gen_step, async_=async_)
|
2420
|
+
return run_gen_step(gen_step, simple=True, async_=async_)
|
2298
2421
|
|
2299
2422
|
########## Upload API ##########
|
2300
2423
|
|
@@ -2677,7 +2800,7 @@ class ClientRequestMixin:
|
|
2677
2800
|
async_=async_,
|
2678
2801
|
**request_kwargs,
|
2679
2802
|
)
|
2680
|
-
return run_gen_step(gen_step, async_=async_)
|
2803
|
+
return run_gen_step(gen_step, simple=True, async_=async_)
|
2681
2804
|
|
2682
2805
|
@overload
|
2683
2806
|
def read_bytes_range(
|
@@ -2792,7 +2915,7 @@ class ClientRequestMixin:
|
|
2792
2915
|
async_=async_,
|
2793
2916
|
**request_kwargs,
|
2794
2917
|
)
|
2795
|
-
return run_gen_step(gen_step, async_=async_)
|
2918
|
+
return run_gen_step(gen_step, simple=True, async_=async_)
|
2796
2919
|
|
2797
2920
|
|
2798
2921
|
class P115OpenClient(ClientRequestMixin):
|
@@ -2888,7 +3011,7 @@ class P115OpenClient(ClientRequestMixin):
|
|
2888
3011
|
self.refresh_token = data["refresh_token"]
|
2889
3012
|
self.access_token = data["access_token"]
|
2890
3013
|
return self
|
2891
|
-
return run_gen_step(gen_step, async_=async_)
|
3014
|
+
return run_gen_step(gen_step, simple=True, async_=async_)
|
2892
3015
|
|
2893
3016
|
@classmethod
|
2894
3017
|
def from_token(cls, /, access_token: str, refresh_token: str) -> P115OpenClient:
|
@@ -2955,7 +3078,7 @@ class P115OpenClient(ClientRequestMixin):
|
|
2955
3078
|
self.refresh_token = data["refresh_token"]
|
2956
3079
|
access_token = self.access_token = data["access_token"]
|
2957
3080
|
return access_token
|
2958
|
-
return run_gen_step(gen_step, async_=async_)
|
3081
|
+
return run_gen_step(gen_step, simple=True, async_=async_)
|
2959
3082
|
|
2960
3083
|
@overload
|
2961
3084
|
def download_url(
|
@@ -3338,9 +3461,675 @@ class P115OpenClient(ClientRequestMixin):
|
|
3338
3461
|
return self.request(url=api, params=payload, async_=async_, **request_kwargs)
|
3339
3462
|
|
3340
3463
|
@overload
|
3341
|
-
def fs_info(
|
3464
|
+
def fs_info(
|
3465
|
+
self,
|
3466
|
+
payload: int | str | dict,
|
3467
|
+
/,
|
3468
|
+
base_url: bool | str | Callable[[], str] = False,
|
3469
|
+
*,
|
3470
|
+
async_: Literal[False] = False,
|
3471
|
+
**request_kwargs,
|
3472
|
+
) -> dict:
|
3473
|
+
...
|
3474
|
+
@overload
|
3475
|
+
def fs_info(
|
3476
|
+
self,
|
3477
|
+
payload: int | str | dict,
|
3478
|
+
/,
|
3479
|
+
base_url: bool | str | Callable[[], str] = False,
|
3480
|
+
*,
|
3481
|
+
async_: Literal[True],
|
3482
|
+
**request_kwargs,
|
3483
|
+
) -> Coroutine[Any, Any, dict]:
|
3484
|
+
...
|
3485
|
+
def fs_info(
|
3486
|
+
self,
|
3487
|
+
payload: int | str | dict,
|
3488
|
+
/,
|
3489
|
+
base_url: bool | str | Callable[[], str] = False,
|
3490
|
+
*,
|
3491
|
+
async_: Literal[False, True] = False,
|
3492
|
+
**request_kwargs,
|
3493
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
3494
|
+
"""获取文件或目录详情
|
3495
|
+
|
3496
|
+
GET https://proapi.115.com/open/folder/get_info
|
3497
|
+
|
3498
|
+
.. hint::
|
3499
|
+
相当于 `P115Client.fs_category_get_app`
|
3500
|
+
|
3501
|
+
.. admonition:: Reference
|
3502
|
+
|
3503
|
+
https://www.yuque.com/115yun/open/rl8zrhe2nag21dfw
|
3504
|
+
|
3505
|
+
:payload:
|
3506
|
+
- file_id: int | str 💡 文件或目录的 id
|
3507
|
+
"""
|
3508
|
+
api = complete_proapi("/open/folder/get_info", base_url)
|
3509
|
+
if isinstance(payload, (int, str)):
|
3510
|
+
payload = {"file_id": payload}
|
3511
|
+
return self.request(url=api, params=payload, async_=async_, **request_kwargs)
|
3512
|
+
|
3513
|
+
@overload
|
3514
|
+
def fs_mkdir(
|
3515
|
+
self,
|
3516
|
+
payload: str | dict,
|
3517
|
+
/,
|
3518
|
+
pid: int = 0,
|
3519
|
+
base_url: bool | str | Callable[[], str] = False,
|
3520
|
+
*,
|
3521
|
+
async_: Literal[False] = False,
|
3522
|
+
**request_kwargs,
|
3523
|
+
) -> dict:
|
3524
|
+
...
|
3525
|
+
@overload
|
3526
|
+
def fs_mkdir(
|
3527
|
+
self,
|
3528
|
+
payload: str | dict,
|
3529
|
+
/,
|
3530
|
+
pid: int = 0,
|
3531
|
+
base_url: bool | str | Callable[[], str] = False,
|
3532
|
+
*,
|
3533
|
+
async_: Literal[True],
|
3534
|
+
**request_kwargs,
|
3535
|
+
) -> Coroutine[Any, Any, dict]:
|
3536
|
+
...
|
3537
|
+
def fs_mkdir(
|
3538
|
+
self,
|
3539
|
+
payload: str | dict,
|
3540
|
+
/,
|
3541
|
+
pid: int = 0,
|
3542
|
+
base_url: bool | str | Callable[[], str] = False,
|
3543
|
+
*,
|
3544
|
+
async_: Literal[False, True] = False,
|
3545
|
+
**request_kwargs,
|
3546
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
3547
|
+
"""新建目录
|
3548
|
+
|
3549
|
+
POST https://proapi.115.com/open/folder/add
|
3550
|
+
|
3551
|
+
.. admonition:: Reference
|
3552
|
+
|
3553
|
+
https://www.yuque.com/115yun/open/qur839kyx9cgxpxi
|
3554
|
+
|
3555
|
+
:payload:
|
3556
|
+
- file_name: str 💡 新建目录名称,限制255个字符
|
3557
|
+
- pid: int | str = 0 💡 新建目录所在的父目录ID (根目录的ID为0)
|
3558
|
+
"""
|
3559
|
+
api = complete_proapi("/open/folder/add", base_url)
|
3560
|
+
if isinstance(payload, str):
|
3561
|
+
payload = {"pid": pid, "file_name": payload}
|
3562
|
+
else:
|
3563
|
+
payload = {"pid": pid, **payload}
|
3564
|
+
return self.request(url=api, method="POST", data=payload, async_=async_, **request_kwargs)
|
3565
|
+
|
3566
|
+
@overload
|
3567
|
+
def fs_move(
|
3568
|
+
self,
|
3569
|
+
payload: int | str | Iterable[int | str] | dict,
|
3570
|
+
/,
|
3571
|
+
pid: int = 0,
|
3572
|
+
base_url: bool | str | Callable[[], str] = False,
|
3573
|
+
*,
|
3574
|
+
async_: Literal[False] = False,
|
3575
|
+
**request_kwargs,
|
3576
|
+
) -> dict:
|
3577
|
+
...
|
3578
|
+
@overload
|
3579
|
+
def fs_move(
|
3580
|
+
self,
|
3581
|
+
payload: int | str | Iterable[int | str] | dict,
|
3582
|
+
/,
|
3583
|
+
pid: int = 0,
|
3584
|
+
base_url: bool | str | Callable[[], str] = False,
|
3585
|
+
*,
|
3586
|
+
async_: Literal[True],
|
3587
|
+
**request_kwargs,
|
3588
|
+
) -> Coroutine[Any, Any, dict]:
|
3589
|
+
...
|
3590
|
+
def fs_move(
|
3591
|
+
self,
|
3592
|
+
payload: int | str | Iterable[int | str] | dict,
|
3593
|
+
/,
|
3594
|
+
pid: int = 0,
|
3595
|
+
base_url: bool | str | Callable[[], str] = False,
|
3596
|
+
*,
|
3597
|
+
async_: Literal[False, True] = False,
|
3598
|
+
**request_kwargs,
|
3599
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
3600
|
+
"""文件移动
|
3601
|
+
|
3602
|
+
POST https://proapi.115.com/open/ufile/move
|
3603
|
+
|
3604
|
+
.. admonition:: Reference
|
3605
|
+
|
3606
|
+
https://www.yuque.com/115yun/open/vc6fhi2mrkenmav2
|
3607
|
+
|
3608
|
+
:payload:
|
3609
|
+
- file_ids: int | str 💡 文件或目录的 id,多个用逗号 "," 隔开
|
3610
|
+
- to_cid: int | str = 0 💡 父目录 id
|
3611
|
+
"""
|
3612
|
+
api = complete_proapi("/open/ufile/move", base_url)
|
3613
|
+
if isinstance(payload, (int, str)):
|
3614
|
+
payload = {"file_ids": payload}
|
3615
|
+
elif isinstance(payload, dict):
|
3616
|
+
payload = dict(payload)
|
3617
|
+
else:
|
3618
|
+
payload = {"file_ids": ",".join(map(str, payload))}
|
3619
|
+
if not payload.get("file_ids"):
|
3620
|
+
return {"state": False, "message": "no op"}
|
3621
|
+
payload = cast(dict, payload)
|
3622
|
+
payload.setdefault("to_cid", pid)
|
3623
|
+
return self.request(url=api, method="POST", data=payload, async_=async_, **request_kwargs)
|
3624
|
+
|
3625
|
+
@overload
|
3626
|
+
def fs_search(
|
3627
|
+
self,
|
3628
|
+
payload: str | dict = ".",
|
3629
|
+
/,
|
3630
|
+
base_url: bool | str | Callable[[], str] = False,
|
3631
|
+
*,
|
3632
|
+
async_: Literal[False] = False,
|
3633
|
+
**request_kwargs,
|
3634
|
+
) -> dict:
|
3635
|
+
...
|
3636
|
+
@overload
|
3637
|
+
def fs_search(
|
3638
|
+
self,
|
3639
|
+
payload: str | dict = ".",
|
3640
|
+
/,
|
3641
|
+
base_url: bool | str | Callable[[], str] = False,
|
3642
|
+
*,
|
3643
|
+
async_: Literal[True],
|
3644
|
+
**request_kwargs,
|
3645
|
+
) -> Coroutine[Any, Any, dict]:
|
3646
|
+
...
|
3647
|
+
def fs_search(
|
3648
|
+
self,
|
3649
|
+
payload: str | dict = ".",
|
3650
|
+
/,
|
3651
|
+
base_url: bool | str | Callable[[], str] = False,
|
3652
|
+
*,
|
3653
|
+
async_: Literal[False, True] = False,
|
3654
|
+
**request_kwargs,
|
3655
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
3656
|
+
"""搜索文件或目录
|
3657
|
+
|
3658
|
+
GET https://proapi.115.com/open/ufile/search
|
3659
|
+
|
3660
|
+
.. hint::
|
3661
|
+
相当于 `P115Client.fs_search_app2`
|
3662
|
+
|
3663
|
+
.. admonition:: Reference
|
3664
|
+
|
3665
|
+
https://www.yuque.com/115yun/open/ft2yelxzopusus38
|
3666
|
+
|
3667
|
+
:payload:
|
3668
|
+
- aid: int | str = 1 💡 area_id。1:正常文件 7:回收站文件 12:瞬间文件 120:彻底删除文件、简历附件
|
3669
|
+
- asc: 0 | 1 = <default> 💡 是否升序排列
|
3670
|
+
- cid: int | str = 0 💡 目录 id。cid=-1 时,表示不返回列表任何内容
|
3671
|
+
- count_folders: 0 | 1 = <default>
|
3672
|
+
- date: str = <default> 💡 筛选日期
|
3673
|
+
- fc: 0 | 1 = <default> 💡 只显示文件或目录。1:只显示目录 2:只显示文件
|
3674
|
+
- fc_mix: 0 | 1 = <default> 💡 是否目录和文件混合,如果为 0 则目录在前(目录置顶)
|
3675
|
+
- file_label: int | str = <default> 💡 标签 id
|
3676
|
+
- format: str = "json" 💡 输出格式(不用管)
|
3677
|
+
- gte_day: str 💡 搜索结果匹配的开始时间;格式:YYYY-MM-DD
|
3678
|
+
- limit: int = 32 💡 一页大小,意思就是 page_size
|
3679
|
+
- lte_day: str 💡 搜索结果匹配的结束时间;格式:YYYY-MM-DD
|
3680
|
+
- o: str = <default> 💡 用某字段排序
|
3681
|
+
|
3682
|
+
- "file_name": 文件名
|
3683
|
+
- "file_size": 文件大小
|
3684
|
+
- "file_type": 文件种类
|
3685
|
+
- "user_utime": 修改时间
|
3686
|
+
- "user_ptime": 创建时间
|
3687
|
+
- "user_otime": 上一次打开时间
|
3688
|
+
|
3689
|
+
- offset: int = 0 💡 索引偏移,索引从 0 开始计算
|
3690
|
+
- pick_code: str = <default> 💡 是否查询提取码,如果该值为 1 则查询提取码为 `search_value` 的文件
|
3691
|
+
- search_value: str = "." 💡 搜索文本,可以是 sha1
|
3692
|
+
- show_dir: 0 | 1 = 1
|
3693
|
+
- source: str = <default>
|
3694
|
+
- star: 0 | 1 = <default>
|
3695
|
+
- suffix: str = <default>
|
3696
|
+
- type: int = <default> 💡 文件类型
|
3697
|
+
|
3698
|
+
- 0: 全部(仅当前目录)
|
3699
|
+
- 1: 文档
|
3700
|
+
- 2: 图片
|
3701
|
+
- 3: 音频
|
3702
|
+
- 4: 视频
|
3703
|
+
- 5: 压缩包
|
3704
|
+
- 6: 软件/应用
|
3705
|
+
- 7: 书籍
|
3706
|
+
- 99: 仅文件
|
3707
|
+
|
3708
|
+
- version: str = <default> 💡 版本号,比如 3.1
|
3709
|
+
"""
|
3710
|
+
api = complete_proapi("/open/ufile/search", base_url)
|
3711
|
+
if isinstance(payload, str):
|
3712
|
+
payload = {
|
3713
|
+
"aid": 1, "cid": 0, "format": "json", "limit": 32, "offset": 0,
|
3714
|
+
"show_dir": 1, "search_value": payload,
|
3715
|
+
}
|
3716
|
+
else:
|
3717
|
+
payload = {
|
3718
|
+
"aid": 1, "cid": 0, "format": "json", "limit": 32, "offset": 0,
|
3719
|
+
"show_dir": 1, "search_value": ".", **payload,
|
3720
|
+
}
|
3721
|
+
return self.request(url=api, params=payload, async_=async_, **request_kwargs)
|
3722
|
+
|
3723
|
+
@overload
|
3724
|
+
def fs_star_set(
|
3725
|
+
self,
|
3726
|
+
payload: int | str | Iterable[int | str] | dict,
|
3727
|
+
/,
|
3728
|
+
star: bool = True,
|
3729
|
+
base_url: bool | str | Callable[[], str] = False,
|
3730
|
+
*,
|
3731
|
+
async_: Literal[False] = False,
|
3732
|
+
**request_kwargs,
|
3733
|
+
) -> dict:
|
3734
|
+
...
|
3735
|
+
@overload
|
3736
|
+
def fs_star_set(
|
3737
|
+
self,
|
3738
|
+
payload: int | str | Iterable[int | str] | dict,
|
3739
|
+
/,
|
3740
|
+
star: bool = True,
|
3741
|
+
base_url: bool | str | Callable[[], str] = False,
|
3742
|
+
*,
|
3743
|
+
async_: Literal[True],
|
3744
|
+
**request_kwargs,
|
3745
|
+
) -> Coroutine[Any, Any, dict]:
|
3746
|
+
...
|
3747
|
+
def fs_star_set(
|
3748
|
+
self,
|
3749
|
+
payload: int | str | Iterable[int | str] | dict,
|
3750
|
+
/,
|
3751
|
+
star: bool = True,
|
3752
|
+
base_url: bool | str | Callable[[], str] = False,
|
3753
|
+
*,
|
3754
|
+
async_: Literal[False, True] = False,
|
3755
|
+
**request_kwargs,
|
3756
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
3757
|
+
"""为文件或目录设置或取消星标,此接口是对 `fs_update_open` 的封装
|
3758
|
+
|
3759
|
+
.. note::
|
3760
|
+
即使其中任何一个 id 目前已经被删除,也可以操作成功
|
3761
|
+
|
3762
|
+
:payload:
|
3763
|
+
- file_id: int | str 💡 只能传入 1 个
|
3764
|
+
- file_id[0]: int | str 💡 如果有多个,则按顺序给出
|
3765
|
+
- file_id[1]: int | str
|
3766
|
+
- ...
|
3767
|
+
- star: 0 | 1 = 1
|
3768
|
+
"""
|
3769
|
+
api = complete_webapi("/files/star", base_url=base_url)
|
3770
|
+
if isinstance(payload, (int, str)):
|
3771
|
+
payload = {"file_id": payload, "star": int(star)}
|
3772
|
+
elif not isinstance(payload, dict):
|
3773
|
+
payload = {f"file_id[{i}]": id for i, id in enumerate(payload)}
|
3774
|
+
if not payload:
|
3775
|
+
return {"state": False, "message": "no op"}
|
3776
|
+
payload["star"] = int(star)
|
3777
|
+
else:
|
3778
|
+
payload = {"star": int(star), **payload}
|
3779
|
+
return self.fs_update(payload, async_=async_, **request_kwargs)
|
3780
|
+
|
3781
|
+
@overload
|
3782
|
+
def fs_video_history(
|
3783
|
+
self,
|
3784
|
+
payload: str | dict,
|
3785
|
+
/,
|
3786
|
+
base_url: bool | str | Callable[[], str] = False,
|
3787
|
+
*,
|
3788
|
+
async_: Literal[False] = False,
|
3789
|
+
**request_kwargs,
|
3790
|
+
) -> dict:
|
3791
|
+
...
|
3792
|
+
@overload
|
3793
|
+
def fs_video_history(
|
3794
|
+
self,
|
3795
|
+
payload: str | dict,
|
3796
|
+
/,
|
3797
|
+
base_url: bool | str | Callable[[], str] = False,
|
3798
|
+
*,
|
3799
|
+
async_: Literal[True],
|
3800
|
+
**request_kwargs,
|
3801
|
+
) -> Coroutine[Any, Any, dict]:
|
3802
|
+
...
|
3803
|
+
def fs_video_history(
|
3804
|
+
self,
|
3805
|
+
payload: str | dict,
|
3806
|
+
/,
|
3807
|
+
base_url: bool | str | Callable[[], str] = False,
|
3808
|
+
*,
|
3809
|
+
async_: Literal[False, True] = False,
|
3810
|
+
**request_kwargs,
|
3811
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
3812
|
+
"""获取视频播放进度
|
3813
|
+
|
3814
|
+
GET https://proapi.115.com/open/video/history
|
3815
|
+
|
3816
|
+
.. admonition:: Reference
|
3817
|
+
|
3818
|
+
https://www.yuque.com/115yun/open/gssqdrsq6vfqigag
|
3819
|
+
|
3820
|
+
:payload:
|
3821
|
+
- pick_code: str 💡 文件提取码
|
3822
|
+
"""
|
3823
|
+
api = complete_proapi("/open/video/history", base_url)
|
3824
|
+
if isinstance(payload, str):
|
3825
|
+
payload = {"pick_code": payload}
|
3826
|
+
return self.request(url=api, params=payload, async_=async_, **request_kwargs)
|
3827
|
+
|
3828
|
+
@overload
|
3829
|
+
def fs_video_history_set(
|
3830
|
+
self,
|
3831
|
+
payload: str | dict,
|
3832
|
+
/,
|
3833
|
+
base_url: bool | str | Callable[[], str] = False,
|
3834
|
+
*,
|
3835
|
+
async_: Literal[False] = False,
|
3836
|
+
**request_kwargs,
|
3837
|
+
) -> dict:
|
3838
|
+
...
|
3839
|
+
@overload
|
3840
|
+
def fs_video_history_set(
|
3841
|
+
self,
|
3842
|
+
payload: str | dict,
|
3843
|
+
/,
|
3844
|
+
base_url: bool | str | Callable[[], str] = False,
|
3845
|
+
*,
|
3846
|
+
async_: Literal[True],
|
3847
|
+
**request_kwargs,
|
3848
|
+
) -> Coroutine[Any, Any, dict]:
|
3849
|
+
...
|
3850
|
+
def fs_video_history_set(
|
3851
|
+
self,
|
3852
|
+
payload: str | dict,
|
3853
|
+
/,
|
3854
|
+
base_url: bool | str | Callable[[], str] = False,
|
3855
|
+
*,
|
3856
|
+
async_: Literal[False, True] = False,
|
3857
|
+
**request_kwargs,
|
3858
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
3859
|
+
"""记忆视频播放进度
|
3860
|
+
|
3861
|
+
POST https://proapi.115.com/open/video/history
|
3862
|
+
|
3863
|
+
.. admonition:: Reference
|
3864
|
+
|
3865
|
+
https://www.yuque.com/115yun/open/bshagbxv1gzqglg4
|
3866
|
+
|
3867
|
+
:payload:
|
3868
|
+
- pick_code: str 💡 文件提取码
|
3869
|
+
- time: int = <default> 💡 视频播放进度时长 (单位秒)
|
3870
|
+
- watch_end: int = <default> 💡 视频是否播放播放完毕 0:未完毕 1:完毕
|
3871
|
+
"""
|
3872
|
+
api = complete_proapi("/open/video/history", base_url)
|
3873
|
+
if isinstance(payload, str):
|
3874
|
+
payload = {"pick_code": payload}
|
3875
|
+
return self.request(url=api, method="POST", data=payload, async_=async_, **request_kwargs)
|
3876
|
+
|
3877
|
+
@overload
|
3878
|
+
def fs_video_play(
|
3879
|
+
self,
|
3880
|
+
payload: str | dict,
|
3881
|
+
/,
|
3882
|
+
base_url: bool | str | Callable[[], str] = False,
|
3883
|
+
*,
|
3884
|
+
async_: Literal[False] = False,
|
3885
|
+
**request_kwargs,
|
3886
|
+
) -> dict:
|
3887
|
+
...
|
3888
|
+
@overload
|
3889
|
+
def fs_video_play(
|
3890
|
+
self,
|
3891
|
+
payload: str | dict,
|
3892
|
+
/,
|
3893
|
+
base_url: bool | str | Callable[[], str] = False,
|
3894
|
+
*,
|
3895
|
+
async_: Literal[True],
|
3896
|
+
**request_kwargs,
|
3897
|
+
) -> Coroutine[Any, Any, dict]:
|
3898
|
+
...
|
3899
|
+
def fs_video_play(
|
3900
|
+
self,
|
3901
|
+
payload: str | dict,
|
3902
|
+
/,
|
3903
|
+
base_url: bool | str | Callable[[], str] = False,
|
3904
|
+
*,
|
3905
|
+
async_: Literal[False, True] = False,
|
3906
|
+
**request_kwargs,
|
3907
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
3908
|
+
"""获取视频在线播放地址(和视频文件相关数据)
|
3909
|
+
|
3910
|
+
GET https://proapi.115.com/open/video/play
|
3911
|
+
|
3912
|
+
.. admonition:: Reference
|
3913
|
+
|
3914
|
+
https://www.yuque.com/115yun/open/hqglxv3cedi3p9dz
|
3915
|
+
|
3916
|
+
.. hint::
|
3917
|
+
需切换音轨时,在请求返回的播放地址中增加请求参数 `&audio_track=${index}`,值就是接口响应中 `multitrack_list` 中某个成员的索引,从 0 开始计数
|
3918
|
+
|
3919
|
+
:payload:
|
3920
|
+
- pick_code: str 💡 文件提取码
|
3921
|
+
- share_id: int | str = <default> 💡 共享 id,获取共享文件播放地址所需
|
3922
|
+
"""
|
3923
|
+
api = complete_proapi("/open/video/play", base_url)
|
3924
|
+
if isinstance(payload, str):
|
3925
|
+
payload = {"pick_code": payload}
|
3926
|
+
return self.request(url=api, params=payload, async_=async_, **request_kwargs)
|
3927
|
+
|
3928
|
+
@overload
|
3929
|
+
def fs_video_push(
|
3930
|
+
self,
|
3931
|
+
payload: str | dict,
|
3932
|
+
/,
|
3933
|
+
base_url: bool | str | Callable[[], str] = False,
|
3934
|
+
*,
|
3935
|
+
async_: Literal[False] = False,
|
3936
|
+
**request_kwargs,
|
3937
|
+
) -> dict:
|
3938
|
+
...
|
3939
|
+
@overload
|
3940
|
+
def fs_video_push(
|
3941
|
+
self,
|
3942
|
+
payload: str | dict,
|
3943
|
+
/,
|
3944
|
+
base_url: bool | str | Callable[[], str] = False,
|
3945
|
+
*,
|
3946
|
+
async_: Literal[True],
|
3947
|
+
**request_kwargs,
|
3948
|
+
) -> Coroutine[Any, Any, dict]:
|
3949
|
+
...
|
3950
|
+
def fs_video_push(
|
3951
|
+
self,
|
3952
|
+
payload: str | dict,
|
3953
|
+
/,
|
3954
|
+
base_url: bool | str | Callable[[], str] = False,
|
3955
|
+
*,
|
3956
|
+
async_: Literal[False, True] = False,
|
3957
|
+
**request_kwargs,
|
3958
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
3959
|
+
"""提交视频转码
|
3960
|
+
|
3961
|
+
POST https://proapi.115.com/open/video/video_push
|
3962
|
+
|
3963
|
+
.. admonition:: Reference
|
3964
|
+
|
3965
|
+
https://www.yuque.com/115yun/open/nxt8r1qcktmg3oan
|
3966
|
+
|
3967
|
+
:payload:
|
3968
|
+
- pick_code: str 💡 文件提取码
|
3969
|
+
- op: str = "vip_push" 💡 提交视频加速转码方式:vip_push:根据;vip 等级加速 pay_push:枫叶加速
|
3970
|
+
"""
|
3971
|
+
api = complete_proapi("/open/video/video_push", base_url)
|
3972
|
+
if isinstance(payload, str):
|
3973
|
+
payload = {"pick_code": payload, "op": "vip_push"}
|
3974
|
+
else:
|
3975
|
+
payload.setdefault("op", "vip_push")
|
3976
|
+
return self.request(url=api, method="POST", data=payload, async_=async_, **request_kwargs)
|
3977
|
+
|
3978
|
+
@overload
|
3979
|
+
def fs_video_subtitle(
|
3980
|
+
self,
|
3981
|
+
payload: str | dict,
|
3982
|
+
/,
|
3983
|
+
base_url: bool | str | Callable[[], str] = False,
|
3984
|
+
*,
|
3985
|
+
async_: Literal[False] = False,
|
3986
|
+
**request_kwargs,
|
3987
|
+
) -> dict:
|
3988
|
+
...
|
3989
|
+
@overload
|
3990
|
+
def fs_video_subtitle(
|
3991
|
+
self,
|
3992
|
+
payload: str | dict,
|
3993
|
+
/,
|
3994
|
+
base_url: bool | str | Callable[[], str] = False,
|
3995
|
+
*,
|
3996
|
+
async_: Literal[True],
|
3997
|
+
**request_kwargs,
|
3998
|
+
) -> Coroutine[Any, Any, dict]:
|
3999
|
+
...
|
4000
|
+
def fs_video_subtitle(
|
4001
|
+
self,
|
4002
|
+
payload: str | dict,
|
4003
|
+
/,
|
4004
|
+
base_url: bool | str | Callable[[], str] = False,
|
4005
|
+
*,
|
4006
|
+
async_: Literal[False, True] = False,
|
4007
|
+
**request_kwargs,
|
4008
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
4009
|
+
"""视频字幕列表
|
4010
|
+
|
4011
|
+
GET https://proapi.115.com/open/video/subtitle
|
4012
|
+
|
4013
|
+
.. admonition:: Reference
|
4014
|
+
|
4015
|
+
https://www.yuque.com/115yun/open/nx076h3glapoyh7u
|
4016
|
+
|
4017
|
+
:payload:
|
4018
|
+
- pick_code: str 💡 文件提取码
|
4019
|
+
"""
|
4020
|
+
api = complete_proapi("/open/video/subtitle", base_url)
|
4021
|
+
if isinstance(payload, str):
|
4022
|
+
payload = {"pick_code": payload}
|
4023
|
+
return self.request(url=api, params=payload, async_=async_, **request_kwargs)
|
4024
|
+
|
4025
|
+
@overload
|
4026
|
+
def fs_update(
|
4027
|
+
self,
|
4028
|
+
payload: dict,
|
4029
|
+
/,
|
4030
|
+
base_url: bool | str | Callable[[], str] = False,
|
4031
|
+
*,
|
4032
|
+
async_: Literal[False] = False,
|
4033
|
+
**request_kwargs,
|
4034
|
+
) -> dict:
|
4035
|
+
...
|
4036
|
+
@overload
|
4037
|
+
def fs_update(
|
4038
|
+
self,
|
4039
|
+
payload: dict,
|
4040
|
+
/,
|
4041
|
+
base_url: bool | str | Callable[[], str] = False,
|
4042
|
+
*,
|
4043
|
+
async_: Literal[True],
|
4044
|
+
**request_kwargs,
|
4045
|
+
) -> Coroutine[Any, Any, dict]:
|
4046
|
+
...
|
4047
|
+
def fs_update(
|
4048
|
+
self,
|
4049
|
+
payload: dict,
|
4050
|
+
/,
|
4051
|
+
base_url: bool | str | Callable[[], str] = False,
|
4052
|
+
*,
|
4053
|
+
async_: Literal[False, True] = False,
|
4054
|
+
**request_kwargs,
|
4055
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
4056
|
+
"""设置文件或目录(备注、标签等)
|
4057
|
+
|
4058
|
+
POST https://proapi.115.com/open/ufile/update
|
4059
|
+
|
4060
|
+
.. hint::
|
4061
|
+
即使文件已经被删除,也可以操作成功
|
4062
|
+
|
4063
|
+
.. admonition:: Reference
|
4064
|
+
|
4065
|
+
https://www.yuque.com/115yun/open/gyrpw5a0zc4sengm
|
4066
|
+
|
4067
|
+
:payload:
|
4068
|
+
- file_id: int | str 💡 只能传入 1 个
|
4069
|
+
- file_id[0]: int | str 💡 如果有多个,则按顺序给出
|
4070
|
+
- file_id[1]: int | str
|
4071
|
+
- ...
|
4072
|
+
- file_name: str = <default> 💡 文件名
|
4073
|
+
- star: 0 | 1 = <default> 💡 是否星标:0:取消星标 1:设置星标
|
4074
|
+
- ...
|
4075
|
+
"""
|
4076
|
+
api = complete_proapi("/open/ufile/update", base_url)
|
4077
|
+
return self.request(url=api, method="POST", data=payload, async_=async_, **request_kwargs)
|
4078
|
+
|
4079
|
+
@overload
|
4080
|
+
def offline_add_torrent(
|
4081
|
+
self,
|
4082
|
+
payload: dict,
|
4083
|
+
/,
|
4084
|
+
base_url: bool | str | Callable[[], str] = False,
|
4085
|
+
*,
|
4086
|
+
async_: Literal[False] = False,
|
4087
|
+
**request_kwargs,
|
4088
|
+
) -> dict:
|
4089
|
+
...
|
4090
|
+
@overload
|
4091
|
+
def offline_add_torrent(
|
4092
|
+
self,
|
4093
|
+
payload: dict,
|
4094
|
+
/,
|
4095
|
+
base_url: bool | str | Callable[[], str] = False,
|
4096
|
+
*,
|
4097
|
+
async_: Literal[True],
|
4098
|
+
**request_kwargs,
|
4099
|
+
) -> Coroutine[Any, Any, dict]:
|
4100
|
+
...
|
4101
|
+
def offline_add_torrent(
|
4102
|
+
self,
|
4103
|
+
payload: dict,
|
4104
|
+
/,
|
4105
|
+
base_url: bool | str | Callable[[], str] = False,
|
4106
|
+
*,
|
4107
|
+
async_: Literal[False, True] = False,
|
4108
|
+
**request_kwargs,
|
4109
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
4110
|
+
"""添加云下载 BT 任务
|
4111
|
+
|
4112
|
+
POST https://proapi.115.com/open/offline/add_task_bt
|
4113
|
+
|
4114
|
+
.. admonition:: Reference
|
4115
|
+
|
4116
|
+
https://www.yuque.com/115yun/open/svfe4unlhayvluly
|
4117
|
+
|
4118
|
+
:payload:
|
4119
|
+
- info_hash: str 💡 种子文件的 info_hash
|
4120
|
+
- pick_code: str 💡 种子文件的提取码
|
4121
|
+
- save_path: str 💡 保存到 `wp_path_id` 对应目录下的相对路径
|
4122
|
+
- torrent_sha1: str 💡 种子文件的 sha1
|
4123
|
+
- wanted: str 💡 选择文件进行下载(是数字索引,从 0 开始计数,用 "," 分隔)
|
4124
|
+
- wp_path_id: int | str = <default> 💡 保存目标文件夹 id
|
4125
|
+
"""
|
4126
|
+
api = complete_proapi("/open/offline/add_task_bt ", base_url)
|
4127
|
+
return self.request(url=api, method="POST", data=payload, async_=async_, **request_kwargs)
|
4128
|
+
|
4129
|
+
@overload
|
4130
|
+
def offline_add_urls(
|
3342
4131
|
self,
|
3343
|
-
payload:
|
4132
|
+
payload: str | Iterable[str] | dict,
|
3344
4133
|
/,
|
3345
4134
|
base_url: bool | str | Callable[[], str] = False,
|
3346
4135
|
*,
|
@@ -3349,9 +4138,9 @@ class P115OpenClient(ClientRequestMixin):
|
|
3349
4138
|
) -> dict:
|
3350
4139
|
...
|
3351
4140
|
@overload
|
3352
|
-
def
|
4141
|
+
def offline_add_urls(
|
3353
4142
|
self,
|
3354
|
-
payload:
|
4143
|
+
payload: str | Iterable[str] | dict,
|
3355
4144
|
/,
|
3356
4145
|
base_url: bool | str | Callable[[], str] = False,
|
3357
4146
|
*,
|
@@ -3359,40 +4148,39 @@ class P115OpenClient(ClientRequestMixin):
|
|
3359
4148
|
**request_kwargs,
|
3360
4149
|
) -> Coroutine[Any, Any, dict]:
|
3361
4150
|
...
|
3362
|
-
def
|
4151
|
+
def offline_add_urls(
|
3363
4152
|
self,
|
3364
|
-
payload:
|
4153
|
+
payload: str | Iterable[str] | dict,
|
3365
4154
|
/,
|
3366
4155
|
base_url: bool | str | Callable[[], str] = False,
|
3367
4156
|
*,
|
3368
4157
|
async_: Literal[False, True] = False,
|
3369
4158
|
**request_kwargs,
|
3370
4159
|
) -> dict | Coroutine[Any, Any, dict]:
|
3371
|
-
"""
|
4160
|
+
"""添加云下载链接任务
|
3372
4161
|
|
3373
|
-
|
3374
|
-
|
3375
|
-
.. hint::
|
3376
|
-
相当于 `P115Client.fs_category_get_app`
|
4162
|
+
POST https://proapi.115.com/open/offline/add_task_urls
|
3377
4163
|
|
3378
4164
|
.. admonition:: Reference
|
3379
4165
|
|
3380
|
-
https://www.yuque.com/115yun/open/
|
4166
|
+
https://www.yuque.com/115yun/open/zkyfq2499gdn3mty
|
3381
4167
|
|
3382
4168
|
:payload:
|
3383
|
-
-
|
4169
|
+
- urls: str 💡 链接,用 "\\n" 分隔,支持HTTP、HTTPS、FTP、磁力链和电驴链接
|
4170
|
+
- wp_path_id: int | str = <default> 💡 保存到目录的 id
|
3384
4171
|
"""
|
3385
|
-
api = complete_proapi("/open/
|
3386
|
-
if isinstance(payload,
|
3387
|
-
payload = {"
|
3388
|
-
|
4172
|
+
api = complete_proapi("/open/offline/add_task_urls", base_url)
|
4173
|
+
if isinstance(payload, str):
|
4174
|
+
payload = {"urls": payload.strip("\n")}
|
4175
|
+
elif not isinstance(payload, dict):
|
4176
|
+
payload = {"urls": ",".join(payload)}
|
4177
|
+
return self.request(url=api, method="POST", data=payload, async_=async_, **request_kwargs)
|
3389
4178
|
|
3390
4179
|
@overload
|
3391
|
-
def
|
4180
|
+
def offline_clear(
|
3392
4181
|
self,
|
3393
|
-
payload:
|
4182
|
+
payload: int | dict = 0,
|
3394
4183
|
/,
|
3395
|
-
pid: int = 0,
|
3396
4184
|
base_url: bool | str | Callable[[], str] = False,
|
3397
4185
|
*,
|
3398
4186
|
async_: Literal[False] = False,
|
@@ -3400,52 +4188,53 @@ class P115OpenClient(ClientRequestMixin):
|
|
3400
4188
|
) -> dict:
|
3401
4189
|
...
|
3402
4190
|
@overload
|
3403
|
-
def
|
4191
|
+
def offline_clear(
|
3404
4192
|
self,
|
3405
|
-
payload:
|
4193
|
+
payload: int | dict = 0,
|
3406
4194
|
/,
|
3407
|
-
pid: int = 0,
|
3408
4195
|
base_url: bool | str | Callable[[], str] = False,
|
3409
4196
|
*,
|
3410
4197
|
async_: Literal[True],
|
3411
4198
|
**request_kwargs,
|
3412
4199
|
) -> Coroutine[Any, Any, dict]:
|
3413
4200
|
...
|
3414
|
-
def
|
4201
|
+
def offline_clear(
|
3415
4202
|
self,
|
3416
|
-
payload:
|
4203
|
+
payload: int | dict = 0,
|
3417
4204
|
/,
|
3418
|
-
pid: int = 0,
|
3419
4205
|
base_url: bool | str | Callable[[], str] = False,
|
3420
4206
|
*,
|
3421
4207
|
async_: Literal[False, True] = False,
|
3422
4208
|
**request_kwargs,
|
3423
4209
|
) -> dict | Coroutine[Any, Any, dict]:
|
3424
|
-
"""
|
4210
|
+
"""清空云下载任务
|
3425
4211
|
|
3426
|
-
POST https://proapi.115.com/open/
|
4212
|
+
POST https://proapi.115.com/open/offline/clear_task
|
3427
4213
|
|
3428
4214
|
.. admonition:: Reference
|
3429
4215
|
|
3430
|
-
https://www.yuque.com/115yun/open/
|
4216
|
+
https://www.yuque.com/115yun/open/uu5i4urb5ylqwfy4
|
3431
4217
|
|
3432
4218
|
:payload:
|
3433
|
-
-
|
3434
|
-
|
4219
|
+
- flag: int = 0 💡 标识,用于对应某种情况
|
4220
|
+
|
4221
|
+
- 0: 已完成
|
4222
|
+
- 1: 全部
|
4223
|
+
- 2: 已失败
|
4224
|
+
- 3: 进行中
|
4225
|
+
- 4: 已完成+删除源文件
|
4226
|
+
- 5: 全部+删除源文件
|
3435
4227
|
"""
|
3436
|
-
api = complete_proapi("/open/
|
3437
|
-
if isinstance(payload,
|
3438
|
-
payload = {"
|
3439
|
-
else:
|
3440
|
-
payload = {"pid": pid, **payload}
|
4228
|
+
api = complete_proapi("/open/offline/clear_task", base_url)
|
4229
|
+
if isinstance(payload, int):
|
4230
|
+
payload = {"flag": payload}
|
3441
4231
|
return self.request(url=api, method="POST", data=payload, async_=async_, **request_kwargs)
|
3442
4232
|
|
3443
4233
|
@overload
|
3444
|
-
def
|
4234
|
+
def offline_list(
|
3445
4235
|
self,
|
3446
|
-
payload: int |
|
4236
|
+
payload: int | dict = 1,
|
3447
4237
|
/,
|
3448
|
-
pid: int = 0,
|
3449
4238
|
base_url: bool | str | Callable[[], str] = False,
|
3450
4239
|
*,
|
3451
4240
|
async_: Literal[False] = False,
|
@@ -3453,56 +4242,44 @@ class P115OpenClient(ClientRequestMixin):
|
|
3453
4242
|
) -> dict:
|
3454
4243
|
...
|
3455
4244
|
@overload
|
3456
|
-
def
|
4245
|
+
def offline_list(
|
3457
4246
|
self,
|
3458
|
-
payload: int |
|
4247
|
+
payload: int | dict = 1,
|
3459
4248
|
/,
|
3460
|
-
pid: int = 0,
|
3461
4249
|
base_url: bool | str | Callable[[], str] = False,
|
3462
4250
|
*,
|
3463
4251
|
async_: Literal[True],
|
3464
4252
|
**request_kwargs,
|
3465
4253
|
) -> Coroutine[Any, Any, dict]:
|
3466
4254
|
...
|
3467
|
-
def
|
4255
|
+
def offline_list(
|
3468
4256
|
self,
|
3469
|
-
payload: int |
|
4257
|
+
payload: int | dict = 1,
|
3470
4258
|
/,
|
3471
|
-
pid: int = 0,
|
3472
4259
|
base_url: bool | str | Callable[[], str] = False,
|
3473
4260
|
*,
|
3474
4261
|
async_: Literal[False, True] = False,
|
3475
4262
|
**request_kwargs,
|
3476
4263
|
) -> dict | Coroutine[Any, Any, dict]:
|
3477
|
-
"""
|
4264
|
+
"""获取用户云下载任务列表
|
3478
4265
|
|
3479
|
-
|
4266
|
+
GET https://proapi.115.com/open/offline/get_task_list
|
3480
4267
|
|
3481
4268
|
.. admonition:: Reference
|
3482
4269
|
|
3483
|
-
https://www.yuque.com/115yun/open/
|
4270
|
+
https://www.yuque.com/115yun/open/av2mluz7uwigz74k
|
3484
4271
|
|
3485
4272
|
:payload:
|
3486
|
-
-
|
3487
|
-
- to_cid: int | str = 0 💡 父目录 id
|
4273
|
+
- page: int | str = 1
|
3488
4274
|
"""
|
3489
|
-
api = complete_proapi("/open/
|
3490
|
-
if isinstance(payload,
|
3491
|
-
payload = {"
|
3492
|
-
|
3493
|
-
payload = dict(payload)
|
3494
|
-
else:
|
3495
|
-
payload = {"file_ids": ",".join(map(str, payload))}
|
3496
|
-
if not payload.get("file_ids"):
|
3497
|
-
return {"state": False, "message": "no op"}
|
3498
|
-
payload = cast(dict, payload)
|
3499
|
-
payload.setdefault("to_cid", pid)
|
3500
|
-
return self.request(url=api, method="POST", data=payload, async_=async_, **request_kwargs)
|
4275
|
+
api = complete_proapi("/open/offline/get_task_list", base_url)
|
4276
|
+
if isinstance(payload, int):
|
4277
|
+
payload = {"page": payload}
|
4278
|
+
return self.request(url=api, params=payload, async_=async_, **request_kwargs)
|
3501
4279
|
|
3502
4280
|
@overload
|
3503
|
-
def
|
4281
|
+
def offline_quota_info(
|
3504
4282
|
self,
|
3505
|
-
payload: str | dict = ".",
|
3506
4283
|
/,
|
3507
4284
|
base_url: bool | str | Callable[[], str] = False,
|
3508
4285
|
*,
|
@@ -3511,9 +4288,8 @@ class P115OpenClient(ClientRequestMixin):
|
|
3511
4288
|
) -> dict:
|
3512
4289
|
...
|
3513
4290
|
@overload
|
3514
|
-
def
|
4291
|
+
def offline_quota_info(
|
3515
4292
|
self,
|
3516
|
-
payload: str | dict = ".",
|
3517
4293
|
/,
|
3518
4294
|
base_url: bool | str | Callable[[], str] = False,
|
3519
4295
|
*,
|
@@ -3521,88 +4297,30 @@ class P115OpenClient(ClientRequestMixin):
|
|
3521
4297
|
**request_kwargs,
|
3522
4298
|
) -> Coroutine[Any, Any, dict]:
|
3523
4299
|
...
|
3524
|
-
def
|
4300
|
+
def offline_quota_info(
|
3525
4301
|
self,
|
3526
|
-
payload: str | dict = ".",
|
3527
4302
|
/,
|
3528
4303
|
base_url: bool | str | Callable[[], str] = False,
|
3529
4304
|
*,
|
3530
4305
|
async_: Literal[False, True] = False,
|
3531
4306
|
**request_kwargs,
|
3532
4307
|
) -> dict | Coroutine[Any, Any, dict]:
|
3533
|
-
"""
|
3534
|
-
|
3535
|
-
GET https://proapi.115.com/open/ufile/search
|
4308
|
+
"""获取云下载配额信息
|
3536
4309
|
|
3537
|
-
|
3538
|
-
相当于 `P115Client.fs_search_app2`
|
4310
|
+
GET https://proapi.115.com/open/offline/get_quota_info
|
3539
4311
|
|
3540
4312
|
.. admonition:: Reference
|
3541
4313
|
|
3542
|
-
https://www.yuque.com/115yun/open/
|
3543
|
-
|
3544
|
-
:payload:
|
3545
|
-
- aid: int | str = 1 💡 area_id。1:正常文件 7:回收站文件 12:瞬间文件 120:彻底删除文件、简历附件
|
3546
|
-
- asc: 0 | 1 = <default> 💡 是否升序排列
|
3547
|
-
- cid: int | str = 0 💡 目录 id。cid=-1 时,表示不返回列表任何内容
|
3548
|
-
- count_folders: 0 | 1 = <default>
|
3549
|
-
- date: str = <default> 💡 筛选日期
|
3550
|
-
- fc: 0 | 1 = <default> 💡 只显示文件或目录。1:只显示目录 2:只显示文件
|
3551
|
-
- fc_mix: 0 | 1 = <default> 💡 是否目录和文件混合,如果为 0 则目录在前(目录置顶)
|
3552
|
-
- file_label: int | str = <default> 💡 标签 id
|
3553
|
-
- format: str = "json" 💡 输出格式(不用管)
|
3554
|
-
- gte_day: str 💡 搜索结果匹配的开始时间;格式:YYYY-MM-DD
|
3555
|
-
- limit: int = 32 💡 一页大小,意思就是 page_size
|
3556
|
-
- lte_day: str 💡 搜索结果匹配的结束时间;格式:YYYY-MM-DD
|
3557
|
-
- o: str = <default> 💡 用某字段排序
|
3558
|
-
|
3559
|
-
- "file_name": 文件名
|
3560
|
-
- "file_size": 文件大小
|
3561
|
-
- "file_type": 文件种类
|
3562
|
-
- "user_utime": 修改时间
|
3563
|
-
- "user_ptime": 创建时间
|
3564
|
-
- "user_otime": 上一次打开时间
|
3565
|
-
|
3566
|
-
- offset: int = 0 💡 索引偏移,索引从 0 开始计算
|
3567
|
-
- pick_code: str = <default> 💡 是否查询提取码,如果该值为 1 则查询提取码为 `search_value` 的文件
|
3568
|
-
- search_value: str = "." 💡 搜索文本,可以是 sha1
|
3569
|
-
- show_dir: 0 | 1 = 1
|
3570
|
-
- source: str = <default>
|
3571
|
-
- star: 0 | 1 = <default>
|
3572
|
-
- suffix: str = <default>
|
3573
|
-
- type: int = <default> 💡 文件类型
|
3574
|
-
|
3575
|
-
- 0: 全部(仅当前目录)
|
3576
|
-
- 1: 文档
|
3577
|
-
- 2: 图片
|
3578
|
-
- 3: 音频
|
3579
|
-
- 4: 视频
|
3580
|
-
- 5: 压缩包
|
3581
|
-
- 6: 软件/应用
|
3582
|
-
- 7: 书籍
|
3583
|
-
- 99: 仅文件
|
3584
|
-
|
3585
|
-
- version: str = <default> 💡 版本号,比如 3.1
|
4314
|
+
https://www.yuque.com/115yun/open/gif2n3smh54kyg0p
|
3586
4315
|
"""
|
3587
|
-
api = complete_proapi("/open/
|
3588
|
-
|
3589
|
-
payload = {
|
3590
|
-
"aid": 1, "cid": 0, "format": "json", "limit": 32, "offset": 0,
|
3591
|
-
"show_dir": 1, "search_value": payload,
|
3592
|
-
}
|
3593
|
-
else:
|
3594
|
-
payload = {
|
3595
|
-
"aid": 1, "cid": 0, "format": "json", "limit": 32, "offset": 0,
|
3596
|
-
"show_dir": 1, "search_value": ".", **payload,
|
3597
|
-
}
|
3598
|
-
return self.request(url=api, params=payload, async_=async_, **request_kwargs)
|
4316
|
+
api = complete_proapi("/open/offline/get_quota_info", base_url)
|
4317
|
+
return self.request(url=api, async_=async_, **request_kwargs)
|
3599
4318
|
|
3600
4319
|
@overload
|
3601
|
-
def
|
4320
|
+
def offline_remove(
|
3602
4321
|
self,
|
3603
|
-
payload:
|
4322
|
+
payload: str | dict,
|
3604
4323
|
/,
|
3605
|
-
star: bool = True,
|
3606
4324
|
base_url: bool | str | Callable[[], str] = False,
|
3607
4325
|
*,
|
3608
4326
|
async_: Literal[False] = False,
|
@@ -3610,53 +4328,44 @@ class P115OpenClient(ClientRequestMixin):
|
|
3610
4328
|
) -> dict:
|
3611
4329
|
...
|
3612
4330
|
@overload
|
3613
|
-
def
|
4331
|
+
def offline_remove(
|
3614
4332
|
self,
|
3615
|
-
payload:
|
4333
|
+
payload: str | dict,
|
3616
4334
|
/,
|
3617
|
-
star: bool = True,
|
3618
4335
|
base_url: bool | str | Callable[[], str] = False,
|
3619
4336
|
*,
|
3620
4337
|
async_: Literal[True],
|
3621
4338
|
**request_kwargs,
|
3622
4339
|
) -> Coroutine[Any, Any, dict]:
|
3623
4340
|
...
|
3624
|
-
def
|
4341
|
+
def offline_remove(
|
3625
4342
|
self,
|
3626
|
-
payload:
|
4343
|
+
payload: str | dict,
|
3627
4344
|
/,
|
3628
|
-
star: bool = True,
|
3629
4345
|
base_url: bool | str | Callable[[], str] = False,
|
3630
4346
|
*,
|
3631
4347
|
async_: Literal[False, True] = False,
|
3632
4348
|
**request_kwargs,
|
3633
4349
|
) -> dict | Coroutine[Any, Any, dict]:
|
3634
|
-
"""
|
4350
|
+
"""删除用户云下载任务
|
3635
4351
|
|
3636
|
-
|
3637
|
-
|
4352
|
+
POST https://proapi.115.com/open/offline/del_task
|
4353
|
+
|
4354
|
+
.. admonition:: Reference
|
4355
|
+
|
4356
|
+
https://www.yuque.com/115yun/open/pmgwc86lpcy238nw
|
3638
4357
|
|
3639
4358
|
:payload:
|
3640
|
-
-
|
3641
|
-
-
|
3642
|
-
- file_id[1]: int | str
|
3643
|
-
- ...
|
3644
|
-
- star: 0 | 1 = 1
|
4359
|
+
- info_hash: str 💡 待删除任务的 info_hash
|
4360
|
+
- del_source_file: 0 | 1 = <default> 💡 是否删除源文件 1:删除 0:不删除
|
3645
4361
|
"""
|
3646
|
-
api =
|
3647
|
-
if isinstance(payload,
|
3648
|
-
payload = {"
|
3649
|
-
|
3650
|
-
payload = {f"file_id[{i}]": id for i, id in enumerate(payload)}
|
3651
|
-
if not payload:
|
3652
|
-
return {"state": False, "message": "no op"}
|
3653
|
-
payload["star"] = int(star)
|
3654
|
-
else:
|
3655
|
-
payload = {"star": int(star), **payload}
|
3656
|
-
return self.fs_update(payload, async_=async_, **request_kwargs)
|
4362
|
+
api = complete_proapi("/open/offline/del_task", base_url)
|
4363
|
+
if isinstance(payload, str):
|
4364
|
+
payload = {"info_hash": payload}
|
4365
|
+
return self.request(api, method="POST", data=payload, async_=async_, **request_kwargs)
|
3657
4366
|
|
3658
4367
|
@overload
|
3659
|
-
def
|
4368
|
+
def offline_torrent_info(
|
3660
4369
|
self,
|
3661
4370
|
payload: dict,
|
3662
4371
|
/,
|
@@ -3667,7 +4376,7 @@ class P115OpenClient(ClientRequestMixin):
|
|
3667
4376
|
) -> dict:
|
3668
4377
|
...
|
3669
4378
|
@overload
|
3670
|
-
def
|
4379
|
+
def offline_torrent_info(
|
3671
4380
|
self,
|
3672
4381
|
payload: dict,
|
3673
4382
|
/,
|
@@ -3677,7 +4386,7 @@ class P115OpenClient(ClientRequestMixin):
|
|
3677
4386
|
**request_kwargs,
|
3678
4387
|
) -> Coroutine[Any, Any, dict]:
|
3679
4388
|
...
|
3680
|
-
def
|
4389
|
+
def offline_torrent_info(
|
3681
4390
|
self,
|
3682
4391
|
payload: dict,
|
3683
4392
|
/,
|
@@ -3686,27 +4395,19 @@ class P115OpenClient(ClientRequestMixin):
|
|
3686
4395
|
async_: Literal[False, True] = False,
|
3687
4396
|
**request_kwargs,
|
3688
4397
|
) -> dict | Coroutine[Any, Any, dict]:
|
3689
|
-
"""
|
3690
|
-
|
3691
|
-
POST https://proapi.115.com/open/ufile/update
|
4398
|
+
"""解析 BT 种子
|
3692
4399
|
|
3693
|
-
|
3694
|
-
即使文件已经被删除,也可以操作成功
|
4400
|
+
POST https://proapi.115.com/open/offline/torrent
|
3695
4401
|
|
3696
4402
|
.. admonition:: Reference
|
3697
4403
|
|
3698
|
-
https://www.yuque.com/115yun/open/
|
4404
|
+
https://www.yuque.com/115yun/open/evez3u50cemoict1
|
3699
4405
|
|
3700
4406
|
:payload:
|
3701
|
-
-
|
3702
|
-
-
|
3703
|
-
- file_id[1]: int | str
|
3704
|
-
- ...
|
3705
|
-
- file_name: str = <default> 💡 文件名
|
3706
|
-
- star: 0 | 1 = <default> 💡 是否星标:0:取消星标 1:设置星标
|
3707
|
-
- ...
|
4407
|
+
- torrent_sha1: str 💡 种子文件的 sha1
|
4408
|
+
- pick_code: str 💡 种子文件的提取码
|
3708
4409
|
"""
|
3709
|
-
api = complete_proapi("/open/
|
4410
|
+
api = complete_proapi("/open/offline/torrent", base_url)
|
3710
4411
|
return self.request(url=api, method="POST", data=payload, async_=async_, **request_kwargs)
|
3711
4412
|
|
3712
4413
|
@overload
|
@@ -3744,7 +4445,8 @@ class P115OpenClient(ClientRequestMixin):
|
|
3744
4445
|
|
3745
4446
|
POST https://proapi.115.com/open/rb/del
|
3746
4447
|
|
3747
|
-
..
|
4448
|
+
.. admonition:: Reference
|
4449
|
+
|
3748
4450
|
https://www.yuque.com/115yun/open/gwtof85nmboulrce
|
3749
4451
|
|
3750
4452
|
:payload:
|
@@ -4102,7 +4804,7 @@ class P115OpenClient(ClientRequestMixin):
|
|
4102
4804
|
check_response(resp)
|
4103
4805
|
resp["data"] = {**payload, **resp["data"], "sha1": filesha1, "cid": pid}
|
4104
4806
|
return resp
|
4105
|
-
return run_gen_step(gen_step, async_=async_)
|
4807
|
+
return run_gen_step(gen_step, simple=True, async_=async_)
|
4106
4808
|
|
4107
4809
|
@overload
|
4108
4810
|
def upload_file(
|
@@ -4446,7 +5148,7 @@ class P115OpenClient(ClientRequestMixin):
|
|
4446
5148
|
async_=async_, # type: ignore
|
4447
5149
|
**request_kwargs,
|
4448
5150
|
)
|
4449
|
-
return run_gen_step(gen_step, async_=async_)
|
5151
|
+
return run_gen_step(gen_step, simple=True, async_=async_)
|
4450
5152
|
|
4451
5153
|
@overload
|
4452
5154
|
def user_info(
|
@@ -4497,7 +5199,19 @@ class P115OpenClient(ClientRequestMixin):
|
|
4497
5199
|
fs_move_open = fs_move
|
4498
5200
|
fs_search_open = fs_search
|
4499
5201
|
fs_star_set_open = fs_star_set
|
5202
|
+
fs_video_history_open = fs_video_history
|
5203
|
+
fs_video_history_set_open = fs_video_history_set
|
5204
|
+
fs_video_play_open = fs_video_play
|
5205
|
+
fs_video_push_open = fs_video_push
|
5206
|
+
fs_video_subtitle_open = fs_video_subtitle
|
4500
5207
|
fs_update_open = fs_update
|
5208
|
+
offline_add_torrent_open = offline_add_torrent
|
5209
|
+
offline_add_urls_open = offline_add_urls
|
5210
|
+
offline_clear_open = offline_clear
|
5211
|
+
offline_list_open = offline_list
|
5212
|
+
offline_quota_info_open = offline_quota_info
|
5213
|
+
offline_remove_open = offline_remove
|
5214
|
+
offline_torrent_info_open = offline_torrent_info
|
4501
5215
|
recyclebin_clean_open = recyclebin_clean
|
4502
5216
|
recyclebin_list_open = recyclebin_list
|
4503
5217
|
recyclebin_revert_open = recyclebin_revert
|
@@ -4815,7 +5529,7 @@ class P115Client(P115OpenClient):
|
|
4815
5529
|
)
|
4816
5530
|
setattr(self, "check_for_relogin", check_for_relogin)
|
4817
5531
|
return self
|
4818
|
-
return run_gen_step(gen_step, async_=async_)
|
5532
|
+
return run_gen_step(gen_step, simple=True, async_=async_)
|
4819
5533
|
|
4820
5534
|
@locked_cacheproperty
|
4821
5535
|
def request_lock(self, /) -> Lock:
|
@@ -4987,7 +5701,7 @@ class P115Client(P115OpenClient):
|
|
4987
5701
|
check_response(resp)
|
4988
5702
|
setattr(self, "cookies", resp["data"]["cookie"])
|
4989
5703
|
return self
|
4990
|
-
return run_gen_step(gen_step, async_=async_)
|
5704
|
+
return run_gen_step(gen_step, simple=True, async_=async_)
|
4991
5705
|
|
4992
5706
|
@overload
|
4993
5707
|
def login_with_app(
|
@@ -5119,7 +5833,7 @@ class P115Client(P115OpenClient):
|
|
5119
5833
|
async_=async_,
|
5120
5834
|
**request_kwargs,
|
5121
5835
|
)
|
5122
|
-
return run_gen_step(gen_step, async_=async_)
|
5836
|
+
return run_gen_step(gen_step, simple=True, async_=async_)
|
5123
5837
|
|
5124
5838
|
@overload
|
5125
5839
|
def login_without_app(
|
@@ -5177,7 +5891,7 @@ class P115Client(P115OpenClient):
|
|
5177
5891
|
)
|
5178
5892
|
check_response(resp)
|
5179
5893
|
return uid
|
5180
|
-
return run_gen_step(gen_step, async_=async_)
|
5894
|
+
return run_gen_step(gen_step, simple=True, async_=async_)
|
5181
5895
|
|
5182
5896
|
@overload
|
5183
5897
|
def login_with_open(
|
@@ -5229,7 +5943,7 @@ class P115Client(P115OpenClient):
|
|
5229
5943
|
resp = yield self.login_qrcode_scan_confirm(login_uid, async_=async_, **request_kwargs)
|
5230
5944
|
check_response(resp)
|
5231
5945
|
return self.login_qrcode_access_token_open(login_uid, async_=async_, **request_kwargs)
|
5232
|
-
return run_gen_step(gen_step, async_=async_)
|
5946
|
+
return run_gen_step(gen_step, simple=True, async_=async_)
|
5233
5947
|
|
5234
5948
|
@overload
|
5235
5949
|
def login_another_app(
|
@@ -5373,7 +6087,7 @@ class P115Client(P115OpenClient):
|
|
5373
6087
|
if self is not inst and ssoent == inst.login_ssoent:
|
5374
6088
|
warn(f"login with the same ssoent {ssoent!r}, {self!r} will expire within 60 seconds", category=P115Warning)
|
5375
6089
|
return inst
|
5376
|
-
return run_gen_step(gen_step, async_=async_)
|
6090
|
+
return run_gen_step(gen_step, simple=True, async_=async_)
|
5377
6091
|
|
5378
6092
|
@overload
|
5379
6093
|
def login_another_open(
|
@@ -5467,7 +6181,7 @@ class P115Client(P115OpenClient):
|
|
5467
6181
|
inst.access_token = data["access_token"]
|
5468
6182
|
inst.app_id = app_id
|
5469
6183
|
return inst
|
5470
|
-
return run_gen_step(gen_step, async_=async_)
|
6184
|
+
return run_gen_step(gen_step, simple=True, async_=async_)
|
5471
6185
|
|
5472
6186
|
@overload
|
5473
6187
|
@classmethod
|
@@ -5586,7 +6300,7 @@ class P115Client(P115OpenClient):
|
|
5586
6300
|
resp = yield cls.login_qrcode_scan_result(uid, app, async_=async_, **request_kwargs)
|
5587
6301
|
cookies = check_response(resp)["data"]["cookie"]
|
5588
6302
|
return cls(cookies, check_for_relogin=check_for_relogin)
|
5589
|
-
return run_gen_step(gen_step, async_=async_)
|
6303
|
+
return run_gen_step(gen_step, simple=True, async_=async_)
|
5590
6304
|
|
5591
6305
|
@overload
|
5592
6306
|
def logout(
|
@@ -5738,7 +6452,7 @@ class P115Client(P115OpenClient):
|
|
5738
6452
|
if async_:
|
5739
6453
|
fetch_cert_headers = ensure_async(fetch_cert_headers)
|
5740
6454
|
if fetch_cert_headers_argcount:
|
5741
|
-
fetch_cert_headers =
|
6455
|
+
fetch_cert_headers = cast(Callable, fetch_cert_headers)(async_)
|
5742
6456
|
if revert_cert_headers is not None and async_:
|
5743
6457
|
revert_cert_headers = ensure_async(revert_cert_headers)
|
5744
6458
|
if is_open_api:
|
@@ -5768,7 +6482,7 @@ class P115Client(P115OpenClient):
|
|
5768
6482
|
def gen_step():
|
5769
6483
|
cert_headers: None | Mapping = None
|
5770
6484
|
if need_fetch_cert_first:
|
5771
|
-
cert_headers = yield fetch_cert_headers
|
6485
|
+
cert_headers = yield cast(Callable, fetch_cert_headers)()
|
5772
6486
|
headers.update(cert_headers)
|
5773
6487
|
if async_:
|
5774
6488
|
lock: Lock | AsyncLock = self.request_alock
|
@@ -5792,8 +6506,7 @@ class P115Client(P115OpenClient):
|
|
5792
6506
|
cert: str = headers["authorization"]
|
5793
6507
|
else:
|
5794
6508
|
cert = headers["cookie"]
|
5795
|
-
resp = yield
|
5796
|
-
cast(Callable, request),
|
6509
|
+
resp = yield cast(Callable, request)(
|
5797
6510
|
url=url,
|
5798
6511
|
method=method,
|
5799
6512
|
**request_kwargs,
|
@@ -5806,14 +6519,14 @@ class P115Client(P115OpenClient):
|
|
5806
6519
|
not is_auth_error and
|
5807
6520
|
get_status_code(e) != 405
|
5808
6521
|
):
|
5809
|
-
yield
|
6522
|
+
yield revert_cert_headers(cert_headers)
|
5810
6523
|
if not need_to_check:
|
5811
6524
|
raise
|
5812
|
-
res = yield
|
6525
|
+
res = yield cast(Callable, check_for_relogin)(e)
|
5813
6526
|
if not res if isinstance(res, bool) else res != 405:
|
5814
6527
|
raise
|
5815
6528
|
if fetch_cert_headers is not None:
|
5816
|
-
cert_headers = yield fetch_cert_headers
|
6529
|
+
cert_headers = yield fetch_cert_headers()
|
5817
6530
|
headers.update(cert_headers)
|
5818
6531
|
elif is_open_api:
|
5819
6532
|
yield lock.acquire
|
@@ -5858,11 +6571,11 @@ class P115Client(P115OpenClient):
|
|
5858
6571
|
lock.release()
|
5859
6572
|
else:
|
5860
6573
|
if cert_headers is not None and revert_cert_headers is not None:
|
5861
|
-
yield
|
6574
|
+
yield revert_cert_headers(cert_headers)
|
5862
6575
|
if check and isinstance(resp, dict):
|
5863
6576
|
check_response(resp)
|
5864
6577
|
return resp
|
5865
|
-
return run_gen_step(gen_step, async_=async_)
|
6578
|
+
return run_gen_step(gen_step, simple=True, async_=async_)
|
5866
6579
|
|
5867
6580
|
def request(
|
5868
6581
|
self,
|
@@ -6714,15 +7427,14 @@ class P115Client(P115OpenClient):
|
|
6714
7427
|
if "sign" not in payload:
|
6715
7428
|
resp = yield self.captcha_sign(async_=async_)
|
6716
7429
|
payload["sign"] = resp["sign"]
|
6717
|
-
return
|
6718
|
-
self.request,
|
7430
|
+
return self.request(
|
6719
7431
|
url=api,
|
6720
7432
|
method="POST",
|
6721
7433
|
data=payload,
|
6722
7434
|
async_=async_,
|
6723
7435
|
**request_kwargs,
|
6724
7436
|
)
|
6725
|
-
return run_gen_step(gen_step, async_=async_)
|
7437
|
+
return run_gen_step(gen_step, simple=True, async_=async_)
|
6726
7438
|
|
6727
7439
|
########## Download API ##########
|
6728
7440
|
|
@@ -15297,7 +16009,7 @@ class P115Client(P115OpenClient):
|
|
15297
16009
|
if device is None:
|
15298
16010
|
return None
|
15299
16011
|
return device["icon"]
|
15300
|
-
return run_gen_step(gen_step, async_=async_)
|
16012
|
+
return run_gen_step(gen_step, simple=True, async_=async_)
|
15301
16013
|
|
15302
16014
|
@overload
|
15303
16015
|
def login_open_auth_detail(
|
@@ -15821,7 +16533,7 @@ class P115Client(P115OpenClient):
|
|
15821
16533
|
return get_default_request()(url=api, async_=async_, **request_kwargs)
|
15822
16534
|
else:
|
15823
16535
|
return request(url=api, **request_kwargs)
|
15824
|
-
return run_gen_step(gen_step, async_=async_)
|
16536
|
+
return run_gen_step(gen_step, simple=True, async_=async_)
|
15825
16537
|
|
15826
16538
|
@overload
|
15827
16539
|
def logout_by_ssoent(
|
@@ -16914,7 +17626,7 @@ class P115Client(P115OpenClient):
|
|
16914
17626
|
method = self._offline_lixianssp_post
|
16915
17627
|
return method(payload, ac, async_=async_, ecdh_encrypt=ecdh_encrypt, **request_kwargs)
|
16916
17628
|
|
16917
|
-
@overload
|
17629
|
+
@overload # type: ignore
|
16918
17630
|
def offline_add_torrent(
|
16919
17631
|
self,
|
16920
17632
|
payload: str | dict,
|
@@ -16956,8 +17668,8 @@ class P115Client(P115OpenClient):
|
|
16956
17668
|
|
16957
17669
|
:payload:
|
16958
17670
|
- info_hash: str 💡 种子文件的 info_hash
|
16959
|
-
- wanted: str = <default> 💡
|
16960
|
-
- savepath: str = <default> 💡
|
17671
|
+
- wanted: str = <default> 💡 选择文件进行下载(是数字索引,从 0 开始计数,用 "," 分隔)
|
17672
|
+
- savepath: str = <default> 💡 保存到 `wp_path_id` 对应目录下的相对路径
|
16961
17673
|
- wp_path_id: int | str = <default> 💡 保存到目录的 id
|
16962
17674
|
"""
|
16963
17675
|
if isinstance(payload, str):
|
@@ -17008,7 +17720,7 @@ class P115Client(P115OpenClient):
|
|
17008
17720
|
payload = {"url": payload}
|
17009
17721
|
return self._offline_post(payload, "add_task_url", use_web_api=use_web_api, async_=async_, **request_kwargs)
|
17010
17722
|
|
17011
|
-
@overload
|
17723
|
+
@overload # type: ignore
|
17012
17724
|
def offline_add_urls(
|
17013
17725
|
self,
|
17014
17726
|
payload: str | Iterable[str] | dict,
|
@@ -17051,7 +17763,7 @@ class P115Client(P115OpenClient):
|
|
17051
17763
|
- wp_path_id: int | str = <default> 💡 保存到目录的 id
|
17052
17764
|
"""
|
17053
17765
|
if isinstance(payload, str):
|
17054
|
-
payload = payload.strip().split("\n")
|
17766
|
+
payload = payload.strip("\n").split("\n")
|
17055
17767
|
if not isinstance(payload, dict):
|
17056
17768
|
payload = {f"url[{i}]": url for i, url in enumerate(payload)}
|
17057
17769
|
if not payload:
|
@@ -17061,7 +17773,7 @@ class P115Client(P115OpenClient):
|
|
17061
17773
|
@overload
|
17062
17774
|
def offline_clear(
|
17063
17775
|
self,
|
17064
|
-
payload: int | dict,
|
17776
|
+
payload: int | dict = 0,
|
17065
17777
|
/,
|
17066
17778
|
base_url: None | bool | str | Callable[[], str] = None,
|
17067
17779
|
*,
|
@@ -17072,7 +17784,7 @@ class P115Client(P115OpenClient):
|
|
17072
17784
|
@overload
|
17073
17785
|
def offline_clear(
|
17074
17786
|
self,
|
17075
|
-
payload: int | dict,
|
17787
|
+
payload: int | dict = 0,
|
17076
17788
|
/,
|
17077
17789
|
base_url: None | bool | str | Callable[[], str] = None,
|
17078
17790
|
*,
|
@@ -17082,7 +17794,7 @@ class P115Client(P115OpenClient):
|
|
17082
17794
|
...
|
17083
17795
|
def offline_clear(
|
17084
17796
|
self,
|
17085
|
-
payload: int | dict =
|
17797
|
+
payload: int | dict = 0,
|
17086
17798
|
/,
|
17087
17799
|
base_url: None | bool | str | Callable[[], str] = None,
|
17088
17800
|
*,
|
@@ -17105,11 +17817,6 @@ class P115Client(P115OpenClient):
|
|
17105
17817
|
"""
|
17106
17818
|
api = complete_lixian_api("?ct=lixian&ac=task_clear", base_url=base_url)
|
17107
17819
|
if isinstance(payload, int):
|
17108
|
-
flag = payload
|
17109
|
-
if flag < 0:
|
17110
|
-
flag = 0
|
17111
|
-
elif flag > 5:
|
17112
|
-
flag = 5
|
17113
17820
|
payload = {"flag": payload}
|
17114
17821
|
return self.request(url=api, method="POST", data=payload, async_=async_, **request_kwargs)
|
17115
17822
|
|
@@ -17183,7 +17890,7 @@ class P115Client(P115OpenClient):
|
|
17183
17890
|
api = complete_api("/?ct=offline&ac=space", base_url=base_url)
|
17184
17891
|
return self.request(url=api, async_=async_, **request_kwargs)
|
17185
17892
|
|
17186
|
-
@overload
|
17893
|
+
@overload # type: ignore
|
17187
17894
|
def offline_list(
|
17188
17895
|
self,
|
17189
17896
|
payload: int | dict = 1,
|
@@ -17219,7 +17926,7 @@ class P115Client(P115OpenClient):
|
|
17219
17926
|
POST https://lixian.115.com/lixian/?ct=lixian&ac=task_lists
|
17220
17927
|
|
17221
17928
|
:payload:
|
17222
|
-
- page: int | str
|
17929
|
+
- page: int | str = 1
|
17223
17930
|
"""
|
17224
17931
|
api = complete_lixian_api("?ct=lixian&ac=task_lists", base_url=base_url)
|
17225
17932
|
if isinstance(payload, int):
|
@@ -17334,7 +18041,7 @@ class P115Client(P115OpenClient):
|
|
17334
18041
|
@overload
|
17335
18042
|
def offline_remove(
|
17336
18043
|
self,
|
17337
|
-
payload: str | dict,
|
18044
|
+
payload: str | Iterable[str] | dict,
|
17338
18045
|
/,
|
17339
18046
|
base_url: None | bool | str | Callable[[], str] = None,
|
17340
18047
|
*,
|
@@ -17345,7 +18052,7 @@ class P115Client(P115OpenClient):
|
|
17345
18052
|
@overload
|
17346
18053
|
def offline_remove(
|
17347
18054
|
self,
|
17348
|
-
payload: str | dict,
|
18055
|
+
payload: str | Iterable[str] | dict,
|
17349
18056
|
/,
|
17350
18057
|
base_url: None | bool | str | Callable[[], str] = None,
|
17351
18058
|
*,
|
@@ -17355,7 +18062,7 @@ class P115Client(P115OpenClient):
|
|
17355
18062
|
...
|
17356
18063
|
def offline_remove(
|
17357
18064
|
self,
|
17358
|
-
payload: str | dict,
|
18065
|
+
payload: str | Iterable[str] | dict,
|
17359
18066
|
/,
|
17360
18067
|
base_url: None | bool | str | Callable[[], str] = None,
|
17361
18068
|
*,
|
@@ -19720,7 +20427,7 @@ class P115Client(P115OpenClient):
|
|
19720
20427
|
if resp["state"]:
|
19721
20428
|
self.user_key = resp["data"]["userkey"]
|
19722
20429
|
return resp
|
19723
|
-
return run_gen_step(gen_step, async_=async_)
|
20430
|
+
return run_gen_step(gen_step, simple=True, async_=async_)
|
19724
20431
|
|
19725
20432
|
@overload
|
19726
20433
|
def upload_resume(
|
@@ -20087,7 +20794,7 @@ class P115Client(P115OpenClient):
|
|
20087
20794
|
"pickcode": resp["pickcode"],
|
20088
20795
|
}
|
20089
20796
|
return resp
|
20090
|
-
return run_gen_step(gen_step, async_=async_)
|
20797
|
+
return run_gen_step(gen_step, simple=True, async_=async_)
|
20091
20798
|
|
20092
20799
|
@overload
|
20093
20800
|
def upload_file_sample(
|
@@ -20223,7 +20930,7 @@ class P115Client(P115OpenClient):
|
|
20223
20930
|
async_=async_,
|
20224
20931
|
**request_kwargs,
|
20225
20932
|
)
|
20226
|
-
return run_gen_step(gen_step, async_=async_)
|
20933
|
+
return run_gen_step(gen_step, simple=True, async_=async_)
|
20227
20934
|
|
20228
20935
|
@overload # type: ignore
|
20229
20936
|
def upload_file(
|
@@ -20582,7 +21289,7 @@ class P115Client(P115OpenClient):
|
|
20582
21289
|
async_=async_, # type: ignore
|
20583
21290
|
**request_kwargs,
|
20584
21291
|
)
|
20585
|
-
return run_gen_step(gen_step, async_=async_)
|
21292
|
+
return run_gen_step(gen_step, simple=True, async_=async_)
|
20586
21293
|
|
20587
21294
|
########## User API ##########
|
20588
21295
|
|