p123client 0.0.6.8__py3-none-any.whl → 0.0.6.9.4__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.
- p123client/client.py +2454 -725
- p123client/const.py +10 -1
- p123client/exception.py +64 -7
- p123client/tool/__init__.py +63 -20
- {p123client-0.0.6.8.dist-info → p123client-0.0.6.9.4.dist-info}/METADATA +119 -23
- p123client-0.0.6.9.4.dist-info/RECORD +12 -0
- p123client-0.0.6.8.dist-info/RECORD +0 -12
- {p123client-0.0.6.8.dist-info → p123client-0.0.6.9.4.dist-info}/LICENSE +0 -0
- {p123client-0.0.6.8.dist-info → p123client-0.0.6.9.4.dist-info}/WHEEL +0 -0
p123client/client.py
CHANGED
@@ -5,21 +5,25 @@ from __future__ import annotations
|
|
5
5
|
|
6
6
|
__all__ = ["check_response", "P123OpenClient", "P123Client"]
|
7
7
|
|
8
|
+
from base64 import b64decode
|
8
9
|
from collections.abc import (
|
9
10
|
AsyncIterable, Awaitable, Buffer, Callable, Coroutine,
|
10
11
|
ItemsView, Iterable, Iterator, Mapping, MutableMapping,
|
11
12
|
)
|
12
|
-
from
|
13
|
+
from contextlib import contextmanager
|
14
|
+
from errno import EAUTH, EIO, EISDIR, ENOENT
|
13
15
|
from functools import partial
|
14
16
|
from hashlib import md5
|
15
17
|
from http.cookiejar import CookieJar
|
16
18
|
from inspect import isawaitable
|
17
19
|
from itertools import chain
|
18
|
-
from os import fsdecode, fstat, PathLike
|
20
|
+
from os import fsdecode, fstat, isatty, PathLike
|
19
21
|
from os.path import basename
|
20
|
-
from
|
22
|
+
from pathlib import Path, PurePath
|
23
|
+
from re import compile as re_compile, MULTILINE
|
24
|
+
from sys import _getframe
|
21
25
|
from tempfile import TemporaryFile
|
22
|
-
from typing import cast, overload, Any, Literal
|
26
|
+
from typing import cast, overload, Any, Final, Literal, Self
|
23
27
|
from uuid import uuid4
|
24
28
|
from warnings import warn
|
25
29
|
|
@@ -31,21 +35,24 @@ from filewrap import (
|
|
31
35
|
copyfileobj, copyfileobj_async, SupportsRead,
|
32
36
|
)
|
33
37
|
from hashtools import file_digest, file_digest_async
|
34
|
-
from http_request import
|
38
|
+
from http_request import (
|
39
|
+
encode_multipart_data, encode_multipart_data_async, SupportsGeturl,
|
40
|
+
)
|
35
41
|
from iterutils import run_gen_step
|
36
42
|
from property import locked_cacheproperty
|
37
43
|
from yarl import URL
|
38
44
|
|
39
|
-
from .
|
45
|
+
from .const import CLIENT_API_METHODS_MAP, CLIENT_METHOD_API_MAP
|
46
|
+
from .exception import P123OSError, P123BrokenUpload, P123LoginError, P123AuthenticationError
|
40
47
|
|
41
48
|
|
42
49
|
# 默认使用的域名
|
43
50
|
# "https://www.123pan.com"
|
44
51
|
# "https://www.123pan.com/a"
|
45
52
|
# "https://www.123pan.com/b"
|
46
|
-
DEFAULT_BASE_URL = "https://www.123pan.com/b"
|
47
|
-
DEFAULT_LOGIN_BASE_URL = "https://login.123pan.com"
|
48
|
-
DEFAULT_OPEN_BASE_URL = "https://open-api.123pan.com"
|
53
|
+
DEFAULT_BASE_URL: Final = "https://www.123pan.com/b"
|
54
|
+
DEFAULT_LOGIN_BASE_URL: Final = "https://login.123pan.com"
|
55
|
+
DEFAULT_OPEN_BASE_URL: Final = "https://open-api.123pan.com"
|
49
56
|
# 默认的请求函数
|
50
57
|
_httpx_request = None
|
51
58
|
|
@@ -147,6 +154,20 @@ def items[K, V](
|
|
147
154
|
return m
|
148
155
|
|
149
156
|
|
157
|
+
@contextmanager
|
158
|
+
def temp_globals(f_globals: None | dict = None, /, **ns):
|
159
|
+
if f_globals is None:
|
160
|
+
f_globals = _getframe(2).f_globals
|
161
|
+
old_globals = f_globals.copy()
|
162
|
+
if ns:
|
163
|
+
f_globals.update(ns)
|
164
|
+
try:
|
165
|
+
yield f_globals
|
166
|
+
finally:
|
167
|
+
f_globals.clear()
|
168
|
+
f_globals.update(old_globals)
|
169
|
+
|
170
|
+
|
150
171
|
@overload
|
151
172
|
def check_response(resp: dict, /) -> dict:
|
152
173
|
...
|
@@ -157,9 +178,16 @@ def check_response(resp: dict | Awaitable[dict], /) -> dict | Coroutine[Any, Any
|
|
157
178
|
"""检测 123 的某个接口的响应,如果成功则直接返回,否则根据具体情况抛出一个异常,基本上是 OSError 的实例
|
158
179
|
"""
|
159
180
|
def check(resp, /) -> dict:
|
160
|
-
if not isinstance(resp, dict)
|
181
|
+
if not isinstance(resp, dict):
|
161
182
|
raise P123OSError(EIO, resp)
|
162
|
-
|
183
|
+
code = resp.get("code", 0)
|
184
|
+
if code in (0, 200):
|
185
|
+
return resp
|
186
|
+
match code:
|
187
|
+
case 401:
|
188
|
+
raise P123AuthenticationError(EAUTH, resp)
|
189
|
+
case _:
|
190
|
+
raise P123OSError(EIO, resp)
|
163
191
|
if isawaitable(resp):
|
164
192
|
async def check_await() -> dict:
|
165
193
|
return check(await resp)
|
@@ -176,17 +204,32 @@ class P123OpenClient:
|
|
176
204
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced
|
177
205
|
"""
|
178
206
|
|
207
|
+
token_path: None | PurePath = None
|
208
|
+
|
179
209
|
def __init__(
|
180
210
|
self, /,
|
181
|
-
client_id: str = "",
|
211
|
+
client_id: str | PathLike = "",
|
182
212
|
client_secret: str = "",
|
183
|
-
token: str =
|
213
|
+
token: None | str | PathLike = None,
|
184
214
|
):
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
self.
|
215
|
+
if isinstance(client_id, PathLike):
|
216
|
+
token = client_id
|
217
|
+
else:
|
218
|
+
self.client_id = client_id
|
219
|
+
self.client_secret = client_secret
|
220
|
+
if token is None:
|
221
|
+
if client_id and client_secret:
|
222
|
+
self.login_open()
|
223
|
+
elif isinstance(token, str):
|
224
|
+
self.token = token.removeprefix("Bearer ")
|
225
|
+
else:
|
226
|
+
if isinstance(token, PurePath) and hasattr(token, "open"):
|
227
|
+
self.token_path = token
|
228
|
+
else:
|
229
|
+
self.token_path = Path(fsdecode(token))
|
230
|
+
self._read_token()
|
231
|
+
if not self.token and client_id and client_secret:
|
232
|
+
self.login_open()
|
190
233
|
|
191
234
|
def __del__(self, /):
|
192
235
|
self.close()
|
@@ -258,20 +301,62 @@ class P123OpenClient:
|
|
258
301
|
|
259
302
|
@property
|
260
303
|
def token(self, /) -> str:
|
261
|
-
return self.
|
304
|
+
return self.__dict__.get("token", "")
|
262
305
|
|
263
306
|
@token.setter
|
264
|
-
def token(self,
|
265
|
-
self.
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
307
|
+
def token(self, token: str, /):
|
308
|
+
if token != self.token:
|
309
|
+
self._write_token(token)
|
310
|
+
ns = self.__dict__
|
311
|
+
ns["token"] = token
|
312
|
+
if token:
|
313
|
+
self.headers["authorization"] = f"Bearer {token}"
|
314
|
+
else:
|
315
|
+
self.headers.pop("authorization", None)
|
316
|
+
ns.pop("token_user_info", None)
|
317
|
+
ns.pop("user_id", None)
|
270
318
|
|
271
319
|
@token.deleter
|
272
320
|
def token(self, /):
|
273
321
|
self.token = ""
|
274
322
|
|
323
|
+
@locked_cacheproperty
|
324
|
+
def token_user_info(self, /) -> dict:
|
325
|
+
from orjson import loads
|
326
|
+
return loads(b64decode(self.token.split(".", 2)[1] + "=="))
|
327
|
+
|
328
|
+
@locked_cacheproperty
|
329
|
+
def user_id(self, /) -> dict:
|
330
|
+
return self.token_user_info["id"]
|
331
|
+
|
332
|
+
def _read_token(
|
333
|
+
self,
|
334
|
+
/,
|
335
|
+
encoding: str = "latin-1",
|
336
|
+
) -> None | str:
|
337
|
+
if token_path := self.token_path:
|
338
|
+
try:
|
339
|
+
with token_path.open("rb") as f: # type: ignore
|
340
|
+
token = str(f.read().strip(), encoding)
|
341
|
+
self.token = token.removeprefix("Bearer ")
|
342
|
+
return token
|
343
|
+
except OSError:
|
344
|
+
pass
|
345
|
+
return self.token
|
346
|
+
|
347
|
+
def _write_token(
|
348
|
+
self,
|
349
|
+
token: None | str = None,
|
350
|
+
/,
|
351
|
+
encoding: str = "latin-1",
|
352
|
+
):
|
353
|
+
if token_path := self.token_path:
|
354
|
+
if token is None:
|
355
|
+
token = self.token
|
356
|
+
token_bytes = bytes(token, encoding)
|
357
|
+
with token_path.open("wb") as f: # type: ignore
|
358
|
+
f.write(token_bytes)
|
359
|
+
|
275
360
|
def close(self, /) -> None:
|
276
361
|
"""删除 session 和 async_session 属性,如果它们未被引用,则应该会被自动清理
|
277
362
|
"""
|
@@ -433,13 +518,16 @@ class P123OpenClient:
|
|
433
518
|
- clientID: str 💡 应用标识,创建应用时分配的 appId
|
434
519
|
- clientSecret: str 💡 应用密钥,创建应用时分配的 secretId
|
435
520
|
"""
|
436
|
-
request_kwargs["url"] = complete_url("/api/v1/access_token", base_url)
|
437
|
-
request_kwargs.setdefault("method", "POST")
|
438
521
|
request_kwargs.setdefault("parse", default_parse)
|
439
522
|
if request is None:
|
440
523
|
request = get_default_request()
|
441
524
|
request_kwargs["async_"] = async_
|
442
|
-
return request(
|
525
|
+
return request(
|
526
|
+
url=complete_url("/api/v1/access_token", base_url),
|
527
|
+
method="POST",
|
528
|
+
json=payload,
|
529
|
+
**request_kwargs,
|
530
|
+
)
|
443
531
|
|
444
532
|
@overload
|
445
533
|
@staticmethod
|
@@ -490,13 +578,16 @@ class P123OpenClient:
|
|
490
578
|
- scope: str = "user:base,file:all:read,file:all:write" 💡 权限
|
491
579
|
- state: str = "" 💡 自定义参数,任意取值
|
492
580
|
"""
|
493
|
-
request_kwargs["url"] = complete_url("/auth", base_url)
|
494
581
|
request_kwargs.setdefault("parse", default_parse)
|
495
582
|
payload = dict_to_lower_merge(payload, scope="user:base,file:all:read,file:all:write")
|
496
583
|
if request is None:
|
497
584
|
request = get_default_request()
|
498
585
|
request_kwargs["async_"] = async_
|
499
|
-
return request(
|
586
|
+
return request(
|
587
|
+
url=complete_url("/auth", base_url),
|
588
|
+
params=payload,
|
589
|
+
**request_kwargs,
|
590
|
+
)
|
500
591
|
|
501
592
|
@overload
|
502
593
|
@staticmethod
|
@@ -556,8 +647,6 @@ class P123OpenClient:
|
|
556
647
|
- redirect_uri: str = <default> 💡 应用注册的回调地址,`grant_type` 为 "authorization_code" 时必携带
|
557
648
|
- refresh_token: str = <default> 💡 刷新 token,单次请求有效
|
558
649
|
"""
|
559
|
-
request_kwargs["url"] = complete_url("/api/v1/oauth2/access_token", base_url)
|
560
|
-
request_kwargs.setdefault("method", "POST")
|
561
650
|
request_kwargs.setdefault("parse", default_parse)
|
562
651
|
payload = dict_to_lower(payload)
|
563
652
|
if not payload.get("grant_type"):
|
@@ -568,7 +657,163 @@ class P123OpenClient:
|
|
568
657
|
if request is None:
|
569
658
|
request = get_default_request()
|
570
659
|
request_kwargs["async_"] = async_
|
571
|
-
return request(
|
660
|
+
return request(
|
661
|
+
url=complete_url("/api/v1/oauth2/access_token", base_url),
|
662
|
+
method="POST",
|
663
|
+
params=payload,
|
664
|
+
**request_kwargs,
|
665
|
+
)
|
666
|
+
|
667
|
+
########## Developer API ##########
|
668
|
+
|
669
|
+
@overload
|
670
|
+
def developer_config_forbide_ip_list(
|
671
|
+
self,
|
672
|
+
/,
|
673
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
674
|
+
*,
|
675
|
+
async_: Literal[False] = False,
|
676
|
+
**request_kwargs,
|
677
|
+
) -> dict:
|
678
|
+
...
|
679
|
+
@overload
|
680
|
+
def developer_config_forbide_ip_list(
|
681
|
+
self,
|
682
|
+
/,
|
683
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
684
|
+
*,
|
685
|
+
async_: Literal[True],
|
686
|
+
**request_kwargs,
|
687
|
+
) -> Coroutine[Any, Any, dict]:
|
688
|
+
...
|
689
|
+
def developer_config_forbide_ip_list(
|
690
|
+
self,
|
691
|
+
/,
|
692
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
693
|
+
*,
|
694
|
+
async_: Literal[False, True] = False,
|
695
|
+
**request_kwargs,
|
696
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
697
|
+
"""ip黑名单列表
|
698
|
+
|
699
|
+
GET https://open-api.123pan.com/api/v1/developer/config/forbide-ip/list
|
700
|
+
|
701
|
+
.. admonition:: Reference
|
702
|
+
/API列表/直链/IP黑名单配置/ip黑名单列表
|
703
|
+
|
704
|
+
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/mxldrm9d5gpw5h2d
|
705
|
+
|
706
|
+
.. caution::
|
707
|
+
获取用户配置的黑名单
|
708
|
+
"""
|
709
|
+
api = complete_url("/api/v1/developer/config/forbide-ip/list", base_url)
|
710
|
+
return self.request(api, async_=async_, **request_kwargs)
|
711
|
+
|
712
|
+
@overload
|
713
|
+
def developer_config_forbide_ip_switch(
|
714
|
+
self,
|
715
|
+
payload: dict | Literal[1, 2] = 1,
|
716
|
+
/,
|
717
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
718
|
+
*,
|
719
|
+
async_: Literal[False] = False,
|
720
|
+
**request_kwargs,
|
721
|
+
) -> dict:
|
722
|
+
...
|
723
|
+
@overload
|
724
|
+
def developer_config_forbide_ip_switch(
|
725
|
+
self,
|
726
|
+
payload: dict | Literal[1, 2] = 1,
|
727
|
+
/,
|
728
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
729
|
+
*,
|
730
|
+
async_: Literal[True],
|
731
|
+
**request_kwargs,
|
732
|
+
) -> Coroutine[Any, Any, dict]:
|
733
|
+
...
|
734
|
+
def developer_config_forbide_ip_switch(
|
735
|
+
self,
|
736
|
+
payload: dict | Literal[1, 2] = 1,
|
737
|
+
/,
|
738
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
739
|
+
*,
|
740
|
+
async_: Literal[False, True] = False,
|
741
|
+
**request_kwargs,
|
742
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
743
|
+
"""开启关闭ip黑名单
|
744
|
+
|
745
|
+
POST https://open-api.123pan.com/api/v1/developer/config/forbide-ip/switch
|
746
|
+
|
747
|
+
.. admonition:: Reference
|
748
|
+
/API列表/直链/IP黑名单配置/开启关闭ip黑名单
|
749
|
+
|
750
|
+
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/xwx77dbzrkxquuxm
|
751
|
+
|
752
|
+
.. caution::
|
753
|
+
此接口需要开通开发者权益
|
754
|
+
|
755
|
+
:payload:
|
756
|
+
- Status: 1 | 2 = 1 💡 状态:1:启用 2:禁用
|
757
|
+
"""
|
758
|
+
api = complete_url("/api/v1/developer/config/forbide-ip/switch", base_url)
|
759
|
+
if not isinstance(payload, dict):
|
760
|
+
payload = {"Status": payload}
|
761
|
+
return self.request(api, "POST", json=payload, async_=async_, **request_kwargs)
|
762
|
+
|
763
|
+
@overload
|
764
|
+
def developer_config_forbide_ip_update(
|
765
|
+
self,
|
766
|
+
payload: dict | Iterable[str],
|
767
|
+
/,
|
768
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
769
|
+
*,
|
770
|
+
async_: Literal[False] = False,
|
771
|
+
**request_kwargs,
|
772
|
+
) -> dict:
|
773
|
+
...
|
774
|
+
@overload
|
775
|
+
def developer_config_forbide_ip_update(
|
776
|
+
self,
|
777
|
+
payload: dict | Iterable[str],
|
778
|
+
/,
|
779
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
780
|
+
*,
|
781
|
+
async_: Literal[True],
|
782
|
+
**request_kwargs,
|
783
|
+
) -> Coroutine[Any, Any, dict]:
|
784
|
+
...
|
785
|
+
def developer_config_forbide_ip_update(
|
786
|
+
self,
|
787
|
+
payload: dict | Iterable[str],
|
788
|
+
/,
|
789
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
790
|
+
*,
|
791
|
+
async_: Literal[False, True] = False,
|
792
|
+
**request_kwargs,
|
793
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
794
|
+
"""更新ip黑名单列表
|
795
|
+
|
796
|
+
POST https://open-api.123pan.com/api/v1/developer/config/forbide-ip/update
|
797
|
+
|
798
|
+
.. admonition:: Reference
|
799
|
+
/API列表/直链/IP黑名单配置/更新ip黑名单列表
|
800
|
+
|
801
|
+
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/tt3s54slh87q8wuh
|
802
|
+
|
803
|
+
.. caution::
|
804
|
+
此接口需要开通开发者权益
|
805
|
+
|
806
|
+
:payload:
|
807
|
+
- IpList: list[str] 💡 IP 地址列表,最多 500 个 IPv4 地址
|
808
|
+
"""
|
809
|
+
api = complete_url("/api/v1/developer/config/forbide-ip/update", base_url)
|
810
|
+
if not isinstance(payload, dict):
|
811
|
+
if not isinstance(payload, (list, tuple)):
|
812
|
+
payload = list(payload)
|
813
|
+
payload = {"IpList": payload}
|
814
|
+
return self.request(api, "POST", json=payload, async_=async_, **request_kwargs)
|
815
|
+
|
816
|
+
########## Direct Link API ##########
|
572
817
|
|
573
818
|
@overload
|
574
819
|
def dlink_disable(
|
@@ -706,6 +951,9 @@ class P123OpenClient:
|
|
706
951
|
|
707
952
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/agmqpmu0dm0iogc9
|
708
953
|
|
954
|
+
.. caution::
|
955
|
+
此接口需要开通开发者权益,并且仅限查询近 3 天的日志数据
|
956
|
+
|
709
957
|
:payload:
|
710
958
|
- pageNum: int 💡 第几页
|
711
959
|
- pageSize: int = 100 💡 分页大小
|
@@ -781,6 +1029,65 @@ class P123OpenClient:
|
|
781
1029
|
payload = {"fileID": payload}
|
782
1030
|
return self.request(api, params=payload, async_=async_, **request_kwargs)
|
783
1031
|
|
1032
|
+
@overload
|
1033
|
+
def dlink_offline_log(
|
1034
|
+
self,
|
1035
|
+
payload: dict | int = 1,
|
1036
|
+
/,
|
1037
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
1038
|
+
*,
|
1039
|
+
async_: Literal[False] = False,
|
1040
|
+
**request_kwargs,
|
1041
|
+
) -> dict:
|
1042
|
+
...
|
1043
|
+
@overload
|
1044
|
+
def dlink_offline_log(
|
1045
|
+
self,
|
1046
|
+
payload: dict | int = 1,
|
1047
|
+
/,
|
1048
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
1049
|
+
*,
|
1050
|
+
async_: Literal[True],
|
1051
|
+
**request_kwargs,
|
1052
|
+
) -> Coroutine[Any, Any, dict]:
|
1053
|
+
...
|
1054
|
+
def dlink_offline_log(
|
1055
|
+
self,
|
1056
|
+
payload: dict | int = 1,
|
1057
|
+
/,
|
1058
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
1059
|
+
*,
|
1060
|
+
async_: Literal[False, True] = False,
|
1061
|
+
**request_kwargs,
|
1062
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
1063
|
+
"""获取直链离线日志
|
1064
|
+
|
1065
|
+
GET https://open-api.123pan.com/api/v1/direct-link/offline/logs
|
1066
|
+
|
1067
|
+
.. admonition:: Reference
|
1068
|
+
/API列表/直链/获取直链离线日志
|
1069
|
+
|
1070
|
+
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/yz4bdynw9yx5erqb
|
1071
|
+
|
1072
|
+
.. caution::
|
1073
|
+
此接口需要开通开发者权益,并且仅限查询近30天的日志数据
|
1074
|
+
|
1075
|
+
:payload:
|
1076
|
+
- pageNum: int 💡 第几页
|
1077
|
+
- pageSize: int = 100 💡 分页大小
|
1078
|
+
- startHour: str = "0001010100" 💡 开始时间,格式:YYYYMMDDhh
|
1079
|
+
- endHour: str. = "9999123123" 💡 结束时间,格式:YYYYMMDDhh
|
1080
|
+
"""
|
1081
|
+
api = complete_url("/api/v1/direct-link/offline/logs", base_url)
|
1082
|
+
if not isinstance(payload, dict):
|
1083
|
+
payload = {"pageNum": payload}
|
1084
|
+
payload = dict_to_lower_merge(payload, {
|
1085
|
+
"pageSize": 100,
|
1086
|
+
"startTime": "0001010100",
|
1087
|
+
"endTime": "9999123123",
|
1088
|
+
})
|
1089
|
+
return self.request(api, params=payload, async_=async_, **request_kwargs)
|
1090
|
+
|
784
1091
|
@overload
|
785
1092
|
def dlink_transcode(
|
786
1093
|
self,
|
@@ -934,6 +1241,8 @@ class P123OpenClient:
|
|
934
1241
|
payload = {"fileID": payload}
|
935
1242
|
return self.request(api, params=payload, async_=async_, **request_kwargs)
|
936
1243
|
|
1244
|
+
########## Download API ##########
|
1245
|
+
|
937
1246
|
@overload
|
938
1247
|
def download_info(
|
939
1248
|
self,
|
@@ -983,6 +1292,8 @@ class P123OpenClient:
|
|
983
1292
|
payload = {"fileId": payload}
|
984
1293
|
return self.request(api, params=payload, async_=async_, **request_kwargs)
|
985
1294
|
|
1295
|
+
########## File System API ##########
|
1296
|
+
|
986
1297
|
@overload
|
987
1298
|
def fs_delete(
|
988
1299
|
self,
|
@@ -1078,6 +1389,9 @@ class P123OpenClient:
|
|
1078
1389
|
|
1079
1390
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/owapsz373dzwiqbp
|
1080
1391
|
|
1392
|
+
.. note::
|
1393
|
+
支持查询单文件夹包含文件大小
|
1394
|
+
|
1081
1395
|
:payload:
|
1082
1396
|
- fileID: int 💡 文件 id
|
1083
1397
|
"""
|
@@ -1188,11 +1502,14 @@ class P123OpenClient:
|
|
1188
1502
|
|
1189
1503
|
.. note::
|
1190
1504
|
如果返回信息中,"lastFileId" 字段的值为 "-1",代表最后一页(无需再翻页查询)。
|
1191
|
-
其它则代表下一页开始的文件 id
|
1505
|
+
其它则代表下一页开始的文件 id,携带到请求参数中,可查询下一页。
|
1506
|
+
|
1507
|
+
.. caution::
|
1508
|
+
此接口查询结果包含回收站的文件,需自行根据字段 `trashed` 判断处理
|
1192
1509
|
|
1193
1510
|
:payload:
|
1194
1511
|
- businessType: int = <default> 💡 业务类型:2:转码空间
|
1195
|
-
- category: int = <default> 💡 分类代码:0:未知 1:音频 2:视频 3:图片
|
1512
|
+
- category: int = <default> 💡 分类代码:0:未知 1:音频 2:视频 3:图片 4:音频 5:其它
|
1196
1513
|
- lastFileId: int = <default> 💡 上一页的最后一条记录的 FileID,翻页查询时需要填写
|
1197
1514
|
- limit: int = 100 💡 分页大小,最多 100
|
1198
1515
|
- parentFileId: int | str = 0 💡 父目录 id,根目录是 0
|
@@ -1215,6 +1532,8 @@ class P123OpenClient:
|
|
1215
1532
|
})
|
1216
1533
|
return self.request(api, params=payload, async_=async_, **request_kwargs)
|
1217
1534
|
|
1535
|
+
fs_list_v2 = fs_list
|
1536
|
+
|
1218
1537
|
@overload
|
1219
1538
|
def fs_list_v1(
|
1220
1539
|
self,
|
@@ -1260,8 +1579,8 @@ class P123OpenClient:
|
|
1260
1579
|
|
1261
1580
|
:payload:
|
1262
1581
|
- limit: int = 100 💡 分页大小,最多 100
|
1263
|
-
- orderBy: str = "
|
1264
|
-
|
1582
|
+
- orderBy: str = "file_name" 💡 排序依据
|
1583
|
+
|
1265
1584
|
- "file_id": 文件 id
|
1266
1585
|
- "file_name": 文件名
|
1267
1586
|
- "size": 文件大小
|
@@ -1285,7 +1604,7 @@ class P123OpenClient:
|
|
1285
1604
|
payload = {"parentFileId": payload}
|
1286
1605
|
payload = dict_to_lower_merge(payload, {
|
1287
1606
|
"limit": 100,
|
1288
|
-
"orderBy": "
|
1607
|
+
"orderBy": "file_name",
|
1289
1608
|
"orderDirection": "asc",
|
1290
1609
|
"page": 1,
|
1291
1610
|
"parentFileId": 0,
|
@@ -1615,6 +1934,8 @@ class P123OpenClient:
|
|
1615
1934
|
payload = {"fileIDs": payload}
|
1616
1935
|
return self.request(api, "POST", json=payload, async_=async_, **request_kwargs)
|
1617
1936
|
|
1937
|
+
########## Offline Download API ##########
|
1938
|
+
|
1618
1939
|
@overload
|
1619
1940
|
def offline_download(
|
1620
1941
|
self,
|
@@ -1724,6 +2045,8 @@ class P123OpenClient:
|
|
1724
2045
|
payload = {"taskID": payload}
|
1725
2046
|
return self.request(api, params=payload, async_=async_, **request_kwargs)
|
1726
2047
|
|
2048
|
+
########## Oss API ##########
|
2049
|
+
|
1727
2050
|
@overload
|
1728
2051
|
def oss_copy(
|
1729
2052
|
self,
|
@@ -2862,6 +3185,8 @@ class P123OpenClient:
|
|
2862
3185
|
}) from e
|
2863
3186
|
return run_gen_step(gen_step, async_)
|
2864
3187
|
|
3188
|
+
########## Share API ##########
|
3189
|
+
|
2865
3190
|
@overload
|
2866
3191
|
def share_create(
|
2867
3192
|
self,
|
@@ -3070,6 +3395,8 @@ class P123OpenClient:
|
|
3070
3395
|
payload = {"limit": payload}
|
3071
3396
|
return self.request(api, params=payload, async_=async_, **request_kwargs)
|
3072
3397
|
|
3398
|
+
########## Transcode API ##########
|
3399
|
+
|
3073
3400
|
@overload
|
3074
3401
|
def transcode_delete(
|
3075
3402
|
self,
|
@@ -3616,6 +3943,8 @@ class P123OpenClient:
|
|
3616
3943
|
api = complete_url("/api/v1/transcode/video", base_url)
|
3617
3944
|
return self.request(api, "POST", json=payload, async_=async_, **request_kwargs)
|
3618
3945
|
|
3946
|
+
########## Upload API ##########
|
3947
|
+
|
3619
3948
|
@overload
|
3620
3949
|
def upload_create(
|
3621
3950
|
self,
|
@@ -4218,6 +4547,8 @@ class P123OpenClient:
|
|
4218
4547
|
}) from e
|
4219
4548
|
return run_gen_step(gen_step, async_)
|
4220
4549
|
|
4550
|
+
########## User API ##########
|
4551
|
+
|
4221
4552
|
@overload
|
4222
4553
|
def user_info(
|
4223
4554
|
self,
|
@@ -4272,6 +4603,8 @@ class P123OpenClient:
|
|
4272
4603
|
api = complete_url("/api/v1/user/info", base_url)
|
4273
4604
|
return self.request(api, async_=async_, **request_kwargs)
|
4274
4605
|
|
4606
|
+
########## API Aliases ##########
|
4607
|
+
|
4275
4608
|
login_open = login
|
4276
4609
|
login_access_token_open = login_access_token
|
4277
4610
|
login_auth_open = login_auth
|
@@ -4288,6 +4621,7 @@ class P123OpenClient:
|
|
4288
4621
|
fs_detail_open = fs_detail
|
4289
4622
|
fs_info_open = fs_info
|
4290
4623
|
fs_list_open = fs_list
|
4624
|
+
fs_list_v2_open = fs_list_v2
|
4291
4625
|
fs_list_v1_open = fs_list_v1
|
4292
4626
|
fs_mkdir_open = fs_mkdir
|
4293
4627
|
fs_move_open = fs_move
|
@@ -4338,19 +4672,36 @@ class P123OpenClient:
|
|
4338
4672
|
|
4339
4673
|
|
4340
4674
|
class P123Client(P123OpenClient):
|
4675
|
+
"""123 的客户端对象
|
4341
4676
|
|
4677
|
+
:param passport: 手机号或邮箱
|
4678
|
+
:param password: 密码
|
4679
|
+
:param token: 123 的访问令牌
|
4680
|
+
"""
|
4342
4681
|
def __init__(
|
4343
4682
|
self,
|
4344
4683
|
/,
|
4345
|
-
passport: int | str = "",
|
4684
|
+
passport: int | str | PathLike = "",
|
4346
4685
|
password: str = "",
|
4347
|
-
token: str =
|
4686
|
+
token: None | str | PathLike = None,
|
4348
4687
|
):
|
4349
|
-
|
4350
|
-
|
4351
|
-
|
4352
|
-
|
4688
|
+
if isinstance(passport, PathLike):
|
4689
|
+
token = passport
|
4690
|
+
else:
|
4691
|
+
self.passport = passport
|
4692
|
+
self.password = password
|
4693
|
+
if token is None:
|
4353
4694
|
self.login()
|
4695
|
+
elif isinstance(token, str):
|
4696
|
+
self.token = token.removeprefix("Bearer ")
|
4697
|
+
else:
|
4698
|
+
if isinstance(token, PurePath) and hasattr(token, "open"):
|
4699
|
+
self.token_path = token
|
4700
|
+
else:
|
4701
|
+
self.token_path = Path(fsdecode(token))
|
4702
|
+
self._read_token()
|
4703
|
+
if not self.token:
|
4704
|
+
self.login()
|
4354
4705
|
|
4355
4706
|
@overload # type: ignore
|
4356
4707
|
def login(
|
@@ -4409,193 +4760,236 @@ class P123Client(P123OpenClient):
|
|
4409
4760
|
else:
|
4410
4761
|
password = self.password
|
4411
4762
|
def gen_step():
|
4412
|
-
|
4413
|
-
|
4414
|
-
|
4415
|
-
|
4416
|
-
|
4417
|
-
|
4418
|
-
|
4419
|
-
|
4420
|
-
|
4763
|
+
if passport and password:
|
4764
|
+
resp = yield self.login_passport(
|
4765
|
+
{"passport": passport, "password": password, "remember": remember},
|
4766
|
+
base_url=base_url,
|
4767
|
+
async_=async_,
|
4768
|
+
**request_kwargs,
|
4769
|
+
)
|
4770
|
+
check_response(resp)
|
4771
|
+
self.token = resp["data"]["token"]
|
4772
|
+
return resp
|
4773
|
+
else:
|
4774
|
+
resp = yield self.login_with_qrcode(
|
4775
|
+
base_url=base_url,
|
4776
|
+
async_=async_,
|
4777
|
+
**request_kwargs,
|
4778
|
+
)
|
4779
|
+
self.token = resp["data"]["token"]
|
4780
|
+
return resp
|
4421
4781
|
return run_gen_step(gen_step, async_)
|
4422
4782
|
|
4423
4783
|
@overload
|
4424
|
-
|
4425
|
-
|
4426
|
-
|
4427
|
-
|
4784
|
+
def login_another(
|
4785
|
+
self,
|
4786
|
+
/,
|
4787
|
+
replace: bool | Self = False,
|
4788
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
4428
4789
|
*,
|
4429
4790
|
async_: Literal[False] = False,
|
4430
4791
|
**request_kwargs,
|
4431
|
-
) ->
|
4792
|
+
) -> Self:
|
4432
4793
|
...
|
4433
4794
|
@overload
|
4434
|
-
|
4435
|
-
|
4436
|
-
|
4437
|
-
|
4795
|
+
def login_another(
|
4796
|
+
self,
|
4797
|
+
/,
|
4798
|
+
replace: bool | Self = False,
|
4799
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
4438
4800
|
*,
|
4439
4801
|
async_: Literal[True],
|
4440
4802
|
**request_kwargs,
|
4441
|
-
) -> Coroutine[Any, Any,
|
4803
|
+
) -> Coroutine[Any, Any, Self]:
|
4442
4804
|
...
|
4443
|
-
|
4444
|
-
|
4445
|
-
|
4446
|
-
|
4805
|
+
def login_another(
|
4806
|
+
self,
|
4807
|
+
/,
|
4808
|
+
replace: bool | Self = False,
|
4809
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
4447
4810
|
*,
|
4448
4811
|
async_: Literal[False, True] = False,
|
4449
4812
|
**request_kwargs,
|
4450
|
-
) ->
|
4451
|
-
"""
|
4813
|
+
) -> Self | Coroutine[Any, Any, Self]:
|
4814
|
+
"""再执行一次登录
|
4452
4815
|
|
4453
|
-
|
4816
|
+
:param replace: 替换某个 client 对象的 token
|
4817
|
+
|
4818
|
+
- 如果为 P123Client, 则更新到此对象
|
4819
|
+
- 如果为 True,则更新到 `self`
|
4820
|
+
- 如果为 False,否则返回新的 `P123Client` 对象
|
4821
|
+
|
4822
|
+
:param base_url: 接口的基地址
|
4823
|
+
:param async_: 是否异步
|
4824
|
+
:param request_kwargs: 其它请求参数
|
4825
|
+
|
4826
|
+
:return: 客户端实例
|
4454
4827
|
"""
|
4455
|
-
|
4456
|
-
|
4457
|
-
|
4458
|
-
|
4459
|
-
|
4460
|
-
|
4828
|
+
def gen_step():
|
4829
|
+
resp = yield self.login_qrcode_auto(
|
4830
|
+
base_url=base_url,
|
4831
|
+
async_=async_,
|
4832
|
+
**request_kwargs,
|
4833
|
+
)
|
4834
|
+
check_response(resp)
|
4835
|
+
if resp["code"] != 200:
|
4836
|
+
raise P123LoginError(EAUTH, resp)
|
4837
|
+
token = resp["data"]["token"]
|
4838
|
+
if replace is False:
|
4839
|
+
return type(self)(passport=self.passport, password=self.password, token=token)
|
4840
|
+
elif replace is True:
|
4841
|
+
inst = self
|
4842
|
+
else:
|
4843
|
+
inst = replace
|
4844
|
+
inst.token = token
|
4845
|
+
return inst
|
4846
|
+
return run_gen_step(gen_step, async_)
|
4461
4847
|
|
4462
4848
|
@overload
|
4463
|
-
|
4464
|
-
|
4465
|
-
|
4466
|
-
|
4849
|
+
def login_qrcode_auto(
|
4850
|
+
self,
|
4851
|
+
/,
|
4852
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
4467
4853
|
*,
|
4468
4854
|
async_: Literal[False] = False,
|
4469
4855
|
**request_kwargs,
|
4470
4856
|
) -> dict:
|
4471
4857
|
...
|
4472
4858
|
@overload
|
4473
|
-
|
4474
|
-
|
4475
|
-
|
4476
|
-
|
4859
|
+
def login_qrcode_auto(
|
4860
|
+
self,
|
4861
|
+
/,
|
4862
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
4477
4863
|
*,
|
4478
4864
|
async_: Literal[True],
|
4479
4865
|
**request_kwargs,
|
4480
4866
|
) -> Coroutine[Any, Any, dict]:
|
4481
4867
|
...
|
4482
|
-
|
4483
|
-
|
4484
|
-
|
4485
|
-
|
4868
|
+
def login_qrcode_auto(
|
4869
|
+
self,
|
4870
|
+
/,
|
4871
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
4486
4872
|
*,
|
4487
4873
|
async_: Literal[False, True] = False,
|
4488
4874
|
**request_kwargs,
|
4489
4875
|
) -> dict | Coroutine[Any, Any, dict]:
|
4490
|
-
"""
|
4876
|
+
"""执行一次自动扫码,但并不因此更新 `self.token`
|
4491
4877
|
|
4492
|
-
|
4878
|
+
:param base_url: 接口的基地址
|
4879
|
+
:param async_: 是否异步
|
4880
|
+
:param request_kwargs: 其它请求参数
|
4881
|
+
|
4882
|
+
:return: 接口响应
|
4493
4883
|
"""
|
4494
|
-
|
4495
|
-
|
4496
|
-
|
4497
|
-
|
4498
|
-
|
4499
|
-
|
4884
|
+
def gen_step():
|
4885
|
+
resp = yield self.login_qrcode_generate(
|
4886
|
+
base_url=base_url,
|
4887
|
+
async_=async_,
|
4888
|
+
**request_kwargs,
|
4889
|
+
)
|
4890
|
+
check_response(resp)
|
4891
|
+
uniID = resp["data"]["uniID"]
|
4892
|
+
resp = yield self.login_qrcode_confirm(
|
4893
|
+
uniID,
|
4894
|
+
base_url=base_url,
|
4895
|
+
async_=async_,
|
4896
|
+
**request_kwargs,
|
4897
|
+
)
|
4898
|
+
check_response(resp)
|
4899
|
+
resp = yield self.login_qrcode_result(
|
4900
|
+
uniID,
|
4901
|
+
base_url=base_url,
|
4902
|
+
async_=async_,
|
4903
|
+
**request_kwargs,
|
4904
|
+
)
|
4905
|
+
return resp
|
4906
|
+
return run_gen_step(gen_step, async_)
|
4500
4907
|
|
4501
4908
|
@overload
|
4502
|
-
|
4503
|
-
|
4504
|
-
|
4909
|
+
@classmethod
|
4910
|
+
def login_with_qrcode(
|
4911
|
+
cls,
|
4505
4912
|
/,
|
4506
|
-
base_url: str | Callable[[], str] =
|
4913
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
4507
4914
|
*,
|
4508
4915
|
async_: Literal[False] = False,
|
4509
4916
|
**request_kwargs,
|
4510
4917
|
) -> dict:
|
4511
4918
|
...
|
4512
4919
|
@overload
|
4513
|
-
|
4514
|
-
|
4515
|
-
|
4920
|
+
@classmethod
|
4921
|
+
def login_with_qrcode(
|
4922
|
+
cls,
|
4516
4923
|
/,
|
4517
|
-
base_url: str | Callable[[], str] =
|
4924
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
4518
4925
|
*,
|
4519
4926
|
async_: Literal[True],
|
4520
4927
|
**request_kwargs,
|
4521
4928
|
) -> Coroutine[Any, Any, dict]:
|
4522
4929
|
...
|
4523
|
-
|
4524
|
-
|
4525
|
-
|
4930
|
+
@classmethod
|
4931
|
+
def login_with_qrcode(
|
4932
|
+
cls,
|
4526
4933
|
/,
|
4527
|
-
base_url: str | Callable[[], str] =
|
4934
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
4528
4935
|
*,
|
4529
4936
|
async_: Literal[False, True] = False,
|
4530
4937
|
**request_kwargs,
|
4531
4938
|
) -> dict | Coroutine[Any, Any, dict]:
|
4532
|
-
"""
|
4533
|
-
|
4534
|
-
POST https://www.123pan.com/api/file/download_info
|
4535
|
-
|
4536
|
-
.. hint::
|
4537
|
-
即使文件已经被删除,只要还有 S3KeyFlag 和 Etag (即 MD5) 就依然可以下载
|
4538
|
-
|
4539
|
-
你完全可以构造这样的查询参数
|
4540
|
-
|
4541
|
-
.. code:: python
|
4542
|
-
|
4543
|
-
payload = {
|
4544
|
-
"Etag": "...", # 必填,文件的 MD5
|
4545
|
-
"FileID": 0, # 可以随便填
|
4546
|
-
"FileName": "a", # 随便填一个名字
|
4547
|
-
"S3KeyFlag": str # 必填,格式为 f"{UID}-0",UID 就是上传此文件的用户的 UID,如果此文件是由你上传的,则可从 `P123Client.user_info` 的响应中获取
|
4548
|
-
"Size": 0, # 可以随便填,填了可能搜索更准确
|
4549
|
-
}
|
4939
|
+
"""二维码扫码登录
|
4550
4940
|
|
4551
|
-
|
4552
|
-
|
4941
|
+
:param base_url: 接口的基地址
|
4942
|
+
:param async_: 是否异步
|
4943
|
+
:param request_kwargs: 其它请求参数
|
4553
4944
|
|
4554
|
-
:
|
4555
|
-
- Etag: str 💡 文件的 MD5 散列值
|
4556
|
-
- S3KeyFlag: str
|
4557
|
-
- FileName: str = <default> 💡 默认用 Etag(即 MD5)作为文件名
|
4558
|
-
- FileID: int | str = 0
|
4559
|
-
- Size: int = <default>
|
4560
|
-
- Type: int = 0
|
4561
|
-
- driveId: int | str = 0
|
4562
|
-
- ...
|
4945
|
+
:return: 接口响应
|
4563
4946
|
"""
|
4564
4947
|
def gen_step():
|
4565
|
-
|
4566
|
-
|
4567
|
-
|
4568
|
-
|
4569
|
-
|
4948
|
+
resp = yield cls.login_qrcode_generate(
|
4949
|
+
base_url=base_url,
|
4950
|
+
async_=async_,
|
4951
|
+
**request_kwargs,
|
4952
|
+
)
|
4953
|
+
check_response(resp)
|
4954
|
+
uniID = resp["data"]["uniID"]
|
4955
|
+
qrcode_url = f"{resp['data']['url']}?env=production&uniID={uniID}&source=123pan&type=login"
|
4956
|
+
from qrcode import QRCode # type: ignore
|
4957
|
+
qr = QRCode(border=1)
|
4958
|
+
qr.add_data(qrcode_url)
|
4959
|
+
qr.print_ascii(tty=isatty(1))
|
4960
|
+
while True:
|
4961
|
+
resp = yield cls.login_qrcode_result(
|
4962
|
+
uniID,
|
4570
4963
|
base_url=base_url,
|
4571
4964
|
async_=async_,
|
4572
4965
|
**request_kwargs,
|
4573
4966
|
)
|
4574
|
-
resp["payload"] = payload
|
4575
4967
|
check_response(resp)
|
4576
|
-
if
|
4577
|
-
|
4578
|
-
|
4579
|
-
|
4580
|
-
|
4581
|
-
|
4582
|
-
|
4583
|
-
|
4584
|
-
|
4585
|
-
|
4586
|
-
|
4587
|
-
|
4588
|
-
|
4589
|
-
|
4590
|
-
|
4591
|
-
|
4592
|
-
|
4968
|
+
if resp["code"] == 200:
|
4969
|
+
return resp
|
4970
|
+
match resp["data"]["loginStatus"]:
|
4971
|
+
case 0:
|
4972
|
+
print("\r\033[1K[loginStatus=0] qrcode: waiting", end="")
|
4973
|
+
case 1:
|
4974
|
+
print("\r\033[1K[loginStatus=1] qrcode: scanned", end="")
|
4975
|
+
case 2:
|
4976
|
+
print("\r\033[1K[loginStatus=2] qrcode: cancelled", end="")
|
4977
|
+
raise P123LoginError(EAUTH, f"qrcode: cancelled with {resp!r}")
|
4978
|
+
case 3:
|
4979
|
+
print("\r\033[1K[loginStatus=3] qrcode: login", end="")
|
4980
|
+
case 4:
|
4981
|
+
print("\r\033[1K[loginStatus=4] qrcode: expired", end="")
|
4982
|
+
raise P123LoginError(EAUTH, f"qrcode: expired with {resp!r}")
|
4983
|
+
case _:
|
4984
|
+
raise P123LoginError(EAUTH, f"qrcode: aborted with {resp!r}")
|
4593
4985
|
return run_gen_step(gen_step, async_)
|
4594
4986
|
|
4987
|
+
########## App API ##########
|
4988
|
+
|
4595
4989
|
@overload
|
4596
|
-
def
|
4990
|
+
def app_config(
|
4597
4991
|
self,
|
4598
|
-
payload: dict |
|
4992
|
+
payload: dict | str = "OfflineDownload",
|
4599
4993
|
/,
|
4600
4994
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4601
4995
|
*,
|
@@ -4604,9 +4998,9 @@ class P123Client(P123OpenClient):
|
|
4604
4998
|
) -> dict:
|
4605
4999
|
...
|
4606
5000
|
@overload
|
4607
|
-
def
|
5001
|
+
def app_config(
|
4608
5002
|
self,
|
4609
|
-
payload: dict |
|
5003
|
+
payload: dict | str = "OfflineDownload",
|
4610
5004
|
/,
|
4611
5005
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4612
5006
|
*,
|
@@ -4614,37 +5008,26 @@ class P123Client(P123OpenClient):
|
|
4614
5008
|
**request_kwargs,
|
4615
5009
|
) -> Coroutine[Any, Any, dict]:
|
4616
5010
|
...
|
4617
|
-
def
|
5011
|
+
def app_config(
|
4618
5012
|
self,
|
4619
|
-
payload: dict |
|
5013
|
+
payload: dict | str = "OfflineDownload",
|
4620
5014
|
/,
|
4621
5015
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4622
5016
|
*,
|
4623
5017
|
async_: Literal[False, True] = False,
|
4624
5018
|
**request_kwargs,
|
4625
5019
|
) -> dict | Coroutine[Any, Any, dict]:
|
4626
|
-
"""
|
4627
|
-
|
4628
|
-
POST https://www.123pan.com/api/file/batch_download_info
|
5020
|
+
"""获取配置信息
|
4629
5021
|
|
4630
|
-
|
4631
|
-
会把一些文件或目录以 zip 包的形式下载,但非会员有流量限制,所以还是推荐用 `P123Client.download_info` 逐个获取下载链接并下载
|
5022
|
+
POST https://www.123pan.com/api/config/get
|
4632
5023
|
|
4633
5024
|
:payload:
|
4634
|
-
-
|
4635
|
-
|
4636
|
-
.. code:: python
|
4637
|
-
|
4638
|
-
FileID = {
|
4639
|
-
"FileId": int | str
|
4640
|
-
}
|
5025
|
+
- business_key: str 💡 配置键名(字段)
|
4641
5026
|
"""
|
4642
|
-
if isinstance(payload,
|
4643
|
-
payload = {"
|
4644
|
-
elif not isinstance(payload, dict):
|
4645
|
-
payload = {"fileIdList": [{"FileId": fid} for fid in payload]}
|
5027
|
+
if not isinstance(payload, dict):
|
5028
|
+
payload = {"business_key": payload}
|
4646
5029
|
return self.request(
|
4647
|
-
"
|
5030
|
+
"config/get",
|
4648
5031
|
"POST",
|
4649
5032
|
json=payload,
|
4650
5033
|
base_url=base_url,
|
@@ -4653,63 +5036,531 @@ class P123Client(P123OpenClient):
|
|
4653
5036
|
)
|
4654
5037
|
|
4655
5038
|
@overload
|
4656
|
-
|
4657
|
-
|
4658
|
-
|
4659
|
-
|
5039
|
+
@staticmethod
|
5040
|
+
def app_dydomain(
|
5041
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5042
|
+
request: None | Callable = None,
|
4660
5043
|
*,
|
4661
5044
|
async_: Literal[False] = False,
|
4662
5045
|
**request_kwargs,
|
4663
|
-
) ->
|
5046
|
+
) -> dict:
|
4664
5047
|
...
|
4665
5048
|
@overload
|
4666
|
-
|
4667
|
-
|
4668
|
-
|
4669
|
-
|
5049
|
+
@staticmethod
|
5050
|
+
def app_dydomain(
|
5051
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5052
|
+
request: None | Callable = None,
|
4670
5053
|
*,
|
4671
5054
|
async_: Literal[True],
|
4672
5055
|
**request_kwargs,
|
4673
|
-
) -> Coroutine[Any, Any,
|
5056
|
+
) -> Coroutine[Any, Any, dict]:
|
4674
5057
|
...
|
4675
|
-
|
4676
|
-
|
4677
|
-
|
4678
|
-
|
5058
|
+
@staticmethod
|
5059
|
+
def app_dydomain(
|
5060
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5061
|
+
request: None | Callable = None,
|
4679
5062
|
*,
|
4680
5063
|
async_: Literal[False, True] = False,
|
4681
5064
|
**request_kwargs,
|
4682
|
-
) ->
|
4683
|
-
"""
|
4684
|
-
|
4685
|
-
.. note::
|
4686
|
-
`payload` 支持多种格式的输入,按下面的规则按顺序进行判断:
|
4687
|
-
|
4688
|
-
1. 如果是 `int` 或 `str`,则视为文件 id,必须在你的网盘中存在此文件
|
4689
|
-
2. 如果是 `dict`(不区分大小写),有 "S3KeyFlag", "Etag" 和 "Size" 的值,则直接获取链接,文件不必在你网盘中
|
4690
|
-
3. 如果是 `dict`(不区分大小写),有 "Etag" 和 "Size" 的值,则会先秒传(临时文件路径为 /.tempfile)再获取链接,文件不必在你网盘中
|
4691
|
-
4. 如果是 `dict`(不区分大小写),有 "FileID",则会先获取信息,再获取链接,必须在你的网盘中存在此文件
|
4692
|
-
5. 否则会报错 ValueError
|
4693
|
-
|
4694
|
-
:params payload: 文件 id 或者文件信息,文件信息必须包含的信息如下:
|
5065
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
5066
|
+
"""获取 123 网盘的各种域名
|
4695
5067
|
|
4696
|
-
|
4697
|
-
|
4698
|
-
|
4699
|
-
|
4700
|
-
|
5068
|
+
GET https://www.123pan.com/api/dydomain
|
5069
|
+
"""
|
5070
|
+
request_kwargs.setdefault("parse", default_parse)
|
5071
|
+
if request is None:
|
5072
|
+
request = get_default_request()
|
5073
|
+
request_kwargs["async_"] = async_
|
5074
|
+
return request(
|
5075
|
+
url=complete_url("/api/dydomain", base_url),
|
5076
|
+
**request_kwargs,
|
5077
|
+
)
|
4701
5078
|
|
4702
|
-
|
4703
|
-
|
5079
|
+
@overload
|
5080
|
+
@staticmethod
|
5081
|
+
def app_id_get(
|
5082
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5083
|
+
request: None | Callable = None,
|
5084
|
+
*,
|
5085
|
+
async_: Literal[False] = False,
|
5086
|
+
**request_kwargs,
|
5087
|
+
) -> dict:
|
5088
|
+
...
|
5089
|
+
@overload
|
5090
|
+
@staticmethod
|
5091
|
+
def app_id_get(
|
5092
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5093
|
+
request: None | Callable = None,
|
5094
|
+
*,
|
5095
|
+
async_: Literal[True],
|
5096
|
+
**request_kwargs,
|
5097
|
+
) -> Coroutine[Any, Any, dict]:
|
5098
|
+
...
|
5099
|
+
@staticmethod
|
5100
|
+
def app_id_get(
|
5101
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5102
|
+
request: None | Callable = None,
|
5103
|
+
*,
|
5104
|
+
async_: Literal[False, True] = False,
|
5105
|
+
**request_kwargs,
|
5106
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
5107
|
+
"""获取 app-id
|
4704
5108
|
|
4705
|
-
|
5109
|
+
GET https://www.123pan.com/api/v3/3rd/app-id
|
4706
5110
|
"""
|
4707
|
-
|
4708
|
-
|
4709
|
-
|
4710
|
-
|
4711
|
-
|
4712
|
-
|
5111
|
+
request_kwargs.setdefault("parse", default_parse)
|
5112
|
+
if request is None:
|
5113
|
+
request = get_default_request()
|
5114
|
+
request_kwargs["async_"] = async_
|
5115
|
+
return request(
|
5116
|
+
url=complete_url("/api/v3/3rd/app-id", base_url),
|
5117
|
+
**request_kwargs,
|
5118
|
+
)
|
5119
|
+
|
5120
|
+
@overload
|
5121
|
+
@staticmethod
|
5122
|
+
def app_server_time(
|
5123
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5124
|
+
request: None | Callable = None,
|
5125
|
+
*,
|
5126
|
+
async_: Literal[False] = False,
|
5127
|
+
**request_kwargs,
|
5128
|
+
) -> dict:
|
5129
|
+
...
|
5130
|
+
@overload
|
5131
|
+
@staticmethod
|
5132
|
+
def app_server_time(
|
5133
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5134
|
+
request: None | Callable = None,
|
5135
|
+
*,
|
5136
|
+
async_: Literal[True],
|
5137
|
+
**request_kwargs,
|
5138
|
+
) -> Coroutine[Any, Any, dict]:
|
5139
|
+
...
|
5140
|
+
@staticmethod
|
5141
|
+
def app_server_time(
|
5142
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5143
|
+
request: None | Callable = None,
|
5144
|
+
*,
|
5145
|
+
async_: Literal[False, True] = False,
|
5146
|
+
**request_kwargs,
|
5147
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
5148
|
+
"""获取 123 网盘的服务器时间戳
|
5149
|
+
|
5150
|
+
GET https://www.123pan.com/api/get/server/time
|
5151
|
+
"""
|
5152
|
+
request_kwargs.setdefault("parse", default_parse)
|
5153
|
+
if request is None:
|
5154
|
+
request = get_default_request()
|
5155
|
+
request_kwargs["async_"] = async_
|
5156
|
+
return request(
|
5157
|
+
url=complete_url("/api/get/server/time", base_url),
|
5158
|
+
**request_kwargs,
|
5159
|
+
)
|
5160
|
+
|
5161
|
+
@overload
|
5162
|
+
@staticmethod
|
5163
|
+
def app_transfer_metrics(
|
5164
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5165
|
+
request: None | Callable = None,
|
5166
|
+
*,
|
5167
|
+
async_: Literal[False] = False,
|
5168
|
+
**request_kwargs,
|
5169
|
+
) -> dict:
|
5170
|
+
...
|
5171
|
+
@overload
|
5172
|
+
@staticmethod
|
5173
|
+
def app_transfer_metrics(
|
5174
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5175
|
+
request: None | Callable = None,
|
5176
|
+
*,
|
5177
|
+
async_: Literal[True],
|
5178
|
+
**request_kwargs,
|
5179
|
+
) -> Coroutine[Any, Any, dict]:
|
5180
|
+
...
|
5181
|
+
@staticmethod
|
5182
|
+
def app_transfer_metrics(
|
5183
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5184
|
+
request: None | Callable = None,
|
5185
|
+
*,
|
5186
|
+
async_: Literal[False, True] = False,
|
5187
|
+
**request_kwargs,
|
5188
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
5189
|
+
"""获取和传输有关的配置信息
|
5190
|
+
|
5191
|
+
GET https://www.123pan.com/api/transfer/metrics/whether/report
|
5192
|
+
"""
|
5193
|
+
request_kwargs.setdefault("parse", default_parse)
|
5194
|
+
if request is None:
|
5195
|
+
request = get_default_request()
|
5196
|
+
request_kwargs["async_"] = async_
|
5197
|
+
return request(
|
5198
|
+
url=complete_url("/api/transfer/metrics/whether/report", base_url),
|
5199
|
+
**request_kwargs,
|
5200
|
+
)
|
5201
|
+
|
5202
|
+
########## Download API ##########
|
5203
|
+
|
5204
|
+
@overload
|
5205
|
+
def dlink_disable(
|
5206
|
+
self,
|
5207
|
+
payload: dict | int | str,
|
5208
|
+
/,
|
5209
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5210
|
+
*,
|
5211
|
+
async_: Literal[False] = False,
|
5212
|
+
**request_kwargs,
|
5213
|
+
) -> dict:
|
5214
|
+
...
|
5215
|
+
@overload
|
5216
|
+
def dlink_disable(
|
5217
|
+
self,
|
5218
|
+
payload: dict | int | str,
|
5219
|
+
/,
|
5220
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5221
|
+
*,
|
5222
|
+
async_: Literal[True],
|
5223
|
+
**request_kwargs,
|
5224
|
+
) -> Coroutine[Any, Any, dict]:
|
5225
|
+
...
|
5226
|
+
def dlink_disable(
|
5227
|
+
self,
|
5228
|
+
payload: dict | int | str,
|
5229
|
+
/,
|
5230
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5231
|
+
*,
|
5232
|
+
async_: Literal[False, True] = False,
|
5233
|
+
**request_kwargs,
|
5234
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
5235
|
+
"""禁用直链空间
|
5236
|
+
|
5237
|
+
POST https://www.123pan.com/api/cdn-link/disable
|
5238
|
+
|
5239
|
+
:payload:
|
5240
|
+
- fileID: int | str 💡 目录 id
|
5241
|
+
"""
|
5242
|
+
if not isinstance(payload, dict):
|
5243
|
+
payload = {"fileID": payload}
|
5244
|
+
return self.request(
|
5245
|
+
"cdn-link/disable",
|
5246
|
+
"POST",
|
5247
|
+
json=payload,
|
5248
|
+
base_url=base_url,
|
5249
|
+
async_=async_,
|
5250
|
+
**request_kwargs,
|
5251
|
+
)
|
5252
|
+
|
5253
|
+
@overload
|
5254
|
+
def dlink_enable(
|
5255
|
+
self,
|
5256
|
+
payload: dict | int | str,
|
5257
|
+
/,
|
5258
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5259
|
+
*,
|
5260
|
+
async_: Literal[False] = False,
|
5261
|
+
**request_kwargs,
|
5262
|
+
) -> dict:
|
5263
|
+
...
|
5264
|
+
@overload
|
5265
|
+
def dlink_enable(
|
5266
|
+
self,
|
5267
|
+
payload: dict | int | str,
|
5268
|
+
/,
|
5269
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5270
|
+
*,
|
5271
|
+
async_: Literal[True],
|
5272
|
+
**request_kwargs,
|
5273
|
+
) -> Coroutine[Any, Any, dict]:
|
5274
|
+
...
|
5275
|
+
def dlink_enable(
|
5276
|
+
self,
|
5277
|
+
payload: dict | int | str,
|
5278
|
+
/,
|
5279
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5280
|
+
*,
|
5281
|
+
async_: Literal[False, True] = False,
|
5282
|
+
**request_kwargs,
|
5283
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
5284
|
+
"""启用直链空间
|
5285
|
+
|
5286
|
+
POST https://www.123pan.com/api/cdn-link/enable
|
5287
|
+
|
5288
|
+
:payload:
|
5289
|
+
- fileID: int | str 💡 目录 id
|
5290
|
+
"""
|
5291
|
+
if not isinstance(payload, dict):
|
5292
|
+
payload = {"fileID": payload}
|
5293
|
+
return self.request(
|
5294
|
+
"cdn-link/enable",
|
5295
|
+
"POST",
|
5296
|
+
json=payload,
|
5297
|
+
base_url=base_url,
|
5298
|
+
async_=async_,
|
5299
|
+
**request_kwargs,
|
5300
|
+
)
|
5301
|
+
|
5302
|
+
@overload
|
5303
|
+
def dlink_url(
|
5304
|
+
self,
|
5305
|
+
payload: dict | int | str,
|
5306
|
+
/,
|
5307
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5308
|
+
*,
|
5309
|
+
async_: Literal[False] = False,
|
5310
|
+
**request_kwargs,
|
5311
|
+
) -> dict:
|
5312
|
+
...
|
5313
|
+
@overload
|
5314
|
+
def dlink_url(
|
5315
|
+
self,
|
5316
|
+
payload: dict | int | str,
|
5317
|
+
/,
|
5318
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5319
|
+
*,
|
5320
|
+
async_: Literal[True],
|
5321
|
+
**request_kwargs,
|
5322
|
+
) -> Coroutine[Any, Any, dict]:
|
5323
|
+
...
|
5324
|
+
def dlink_url(
|
5325
|
+
self,
|
5326
|
+
payload: dict | int | str,
|
5327
|
+
/,
|
5328
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5329
|
+
*,
|
5330
|
+
async_: Literal[False, True] = False,
|
5331
|
+
**request_kwargs,
|
5332
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
5333
|
+
"""获取直链链接
|
5334
|
+
|
5335
|
+
GET https://www.123pan.com/api/cdn-link/url
|
5336
|
+
|
5337
|
+
:payload:
|
5338
|
+
- fileID: int | str 💡 文件 id
|
5339
|
+
"""
|
5340
|
+
if not isinstance(payload, dict):
|
5341
|
+
payload = {"fileID": payload}
|
5342
|
+
return self.request(
|
5343
|
+
"cdn-link/url",
|
5344
|
+
params=payload,
|
5345
|
+
base_url=base_url,
|
5346
|
+
async_=async_,
|
5347
|
+
**request_kwargs,
|
5348
|
+
)
|
5349
|
+
|
5350
|
+
########## Download API ##########
|
5351
|
+
|
5352
|
+
@overload
|
5353
|
+
def download_info(
|
5354
|
+
self,
|
5355
|
+
payload: dict | int | str,
|
5356
|
+
/,
|
5357
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5358
|
+
*,
|
5359
|
+
async_: Literal[False] = False,
|
5360
|
+
**request_kwargs,
|
5361
|
+
) -> dict:
|
5362
|
+
...
|
5363
|
+
@overload
|
5364
|
+
def download_info(
|
5365
|
+
self,
|
5366
|
+
payload: dict | int | str,
|
5367
|
+
/,
|
5368
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5369
|
+
*,
|
5370
|
+
async_: Literal[True],
|
5371
|
+
**request_kwargs,
|
5372
|
+
) -> Coroutine[Any, Any, dict]:
|
5373
|
+
...
|
5374
|
+
def download_info(
|
5375
|
+
self,
|
5376
|
+
payload: dict | int | str,
|
5377
|
+
/,
|
5378
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5379
|
+
*,
|
5380
|
+
async_: Literal[False, True] = False,
|
5381
|
+
**request_kwargs,
|
5382
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
5383
|
+
"""获取下载信息
|
5384
|
+
|
5385
|
+
POST https://www.123pan.com/api/file/download_info
|
5386
|
+
|
5387
|
+
.. hint::
|
5388
|
+
即使文件已经被删除,只要还有 S3KeyFlag 和 Etag (即 MD5) 就依然可以下载
|
5389
|
+
|
5390
|
+
你完全可以构造这样的查询参数
|
5391
|
+
|
5392
|
+
.. code:: python
|
5393
|
+
|
5394
|
+
payload = {
|
5395
|
+
"Etag": "...", # 必填,文件的 MD5
|
5396
|
+
"FileID": 0, # 可以随便填
|
5397
|
+
"FileName": "a", # 随便填一个名字
|
5398
|
+
"S3KeyFlag": str # 必填,格式为 f"{UID}-0",UID 就是上传此文件的用户的 UID,如果此文件是由你上传的,则可从 `P123Client.user_info` 的响应中获取
|
5399
|
+
"Size": 0, # 可以随便填,填了可能搜索更准确
|
5400
|
+
}
|
5401
|
+
|
5402
|
+
.. note::
|
5403
|
+
获取的直链有效期是 24 小时
|
5404
|
+
|
5405
|
+
:payload:
|
5406
|
+
- Etag: str 💡 文件的 MD5 散列值
|
5407
|
+
- S3KeyFlag: str
|
5408
|
+
- FileName: str = <default> 💡 默认用 Etag(即 MD5)作为文件名
|
5409
|
+
- FileID: int | str = 0
|
5410
|
+
- Size: int = <default>
|
5411
|
+
- Type: int = 0
|
5412
|
+
- driveId: int | str = 0
|
5413
|
+
- ...
|
5414
|
+
"""
|
5415
|
+
def gen_step():
|
5416
|
+
nonlocal payload
|
5417
|
+
update_headers_in_kwargs(request_kwargs, platform="android")
|
5418
|
+
if not isinstance(payload, dict):
|
5419
|
+
resp = yield self.fs_info(
|
5420
|
+
payload,
|
5421
|
+
base_url=base_url,
|
5422
|
+
async_=async_,
|
5423
|
+
**request_kwargs,
|
5424
|
+
)
|
5425
|
+
resp["payload"] = payload
|
5426
|
+
check_response(resp)
|
5427
|
+
if not (info_list := resp["data"]["infoList"]):
|
5428
|
+
raise FileNotFoundError(ENOENT, resp)
|
5429
|
+
payload = cast(dict, info_list[0])
|
5430
|
+
if payload["Type"]:
|
5431
|
+
raise IsADirectoryError(EISDIR, resp)
|
5432
|
+
payload = dict_to_lower_merge(
|
5433
|
+
payload, {"driveId": 0, "Type": 0, "FileID": 0})
|
5434
|
+
if "filename" not in payload:
|
5435
|
+
payload["filename"] = payload["etag"]
|
5436
|
+
return self.request(
|
5437
|
+
"file/download_info",
|
5438
|
+
"POST",
|
5439
|
+
json=payload,
|
5440
|
+
base_url=base_url,
|
5441
|
+
async_=async_,
|
5442
|
+
**request_kwargs,
|
5443
|
+
)
|
5444
|
+
return run_gen_step(gen_step, async_)
|
5445
|
+
|
5446
|
+
@overload
|
5447
|
+
def download_info_batch(
|
5448
|
+
self,
|
5449
|
+
payload: dict | int | str | Iterable[int | str],
|
5450
|
+
/,
|
5451
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5452
|
+
*,
|
5453
|
+
async_: Literal[False] = False,
|
5454
|
+
**request_kwargs,
|
5455
|
+
) -> dict:
|
5456
|
+
...
|
5457
|
+
@overload
|
5458
|
+
def download_info_batch(
|
5459
|
+
self,
|
5460
|
+
payload: dict | int | str | Iterable[int | str],
|
5461
|
+
/,
|
5462
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5463
|
+
*,
|
5464
|
+
async_: Literal[True],
|
5465
|
+
**request_kwargs,
|
5466
|
+
) -> Coroutine[Any, Any, dict]:
|
5467
|
+
...
|
5468
|
+
def download_info_batch(
|
5469
|
+
self,
|
5470
|
+
payload: dict | int | str | Iterable[int | str],
|
5471
|
+
/,
|
5472
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5473
|
+
*,
|
5474
|
+
async_: Literal[False, True] = False,
|
5475
|
+
**request_kwargs,
|
5476
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
5477
|
+
"""获取批量下载信息
|
5478
|
+
|
5479
|
+
POST https://www.123pan.com/api/file/batch_download_info
|
5480
|
+
|
5481
|
+
.. warning::
|
5482
|
+
会把一些文件或目录以 zip 包的形式下载,但非会员有流量限制,所以还是推荐用 `P123Client.download_info` 逐个获取下载链接并下载
|
5483
|
+
|
5484
|
+
:payload:
|
5485
|
+
- fileIdList: list[FileID]
|
5486
|
+
|
5487
|
+
.. code:: python
|
5488
|
+
|
5489
|
+
FileID = {
|
5490
|
+
"FileId": int | str
|
5491
|
+
}
|
5492
|
+
"""
|
5493
|
+
if isinstance(payload, (int, str)):
|
5494
|
+
payload = {"fileIdList": [{"FileId": payload}]}
|
5495
|
+
elif not isinstance(payload, dict):
|
5496
|
+
payload = {"fileIdList": [{"FileId": fid} for fid in payload]}
|
5497
|
+
return self.request(
|
5498
|
+
"file/batch_download_info",
|
5499
|
+
"POST",
|
5500
|
+
json=payload,
|
5501
|
+
base_url=base_url,
|
5502
|
+
async_=async_,
|
5503
|
+
**request_kwargs,
|
5504
|
+
)
|
5505
|
+
|
5506
|
+
@overload
|
5507
|
+
def download_url(
|
5508
|
+
self,
|
5509
|
+
payload: dict | int | str,
|
5510
|
+
/,
|
5511
|
+
*,
|
5512
|
+
async_: Literal[False] = False,
|
5513
|
+
**request_kwargs,
|
5514
|
+
) -> str:
|
5515
|
+
...
|
5516
|
+
@overload
|
5517
|
+
def download_url(
|
5518
|
+
self,
|
5519
|
+
payload: dict | int | str,
|
5520
|
+
/,
|
5521
|
+
*,
|
5522
|
+
async_: Literal[True],
|
5523
|
+
**request_kwargs,
|
5524
|
+
) -> Coroutine[Any, Any, str]:
|
5525
|
+
...
|
5526
|
+
def download_url(
|
5527
|
+
self,
|
5528
|
+
payload: dict | int | str,
|
5529
|
+
/,
|
5530
|
+
*,
|
5531
|
+
async_: Literal[False, True] = False,
|
5532
|
+
**request_kwargs,
|
5533
|
+
) -> str | Coroutine[Any, Any, str]:
|
5534
|
+
"""获取下载链接
|
5535
|
+
|
5536
|
+
.. note::
|
5537
|
+
`payload` 支持多种格式的输入,按下面的规则按顺序进行判断:
|
5538
|
+
|
5539
|
+
1. 如果是 `int` 或 `str`,则视为文件 id,必须在你的网盘中存在此文件
|
5540
|
+
2. 如果是 `dict`(不区分大小写),有 "S3KeyFlag", "Etag" 和 "Size" 的值,则直接获取链接,文件不必在你网盘中
|
5541
|
+
3. 如果是 `dict`(不区分大小写),有 "Etag" 和 "Size" 的值,则会先秒传(临时文件路径为 /.tempfile)再获取链接,文件不必在你网盘中
|
5542
|
+
4. 如果是 `dict`(不区分大小写),有 "FileID",则会先获取信息,再获取链接,必须在你的网盘中存在此文件
|
5543
|
+
5. 否则会报错 ValueError
|
5544
|
+
|
5545
|
+
:params payload: 文件 id 或者文件信息,文件信息必须包含的信息如下:
|
5546
|
+
|
5547
|
+
- FileID: int | str 💡 下载链接
|
5548
|
+
- S3KeyFlag: str 💡 s3 存储名
|
5549
|
+
- Etag: str 💡 文件的 MD5 散列值
|
5550
|
+
- Size: int 💡 文件大小
|
5551
|
+
- FileName: str 💡 默认用 Etag(即 MD5)作为文件名,可以省略
|
5552
|
+
|
5553
|
+
:params async_: 是否异步
|
5554
|
+
:params request_kwargs: 其它请求参数
|
5555
|
+
|
5556
|
+
:return: 下载链接
|
5557
|
+
"""
|
5558
|
+
def gen_step():
|
5559
|
+
nonlocal payload
|
5560
|
+
if isinstance(payload, dict):
|
5561
|
+
payload = dict_to_lower(payload)
|
5562
|
+
if not ("size" in payload and "etag" in payload):
|
5563
|
+
if fileid := payload.get("fileid"):
|
4713
5564
|
resp = yield self.fs_info(fileid, async_=async_, **request_kwargs)
|
4714
5565
|
check_response(resp)
|
4715
5566
|
if not (info_list := resp["data"]["infoList"]):
|
@@ -4750,15 +5601,948 @@ class P123Client(P123OpenClient):
|
|
4750
5601
|
**request_kwargs,
|
4751
5602
|
)
|
4752
5603
|
check_response(resp)
|
4753
|
-
return resp["data"]["downloadUrl"]
|
5604
|
+
return resp["data"]["downloadUrl"]
|
5605
|
+
return run_gen_step(gen_step, async_)
|
5606
|
+
|
5607
|
+
########## File System API ##########
|
5608
|
+
|
5609
|
+
@overload
|
5610
|
+
def fs_abnormal_count(
|
5611
|
+
self,
|
5612
|
+
/,
|
5613
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5614
|
+
*,
|
5615
|
+
async_: Literal[False] = False,
|
5616
|
+
**request_kwargs,
|
5617
|
+
) -> dict:
|
5618
|
+
...
|
5619
|
+
@overload
|
5620
|
+
def fs_abnormal_count(
|
5621
|
+
self,
|
5622
|
+
/,
|
5623
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5624
|
+
*,
|
5625
|
+
async_: Literal[True],
|
5626
|
+
**request_kwargs,
|
5627
|
+
) -> Coroutine[Any, Any, dict]:
|
5628
|
+
...
|
5629
|
+
def fs_abnormal_count(
|
5630
|
+
self,
|
5631
|
+
/,
|
5632
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5633
|
+
*,
|
5634
|
+
async_: Literal[False, True] = False,
|
5635
|
+
**request_kwargs,
|
5636
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
5637
|
+
"""获取异常文件数
|
5638
|
+
|
5639
|
+
GET https://www.123pan.com/b/api/file/abnormal/count
|
5640
|
+
"""
|
5641
|
+
return self.request(
|
5642
|
+
"file/abnormal/count",
|
5643
|
+
base_url=base_url,
|
5644
|
+
async_=async_,
|
5645
|
+
**request_kwargs,
|
5646
|
+
)
|
5647
|
+
|
5648
|
+
@overload
|
5649
|
+
def fs_copy(
|
5650
|
+
self,
|
5651
|
+
payload: dict | int | str | Iterable[int | str],
|
5652
|
+
/,
|
5653
|
+
parent_id: int | str = 0,
|
5654
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5655
|
+
*,
|
5656
|
+
async_: Literal[False] = False,
|
5657
|
+
**request_kwargs,
|
5658
|
+
) -> dict:
|
5659
|
+
...
|
5660
|
+
@overload
|
5661
|
+
def fs_copy(
|
5662
|
+
self,
|
5663
|
+
payload: dict | int | str | Iterable[int | str],
|
5664
|
+
/,
|
5665
|
+
parent_id: int | str = 0,
|
5666
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5667
|
+
*,
|
5668
|
+
async_: Literal[True],
|
5669
|
+
**request_kwargs,
|
5670
|
+
) -> Coroutine[Any, Any, dict]:
|
5671
|
+
...
|
5672
|
+
def fs_copy(
|
5673
|
+
self,
|
5674
|
+
payload: dict | int | str | Iterable[int | str],
|
5675
|
+
/,
|
5676
|
+
parent_id: int | str = 0,
|
5677
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5678
|
+
*,
|
5679
|
+
async_: Literal[False, True] = False,
|
5680
|
+
**request_kwargs,
|
5681
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
5682
|
+
"""复制
|
5683
|
+
|
5684
|
+
POST https://www.123pan.com/api/restful/goapi/v1/file/copy/async
|
5685
|
+
|
5686
|
+
:payload:
|
5687
|
+
- fileList: list[File] 💡 信息可以取自 `P123Client.fs_info` 接口
|
5688
|
+
|
5689
|
+
.. code:: python
|
5690
|
+
|
5691
|
+
File = {
|
5692
|
+
"FileId": int | str,
|
5693
|
+
...
|
5694
|
+
}
|
5695
|
+
|
5696
|
+
- targetFileId: int | str = 0
|
5697
|
+
"""
|
5698
|
+
def gen_step():
|
5699
|
+
nonlocal payload
|
5700
|
+
if not isinstance(payload, dict):
|
5701
|
+
resp = yield self.fs_info(
|
5702
|
+
payload,
|
5703
|
+
base_url=base_url,
|
5704
|
+
async_=async_,
|
5705
|
+
**request_kwargs,
|
5706
|
+
)
|
5707
|
+
resp["payload"] = payload
|
5708
|
+
check_response(resp)
|
5709
|
+
info_list = resp["data"]["infoList"]
|
5710
|
+
if not info_list:
|
5711
|
+
raise FileNotFoundError(ENOENT, resp)
|
5712
|
+
payload = {"fileList": info_list}
|
5713
|
+
payload = dict_to_lower_merge(payload, targetFileId=parent_id)
|
5714
|
+
return self.request(
|
5715
|
+
"restful/goapi/v1/file/copy/async",
|
5716
|
+
"POST",
|
5717
|
+
json=payload,
|
5718
|
+
base_url=base_url,
|
5719
|
+
async_=async_,
|
5720
|
+
**request_kwargs,
|
5721
|
+
)
|
4754
5722
|
return run_gen_step(gen_step, async_)
|
4755
5723
|
|
4756
5724
|
@overload
|
4757
|
-
def
|
5725
|
+
def fs_detail(
|
5726
|
+
self,
|
5727
|
+
payload: dict | int | str,
|
5728
|
+
/,
|
5729
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5730
|
+
*,
|
5731
|
+
async_: Literal[False] = False,
|
5732
|
+
**request_kwargs,
|
5733
|
+
) -> dict:
|
5734
|
+
...
|
5735
|
+
@overload
|
5736
|
+
def fs_detail(
|
5737
|
+
self,
|
5738
|
+
payload: dict | int | str,
|
5739
|
+
/,
|
5740
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5741
|
+
*,
|
5742
|
+
async_: Literal[True],
|
5743
|
+
**request_kwargs,
|
5744
|
+
) -> Coroutine[Any, Any, dict]:
|
5745
|
+
...
|
5746
|
+
def fs_detail(
|
5747
|
+
self,
|
5748
|
+
payload: dict | int | str,
|
5749
|
+
/,
|
5750
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5751
|
+
*,
|
5752
|
+
async_: Literal[False, True] = False,
|
5753
|
+
**request_kwargs,
|
5754
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
5755
|
+
"""获取文件或目录详情(文件数、目录数、总大小)
|
5756
|
+
|
5757
|
+
GET https://www.123pan.com/api/file/detail
|
5758
|
+
|
5759
|
+
:payload:
|
5760
|
+
- fileID: int | str
|
5761
|
+
"""
|
5762
|
+
if isinstance(payload, (int, str)):
|
5763
|
+
payload = {"fileID": payload}
|
5764
|
+
return self.request(
|
5765
|
+
"file/detail",
|
5766
|
+
params=payload,
|
5767
|
+
base_url=base_url,
|
5768
|
+
async_=async_,
|
5769
|
+
**request_kwargs,
|
5770
|
+
)
|
5771
|
+
|
5772
|
+
@overload
|
5773
|
+
def fs_delete(
|
5774
|
+
self,
|
5775
|
+
payload: dict | int | str | Iterable[int | str] = 0,
|
5776
|
+
/,
|
5777
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5778
|
+
*,
|
5779
|
+
async_: Literal[False] = False,
|
5780
|
+
**request_kwargs,
|
5781
|
+
) -> dict:
|
5782
|
+
...
|
5783
|
+
@overload
|
5784
|
+
def fs_delete(
|
5785
|
+
self,
|
5786
|
+
payload: dict | int | str | Iterable[int | str] = 0,
|
5787
|
+
/,
|
5788
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5789
|
+
*,
|
5790
|
+
async_: Literal[True],
|
5791
|
+
**request_kwargs,
|
5792
|
+
) -> Coroutine[Any, Any, dict]:
|
5793
|
+
...
|
5794
|
+
def fs_delete(
|
5795
|
+
self,
|
5796
|
+
payload: dict | int | str | Iterable[int | str] = 0,
|
5797
|
+
/,
|
5798
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5799
|
+
*,
|
5800
|
+
async_: Literal[False, True] = False,
|
5801
|
+
**request_kwargs,
|
5802
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
5803
|
+
"""彻底删除
|
5804
|
+
|
5805
|
+
POST https://www.123pan.com/api/file/delete
|
5806
|
+
|
5807
|
+
.. hint::
|
5808
|
+
彻底删除文件前,文件必须要在回收站中,否则无法删除
|
5809
|
+
|
5810
|
+
:payload:
|
5811
|
+
- fileIdList: list[FileID]
|
5812
|
+
|
5813
|
+
.. code:: python
|
5814
|
+
|
5815
|
+
FileID = {
|
5816
|
+
"FileId": int | str
|
5817
|
+
}
|
5818
|
+
|
5819
|
+
- event: str = "recycleDelete"
|
5820
|
+
"""
|
5821
|
+
if isinstance(payload, (int, str)):
|
5822
|
+
payload = {"fileIdList": [{"FileId": payload}]}
|
5823
|
+
elif not isinstance(payload, dict):
|
5824
|
+
payload = {"fileIdList": [{"FileId": fid} for fid in payload]}
|
5825
|
+
payload = cast(dict, payload)
|
5826
|
+
payload.setdefault("event", "recycleDelete")
|
5827
|
+
return self.request(
|
5828
|
+
"file/delete",
|
5829
|
+
"POST",
|
5830
|
+
json=payload,
|
5831
|
+
base_url=base_url,
|
5832
|
+
async_=async_,
|
5833
|
+
**request_kwargs,
|
5834
|
+
)
|
5835
|
+
|
5836
|
+
@overload
|
5837
|
+
def fs_get_path(
|
5838
|
+
self,
|
5839
|
+
payload: dict | int,
|
5840
|
+
/,
|
5841
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5842
|
+
*,
|
5843
|
+
async_: Literal[False] = False,
|
5844
|
+
**request_kwargs,
|
5845
|
+
) -> dict:
|
5846
|
+
...
|
5847
|
+
@overload
|
5848
|
+
def fs_get_path(
|
5849
|
+
self,
|
5850
|
+
payload: dict | int,
|
5851
|
+
/,
|
5852
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5853
|
+
*,
|
5854
|
+
async_: Literal[True],
|
5855
|
+
**request_kwargs,
|
5856
|
+
) -> Coroutine[Any, Any, dict]:
|
5857
|
+
...
|
5858
|
+
def fs_get_path(
|
5859
|
+
self,
|
5860
|
+
payload: dict | int,
|
5861
|
+
/,
|
5862
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5863
|
+
*,
|
5864
|
+
async_: Literal[False, True] = False,
|
5865
|
+
**request_kwargs,
|
5866
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
5867
|
+
"""获取某个 id 对应的祖先节点列表
|
5868
|
+
|
5869
|
+
POST https://www.123pan.com/api/file/get_path
|
5870
|
+
|
5871
|
+
:payload:
|
5872
|
+
- fileId: int 💡 文件 id
|
5873
|
+
"""
|
5874
|
+
if isinstance(payload, int):
|
5875
|
+
payload = {"fileId": payload}
|
5876
|
+
return self.request(
|
5877
|
+
"file/get_path",
|
5878
|
+
"POST",
|
5879
|
+
json=payload,
|
5880
|
+
base_url=base_url,
|
5881
|
+
async_=async_,
|
5882
|
+
**request_kwargs,
|
5883
|
+
)
|
5884
|
+
|
5885
|
+
@overload
|
5886
|
+
def fs_info(
|
5887
|
+
self,
|
5888
|
+
payload: dict | int | str | Iterable[int | str] = 0,
|
5889
|
+
/,
|
5890
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5891
|
+
*,
|
5892
|
+
async_: Literal[False] = False,
|
5893
|
+
**request_kwargs,
|
5894
|
+
) -> dict:
|
5895
|
+
...
|
5896
|
+
@overload
|
5897
|
+
def fs_info(
|
5898
|
+
self,
|
5899
|
+
payload: dict | int | str | Iterable[int | str] = 0,
|
5900
|
+
/,
|
5901
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5902
|
+
*,
|
5903
|
+
async_: Literal[True],
|
5904
|
+
**request_kwargs,
|
5905
|
+
) -> Coroutine[Any, Any, dict]:
|
5906
|
+
...
|
5907
|
+
def fs_info(
|
5908
|
+
self,
|
5909
|
+
payload: dict | int | str | Iterable[int | str] = 0,
|
5910
|
+
/,
|
5911
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5912
|
+
*,
|
5913
|
+
async_: Literal[False, True] = False,
|
5914
|
+
**request_kwargs,
|
5915
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
5916
|
+
"""获取文件信息
|
5917
|
+
|
5918
|
+
POST https://www.123pan.com/api/file/info
|
5919
|
+
|
5920
|
+
:payload:
|
5921
|
+
- fileIdList: list[FileID]
|
5922
|
+
|
5923
|
+
.. code:: python
|
5924
|
+
|
5925
|
+
FileID = {
|
5926
|
+
"FileId": int | str
|
5927
|
+
}
|
5928
|
+
"""
|
5929
|
+
if isinstance(payload, (int, str)):
|
5930
|
+
payload = {"fileIdList": [{"FileId": payload}]}
|
5931
|
+
elif not isinstance(payload, dict):
|
5932
|
+
payload = {"fileIdList": [{"FileId": fid} for fid in payload]}
|
5933
|
+
return self.request(
|
5934
|
+
"file/info",
|
5935
|
+
"POST",
|
5936
|
+
json=payload,
|
5937
|
+
base_url=base_url,
|
5938
|
+
async_=async_,
|
5939
|
+
**request_kwargs,
|
5940
|
+
)
|
5941
|
+
|
5942
|
+
@overload # type: ignore
|
5943
|
+
def fs_list(
|
5944
|
+
self,
|
5945
|
+
payload: dict | int | str = 0,
|
5946
|
+
/,
|
5947
|
+
event: str = "homeListFile",
|
5948
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5949
|
+
*,
|
5950
|
+
async_: Literal[False] = False,
|
5951
|
+
**request_kwargs,
|
5952
|
+
) -> dict:
|
5953
|
+
...
|
5954
|
+
@overload
|
5955
|
+
def fs_list(
|
5956
|
+
self,
|
5957
|
+
payload: dict | int | str = 0,
|
5958
|
+
/,
|
5959
|
+
event: str = "homeListFile",
|
5960
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5961
|
+
*,
|
5962
|
+
async_: Literal[True],
|
5963
|
+
**request_kwargs,
|
5964
|
+
) -> Coroutine[Any, Any, dict]:
|
5965
|
+
...
|
5966
|
+
def fs_list(
|
5967
|
+
self,
|
5968
|
+
payload: dict | int | str = 0,
|
5969
|
+
/,
|
5970
|
+
event: str = "homeListFile",
|
5971
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5972
|
+
*,
|
5973
|
+
async_: Literal[False, True] = False,
|
5974
|
+
**request_kwargs,
|
5975
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
5976
|
+
"""获取文件列表(可搜索)
|
5977
|
+
|
5978
|
+
GET https://www.123pan.com/api/file/list
|
5979
|
+
|
5980
|
+
.. note::
|
5981
|
+
如果返回信息中,"Next" 字段的值为 "-1",代表最后一页(无需再翻页查询)
|
5982
|
+
|
5983
|
+
:payload:
|
5984
|
+
- driveId: int | str = 0
|
5985
|
+
- limit: int = 100 💡 分页大小,最多 100 个
|
5986
|
+
- next: int = 0 💡 下一批拉取开始的 id
|
5987
|
+
- orderBy: str = "file_name" 💡 排序依据
|
5988
|
+
|
5989
|
+
- "file_id": 文件 id,也可以写作 "fileId"
|
5990
|
+
- "file_name": 文件名
|
5991
|
+
- "size": 文件大小
|
5992
|
+
- "create_at": 创建时间
|
5993
|
+
- "update_at": 更新时间
|
5994
|
+
- "share_id": 分享 id
|
5995
|
+
- ...
|
5996
|
+
|
5997
|
+
- orderDirection: "asc" | "desc" = "asc" 💡 排序顺序
|
5998
|
+
- Page: int = <default> 💡 第几页,从 1 开始,可以是 0
|
5999
|
+
- parentFileId: int | str = 0 💡 父目录 id
|
6000
|
+
- trashed: "false" | "true" = <default> 💡 是否查看回收站的文件
|
6001
|
+
- inDirectSpace: "false" | "true" = "false"
|
6002
|
+
- event: str = "homeListFile" 💡 事件名称
|
6003
|
+
|
6004
|
+
- "homeListFile": 全部文件
|
6005
|
+
- "recycleListFile": 回收站
|
6006
|
+
- "syncFileList": 同步空间
|
6007
|
+
|
6008
|
+
- operateType: int | str = <default> 💡 操作类型,如果在同步空间,则需要指定为 "SyncSpacePage"
|
6009
|
+
- SearchData: str = <default> 💡 搜索关键字(将无视 `parentFileId` 参数)
|
6010
|
+
- OnlyLookAbnormalFile: int = <default>
|
6011
|
+
"""
|
6012
|
+
if isinstance(payload, (int, str)):
|
6013
|
+
payload = {"parentFileId": payload}
|
6014
|
+
payload = dict_to_lower_merge(payload, {
|
6015
|
+
"driveId": 0,
|
6016
|
+
"limit": 100,
|
6017
|
+
"next": 0,
|
6018
|
+
"orderBy": "file_name",
|
6019
|
+
"orderDirection": "asc",
|
6020
|
+
"parentFileId": 0,
|
6021
|
+
"inDirectSpace": "false",
|
6022
|
+
"event": event,
|
6023
|
+
})
|
6024
|
+
if not payload.get("trashed"):
|
6025
|
+
match payload["event"]:
|
6026
|
+
case "recycleListFile":
|
6027
|
+
payload["trashed"] = "true"
|
6028
|
+
case _:
|
6029
|
+
payload["trashed"] = "false"
|
6030
|
+
return self.request(
|
6031
|
+
"file/list",
|
6032
|
+
params=payload,
|
6033
|
+
base_url=base_url,
|
6034
|
+
async_=async_,
|
6035
|
+
**request_kwargs,
|
6036
|
+
)
|
6037
|
+
|
6038
|
+
@overload
|
6039
|
+
def fs_list_by_type(
|
6040
|
+
self,
|
6041
|
+
payload: dict | int = 1,
|
6042
|
+
/,
|
6043
|
+
event: str = "homeListFile",
|
6044
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6045
|
+
*,
|
6046
|
+
async_: Literal[False] = False,
|
6047
|
+
**request_kwargs,
|
6048
|
+
) -> dict:
|
6049
|
+
...
|
6050
|
+
@overload
|
6051
|
+
def fs_list_by_type(
|
6052
|
+
self,
|
6053
|
+
payload: dict | int = 1,
|
6054
|
+
/,
|
6055
|
+
event: str = "homeListFile",
|
6056
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6057
|
+
*,
|
6058
|
+
async_: Literal[True],
|
6059
|
+
**request_kwargs,
|
6060
|
+
) -> Coroutine[Any, Any, dict]:
|
6061
|
+
...
|
6062
|
+
def fs_list_by_type(
|
6063
|
+
self,
|
6064
|
+
payload: dict | int = 1,
|
6065
|
+
/,
|
6066
|
+
event: str = "homeListFile",
|
6067
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6068
|
+
*,
|
6069
|
+
async_: Literal[False, True] = False,
|
6070
|
+
**request_kwargs,
|
6071
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
6072
|
+
"""按类型获取文件列表
|
6073
|
+
|
6074
|
+
GET https://www.123pan.com/api/restful/goapi/v1/file/category/list-by-type
|
6075
|
+
|
6076
|
+
:payload:
|
6077
|
+
- driveId: int | str = 0
|
6078
|
+
- limit: int = 100 💡 分页大小,最多 100 个
|
6079
|
+
- next: int = 0 💡 下一批拉取开始的 id
|
6080
|
+
- category: int = 1 💡 分类代码
|
6081
|
+
|
6082
|
+
- 1: 音频
|
6083
|
+
- 2: 视频
|
6084
|
+
- 3: 图片
|
6085
|
+
- 4: 音频
|
6086
|
+
- 5: 其它
|
6087
|
+
|
6088
|
+
- dateGranularity: int = <default> 💡 按时间分组展示
|
6089
|
+
|
6090
|
+
- 1: 日
|
6091
|
+
- 2: 月
|
6092
|
+
- 3: 年
|
6093
|
+
|
6094
|
+
- orderBy: str = "file_name" 💡 排序依据
|
6095
|
+
|
6096
|
+
- "file_id": 文件 id,也可以写作 "fileId"
|
6097
|
+
- "file_name": 文件名
|
6098
|
+
- "size": 文件大小
|
6099
|
+
- "create_at": 创建时间
|
6100
|
+
- "update_at": 更新时间
|
6101
|
+
- "trashed_at": 删除时间
|
6102
|
+
- "share_id": 分享 id
|
6103
|
+
- "remain_days": 剩余保留天数
|
6104
|
+
- ...
|
6105
|
+
|
6106
|
+
- orderDirection: "asc" | "desc" = "asc" 💡 排序顺序
|
6107
|
+
- Page: int = 1 💡 第几页,从 1 开始
|
6108
|
+
- parentFileId: int | str = 0 💡 父目录 id
|
6109
|
+
- trashed: "false" | "true" = <default> 💡 是否查看回收站的文件
|
6110
|
+
- inDirectSpace: "false" | "true" = "false"
|
6111
|
+
- event: str = "homeListFile" 💡 事件名称
|
6112
|
+
|
6113
|
+
- "homeListFile": 全部文件
|
6114
|
+
- "recycleListFile": 回收站
|
6115
|
+
- "syncFileList": 同步空间
|
6116
|
+
|
6117
|
+
- operateType: int | str = <default> 💡 操作类型,如果在同步空间,则需要指定为 "SyncSpacePage"
|
6118
|
+
|
6119
|
+
.. note::
|
6120
|
+
这个值似乎不影响结果,所以可以忽略。我在浏览器中,看到罗列根目录为 1,搜索(指定 `SearchData`)为 2,同步空间的根目录为 3,罗列其它目录大多为 4,偶尔为 8,也可能是其它值
|
6121
|
+
|
6122
|
+
- SearchData: str = <default> 💡 搜索关键字(将无视 `parentFileId` 参数)
|
6123
|
+
- OnlyLookAbnormalFile: int = 0 💡 大概可传入 0 或 1
|
6124
|
+
"""
|
6125
|
+
if not isinstance(payload, dict):
|
6126
|
+
payload = {"Page": payload}
|
6127
|
+
payload = dict_to_lower_merge(payload, {
|
6128
|
+
"driveId": 0,
|
6129
|
+
"limit": 100,
|
6130
|
+
"next": 0,
|
6131
|
+
"category": 1,
|
6132
|
+
"orderBy": "file_name",
|
6133
|
+
"orderDirection": "asc",
|
6134
|
+
"parentFileId": 0,
|
6135
|
+
"inDirectSpace": "false",
|
6136
|
+
"event": event,
|
6137
|
+
"OnlyLookAbnormalFile": 0,
|
6138
|
+
"Page": 1,
|
6139
|
+
})
|
6140
|
+
if not payload.get("trashed"):
|
6141
|
+
match payload["event"]:
|
6142
|
+
case "recycleListFile":
|
6143
|
+
payload["trashed"] = "true"
|
6144
|
+
case _:
|
6145
|
+
payload["trashed"] = "false"
|
6146
|
+
return self.request(
|
6147
|
+
"restful/goapi/v1/file/category/list-by-type",
|
6148
|
+
params=payload,
|
6149
|
+
base_url=base_url,
|
6150
|
+
async_=async_,
|
6151
|
+
**request_kwargs,
|
6152
|
+
)
|
6153
|
+
|
6154
|
+
@overload
|
6155
|
+
def fs_list_new(
|
6156
|
+
self,
|
6157
|
+
payload: dict | int | str = 0,
|
6158
|
+
/,
|
6159
|
+
event: str = "homeListFile",
|
6160
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6161
|
+
*,
|
6162
|
+
async_: Literal[False] = False,
|
6163
|
+
**request_kwargs,
|
6164
|
+
) -> dict:
|
6165
|
+
...
|
6166
|
+
@overload
|
6167
|
+
def fs_list_new(
|
6168
|
+
self,
|
6169
|
+
payload: dict | int | str = 0,
|
6170
|
+
/,
|
6171
|
+
event: str = "homeListFile",
|
6172
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6173
|
+
*,
|
6174
|
+
async_: Literal[True],
|
6175
|
+
**request_kwargs,
|
6176
|
+
) -> Coroutine[Any, Any, dict]:
|
6177
|
+
...
|
6178
|
+
def fs_list_new(
|
6179
|
+
self,
|
6180
|
+
payload: dict | int | str = 0,
|
6181
|
+
/,
|
6182
|
+
event: str = "homeListFile",
|
6183
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6184
|
+
*,
|
6185
|
+
async_: Literal[False, True] = False,
|
6186
|
+
**request_kwargs,
|
6187
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
6188
|
+
"""获取文件列表(可搜索)
|
6189
|
+
|
6190
|
+
GET https://www.123pan.com/api/file/list/new
|
6191
|
+
|
6192
|
+
.. note::
|
6193
|
+
如果返回信息中,"Next" 字段的值为 "-1",代表最后一页(无需再翻页查询)
|
6194
|
+
|
6195
|
+
:payload:
|
6196
|
+
- driveId: int | str = 0
|
6197
|
+
- limit: int = 100 💡 分页大小,最多 100 个
|
6198
|
+
- next: int = 0 💡 下一批拉取开始的 id
|
6199
|
+
- orderBy: str = "file_name" 💡 排序依据
|
6200
|
+
|
6201
|
+
- "file_id": 文件 id,也可以写作 "fileId"
|
6202
|
+
- "file_name": 文件名
|
6203
|
+
- "size": 文件大小
|
6204
|
+
- "create_at": 创建时间
|
6205
|
+
- "update_at": 更新时间
|
6206
|
+
- "trashed_at": 删除时间
|
6207
|
+
- "share_id": 分享 id
|
6208
|
+
- "remain_days": 剩余保留天数
|
6209
|
+
- ...
|
6210
|
+
|
6211
|
+
- orderDirection: "asc" | "desc" = "asc" 💡 排序顺序
|
6212
|
+
- Page: int = 1 💡 第几页,从 1 开始
|
6213
|
+
- parentFileId: int | str = 0 💡 父目录 id
|
6214
|
+
- trashed: "false" | "true" = <default> 💡 是否查看回收站的文件
|
6215
|
+
- inDirectSpace: "false" | "true" = "false"
|
6216
|
+
- event: str = "homeListFile" 💡 事件名称
|
6217
|
+
|
6218
|
+
- "homeListFile": 全部文件
|
6219
|
+
- "recycleListFile": 回收站
|
6220
|
+
- "syncFileList": 同步空间
|
6221
|
+
|
6222
|
+
- operateType: int | str = <default> 💡 操作类型,如果在同步空间,则需要指定为 "SyncSpacePage"
|
6223
|
+
|
6224
|
+
.. note::
|
6225
|
+
这个值似乎不影响结果,所以可以忽略。我在浏览器中,看到罗列根目录为 1,搜索(指定 `SearchData`)为 2,同步空间的根目录为 3,罗列其它目录大多为 4,偶尔为 8,也可能是其它值
|
6226
|
+
|
6227
|
+
- SearchData: str = <default> 💡 搜索关键字(将无视 `parentFileId` 参数)
|
6228
|
+
- OnlyLookAbnormalFile: int = 0 💡 大概可传入 0 或 1
|
6229
|
+
- RequestSource: int = <default> 💡 浏览器中,在同步空间中为 1
|
6230
|
+
"""
|
6231
|
+
if isinstance(payload, (int, str)):
|
6232
|
+
payload = {"parentFileId": payload}
|
6233
|
+
payload = dict_to_lower_merge(payload, {
|
6234
|
+
"driveId": 0,
|
6235
|
+
"limit": 100,
|
6236
|
+
"next": 0,
|
6237
|
+
"orderBy": "file_name",
|
6238
|
+
"orderDirection": "asc",
|
6239
|
+
"parentFileId": 0,
|
6240
|
+
"inDirectSpace": "false",
|
6241
|
+
"event": event,
|
6242
|
+
"OnlyLookAbnormalFile": 0,
|
6243
|
+
"Page": 1,
|
6244
|
+
})
|
6245
|
+
if not payload.get("trashed"):
|
6246
|
+
match payload["event"]:
|
6247
|
+
case "recycleListFile":
|
6248
|
+
payload["trashed"] = "true"
|
6249
|
+
case _:
|
6250
|
+
payload["trashed"] = "false"
|
6251
|
+
return self.request(
|
6252
|
+
"file/list/new",
|
6253
|
+
params=payload,
|
6254
|
+
base_url=base_url,
|
6255
|
+
async_=async_,
|
6256
|
+
**request_kwargs,
|
6257
|
+
)
|
6258
|
+
|
6259
|
+
@overload # type: ignore
|
6260
|
+
def fs_mkdir(
|
6261
|
+
self,
|
6262
|
+
name: str,
|
6263
|
+
/,
|
6264
|
+
parent_id: int | str = 0,
|
6265
|
+
duplicate: Literal[0, 1, 2] = 0,
|
6266
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6267
|
+
*,
|
6268
|
+
async_: Literal[False] = False,
|
6269
|
+
**request_kwargs,
|
6270
|
+
) -> dict:
|
6271
|
+
...
|
6272
|
+
@overload
|
6273
|
+
def fs_mkdir(
|
6274
|
+
self,
|
6275
|
+
name: str,
|
6276
|
+
/,
|
6277
|
+
parent_id: int | str = 0,
|
6278
|
+
duplicate: Literal[0, 1, 2] = 0,
|
6279
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6280
|
+
*,
|
6281
|
+
async_: Literal[True],
|
6282
|
+
**request_kwargs,
|
6283
|
+
) -> Coroutine[Any, Any, dict]:
|
6284
|
+
...
|
6285
|
+
def fs_mkdir(
|
6286
|
+
self,
|
6287
|
+
name: str,
|
6288
|
+
/,
|
6289
|
+
parent_id: int | str = 0,
|
6290
|
+
duplicate: Literal[0, 1, 2] = 0,
|
6291
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6292
|
+
*,
|
6293
|
+
async_: Literal[False, True] = False,
|
6294
|
+
**request_kwargs,
|
6295
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
6296
|
+
"""创建目录
|
6297
|
+
|
6298
|
+
:param name: 目录名
|
6299
|
+
:param parent_id: 父目录 id
|
6300
|
+
:param duplicate: 处理同名:0: 复用 1: 保留两者 2: 替换
|
6301
|
+
:param async_: 是否异步
|
6302
|
+
:param request_kwargs: 其它请求参数
|
6303
|
+
|
6304
|
+
:return: 接口响应
|
6305
|
+
"""
|
6306
|
+
payload = {"filename": name, "parentFileId": parent_id}
|
6307
|
+
if duplicate:
|
6308
|
+
payload["NotReuse"] = True
|
6309
|
+
payload["duplicate"] = duplicate
|
6310
|
+
return self.upload_request(
|
6311
|
+
payload,
|
6312
|
+
base_url=base_url,
|
6313
|
+
async_=async_,
|
6314
|
+
**request_kwargs,
|
6315
|
+
)
|
6316
|
+
|
6317
|
+
@overload
|
6318
|
+
def fs_move(
|
6319
|
+
self,
|
6320
|
+
payload: dict | int | str | Iterable[int | str],
|
6321
|
+
/,
|
6322
|
+
parent_id: int | str = 0,
|
6323
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6324
|
+
*,
|
6325
|
+
async_: Literal[False] = False,
|
6326
|
+
**request_kwargs,
|
6327
|
+
) -> dict:
|
6328
|
+
...
|
6329
|
+
@overload
|
6330
|
+
def fs_move(
|
6331
|
+
self,
|
6332
|
+
payload: dict | int | str | Iterable[int | str],
|
6333
|
+
/,
|
6334
|
+
parent_id: int | str = 0,
|
6335
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6336
|
+
*,
|
6337
|
+
async_: Literal[True],
|
6338
|
+
**request_kwargs,
|
6339
|
+
) -> Coroutine[Any, Any, dict]:
|
6340
|
+
...
|
6341
|
+
def fs_move(
|
6342
|
+
self,
|
6343
|
+
payload: dict | int | str | Iterable[int | str],
|
6344
|
+
/,
|
6345
|
+
parent_id: int | str = 0,
|
6346
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6347
|
+
*,
|
6348
|
+
async_: Literal[False, True] = False,
|
6349
|
+
**request_kwargs,
|
6350
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
6351
|
+
"""移动
|
6352
|
+
|
6353
|
+
POST https://www.123pan.com/api/file/mod_pid
|
6354
|
+
|
6355
|
+
:payload:
|
6356
|
+
- fileIdList: list[FileID]
|
6357
|
+
|
6358
|
+
.. code:: python
|
6359
|
+
|
6360
|
+
FileID = {
|
6361
|
+
"FileId": int | str
|
6362
|
+
}
|
6363
|
+
|
6364
|
+
- parentFileId: int | str = 0
|
6365
|
+
- event: str = "fileMove"
|
6366
|
+
"""
|
6367
|
+
if isinstance(payload, (int, str)):
|
6368
|
+
payload = {"fileIdList": [{"FileId": payload}]}
|
6369
|
+
elif not isinstance(payload, dict):
|
6370
|
+
payload = {"fileIdList": [{"FileId": fid} for fid in payload]}
|
6371
|
+
payload = dict_to_lower_merge(payload, {"parentFileId": parent_id, "event": "fileMove"})
|
6372
|
+
return self.request(
|
6373
|
+
"file/mod_pid",
|
6374
|
+
"POST",
|
6375
|
+
json=payload,
|
6376
|
+
base_url=base_url,
|
6377
|
+
async_=async_,
|
6378
|
+
**request_kwargs,
|
6379
|
+
)
|
6380
|
+
|
6381
|
+
@overload
|
6382
|
+
def fs_refresh(
|
6383
|
+
self,
|
6384
|
+
payload: dict = {},
|
6385
|
+
/,
|
6386
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6387
|
+
*,
|
6388
|
+
async_: Literal[False] = False,
|
6389
|
+
**request_kwargs,
|
6390
|
+
) -> dict:
|
6391
|
+
...
|
6392
|
+
@overload
|
6393
|
+
def fs_refresh(
|
6394
|
+
self,
|
6395
|
+
payload: dict = {},
|
6396
|
+
/,
|
6397
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6398
|
+
*,
|
6399
|
+
async_: Literal[True],
|
6400
|
+
**request_kwargs,
|
6401
|
+
) -> Coroutine[Any, Any, dict]:
|
6402
|
+
...
|
6403
|
+
def fs_refresh(
|
6404
|
+
self,
|
6405
|
+
payload: dict = {},
|
6406
|
+
/,
|
6407
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6408
|
+
*,
|
6409
|
+
async_: Literal[False, True] = False,
|
6410
|
+
**request_kwargs,
|
6411
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
6412
|
+
"""刷新列表和直链缓存
|
6413
|
+
|
6414
|
+
POST https://www.123pan.com/api/restful/goapi/v1/cdnLink/cache/refresh
|
6415
|
+
"""
|
6416
|
+
return self.request(
|
6417
|
+
"restful/goapi/v1/cdnLink/cache/refresh",
|
6418
|
+
"POST",
|
6419
|
+
json=payload,
|
6420
|
+
base_url=base_url,
|
6421
|
+
async_=async_,
|
6422
|
+
**request_kwargs,
|
6423
|
+
)
|
6424
|
+
|
6425
|
+
@overload # type: ignore
|
6426
|
+
def fs_rename(
|
6427
|
+
self,
|
6428
|
+
payload: dict,
|
6429
|
+
/,
|
6430
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6431
|
+
*,
|
6432
|
+
async_: Literal[False] = False,
|
6433
|
+
**request_kwargs,
|
6434
|
+
) -> dict:
|
6435
|
+
...
|
6436
|
+
@overload
|
6437
|
+
def fs_rename(
|
6438
|
+
self,
|
6439
|
+
payload: dict,
|
6440
|
+
/,
|
6441
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6442
|
+
*,
|
6443
|
+
async_: Literal[True],
|
6444
|
+
**request_kwargs,
|
6445
|
+
) -> Coroutine[Any, Any, dict]:
|
6446
|
+
...
|
6447
|
+
def fs_rename(
|
6448
|
+
self,
|
6449
|
+
payload: dict,
|
6450
|
+
/,
|
6451
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6452
|
+
*,
|
6453
|
+
async_: Literal[False, True] = False,
|
6454
|
+
**request_kwargs,
|
6455
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
6456
|
+
"""(单个)改名
|
6457
|
+
|
6458
|
+
POST https://www.123pan.com/api/file/rename
|
6459
|
+
|
6460
|
+
:payload:
|
6461
|
+
- FileId: int | str
|
6462
|
+
- fileName: str
|
6463
|
+
- driveId: int | str = 0
|
6464
|
+
- duplicate: 0 | 1 | 2 = 0 💡 处理同名:0: 提示/忽略 1: 保留两者 2: 替换
|
6465
|
+
- event: str = "fileRename"
|
6466
|
+
"""
|
6467
|
+
payload = dict_to_lower_merge(payload, {
|
6468
|
+
"driveId": 0,
|
6469
|
+
"duplicate": 0,
|
6470
|
+
"event": "fileRename",
|
6471
|
+
})
|
6472
|
+
return self.request(
|
6473
|
+
"file/rename",
|
6474
|
+
"POST",
|
6475
|
+
json=payload,
|
6476
|
+
base_url=base_url,
|
6477
|
+
async_=async_,
|
6478
|
+
**request_kwargs,
|
6479
|
+
)
|
6480
|
+
|
6481
|
+
@overload
|
6482
|
+
def fs_star(
|
6483
|
+
self,
|
6484
|
+
payload: dict | int | str | Iterable[int | str],
|
6485
|
+
/,
|
6486
|
+
star: bool = True,
|
6487
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6488
|
+
*,
|
6489
|
+
async_: Literal[False] = False,
|
6490
|
+
**request_kwargs,
|
6491
|
+
) -> dict:
|
6492
|
+
...
|
6493
|
+
@overload
|
6494
|
+
def fs_star(
|
6495
|
+
self,
|
6496
|
+
payload: dict | int | str | Iterable[int | str],
|
6497
|
+
/,
|
6498
|
+
star: bool = True,
|
6499
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6500
|
+
*,
|
6501
|
+
async_: Literal[True],
|
6502
|
+
**request_kwargs,
|
6503
|
+
) -> Coroutine[Any, Any, dict]:
|
6504
|
+
...
|
6505
|
+
def fs_star(
|
6506
|
+
self,
|
6507
|
+
payload: dict | int | str | Iterable[int | str],
|
6508
|
+
/,
|
6509
|
+
star: bool = True,
|
6510
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6511
|
+
*,
|
6512
|
+
async_: Literal[False, True] = False,
|
6513
|
+
**request_kwargs,
|
6514
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
6515
|
+
"""给文件或目录,设置或取消星标
|
6516
|
+
|
6517
|
+
POST https://www.123pan.com/api/restful/goapi/v1/file/starred
|
6518
|
+
|
6519
|
+
:payload:
|
6520
|
+
- fileIdList: list[int | str] 💡 id 列表
|
6521
|
+
- starredStatus: int = 255 💡 是否设置星标:1:取消 255:设置
|
6522
|
+
"""
|
6523
|
+
if isinstance(payload, (int, str)):
|
6524
|
+
payload = {"fileIdList": [payload], "starredStatus": 255}
|
6525
|
+
elif not isinstance(payload, dict):
|
6526
|
+
if not isinstance(payload, (tuple, list)):
|
6527
|
+
payload = list(payload)
|
6528
|
+
payload = {"fileIdList": payload, "starredStatus": 255}
|
6529
|
+
else:
|
6530
|
+
payload.setdefault("starredStatus", 255 if star else 1)
|
6531
|
+
return self.request(
|
6532
|
+
"restful/goapi/v1/file/starred",
|
6533
|
+
"POST",
|
6534
|
+
json=payload,
|
6535
|
+
base_url=base_url,
|
6536
|
+
async_=async_,
|
6537
|
+
**request_kwargs,
|
6538
|
+
)
|
6539
|
+
|
6540
|
+
@overload
|
6541
|
+
def fs_star_list(
|
4758
6542
|
self,
|
4759
|
-
payload: dict | int
|
6543
|
+
payload: dict | int = 1,
|
4760
6544
|
/,
|
4761
|
-
|
6545
|
+
event: str = "homeListFile",
|
4762
6546
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4763
6547
|
*,
|
4764
6548
|
async_: Literal[False] = False,
|
@@ -4766,73 +6550,98 @@ class P123Client(P123OpenClient):
|
|
4766
6550
|
) -> dict:
|
4767
6551
|
...
|
4768
6552
|
@overload
|
4769
|
-
def
|
6553
|
+
def fs_star_list(
|
4770
6554
|
self,
|
4771
|
-
payload: dict | int
|
6555
|
+
payload: dict | int = 1,
|
4772
6556
|
/,
|
4773
|
-
|
6557
|
+
event: str = "homeListFile",
|
4774
6558
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4775
6559
|
*,
|
4776
6560
|
async_: Literal[True],
|
4777
6561
|
**request_kwargs,
|
4778
6562
|
) -> Coroutine[Any, Any, dict]:
|
4779
6563
|
...
|
4780
|
-
def
|
6564
|
+
def fs_star_list(
|
4781
6565
|
self,
|
4782
|
-
payload: dict | int
|
6566
|
+
payload: dict | int = 1,
|
4783
6567
|
/,
|
4784
|
-
|
6568
|
+
event: str = "homeListFile",
|
4785
6569
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4786
6570
|
*,
|
4787
6571
|
async_: Literal[False, True] = False,
|
4788
6572
|
**request_kwargs,
|
4789
6573
|
) -> dict | Coroutine[Any, Any, dict]:
|
4790
|
-
"""
|
6574
|
+
"""罗列已星标的文件或目录
|
4791
6575
|
|
4792
|
-
|
6576
|
+
GET https://www.123pan.com/api/restful/goapi/v1/file/starred/list
|
4793
6577
|
|
4794
6578
|
:payload:
|
4795
|
-
-
|
6579
|
+
- driveId: int | str = 0
|
6580
|
+
- next: int = 0 💡 下一批拉取开始的 id
|
6581
|
+
- orderBy: str = "file_name" 💡 排序依据
|
4796
6582
|
|
4797
|
-
|
6583
|
+
- "file_id": 文件 id,也可以写作 "fileId"
|
6584
|
+
- "file_name": 文件名
|
6585
|
+
- "size": 文件大小
|
6586
|
+
- "create_at": 创建时间
|
6587
|
+
- "update_at": 更新时间
|
6588
|
+
- "trashed_at": 删除时间
|
6589
|
+
- "share_id": 分享 id
|
6590
|
+
- "remain_days": 剩余保留天数
|
6591
|
+
- ...
|
4798
6592
|
|
4799
|
-
|
4800
|
-
|
4801
|
-
|
4802
|
-
|
6593
|
+
- orderDirection: "asc" | "desc" = "asc" 💡 排序顺序
|
6594
|
+
- Page: int = 1 💡 第几页,从 1 开始
|
6595
|
+
- pageSize: int = 100 💡 分页大小,最多 100 个
|
6596
|
+
- parentFileId: int | str = 0 💡 父目录 id
|
6597
|
+
- trashed: "false" | "true" = <default> 💡 是否查看回收站的文件
|
6598
|
+
- inDirectSpace: "false" | "true" = "false"
|
6599
|
+
- event: str = "homeListFile" 💡 事件名称
|
4803
6600
|
|
4804
|
-
|
6601
|
+
- "homeListFile": 全部文件
|
6602
|
+
- "recycleListFile": 回收站
|
6603
|
+
- "syncFileList": 同步空间
|
6604
|
+
|
6605
|
+
- operateType: int | str = <default> 💡 操作类型,如果在同步空间,则需要指定为 "SyncSpacePage"
|
6606
|
+
|
6607
|
+
.. note::
|
6608
|
+
这个值似乎不影响结果,所以可以忽略。我在浏览器中,看到罗列根目录为 1,搜索(指定 `SearchData`)为 2,同步空间的根目录为 3,罗列其它目录大多为 4,偶尔为 8,也可能是其它值
|
6609
|
+
|
6610
|
+
- SearchData: str = <default> 💡 搜索关键字(将无视 `parentFileId` 参数)
|
6611
|
+
- OnlyLookAbnormalFile: int = 0 💡 大概可传入 0 或 1
|
4805
6612
|
"""
|
4806
|
-
|
4807
|
-
|
4808
|
-
|
4809
|
-
|
4810
|
-
|
4811
|
-
|
4812
|
-
|
4813
|
-
|
4814
|
-
|
4815
|
-
|
4816
|
-
|
4817
|
-
|
4818
|
-
|
4819
|
-
|
4820
|
-
|
4821
|
-
|
4822
|
-
|
4823
|
-
|
4824
|
-
|
4825
|
-
|
4826
|
-
|
4827
|
-
|
4828
|
-
|
4829
|
-
|
4830
|
-
|
6613
|
+
if not isinstance(payload, dict):
|
6614
|
+
payload = {"Page": payload}
|
6615
|
+
payload = dict_to_lower_merge(payload, {
|
6616
|
+
"driveId": 0,
|
6617
|
+
"next": 0,
|
6618
|
+
"orderBy": "file_name",
|
6619
|
+
"orderDirection": "asc",
|
6620
|
+
"Page": 1,
|
6621
|
+
"pageSize": 100,
|
6622
|
+
"parentFileId": 0,
|
6623
|
+
"inDirectSpace": "false",
|
6624
|
+
"event": event,
|
6625
|
+
"OnlyLookAbnormalFile": 0,
|
6626
|
+
})
|
6627
|
+
if not payload.get("trashed"):
|
6628
|
+
match payload["event"]:
|
6629
|
+
case "recycleListFile":
|
6630
|
+
payload["trashed"] = "true"
|
6631
|
+
case _:
|
6632
|
+
payload["trashed"] = "false"
|
6633
|
+
return self.request(
|
6634
|
+
"restful/goapi/v1/file/starred/list",
|
6635
|
+
params=payload,
|
6636
|
+
base_url=base_url,
|
6637
|
+
async_=async_,
|
6638
|
+
**request_kwargs,
|
6639
|
+
)
|
4831
6640
|
|
4832
6641
|
@overload
|
4833
|
-
def
|
6642
|
+
def fs_sync_log(
|
4834
6643
|
self,
|
4835
|
-
payload: dict | int
|
6644
|
+
payload: dict | int = 1,
|
4836
6645
|
/,
|
4837
6646
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4838
6647
|
*,
|
@@ -4841,9 +6650,9 @@ class P123Client(P123OpenClient):
|
|
4841
6650
|
) -> dict:
|
4842
6651
|
...
|
4843
6652
|
@overload
|
4844
|
-
def
|
6653
|
+
def fs_sync_log(
|
4845
6654
|
self,
|
4846
|
-
payload: dict | int
|
6655
|
+
payload: dict | int = 1,
|
4847
6656
|
/,
|
4848
6657
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4849
6658
|
*,
|
@@ -4851,37 +6660,40 @@ class P123Client(P123OpenClient):
|
|
4851
6660
|
**request_kwargs,
|
4852
6661
|
) -> Coroutine[Any, Any, dict]:
|
4853
6662
|
...
|
4854
|
-
def
|
6663
|
+
def fs_sync_log(
|
4855
6664
|
self,
|
4856
|
-
payload: dict | int
|
6665
|
+
payload: dict | int = 1,
|
4857
6666
|
/,
|
4858
6667
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4859
6668
|
*,
|
4860
6669
|
async_: Literal[False, True] = False,
|
4861
6670
|
**request_kwargs,
|
4862
6671
|
) -> dict | Coroutine[Any, Any, dict]:
|
4863
|
-
"""
|
6672
|
+
"""获取同步空间的操作记录
|
4864
6673
|
|
4865
|
-
GET https://www.123pan.com/api/file/
|
6674
|
+
GET https://www.123pan.com/api/restful/goapi/v1/sync-disk/file/log
|
4866
6675
|
|
4867
6676
|
:payload:
|
4868
|
-
-
|
6677
|
+
- page: int = 1 💡 第几页
|
6678
|
+
- pageSize: int = 100 💡 每页大小
|
6679
|
+
- searchData: str = <default> 💡 搜索关键字
|
4869
6680
|
"""
|
4870
|
-
if isinstance(payload,
|
4871
|
-
payload = {"
|
6681
|
+
if not isinstance(payload, dict):
|
6682
|
+
payload = {"page": payload, "pageSize": 100}
|
4872
6683
|
return self.request(
|
4873
|
-
"file/
|
6684
|
+
"restful/goapi/v1/sync-disk/file/log",
|
4874
6685
|
params=payload,
|
4875
6686
|
base_url=base_url,
|
4876
6687
|
async_=async_,
|
4877
6688
|
**request_kwargs,
|
4878
6689
|
)
|
4879
6690
|
|
4880
|
-
@overload
|
4881
|
-
def
|
6691
|
+
@overload # type: ignore
|
6692
|
+
def fs_trash(
|
4882
6693
|
self,
|
4883
|
-
payload: dict | int | str | Iterable[int | str]
|
6694
|
+
payload: dict | int | str | Iterable[int | str],
|
4884
6695
|
/,
|
6696
|
+
event: str = "intoRecycle",
|
4885
6697
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4886
6698
|
*,
|
4887
6699
|
async_: Literal[False] = False,
|
@@ -4889,51 +6701,64 @@ class P123Client(P123OpenClient):
|
|
4889
6701
|
) -> dict:
|
4890
6702
|
...
|
4891
6703
|
@overload
|
4892
|
-
def
|
6704
|
+
def fs_trash(
|
4893
6705
|
self,
|
4894
|
-
payload: dict | int | str | Iterable[int | str]
|
6706
|
+
payload: dict | int | str | Iterable[int | str],
|
4895
6707
|
/,
|
6708
|
+
event: str = "intoRecycle",
|
4896
6709
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4897
6710
|
*,
|
4898
6711
|
async_: Literal[True],
|
4899
6712
|
**request_kwargs,
|
4900
6713
|
) -> Coroutine[Any, Any, dict]:
|
4901
6714
|
...
|
4902
|
-
def
|
6715
|
+
def fs_trash(
|
4903
6716
|
self,
|
4904
|
-
payload: dict | int | str | Iterable[int | str]
|
6717
|
+
payload: dict | int | str | Iterable[int | str],
|
4905
6718
|
/,
|
6719
|
+
event: str = "intoRecycle",
|
4906
6720
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4907
6721
|
*,
|
4908
6722
|
async_: Literal[False, True] = False,
|
4909
6723
|
**request_kwargs,
|
4910
6724
|
) -> dict | Coroutine[Any, Any, dict]:
|
4911
|
-
"""
|
4912
|
-
|
4913
|
-
POST https://www.123pan.com/api/file/delete
|
6725
|
+
"""操作回收站
|
4914
6726
|
|
4915
|
-
|
4916
|
-
彻底删除文件前,文件必须要在回收站中,否则无法删除
|
6727
|
+
POST https://www.123pan.com/api/file/trash
|
4917
6728
|
|
4918
6729
|
:payload:
|
4919
|
-
-
|
6730
|
+
- fileTrashInfoList: list[File] 💡 信息可以取自 `P123Client.fs_info` 接口
|
4920
6731
|
|
4921
6732
|
.. code:: python
|
4922
6733
|
|
4923
|
-
|
4924
|
-
"FileId": int | str
|
6734
|
+
File = {
|
6735
|
+
"FileId": int | str,
|
6736
|
+
...
|
4925
6737
|
}
|
4926
6738
|
|
4927
|
-
-
|
6739
|
+
- driveId: int = 0
|
6740
|
+
- event: str = "intoRecycle" 💡 事件类型
|
6741
|
+
|
6742
|
+
- "intoRecycle": 移入回收站
|
6743
|
+
- "recycleRestore": 移出回收站
|
6744
|
+
|
6745
|
+
- operation: bool = <default>
|
6746
|
+
- operatePlace: int = <default>
|
6747
|
+
- RequestSource: int = <default> 💡 浏览器中,在同步空间中为 1
|
4928
6748
|
"""
|
4929
6749
|
if isinstance(payload, (int, str)):
|
4930
|
-
payload = {"
|
6750
|
+
payload = {"fileTrashInfoList": [{"FileId": payload}]}
|
4931
6751
|
elif not isinstance(payload, dict):
|
4932
|
-
payload = {"
|
4933
|
-
payload =
|
4934
|
-
payload.
|
6752
|
+
payload = {"fileTrashInfoList": [{"FileId": fid} for fid in payload]}
|
6753
|
+
payload = dict_to_lower_merge(payload, {"driveId": 0, "event": event})
|
6754
|
+
if payload.get("operation") is None:
|
6755
|
+
match payload["event"]:
|
6756
|
+
case "recycleRestore":
|
6757
|
+
payload["operation"] = False
|
6758
|
+
case _:
|
6759
|
+
payload["operation"] = True
|
4935
6760
|
return self.request(
|
4936
|
-
"file/
|
6761
|
+
"file/trash",
|
4937
6762
|
"POST",
|
4938
6763
|
json=payload,
|
4939
6764
|
base_url=base_url,
|
@@ -4942,9 +6767,9 @@ class P123Client(P123OpenClient):
|
|
4942
6767
|
)
|
4943
6768
|
|
4944
6769
|
@overload
|
4945
|
-
def
|
6770
|
+
def fs_trash_clear(
|
4946
6771
|
self,
|
4947
|
-
payload: dict
|
6772
|
+
payload: dict = {"event": "recycleClear"},
|
4948
6773
|
/,
|
4949
6774
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4950
6775
|
*,
|
@@ -4953,9 +6778,9 @@ class P123Client(P123OpenClient):
|
|
4953
6778
|
) -> dict:
|
4954
6779
|
...
|
4955
6780
|
@overload
|
4956
|
-
def
|
6781
|
+
def fs_trash_clear(
|
4957
6782
|
self,
|
4958
|
-
payload: dict
|
6783
|
+
payload: dict = {"event": "recycleClear"},
|
4959
6784
|
/,
|
4960
6785
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4961
6786
|
*,
|
@@ -4963,26 +6788,25 @@ class P123Client(P123OpenClient):
|
|
4963
6788
|
**request_kwargs,
|
4964
6789
|
) -> Coroutine[Any, Any, dict]:
|
4965
6790
|
...
|
4966
|
-
def
|
6791
|
+
def fs_trash_clear(
|
4967
6792
|
self,
|
4968
|
-
payload: dict
|
6793
|
+
payload: dict = {"event": "recycleClear"},
|
4969
6794
|
/,
|
4970
6795
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4971
6796
|
*,
|
4972
6797
|
async_: Literal[False, True] = False,
|
4973
6798
|
**request_kwargs,
|
4974
6799
|
) -> dict | Coroutine[Any, Any, dict]:
|
4975
|
-
"""
|
6800
|
+
"""清空回收站
|
4976
6801
|
|
4977
|
-
POST https://www.123pan.com/api/file/
|
6802
|
+
POST https://www.123pan.com/api/file/trash_delete_all
|
4978
6803
|
|
4979
6804
|
:payload:
|
4980
|
-
-
|
6805
|
+
- event: str = "recycleClear"
|
4981
6806
|
"""
|
4982
|
-
|
4983
|
-
payload = {"fileId": payload}
|
6807
|
+
payload.setdefault("event", "recycleClear")
|
4984
6808
|
return self.request(
|
4985
|
-
"file/
|
6809
|
+
"file/trash_delete_all",
|
4986
6810
|
"POST",
|
4987
6811
|
json=payload,
|
4988
6812
|
base_url=base_url,
|
@@ -4991,68 +6815,51 @@ class P123Client(P123OpenClient):
|
|
4991
6815
|
)
|
4992
6816
|
|
4993
6817
|
@overload
|
4994
|
-
|
4995
|
-
|
4996
|
-
payload: dict | int | str | Iterable[int | str] = 0,
|
4997
|
-
/,
|
6818
|
+
@staticmethod
|
6819
|
+
def fs_video_play_conf(
|
4998
6820
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6821
|
+
request: None | Callable = None,
|
4999
6822
|
*,
|
5000
6823
|
async_: Literal[False] = False,
|
5001
6824
|
**request_kwargs,
|
5002
6825
|
) -> dict:
|
5003
6826
|
...
|
5004
6827
|
@overload
|
5005
|
-
|
5006
|
-
|
5007
|
-
payload: dict | int | str | Iterable[int | str] = 0,
|
5008
|
-
/,
|
6828
|
+
@staticmethod
|
6829
|
+
def fs_video_play_conf(
|
5009
6830
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6831
|
+
request: None | Callable = None,
|
5010
6832
|
*,
|
5011
6833
|
async_: Literal[True],
|
5012
6834
|
**request_kwargs,
|
5013
6835
|
) -> Coroutine[Any, Any, dict]:
|
5014
6836
|
...
|
5015
|
-
|
5016
|
-
|
5017
|
-
payload: dict | int | str | Iterable[int | str] = 0,
|
5018
|
-
/,
|
6837
|
+
@staticmethod
|
6838
|
+
def fs_video_play_conf(
|
5019
6839
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5020
|
-
|
5021
|
-
|
5022
|
-
|
5023
|
-
|
5024
|
-
|
5025
|
-
|
5026
|
-
|
5027
|
-
|
5028
|
-
|
5029
|
-
|
5030
|
-
|
5031
|
-
|
5032
|
-
|
5033
|
-
|
5034
|
-
|
5035
|
-
}
|
5036
|
-
"""
|
5037
|
-
if isinstance(payload, (int, str)):
|
5038
|
-
payload = {"fileIdList": [{"FileId": payload}]}
|
5039
|
-
elif not isinstance(payload, dict):
|
5040
|
-
payload = {"fileIdList": [{"FileId": fid} for fid in payload]}
|
5041
|
-
return self.request(
|
5042
|
-
"file/info",
|
5043
|
-
"POST",
|
5044
|
-
json=payload,
|
5045
|
-
base_url=base_url,
|
5046
|
-
async_=async_,
|
6840
|
+
request: None | Callable = None,
|
6841
|
+
*,
|
6842
|
+
async_: Literal[False, True] = False,
|
6843
|
+
**request_kwargs,
|
6844
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
6845
|
+
"""获取视频播放列表的配置信息
|
6846
|
+
|
6847
|
+
GET https://www.123pan.com/api/video/play/conf
|
6848
|
+
"""
|
6849
|
+
request_kwargs.setdefault("parse", default_parse)
|
6850
|
+
if request is None:
|
6851
|
+
request = get_default_request()
|
6852
|
+
request_kwargs["async_"] = async_
|
6853
|
+
return request(
|
6854
|
+
url=complete_url("/api/get/server/time", base_url),
|
5047
6855
|
**request_kwargs,
|
5048
6856
|
)
|
5049
6857
|
|
5050
|
-
@overload
|
5051
|
-
def
|
6858
|
+
@overload
|
6859
|
+
def fs_video_play_list(
|
5052
6860
|
self,
|
5053
6861
|
payload: dict | int | str = 0,
|
5054
6862
|
/,
|
5055
|
-
event: str = "homeListFile",
|
5056
6863
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5057
6864
|
*,
|
5058
6865
|
async_: Literal[False] = False,
|
@@ -5060,95 +6867,54 @@ class P123Client(P123OpenClient):
|
|
5060
6867
|
) -> dict:
|
5061
6868
|
...
|
5062
6869
|
@overload
|
5063
|
-
def
|
6870
|
+
def fs_video_play_list(
|
5064
6871
|
self,
|
5065
6872
|
payload: dict | int | str = 0,
|
5066
6873
|
/,
|
5067
|
-
event: str = "homeListFile",
|
5068
6874
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5069
6875
|
*,
|
5070
6876
|
async_: Literal[True],
|
5071
6877
|
**request_kwargs,
|
5072
6878
|
) -> Coroutine[Any, Any, dict]:
|
5073
6879
|
...
|
5074
|
-
def
|
6880
|
+
def fs_video_play_list(
|
5075
6881
|
self,
|
5076
6882
|
payload: dict | int | str = 0,
|
5077
6883
|
/,
|
5078
|
-
event: str = "homeListFile",
|
5079
6884
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5080
6885
|
*,
|
5081
6886
|
async_: Literal[False, True] = False,
|
5082
6887
|
**request_kwargs,
|
5083
6888
|
) -> dict | Coroutine[Any, Any, dict]:
|
5084
|
-
"""
|
5085
|
-
|
5086
|
-
GET https://www.123pan.com/api/file/list
|
6889
|
+
"""获取某个目录下的视频列表
|
5087
6890
|
|
5088
|
-
|
5089
|
-
如果返回信息中,"Next" 字段的值为 "-1",代表最后一页(无需再翻页查询)
|
6891
|
+
GET https://www.123pan.com/api/file/video/play/list
|
5090
6892
|
|
5091
6893
|
:payload:
|
5092
|
-
-
|
5093
|
-
-
|
5094
|
-
-
|
5095
|
-
- orderBy: str = "file_id" 💡 排序依据
|
5096
|
-
|
5097
|
-
- "file_id": 文件 id
|
5098
|
-
- "file_name": 文件名
|
5099
|
-
- "size": 文件大小
|
5100
|
-
- "create_at": 创建时间
|
5101
|
-
- "update_at": 更新时间
|
5102
|
-
- "share_id": 分享 id
|
5103
|
-
- ...
|
5104
|
-
|
5105
|
-
- orderDirection: "asc" | "desc" = "asc" 💡 排序顺序
|
5106
|
-
- Page: int = <default> 💡 第几页,从 1 开始,可以是 0
|
5107
|
-
- parentFileId: int | str = 0 💡 父目录 id
|
5108
|
-
- trashed: "false" | "true" = <default> 💡 是否查看回收站的文件
|
5109
|
-
- inDirectSpace: "false" | "true" = "false"
|
5110
|
-
- event: str = "homeListFile" 💡 事件名称
|
5111
|
-
|
5112
|
-
- "homeListFile": 全部文件
|
5113
|
-
- "recycleListFile": 回收站
|
5114
|
-
- "syncFileList": 同步空间
|
5115
|
-
|
5116
|
-
- operateType: int | str = <default> 💡 操作类型,如果在同步空间,则需要指定为 "SyncSpacePage"
|
5117
|
-
- SearchData: str = <default> 💡 搜索关键字(将无视 `parentFileId` 参数)
|
5118
|
-
- OnlyLookAbnormalFile: int = <default>
|
6894
|
+
- page: int = 1
|
6895
|
+
- page_size: int = 100
|
6896
|
+
- parent_file_id: int = 0
|
5119
6897
|
"""
|
5120
|
-
if isinstance(payload,
|
5121
|
-
payload = {"
|
5122
|
-
payload
|
5123
|
-
|
5124
|
-
"limit": 100,
|
5125
|
-
"next": 0,
|
5126
|
-
"orderBy": "file_id",
|
5127
|
-
"orderDirection": "asc",
|
5128
|
-
"parentFileId": 0,
|
5129
|
-
"inDirectSpace": "false",
|
5130
|
-
"event": event,
|
5131
|
-
})
|
5132
|
-
if not payload.get("trashed"):
|
5133
|
-
match payload["event"]:
|
5134
|
-
case "recycleListFile":
|
5135
|
-
payload["trashed"] = "true"
|
5136
|
-
case _:
|
5137
|
-
payload["trashed"] = "false"
|
6898
|
+
if not isinstance(payload, dict):
|
6899
|
+
payload = {"parent_file_id": payload}
|
6900
|
+
payload.setdefault("page", 1)
|
6901
|
+
payload.setdefault("page_size", 100)
|
5138
6902
|
return self.request(
|
5139
|
-
"file/list",
|
6903
|
+
"file/video/play/list",
|
5140
6904
|
params=payload,
|
5141
6905
|
base_url=base_url,
|
5142
6906
|
async_=async_,
|
5143
6907
|
**request_kwargs,
|
5144
6908
|
)
|
5145
6909
|
|
6910
|
+
########## Qrcode API ##########
|
6911
|
+
|
5146
6912
|
@overload
|
5147
|
-
|
5148
|
-
|
5149
|
-
payload: dict
|
6913
|
+
@staticmethod
|
6914
|
+
def login_passport(
|
6915
|
+
payload: dict,
|
5150
6916
|
/,
|
5151
|
-
|
6917
|
+
request: None | Callable = None,
|
5152
6918
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5153
6919
|
*,
|
5154
6920
|
async_: Literal[False] = False,
|
@@ -5156,211 +6922,141 @@ class P123Client(P123OpenClient):
|
|
5156
6922
|
) -> dict:
|
5157
6923
|
...
|
5158
6924
|
@overload
|
5159
|
-
|
5160
|
-
|
5161
|
-
payload: dict
|
6925
|
+
@staticmethod
|
6926
|
+
def login_passport(
|
6927
|
+
payload: dict,
|
5162
6928
|
/,
|
5163
|
-
|
6929
|
+
request: None | Callable = None,
|
5164
6930
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5165
6931
|
*,
|
5166
6932
|
async_: Literal[True],
|
5167
6933
|
**request_kwargs,
|
5168
6934
|
) -> Coroutine[Any, Any, dict]:
|
5169
6935
|
...
|
5170
|
-
|
5171
|
-
|
5172
|
-
payload: dict
|
6936
|
+
@staticmethod
|
6937
|
+
def login_passport(
|
6938
|
+
payload: dict,
|
5173
6939
|
/,
|
5174
|
-
|
6940
|
+
request: None | Callable = None,
|
5175
6941
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5176
6942
|
*,
|
5177
6943
|
async_: Literal[False, True] = False,
|
5178
6944
|
**request_kwargs,
|
5179
6945
|
) -> dict | Coroutine[Any, Any, dict]:
|
5180
|
-
"""
|
6946
|
+
"""使用账号和密码登录
|
5181
6947
|
|
5182
|
-
|
6948
|
+
POST https://www.123pan.com/api/user/sign_in
|
5183
6949
|
|
5184
6950
|
.. note::
|
5185
|
-
|
6951
|
+
获取的 token 有效期 30 天
|
5186
6952
|
|
5187
6953
|
:payload:
|
5188
|
-
-
|
5189
|
-
-
|
5190
|
-
-
|
5191
|
-
- orderBy: str = "file_id" 💡 排序依据
|
5192
|
-
|
5193
|
-
- "fileId": 文件 id
|
5194
|
-
- "file_name": 文件名
|
5195
|
-
- "size": 文件大小
|
5196
|
-
- "create_at": 创建时间
|
5197
|
-
- "update_at": 更新时间
|
5198
|
-
- "share_id": 分享 id
|
5199
|
-
- ...
|
5200
|
-
|
5201
|
-
- orderDirection: "asc" | "desc" = "asc" 💡 排序顺序
|
5202
|
-
- Page: int = 1 💡 第几页,从 1 开始
|
5203
|
-
- parentFileId: int | str = 0 💡 父目录 id
|
5204
|
-
- trashed: "false" | "true" = <default> 💡 是否查看回收站的文件
|
5205
|
-
- inDirectSpace: "false" | "true" = "false"
|
5206
|
-
- event: str = "homeListFile" 💡 事件名称
|
5207
|
-
|
5208
|
-
- "homeListFile": 全部文件
|
5209
|
-
- "recycleListFile": 回收站
|
5210
|
-
- "syncFileList": 同步空间
|
5211
|
-
|
5212
|
-
- operateType: int | str = <default> 💡 操作类型,如果在同步空间,则需要指定为 "SyncSpacePage"
|
5213
|
-
|
5214
|
-
.. note::
|
5215
|
-
这个值似乎不影响结果,所以可以忽略。我在浏览器中,看到罗列根目录为 1,搜索(指定 `SearchData`)为 2,同步空间的根目录为 3,罗列其它目录大多为 4,偶尔为 8,也可能是其它值
|
5216
|
-
|
5217
|
-
- SearchData: str = <default> 💡 搜索关键字(将无视 `parentFileId` 参数)
|
5218
|
-
- OnlyLookAbnormalFile: int = 0 💡 大概可传入 0 或 1
|
5219
|
-
- RequestSource: int = <default> 💡 浏览器中,在同步空间中为 1
|
6954
|
+
- passport: int | str 💡 手机号或邮箱
|
6955
|
+
- password: str 💡 密码
|
6956
|
+
- remember: bool = True 💡 是否记住密码(不用管)
|
5220
6957
|
"""
|
5221
|
-
|
5222
|
-
|
5223
|
-
|
5224
|
-
|
5225
|
-
"
|
5226
|
-
|
5227
|
-
"orderBy": "file_id",
|
5228
|
-
"orderDirection": "asc",
|
5229
|
-
"parentFileId": 0,
|
5230
|
-
"inDirectSpace": "false",
|
5231
|
-
"event": event,
|
5232
|
-
"OnlyLookAbnormalFile": 0,
|
5233
|
-
"Page": 1,
|
5234
|
-
})
|
5235
|
-
if not payload.get("trashed"):
|
5236
|
-
match payload["event"]:
|
5237
|
-
case "recycleListFile":
|
5238
|
-
payload["trashed"] = "true"
|
5239
|
-
case _:
|
5240
|
-
payload["trashed"] = "false"
|
5241
|
-
return self.request(
|
5242
|
-
"file/list/new",
|
5243
|
-
params=payload,
|
5244
|
-
base_url=base_url,
|
5245
|
-
async_=async_,
|
5246
|
-
**request_kwargs,
|
5247
|
-
)
|
6958
|
+
api = complete_url("user/sign_in", base_url)
|
6959
|
+
request_kwargs.setdefault("parse", default_parse)
|
6960
|
+
if request is None:
|
6961
|
+
request = get_default_request()
|
6962
|
+
request_kwargs["async_"] = async_
|
6963
|
+
return request(url=api, method="POST", json=payload, **request_kwargs)
|
5248
6964
|
|
5249
|
-
@overload
|
5250
|
-
|
5251
|
-
|
5252
|
-
|
6965
|
+
@overload
|
6966
|
+
@staticmethod
|
6967
|
+
def login_qrcode_bind_wx_code(
|
6968
|
+
payload: dict,
|
5253
6969
|
/,
|
5254
|
-
|
5255
|
-
|
5256
|
-
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6970
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
6971
|
+
request: None | Callable = None,
|
5257
6972
|
*,
|
5258
6973
|
async_: Literal[False] = False,
|
5259
6974
|
**request_kwargs,
|
5260
6975
|
) -> dict:
|
5261
6976
|
...
|
5262
6977
|
@overload
|
5263
|
-
|
5264
|
-
|
5265
|
-
|
6978
|
+
@staticmethod
|
6979
|
+
def login_qrcode_bind_wx_code(
|
6980
|
+
payload: dict,
|
5266
6981
|
/,
|
5267
|
-
|
5268
|
-
|
5269
|
-
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6982
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
6983
|
+
request: None | Callable = None,
|
5270
6984
|
*,
|
5271
6985
|
async_: Literal[True],
|
5272
6986
|
**request_kwargs,
|
5273
6987
|
) -> Coroutine[Any, Any, dict]:
|
5274
6988
|
...
|
5275
|
-
|
5276
|
-
|
5277
|
-
|
6989
|
+
@staticmethod
|
6990
|
+
def login_qrcode_bind_wx_code(
|
6991
|
+
payload: dict,
|
5278
6992
|
/,
|
5279
|
-
|
5280
|
-
|
5281
|
-
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6993
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
6994
|
+
request: None | Callable = None,
|
5282
6995
|
*,
|
5283
6996
|
async_: Literal[False, True] = False,
|
5284
6997
|
**request_kwargs,
|
5285
6998
|
) -> dict | Coroutine[Any, Any, dict]:
|
5286
|
-
"""
|
6999
|
+
"""绑定微信号
|
5287
7000
|
|
5288
|
-
|
5289
|
-
:param parent_id: 父目录 id
|
5290
|
-
:param duplicate: 处理同名:0: 复用 1: 保留两者 2: 替换
|
5291
|
-
:param async_: 是否异步
|
5292
|
-
:param request_kwargs: 其它请求参数
|
7001
|
+
POST https://login.123pan.com/api/user/qr-code/bind_wx_code
|
5293
7002
|
|
5294
|
-
:
|
7003
|
+
:payload:
|
7004
|
+
- uniID: str 💡 二维码 id
|
7005
|
+
- wxcode: str 💡 微信码
|
5295
7006
|
"""
|
5296
|
-
|
5297
|
-
if
|
5298
|
-
|
5299
|
-
|
5300
|
-
return
|
5301
|
-
|
5302
|
-
|
5303
|
-
|
7007
|
+
request_kwargs.setdefault("parse", default_parse)
|
7008
|
+
if request is None:
|
7009
|
+
request = get_default_request()
|
7010
|
+
request_kwargs["async_"] = async_
|
7011
|
+
return request(
|
7012
|
+
url=complete_url("user/qr-code/bind_wx_code", base_url),
|
7013
|
+
method="POST",
|
7014
|
+
json=payload,
|
5304
7015
|
**request_kwargs,
|
5305
7016
|
)
|
5306
7017
|
|
5307
7018
|
@overload
|
5308
|
-
def
|
7019
|
+
def login_qrcode_confirm(
|
5309
7020
|
self,
|
5310
|
-
payload: dict |
|
7021
|
+
payload: dict | str,
|
5311
7022
|
/,
|
5312
|
-
|
5313
|
-
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
7023
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
5314
7024
|
*,
|
5315
7025
|
async_: Literal[False] = False,
|
5316
7026
|
**request_kwargs,
|
5317
7027
|
) -> dict:
|
5318
7028
|
...
|
5319
7029
|
@overload
|
5320
|
-
def
|
7030
|
+
def login_qrcode_confirm(
|
5321
7031
|
self,
|
5322
|
-
payload: dict |
|
7032
|
+
payload: dict | str,
|
5323
7033
|
/,
|
5324
|
-
|
5325
|
-
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
7034
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
5326
7035
|
*,
|
5327
7036
|
async_: Literal[True],
|
5328
7037
|
**request_kwargs,
|
5329
7038
|
) -> Coroutine[Any, Any, dict]:
|
5330
7039
|
...
|
5331
|
-
def
|
7040
|
+
def login_qrcode_confirm(
|
5332
7041
|
self,
|
5333
|
-
payload: dict |
|
7042
|
+
payload: dict | str,
|
5334
7043
|
/,
|
5335
|
-
|
5336
|
-
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
7044
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
5337
7045
|
*,
|
5338
7046
|
async_: Literal[False, True] = False,
|
5339
7047
|
**request_kwargs,
|
5340
7048
|
) -> dict | Coroutine[Any, Any, dict]:
|
5341
|
-
"""
|
7049
|
+
"""确认扫码登录
|
5342
7050
|
|
5343
|
-
POST https://
|
7051
|
+
POST https://login.123pan.com/api/user/qr-code/login
|
5344
7052
|
|
5345
7053
|
:payload:
|
5346
|
-
-
|
5347
|
-
|
5348
|
-
.. code:: python
|
5349
|
-
|
5350
|
-
FileID = {
|
5351
|
-
"FileId": int | str
|
5352
|
-
}
|
5353
|
-
|
5354
|
-
- parentFileId: int | str = 0
|
5355
|
-
- event: str = "fileMove"
|
7054
|
+
- uniID: str 💡 二维码 id
|
5356
7055
|
"""
|
5357
|
-
if isinstance(payload,
|
5358
|
-
payload = {"
|
5359
|
-
elif not isinstance(payload, dict):
|
5360
|
-
payload = {"fileIdList": [{"FileId": fid} for fid in payload]}
|
5361
|
-
payload = dict_to_lower_merge(payload, {"parentFileId": parent_id, "event": "fileMove"})
|
7056
|
+
if not isinstance(payload, dict):
|
7057
|
+
payload = {"uniID": payload}
|
5362
7058
|
return self.request(
|
5363
|
-
"
|
7059
|
+
"user/qr-code/login",
|
5364
7060
|
"POST",
|
5365
7061
|
json=payload,
|
5366
7062
|
base_url=base_url,
|
@@ -5369,237 +7065,221 @@ class P123Client(P123OpenClient):
|
|
5369
7065
|
)
|
5370
7066
|
|
5371
7067
|
@overload
|
5372
|
-
|
5373
|
-
|
5374
|
-
payload: dict
|
7068
|
+
@staticmethod
|
7069
|
+
def login_qrcode_deny(
|
7070
|
+
payload: dict | str,
|
5375
7071
|
/,
|
5376
|
-
base_url: str | Callable[[], str] =
|
7072
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
7073
|
+
request: None | Callable = None,
|
5377
7074
|
*,
|
5378
7075
|
async_: Literal[False] = False,
|
5379
7076
|
**request_kwargs,
|
5380
7077
|
) -> dict:
|
5381
7078
|
...
|
5382
7079
|
@overload
|
5383
|
-
|
5384
|
-
|
5385
|
-
payload: dict
|
7080
|
+
@staticmethod
|
7081
|
+
def login_qrcode_deny(
|
7082
|
+
payload: dict | str,
|
5386
7083
|
/,
|
5387
|
-
base_url: str | Callable[[], str] =
|
7084
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
7085
|
+
request: None | Callable = None,
|
5388
7086
|
*,
|
5389
7087
|
async_: Literal[True],
|
5390
7088
|
**request_kwargs,
|
5391
7089
|
) -> Coroutine[Any, Any, dict]:
|
5392
7090
|
...
|
5393
|
-
|
5394
|
-
|
5395
|
-
payload: dict
|
7091
|
+
@staticmethod
|
7092
|
+
def login_qrcode_deny(
|
7093
|
+
payload: dict | str,
|
5396
7094
|
/,
|
5397
|
-
base_url: str | Callable[[], str] =
|
7095
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
7096
|
+
request: None | Callable = None,
|
5398
7097
|
*,
|
5399
7098
|
async_: Literal[False, True] = False,
|
5400
7099
|
**request_kwargs,
|
5401
7100
|
) -> dict | Coroutine[Any, Any, dict]:
|
5402
|
-
"""
|
7101
|
+
"""更新扫码状态为:已取消(loginStatus=2)
|
5403
7102
|
|
5404
|
-
POST https://
|
7103
|
+
POST https://login.123pan.com/api/user/qr-code/deny
|
7104
|
+
|
7105
|
+
:payload:
|
7106
|
+
- uniID: str 💡 二维码 id
|
5405
7107
|
"""
|
5406
|
-
|
5407
|
-
"
|
5408
|
-
|
7108
|
+
if not isinstance(payload, dict):
|
7109
|
+
payload = {"uniID": payload}
|
7110
|
+
request_kwargs.setdefault("parse", default_parse)
|
7111
|
+
if request is None:
|
7112
|
+
request = get_default_request()
|
7113
|
+
request_kwargs["async_"] = async_
|
7114
|
+
return request(
|
7115
|
+
url=complete_url("user/qr-code/deny", base_url),
|
7116
|
+
method="POST",
|
5409
7117
|
json=payload,
|
5410
|
-
base_url=base_url,
|
5411
|
-
async_=async_,
|
5412
7118
|
**request_kwargs,
|
5413
7119
|
)
|
5414
7120
|
|
5415
|
-
@overload
|
5416
|
-
|
5417
|
-
|
5418
|
-
|
5419
|
-
|
5420
|
-
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
7121
|
+
@overload
|
7122
|
+
@staticmethod
|
7123
|
+
def login_qrcode_generate(
|
7124
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
7125
|
+
request: None | Callable = None,
|
5421
7126
|
*,
|
5422
7127
|
async_: Literal[False] = False,
|
5423
7128
|
**request_kwargs,
|
5424
7129
|
) -> dict:
|
5425
7130
|
...
|
5426
7131
|
@overload
|
5427
|
-
|
5428
|
-
|
5429
|
-
|
5430
|
-
|
5431
|
-
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
7132
|
+
@staticmethod
|
7133
|
+
def login_qrcode_generate(
|
7134
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
7135
|
+
request: None | Callable = None,
|
5432
7136
|
*,
|
5433
7137
|
async_: Literal[True],
|
5434
7138
|
**request_kwargs,
|
5435
7139
|
) -> Coroutine[Any, Any, dict]:
|
5436
7140
|
...
|
5437
|
-
|
5438
|
-
|
5439
|
-
|
5440
|
-
|
5441
|
-
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
7141
|
+
@staticmethod
|
7142
|
+
def login_qrcode_generate(
|
7143
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
7144
|
+
request: None | Callable = None,
|
5442
7145
|
*,
|
5443
7146
|
async_: Literal[False, True] = False,
|
5444
7147
|
**request_kwargs,
|
5445
7148
|
) -> dict | Coroutine[Any, Any, dict]:
|
5446
|
-
"""
|
5447
|
-
|
5448
|
-
POST https://www.123pan.com/api/file/rename
|
7149
|
+
"""产生二维码
|
5449
7150
|
|
5450
|
-
|
5451
|
-
- FileId: int | str
|
5452
|
-
- fileName: str
|
5453
|
-
- driveId: int | str = 0
|
5454
|
-
- duplicate: 0 | 1 | 2 = 0 💡 处理同名:0: 提示/忽略 1: 保留两者 2: 替换
|
5455
|
-
- event: str = "fileRename"
|
7151
|
+
GET https://login.123pan.com/api/user/qr-code/generate
|
5456
7152
|
"""
|
5457
|
-
|
5458
|
-
|
5459
|
-
|
5460
|
-
"
|
5461
|
-
|
5462
|
-
|
5463
|
-
"file/rename",
|
5464
|
-
"POST",
|
5465
|
-
json=payload,
|
5466
|
-
base_url=base_url,
|
5467
|
-
async_=async_,
|
7153
|
+
request_kwargs.setdefault("parse", default_parse)
|
7154
|
+
if request is None:
|
7155
|
+
request = get_default_request()
|
7156
|
+
request_kwargs["async_"] = async_
|
7157
|
+
return request(
|
7158
|
+
url=complete_url("user/qr-code/generate", base_url),
|
5468
7159
|
**request_kwargs,
|
5469
7160
|
)
|
5470
7161
|
|
5471
7162
|
@overload
|
5472
|
-
|
5473
|
-
|
5474
|
-
payload: dict |
|
7163
|
+
@staticmethod
|
7164
|
+
def login_qrcode_result(
|
7165
|
+
payload: dict | str,
|
5475
7166
|
/,
|
5476
|
-
base_url: str | Callable[[], str] =
|
7167
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
7168
|
+
request: None | Callable = None,
|
5477
7169
|
*,
|
5478
7170
|
async_: Literal[False] = False,
|
5479
7171
|
**request_kwargs,
|
5480
7172
|
) -> dict:
|
5481
7173
|
...
|
5482
7174
|
@overload
|
5483
|
-
|
5484
|
-
|
5485
|
-
payload: dict |
|
7175
|
+
@staticmethod
|
7176
|
+
def login_qrcode_result(
|
7177
|
+
payload: dict | str,
|
5486
7178
|
/,
|
5487
|
-
base_url: str | Callable[[], str] =
|
7179
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
7180
|
+
request: None | Callable = None,
|
5488
7181
|
*,
|
5489
7182
|
async_: Literal[True],
|
5490
7183
|
**request_kwargs,
|
5491
7184
|
) -> Coroutine[Any, Any, dict]:
|
5492
7185
|
...
|
5493
|
-
|
5494
|
-
|
5495
|
-
payload: dict |
|
7186
|
+
@staticmethod
|
7187
|
+
def login_qrcode_result(
|
7188
|
+
payload: dict | str,
|
5496
7189
|
/,
|
5497
|
-
base_url: str | Callable[[], str] =
|
7190
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
7191
|
+
request: None | Callable = None,
|
5498
7192
|
*,
|
5499
7193
|
async_: Literal[False, True] = False,
|
5500
7194
|
**request_kwargs,
|
5501
7195
|
) -> dict | Coroutine[Any, Any, dict]:
|
5502
|
-
"""
|
7196
|
+
"""获取扫码结果
|
5503
7197
|
|
5504
|
-
GET https://
|
7198
|
+
GET https://login.123pan.com/api/user/qr-code/result
|
7199
|
+
|
7200
|
+
.. note::
|
7201
|
+
返回值中有个 "loginStatus" 字段,值为数字,分别表示的意思为:
|
7202
|
+
|
7203
|
+
- 0: 等待扫码
|
7204
|
+
- 1: 已扫码
|
7205
|
+
- 2: 已取消
|
7206
|
+
- 3: 已登录
|
7207
|
+
- 4: 已失效
|
5505
7208
|
|
5506
7209
|
:payload:
|
5507
|
-
-
|
5508
|
-
- pageSize: int = 100 💡 每页大小
|
5509
|
-
- searchData: str = <default> 💡 搜索关键字
|
7210
|
+
- uniID: str 💡 二维码 id
|
5510
7211
|
"""
|
5511
7212
|
if not isinstance(payload, dict):
|
5512
|
-
payload = {"
|
5513
|
-
|
5514
|
-
|
7213
|
+
payload = {"uniID": payload}
|
7214
|
+
request_kwargs.setdefault("parse", default_parse)
|
7215
|
+
if request is None:
|
7216
|
+
request = get_default_request()
|
7217
|
+
request_kwargs["async_"] = async_
|
7218
|
+
return request(
|
7219
|
+
url=complete_url("user/qr-code/result", base_url),
|
5515
7220
|
params=payload,
|
5516
|
-
base_url=base_url,
|
5517
|
-
async_=async_,
|
5518
7221
|
**request_kwargs,
|
5519
7222
|
)
|
5520
7223
|
|
5521
|
-
@overload
|
5522
|
-
|
5523
|
-
|
5524
|
-
payload: dict |
|
7224
|
+
@overload
|
7225
|
+
@staticmethod
|
7226
|
+
def login_qrcode_scan(
|
7227
|
+
payload: dict | str,
|
5525
7228
|
/,
|
5526
|
-
|
5527
|
-
|
7229
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
7230
|
+
request: None | Callable = None,
|
5528
7231
|
*,
|
5529
7232
|
async_: Literal[False] = False,
|
5530
7233
|
**request_kwargs,
|
5531
7234
|
) -> dict:
|
5532
7235
|
...
|
5533
7236
|
@overload
|
5534
|
-
|
5535
|
-
|
5536
|
-
payload: dict |
|
7237
|
+
@staticmethod
|
7238
|
+
def login_qrcode_scan(
|
7239
|
+
payload: dict | str,
|
5537
7240
|
/,
|
5538
|
-
|
5539
|
-
|
7241
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
7242
|
+
request: None | Callable = None,
|
5540
7243
|
*,
|
5541
7244
|
async_: Literal[True],
|
5542
7245
|
**request_kwargs,
|
5543
7246
|
) -> Coroutine[Any, Any, dict]:
|
5544
7247
|
...
|
5545
|
-
|
5546
|
-
|
5547
|
-
payload: dict |
|
7248
|
+
@staticmethod
|
7249
|
+
def login_qrcode_scan(
|
7250
|
+
payload: dict | str,
|
5548
7251
|
/,
|
5549
|
-
|
5550
|
-
|
7252
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
7253
|
+
request: None | Callable = None,
|
5551
7254
|
*,
|
5552
7255
|
async_: Literal[False, True] = False,
|
5553
7256
|
**request_kwargs,
|
5554
7257
|
) -> dict | Coroutine[Any, Any, dict]:
|
5555
|
-
"""
|
7258
|
+
"""更新扫码状态为:已扫码(loginStatus=1)
|
5556
7259
|
|
5557
|
-
POST https://
|
7260
|
+
POST https://login.123pan.com/api/user/qr-code/scan
|
5558
7261
|
|
5559
7262
|
:payload:
|
5560
|
-
-
|
5561
|
-
|
5562
|
-
.. code:: python
|
5563
|
-
|
5564
|
-
File = {
|
5565
|
-
"FileId": int | str,
|
5566
|
-
...
|
5567
|
-
}
|
5568
|
-
|
5569
|
-
- driveId: int = 0
|
5570
|
-
- event: str = "intoRecycle" 💡 事件类型
|
5571
|
-
|
5572
|
-
- "intoRecycle": 移入回收站
|
5573
|
-
- "recycleRestore": 移出回收站
|
5574
|
-
|
5575
|
-
- operation: bool = <default>
|
5576
|
-
- operatePlace: int = <default>
|
5577
|
-
- RequestSource: int = <default>
|
7263
|
+
- uniID: str 💡 二维码 id
|
7264
|
+
- scanPlatform: int = 4 💡 扫码的平台代码,微信是 4
|
5578
7265
|
"""
|
5579
|
-
if isinstance(payload,
|
5580
|
-
payload = {"
|
5581
|
-
|
5582
|
-
|
5583
|
-
|
5584
|
-
|
5585
|
-
|
5586
|
-
|
5587
|
-
|
5588
|
-
|
5589
|
-
payload["operation"] = True
|
5590
|
-
return self.request(
|
5591
|
-
"file/trash",
|
5592
|
-
"POST",
|
7266
|
+
if not isinstance(payload, dict):
|
7267
|
+
payload = {"uniID": payload}
|
7268
|
+
payload.setdefault("scanPlatform", 4)
|
7269
|
+
request_kwargs.setdefault("parse", default_parse)
|
7270
|
+
if request is None:
|
7271
|
+
request = get_default_request()
|
7272
|
+
request_kwargs["async_"] = async_
|
7273
|
+
return request(
|
7274
|
+
url=complete_url("user/qr-code/scan", base_url),
|
7275
|
+
method="POST",
|
5593
7276
|
json=payload,
|
5594
|
-
base_url=base_url,
|
5595
|
-
async_=async_,
|
5596
7277
|
**request_kwargs,
|
5597
7278
|
)
|
5598
7279
|
|
5599
7280
|
@overload
|
5600
|
-
def
|
7281
|
+
def logout(
|
5601
7282
|
self,
|
5602
|
-
payload: dict = {"event": "recycleClear"},
|
5603
7283
|
/,
|
5604
7284
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5605
7285
|
*,
|
@@ -5608,9 +7288,8 @@ class P123Client(P123OpenClient):
|
|
5608
7288
|
) -> dict:
|
5609
7289
|
...
|
5610
7290
|
@overload
|
5611
|
-
def
|
7291
|
+
def logout(
|
5612
7292
|
self,
|
5613
|
-
payload: dict = {"event": "recycleClear"},
|
5614
7293
|
/,
|
5615
7294
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5616
7295
|
*,
|
@@ -5618,32 +7297,28 @@ class P123Client(P123OpenClient):
|
|
5618
7297
|
**request_kwargs,
|
5619
7298
|
) -> Coroutine[Any, Any, dict]:
|
5620
7299
|
...
|
5621
|
-
def
|
7300
|
+
def logout(
|
5622
7301
|
self,
|
5623
|
-
payload: dict = {"event": "recycleClear"},
|
5624
7302
|
/,
|
5625
7303
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5626
7304
|
*,
|
5627
7305
|
async_: Literal[False, True] = False,
|
5628
7306
|
**request_kwargs,
|
5629
7307
|
) -> dict | Coroutine[Any, Any, dict]:
|
5630
|
-
"""
|
5631
|
-
|
5632
|
-
POST https://www.123pan.com/api/file/trash_delete_all
|
7308
|
+
"""退出登录
|
5633
7309
|
|
5634
|
-
|
5635
|
-
- event: str = "recycleClear"
|
7310
|
+
POST https://www.123pan.com/api/user/logout
|
5636
7311
|
"""
|
5637
|
-
payload.setdefault("event", "recycleClear")
|
5638
7312
|
return self.request(
|
5639
|
-
"
|
7313
|
+
"user/logout",
|
5640
7314
|
"POST",
|
5641
|
-
json=payload,
|
5642
7315
|
base_url=base_url,
|
5643
7316
|
async_=async_,
|
5644
7317
|
**request_kwargs,
|
5645
7318
|
)
|
5646
7319
|
|
7320
|
+
########## Offline Download API ##########
|
7321
|
+
|
5647
7322
|
@overload
|
5648
7323
|
def offline_task_delete(
|
5649
7324
|
self,
|
@@ -5681,7 +7356,7 @@ class P123Client(P123OpenClient):
|
|
5681
7356
|
|
5682
7357
|
:payload:
|
5683
7358
|
- task_ids: list[int] 💡 任务 id 列表
|
5684
|
-
- status_arr: list[0|1|2] = [] 💡 状态列表:0
|
7359
|
+
- status_arr: list[ 0 | 1 | 2 | 3 | 4 ] = [] 💡 状态列表:0:进行中 1:下载失败 2:下载成功 3:重试中
|
5685
7360
|
"""
|
5686
7361
|
if isinstance(payload, int):
|
5687
7362
|
payload = {"task_ids": [payload], "status_arr": []}
|
@@ -5736,12 +7411,12 @@ class P123Client(P123OpenClient):
|
|
5736
7411
|
:payload:
|
5737
7412
|
- current_page: int = 1
|
5738
7413
|
- page_size: 100
|
5739
|
-
- status_arr: list[0|1|2] = [0, 1] 💡 状态列表:0
|
7414
|
+
- status_arr: list[ 0 | 1 | 2 | 3 | 4 ] = [0, 1, 2, 3, 4] 💡 状态列表:0:进行中 1:下载失败 2:下载成功 3:重试中
|
5740
7415
|
"""
|
5741
7416
|
if isinstance(payload, int):
|
5742
|
-
payload = {"current_page": payload, "page_size": 100, "status_arr": [0, 1]}
|
7417
|
+
payload = {"current_page": payload, "page_size": 100, "status_arr": [0, 1, 2, 3, 4]}
|
5743
7418
|
else:
|
5744
|
-
payload = {"current_page": 1, "page_size": 100, "status_arr": [0, 1], **payload}
|
7419
|
+
payload = {"current_page": 1, "page_size": 100, "status_arr": [0, 1, 2, 3, 4], **payload}
|
5745
7420
|
return self.request(
|
5746
7421
|
"offline_download/task/list",
|
5747
7422
|
"POST",
|
@@ -5908,6 +7583,8 @@ class P123Client(P123OpenClient):
|
|
5908
7583
|
**request_kwargs,
|
5909
7584
|
)
|
5910
7585
|
|
7586
|
+
########## Share API ##########
|
7587
|
+
|
5911
7588
|
@overload
|
5912
7589
|
def share_cancel(
|
5913
7590
|
self,
|
@@ -6684,6 +8361,8 @@ class P123Client(P123OpenClient):
|
|
6684
8361
|
**request_kwargs,
|
6685
8362
|
)
|
6686
8363
|
|
8364
|
+
########## Upload API ##########
|
8365
|
+
|
6687
8366
|
@overload
|
6688
8367
|
def upload_auth(
|
6689
8368
|
self,
|
@@ -7407,6 +9086,8 @@ class P123Client(P123OpenClient):
|
|
7407
9086
|
)
|
7408
9087
|
return run_gen_step(gen_step, async_)
|
7409
9088
|
|
9089
|
+
########## User API ##########
|
9090
|
+
|
7410
9091
|
@overload
|
7411
9092
|
def user_device_list(
|
7412
9093
|
self,
|
@@ -7496,11 +9177,9 @@ class P123Client(P123OpenClient):
|
|
7496
9177
|
)
|
7497
9178
|
|
7498
9179
|
@overload
|
7499
|
-
|
7500
|
-
|
7501
|
-
payload: dict,
|
9180
|
+
def user_referral_info(
|
9181
|
+
self,
|
7502
9182
|
/,
|
7503
|
-
request: None | Callable = None,
|
7504
9183
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
7505
9184
|
*,
|
7506
9185
|
async_: Literal[False] = False,
|
@@ -7508,45 +9187,72 @@ class P123Client(P123OpenClient):
|
|
7508
9187
|
) -> dict:
|
7509
9188
|
...
|
7510
9189
|
@overload
|
7511
|
-
|
7512
|
-
|
7513
|
-
payload: dict,
|
9190
|
+
def user_referral_info(
|
9191
|
+
self,
|
7514
9192
|
/,
|
7515
|
-
request: None | Callable = None,
|
7516
9193
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
7517
9194
|
*,
|
7518
9195
|
async_: Literal[True],
|
7519
9196
|
**request_kwargs,
|
7520
9197
|
) -> Coroutine[Any, Any, dict]:
|
7521
9198
|
...
|
7522
|
-
|
7523
|
-
|
7524
|
-
payload: dict,
|
9199
|
+
def user_referral_info(
|
9200
|
+
self,
|
7525
9201
|
/,
|
7526
|
-
request: None | Callable = None,
|
7527
9202
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
7528
9203
|
*,
|
7529
9204
|
async_: Literal[False, True] = False,
|
7530
9205
|
**request_kwargs,
|
7531
9206
|
) -> dict | Coroutine[Any, Any, dict]:
|
7532
|
-
"""
|
9207
|
+
"""用户拉人头信息
|
7533
9208
|
|
7534
|
-
|
9209
|
+
GET https://www.123pan.com/api/referral/my-info
|
9210
|
+
"""
|
9211
|
+
return self.request(
|
9212
|
+
"referral/my-info",
|
9213
|
+
base_url=base_url,
|
9214
|
+
async_=async_,
|
9215
|
+
**request_kwargs,
|
9216
|
+
)
|
7535
9217
|
|
7536
|
-
|
7537
|
-
|
9218
|
+
@overload
|
9219
|
+
def user_report_info(
|
9220
|
+
self,
|
9221
|
+
/,
|
9222
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
9223
|
+
*,
|
9224
|
+
async_: Literal[False] = False,
|
9225
|
+
**request_kwargs,
|
9226
|
+
) -> dict:
|
9227
|
+
...
|
9228
|
+
@overload
|
9229
|
+
def user_report_info(
|
9230
|
+
self,
|
9231
|
+
/,
|
9232
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
9233
|
+
*,
|
9234
|
+
async_: Literal[True],
|
9235
|
+
**request_kwargs,
|
9236
|
+
) -> Coroutine[Any, Any, dict]:
|
9237
|
+
...
|
9238
|
+
def user_report_info(
|
9239
|
+
self,
|
9240
|
+
/,
|
9241
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
9242
|
+
*,
|
9243
|
+
async_: Literal[False, True] = False,
|
9244
|
+
**request_kwargs,
|
9245
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
9246
|
+
"""用户推送消息配置
|
7538
9247
|
|
7539
|
-
|
7540
|
-
- passport: int | str 💡 手机号或邮箱
|
7541
|
-
- password: str 💡 密码
|
7542
|
-
- remember: bool = True 💡 是否记住密码(不用管)
|
9248
|
+
GET https://www.123pan.com/b/api/restful/goapi/v1/user/report/info
|
7543
9249
|
"""
|
7544
|
-
|
7545
|
-
|
7546
|
-
|
7547
|
-
|
7548
|
-
request_kwargs
|
7549
|
-
|
9250
|
+
return self.request(
|
9251
|
+
"restful/goapi/v1/user/report/info",
|
9252
|
+
base_url=base_url,
|
9253
|
+
async_=async_,
|
9254
|
+
**request_kwargs,
|
9255
|
+
)
|
7550
9256
|
|
7551
9257
|
@overload
|
7552
9258
|
def user_use_history(
|
@@ -7596,8 +9302,31 @@ class P123Client(P123OpenClient):
|
|
7596
9302
|
**request_kwargs,
|
7597
9303
|
)
|
7598
9304
|
|
7599
|
-
|
7600
|
-
|
7601
|
-
|
7602
|
-
|
9305
|
+
|
9306
|
+
with temp_globals():
|
9307
|
+
CRE_CLIENT_API_search: Final = re_compile(r"^ +((?:GET|POST|PUT|DELETE|PATCH) .*)", MULTILINE).search
|
9308
|
+
for name in dir(P123Client):
|
9309
|
+
method = getattr(P123Client, name)
|
9310
|
+
if not (callable(method) and method.__doc__):
|
9311
|
+
continue
|
9312
|
+
match = CRE_CLIENT_API_search(method.__doc__)
|
9313
|
+
if match is not None:
|
9314
|
+
api = match[1]
|
9315
|
+
name = "P123Client." + name
|
9316
|
+
CLIENT_METHOD_API_MAP[name] = api
|
9317
|
+
try:
|
9318
|
+
CLIENT_API_METHODS_MAP[api].append(name)
|
9319
|
+
except KeyError:
|
9320
|
+
CLIENT_API_METHODS_MAP[api] = [name]
|
9321
|
+
|
9322
|
+
|
7603
9323
|
# TODO: 对于某些工具的接口封装,例如 重复文件清理
|
9324
|
+
# TODO: 同步空间
|
9325
|
+
# TODO: 直链空间
|
9326
|
+
# TODO: 图床
|
9327
|
+
# TODO: 视频转码
|
9328
|
+
# TODO: 移入保险箱
|
9329
|
+
# TODO: 申诉和申诉列表
|
9330
|
+
# TODO: 歌单(以及批量加入歌单)
|
9331
|
+
# TODO: 最近查看
|
9332
|
+
# TODO: 消息通知列表和操作
|