p123client 0.0.6.9__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 +2451 -726
- p123client/const.py +10 -1
- p123client/exception.py +64 -7
- p123client/tool/__init__.py +5 -6
- {p123client-0.0.6.9.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.9.dist-info/RECORD +0 -12
- {p123client-0.0.6.9.dist-info → p123client-0.0.6.9.4.dist-info}/LICENSE +0 -0
- {p123client-0.0.6.9.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
|
@@ -1262,7 +1579,7 @@ class P123OpenClient:
|
|
1262
1579
|
|
1263
1580
|
:payload:
|
1264
1581
|
- limit: int = 100 💡 分页大小,最多 100
|
1265
|
-
- orderBy: str = "
|
1582
|
+
- orderBy: str = "file_name" 💡 排序依据
|
1266
1583
|
|
1267
1584
|
- "file_id": 文件 id
|
1268
1585
|
- "file_name": 文件名
|
@@ -1287,7 +1604,7 @@ class P123OpenClient:
|
|
1287
1604
|
payload = {"parentFileId": payload}
|
1288
1605
|
payload = dict_to_lower_merge(payload, {
|
1289
1606
|
"limit": 100,
|
1290
|
-
"orderBy": "
|
1607
|
+
"orderBy": "file_name",
|
1291
1608
|
"orderDirection": "asc",
|
1292
1609
|
"page": 1,
|
1293
1610
|
"parentFileId": 0,
|
@@ -1617,6 +1934,8 @@ class P123OpenClient:
|
|
1617
1934
|
payload = {"fileIDs": payload}
|
1618
1935
|
return self.request(api, "POST", json=payload, async_=async_, **request_kwargs)
|
1619
1936
|
|
1937
|
+
########## Offline Download API ##########
|
1938
|
+
|
1620
1939
|
@overload
|
1621
1940
|
def offline_download(
|
1622
1941
|
self,
|
@@ -1726,6 +2045,8 @@ class P123OpenClient:
|
|
1726
2045
|
payload = {"taskID": payload}
|
1727
2046
|
return self.request(api, params=payload, async_=async_, **request_kwargs)
|
1728
2047
|
|
2048
|
+
########## Oss API ##########
|
2049
|
+
|
1729
2050
|
@overload
|
1730
2051
|
def oss_copy(
|
1731
2052
|
self,
|
@@ -2864,6 +3185,8 @@ class P123OpenClient:
|
|
2864
3185
|
}) from e
|
2865
3186
|
return run_gen_step(gen_step, async_)
|
2866
3187
|
|
3188
|
+
########## Share API ##########
|
3189
|
+
|
2867
3190
|
@overload
|
2868
3191
|
def share_create(
|
2869
3192
|
self,
|
@@ -3072,6 +3395,8 @@ class P123OpenClient:
|
|
3072
3395
|
payload = {"limit": payload}
|
3073
3396
|
return self.request(api, params=payload, async_=async_, **request_kwargs)
|
3074
3397
|
|
3398
|
+
########## Transcode API ##########
|
3399
|
+
|
3075
3400
|
@overload
|
3076
3401
|
def transcode_delete(
|
3077
3402
|
self,
|
@@ -3618,6 +3943,8 @@ class P123OpenClient:
|
|
3618
3943
|
api = complete_url("/api/v1/transcode/video", base_url)
|
3619
3944
|
return self.request(api, "POST", json=payload, async_=async_, **request_kwargs)
|
3620
3945
|
|
3946
|
+
########## Upload API ##########
|
3947
|
+
|
3621
3948
|
@overload
|
3622
3949
|
def upload_create(
|
3623
3950
|
self,
|
@@ -4220,6 +4547,8 @@ class P123OpenClient:
|
|
4220
4547
|
}) from e
|
4221
4548
|
return run_gen_step(gen_step, async_)
|
4222
4549
|
|
4550
|
+
########## User API ##########
|
4551
|
+
|
4223
4552
|
@overload
|
4224
4553
|
def user_info(
|
4225
4554
|
self,
|
@@ -4274,6 +4603,8 @@ class P123OpenClient:
|
|
4274
4603
|
api = complete_url("/api/v1/user/info", base_url)
|
4275
4604
|
return self.request(api, async_=async_, **request_kwargs)
|
4276
4605
|
|
4606
|
+
########## API Aliases ##########
|
4607
|
+
|
4277
4608
|
login_open = login
|
4278
4609
|
login_access_token_open = login_access_token
|
4279
4610
|
login_auth_open = login_auth
|
@@ -4341,19 +4672,36 @@ class P123OpenClient:
|
|
4341
4672
|
|
4342
4673
|
|
4343
4674
|
class P123Client(P123OpenClient):
|
4675
|
+
"""123 的客户端对象
|
4344
4676
|
|
4677
|
+
:param passport: 手机号或邮箱
|
4678
|
+
:param password: 密码
|
4679
|
+
:param token: 123 的访问令牌
|
4680
|
+
"""
|
4345
4681
|
def __init__(
|
4346
4682
|
self,
|
4347
4683
|
/,
|
4348
|
-
passport: int | str = "",
|
4684
|
+
passport: int | str | PathLike = "",
|
4349
4685
|
password: str = "",
|
4350
|
-
token: str =
|
4686
|
+
token: None | str | PathLike = None,
|
4351
4687
|
):
|
4352
|
-
|
4353
|
-
|
4354
|
-
|
4355
|
-
|
4688
|
+
if isinstance(passport, PathLike):
|
4689
|
+
token = passport
|
4690
|
+
else:
|
4691
|
+
self.passport = passport
|
4692
|
+
self.password = password
|
4693
|
+
if token is None:
|
4356
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()
|
4357
4705
|
|
4358
4706
|
@overload # type: ignore
|
4359
4707
|
def login(
|
@@ -4412,193 +4760,236 @@ class P123Client(P123OpenClient):
|
|
4412
4760
|
else:
|
4413
4761
|
password = self.password
|
4414
4762
|
def gen_step():
|
4415
|
-
|
4416
|
-
|
4417
|
-
|
4418
|
-
|
4419
|
-
|
4420
|
-
|
4421
|
-
|
4422
|
-
|
4423
|
-
|
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
|
4424
4781
|
return run_gen_step(gen_step, async_)
|
4425
4782
|
|
4426
4783
|
@overload
|
4427
|
-
|
4428
|
-
|
4429
|
-
|
4430
|
-
|
4784
|
+
def login_another(
|
4785
|
+
self,
|
4786
|
+
/,
|
4787
|
+
replace: bool | Self = False,
|
4788
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
4431
4789
|
*,
|
4432
4790
|
async_: Literal[False] = False,
|
4433
4791
|
**request_kwargs,
|
4434
|
-
) ->
|
4792
|
+
) -> Self:
|
4435
4793
|
...
|
4436
4794
|
@overload
|
4437
|
-
|
4438
|
-
|
4439
|
-
|
4440
|
-
|
4795
|
+
def login_another(
|
4796
|
+
self,
|
4797
|
+
/,
|
4798
|
+
replace: bool | Self = False,
|
4799
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
4441
4800
|
*,
|
4442
4801
|
async_: Literal[True],
|
4443
4802
|
**request_kwargs,
|
4444
|
-
) -> Coroutine[Any, Any,
|
4803
|
+
) -> Coroutine[Any, Any, Self]:
|
4445
4804
|
...
|
4446
|
-
|
4447
|
-
|
4448
|
-
|
4449
|
-
|
4805
|
+
def login_another(
|
4806
|
+
self,
|
4807
|
+
/,
|
4808
|
+
replace: bool | Self = False,
|
4809
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
4450
4810
|
*,
|
4451
4811
|
async_: Literal[False, True] = False,
|
4452
4812
|
**request_kwargs,
|
4453
|
-
) ->
|
4454
|
-
"""
|
4813
|
+
) -> Self | Coroutine[Any, Any, Self]:
|
4814
|
+
"""再执行一次登录
|
4455
4815
|
|
4456
|
-
|
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: 客户端实例
|
4457
4827
|
"""
|
4458
|
-
|
4459
|
-
|
4460
|
-
|
4461
|
-
|
4462
|
-
|
4463
|
-
|
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_)
|
4464
4847
|
|
4465
4848
|
@overload
|
4466
|
-
|
4467
|
-
|
4468
|
-
|
4469
|
-
|
4849
|
+
def login_qrcode_auto(
|
4850
|
+
self,
|
4851
|
+
/,
|
4852
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
4470
4853
|
*,
|
4471
4854
|
async_: Literal[False] = False,
|
4472
4855
|
**request_kwargs,
|
4473
4856
|
) -> dict:
|
4474
4857
|
...
|
4475
4858
|
@overload
|
4476
|
-
|
4477
|
-
|
4478
|
-
|
4479
|
-
|
4859
|
+
def login_qrcode_auto(
|
4860
|
+
self,
|
4861
|
+
/,
|
4862
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
4480
4863
|
*,
|
4481
4864
|
async_: Literal[True],
|
4482
4865
|
**request_kwargs,
|
4483
4866
|
) -> Coroutine[Any, Any, dict]:
|
4484
4867
|
...
|
4485
|
-
|
4486
|
-
|
4487
|
-
|
4488
|
-
|
4868
|
+
def login_qrcode_auto(
|
4869
|
+
self,
|
4870
|
+
/,
|
4871
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
4489
4872
|
*,
|
4490
4873
|
async_: Literal[False, True] = False,
|
4491
4874
|
**request_kwargs,
|
4492
4875
|
) -> dict | Coroutine[Any, Any, dict]:
|
4493
|
-
"""
|
4876
|
+
"""执行一次自动扫码,但并不因此更新 `self.token`
|
4494
4877
|
|
4495
|
-
|
4878
|
+
:param base_url: 接口的基地址
|
4879
|
+
:param async_: 是否异步
|
4880
|
+
:param request_kwargs: 其它请求参数
|
4881
|
+
|
4882
|
+
:return: 接口响应
|
4496
4883
|
"""
|
4497
|
-
|
4498
|
-
|
4499
|
-
|
4500
|
-
|
4501
|
-
|
4502
|
-
|
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_)
|
4503
4907
|
|
4504
4908
|
@overload
|
4505
|
-
|
4506
|
-
|
4507
|
-
|
4909
|
+
@classmethod
|
4910
|
+
def login_with_qrcode(
|
4911
|
+
cls,
|
4508
4912
|
/,
|
4509
|
-
base_url: str | Callable[[], str] =
|
4913
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
4510
4914
|
*,
|
4511
4915
|
async_: Literal[False] = False,
|
4512
4916
|
**request_kwargs,
|
4513
4917
|
) -> dict:
|
4514
4918
|
...
|
4515
4919
|
@overload
|
4516
|
-
|
4517
|
-
|
4518
|
-
|
4920
|
+
@classmethod
|
4921
|
+
def login_with_qrcode(
|
4922
|
+
cls,
|
4519
4923
|
/,
|
4520
|
-
base_url: str | Callable[[], str] =
|
4924
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
4521
4925
|
*,
|
4522
4926
|
async_: Literal[True],
|
4523
4927
|
**request_kwargs,
|
4524
4928
|
) -> Coroutine[Any, Any, dict]:
|
4525
4929
|
...
|
4526
|
-
|
4527
|
-
|
4528
|
-
|
4930
|
+
@classmethod
|
4931
|
+
def login_with_qrcode(
|
4932
|
+
cls,
|
4529
4933
|
/,
|
4530
|
-
base_url: str | Callable[[], str] =
|
4934
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
4531
4935
|
*,
|
4532
4936
|
async_: Literal[False, True] = False,
|
4533
4937
|
**request_kwargs,
|
4534
4938
|
) -> dict | Coroutine[Any, Any, dict]:
|
4535
|
-
"""
|
4536
|
-
|
4537
|
-
POST https://www.123pan.com/api/file/download_info
|
4939
|
+
"""二维码扫码登录
|
4538
4940
|
|
4539
|
-
|
4540
|
-
|
4541
|
-
|
4542
|
-
你完全可以构造这样的查询参数
|
4543
|
-
|
4544
|
-
.. code:: python
|
4545
|
-
|
4546
|
-
payload = {
|
4547
|
-
"Etag": "...", # 必填,文件的 MD5
|
4548
|
-
"FileID": 0, # 可以随便填
|
4549
|
-
"FileName": "a", # 随便填一个名字
|
4550
|
-
"S3KeyFlag": str # 必填,格式为 f"{UID}-0",UID 就是上传此文件的用户的 UID,如果此文件是由你上传的,则可从 `P123Client.user_info` 的响应中获取
|
4551
|
-
"Size": 0, # 可以随便填,填了可能搜索更准确
|
4552
|
-
}
|
4553
|
-
|
4554
|
-
.. note::
|
4555
|
-
获取的直链有效期是 24 小时
|
4941
|
+
:param base_url: 接口的基地址
|
4942
|
+
:param async_: 是否异步
|
4943
|
+
:param request_kwargs: 其它请求参数
|
4556
4944
|
|
4557
|
-
:
|
4558
|
-
- Etag: str 💡 文件的 MD5 散列值
|
4559
|
-
- S3KeyFlag: str
|
4560
|
-
- FileName: str = <default> 💡 默认用 Etag(即 MD5)作为文件名
|
4561
|
-
- FileID: int | str = 0
|
4562
|
-
- Size: int = <default>
|
4563
|
-
- Type: int = 0
|
4564
|
-
- driveId: int | str = 0
|
4565
|
-
- ...
|
4945
|
+
:return: 接口响应
|
4566
4946
|
"""
|
4567
4947
|
def gen_step():
|
4568
|
-
|
4569
|
-
|
4570
|
-
|
4571
|
-
|
4572
|
-
|
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,
|
4573
4963
|
base_url=base_url,
|
4574
4964
|
async_=async_,
|
4575
4965
|
**request_kwargs,
|
4576
4966
|
)
|
4577
|
-
resp["payload"] = payload
|
4578
4967
|
check_response(resp)
|
4579
|
-
if
|
4580
|
-
|
4581
|
-
|
4582
|
-
|
4583
|
-
|
4584
|
-
|
4585
|
-
|
4586
|
-
|
4587
|
-
|
4588
|
-
|
4589
|
-
|
4590
|
-
|
4591
|
-
|
4592
|
-
|
4593
|
-
|
4594
|
-
|
4595
|
-
|
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}")
|
4596
4985
|
return run_gen_step(gen_step, async_)
|
4597
4986
|
|
4987
|
+
########## App API ##########
|
4988
|
+
|
4598
4989
|
@overload
|
4599
|
-
def
|
4990
|
+
def app_config(
|
4600
4991
|
self,
|
4601
|
-
payload: dict |
|
4992
|
+
payload: dict | str = "OfflineDownload",
|
4602
4993
|
/,
|
4603
4994
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4604
4995
|
*,
|
@@ -4607,9 +4998,9 @@ class P123Client(P123OpenClient):
|
|
4607
4998
|
) -> dict:
|
4608
4999
|
...
|
4609
5000
|
@overload
|
4610
|
-
def
|
5001
|
+
def app_config(
|
4611
5002
|
self,
|
4612
|
-
payload: dict |
|
5003
|
+
payload: dict | str = "OfflineDownload",
|
4613
5004
|
/,
|
4614
5005
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4615
5006
|
*,
|
@@ -4617,37 +5008,26 @@ class P123Client(P123OpenClient):
|
|
4617
5008
|
**request_kwargs,
|
4618
5009
|
) -> Coroutine[Any, Any, dict]:
|
4619
5010
|
...
|
4620
|
-
def
|
5011
|
+
def app_config(
|
4621
5012
|
self,
|
4622
|
-
payload: dict |
|
5013
|
+
payload: dict | str = "OfflineDownload",
|
4623
5014
|
/,
|
4624
5015
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4625
5016
|
*,
|
4626
5017
|
async_: Literal[False, True] = False,
|
4627
5018
|
**request_kwargs,
|
4628
5019
|
) -> dict | Coroutine[Any, Any, dict]:
|
4629
|
-
"""
|
4630
|
-
|
4631
|
-
POST https://www.123pan.com/api/file/batch_download_info
|
5020
|
+
"""获取配置信息
|
4632
5021
|
|
4633
|
-
|
4634
|
-
会把一些文件或目录以 zip 包的形式下载,但非会员有流量限制,所以还是推荐用 `P123Client.download_info` 逐个获取下载链接并下载
|
5022
|
+
POST https://www.123pan.com/api/config/get
|
4635
5023
|
|
4636
5024
|
:payload:
|
4637
|
-
-
|
4638
|
-
|
4639
|
-
.. code:: python
|
4640
|
-
|
4641
|
-
FileID = {
|
4642
|
-
"FileId": int | str
|
4643
|
-
}
|
5025
|
+
- business_key: str 💡 配置键名(字段)
|
4644
5026
|
"""
|
4645
|
-
if isinstance(payload,
|
4646
|
-
payload = {"
|
4647
|
-
elif not isinstance(payload, dict):
|
4648
|
-
payload = {"fileIdList": [{"FileId": fid} for fid in payload]}
|
5027
|
+
if not isinstance(payload, dict):
|
5028
|
+
payload = {"business_key": payload}
|
4649
5029
|
return self.request(
|
4650
|
-
"
|
5030
|
+
"config/get",
|
4651
5031
|
"POST",
|
4652
5032
|
json=payload,
|
4653
5033
|
base_url=base_url,
|
@@ -4656,65 +5036,533 @@ class P123Client(P123OpenClient):
|
|
4656
5036
|
)
|
4657
5037
|
|
4658
5038
|
@overload
|
4659
|
-
|
4660
|
-
|
4661
|
-
|
4662
|
-
|
5039
|
+
@staticmethod
|
5040
|
+
def app_dydomain(
|
5041
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5042
|
+
request: None | Callable = None,
|
4663
5043
|
*,
|
4664
5044
|
async_: Literal[False] = False,
|
4665
5045
|
**request_kwargs,
|
4666
|
-
) ->
|
5046
|
+
) -> dict:
|
4667
5047
|
...
|
4668
5048
|
@overload
|
4669
|
-
|
4670
|
-
|
4671
|
-
|
4672
|
-
|
5049
|
+
@staticmethod
|
5050
|
+
def app_dydomain(
|
5051
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5052
|
+
request: None | Callable = None,
|
4673
5053
|
*,
|
4674
5054
|
async_: Literal[True],
|
4675
5055
|
**request_kwargs,
|
4676
|
-
) -> Coroutine[Any, Any,
|
5056
|
+
) -> Coroutine[Any, Any, dict]:
|
4677
5057
|
...
|
4678
|
-
|
4679
|
-
|
4680
|
-
|
4681
|
-
|
5058
|
+
@staticmethod
|
5059
|
+
def app_dydomain(
|
5060
|
+
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5061
|
+
request: None | Callable = None,
|
4682
5062
|
*,
|
4683
5063
|
async_: Literal[False, True] = False,
|
4684
5064
|
**request_kwargs,
|
4685
|
-
) ->
|
4686
|
-
"""
|
4687
|
-
|
4688
|
-
.. note::
|
4689
|
-
`payload` 支持多种格式的输入,按下面的规则按顺序进行判断:
|
4690
|
-
|
4691
|
-
1. 如果是 `int` 或 `str`,则视为文件 id,必须在你的网盘中存在此文件
|
4692
|
-
2. 如果是 `dict`(不区分大小写),有 "S3KeyFlag", "Etag" 和 "Size" 的值,则直接获取链接,文件不必在你网盘中
|
4693
|
-
3. 如果是 `dict`(不区分大小写),有 "Etag" 和 "Size" 的值,则会先秒传(临时文件路径为 /.tempfile)再获取链接,文件不必在你网盘中
|
4694
|
-
4. 如果是 `dict`(不区分大小写),有 "FileID",则会先获取信息,再获取链接,必须在你的网盘中存在此文件
|
4695
|
-
5. 否则会报错 ValueError
|
4696
|
-
|
4697
|
-
:params payload: 文件 id 或者文件信息,文件信息必须包含的信息如下:
|
5065
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
5066
|
+
"""获取 123 网盘的各种域名
|
4698
5067
|
|
4699
|
-
|
4700
|
-
|
4701
|
-
|
4702
|
-
|
4703
|
-
|
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
|
+
)
|
4704
5078
|
|
4705
|
-
|
4706
|
-
|
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
|
4707
5108
|
|
4708
|
-
|
5109
|
+
GET https://www.123pan.com/api/v3/3rd/app-id
|
4709
5110
|
"""
|
4710
|
-
|
4711
|
-
|
4712
|
-
|
4713
|
-
|
4714
|
-
|
4715
|
-
|
4716
|
-
|
4717
|
-
|
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"):
|
5564
|
+
resp = yield self.fs_info(fileid, async_=async_, **request_kwargs)
|
5565
|
+
check_response(resp)
|
4718
5566
|
if not (info_list := resp["data"]["infoList"]):
|
4719
5567
|
raise P123OSError(ENOENT, resp)
|
4720
5568
|
info = info_list[0]
|
@@ -4753,15 +5601,948 @@ class P123Client(P123OpenClient):
|
|
4753
5601
|
**request_kwargs,
|
4754
5602
|
)
|
4755
5603
|
check_response(resp)
|
4756
|
-
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
|
+
)
|
4757
5722
|
return run_gen_step(gen_step, async_)
|
4758
5723
|
|
4759
5724
|
@overload
|
4760
|
-
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(
|
4761
6542
|
self,
|
4762
|
-
payload: dict | int
|
6543
|
+
payload: dict | int = 1,
|
4763
6544
|
/,
|
4764
|
-
|
6545
|
+
event: str = "homeListFile",
|
4765
6546
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4766
6547
|
*,
|
4767
6548
|
async_: Literal[False] = False,
|
@@ -4769,73 +6550,98 @@ class P123Client(P123OpenClient):
|
|
4769
6550
|
) -> dict:
|
4770
6551
|
...
|
4771
6552
|
@overload
|
4772
|
-
def
|
6553
|
+
def fs_star_list(
|
4773
6554
|
self,
|
4774
|
-
payload: dict | int
|
6555
|
+
payload: dict | int = 1,
|
4775
6556
|
/,
|
4776
|
-
|
6557
|
+
event: str = "homeListFile",
|
4777
6558
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4778
6559
|
*,
|
4779
6560
|
async_: Literal[True],
|
4780
6561
|
**request_kwargs,
|
4781
6562
|
) -> Coroutine[Any, Any, dict]:
|
4782
6563
|
...
|
4783
|
-
def
|
6564
|
+
def fs_star_list(
|
4784
6565
|
self,
|
4785
|
-
payload: dict | int
|
6566
|
+
payload: dict | int = 1,
|
4786
6567
|
/,
|
4787
|
-
|
6568
|
+
event: str = "homeListFile",
|
4788
6569
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4789
6570
|
*,
|
4790
6571
|
async_: Literal[False, True] = False,
|
4791
6572
|
**request_kwargs,
|
4792
6573
|
) -> dict | Coroutine[Any, Any, dict]:
|
4793
|
-
"""
|
6574
|
+
"""罗列已星标的文件或目录
|
4794
6575
|
|
4795
|
-
|
6576
|
+
GET https://www.123pan.com/api/restful/goapi/v1/file/starred/list
|
4796
6577
|
|
4797
6578
|
:payload:
|
4798
|
-
-
|
6579
|
+
- driveId: int | str = 0
|
6580
|
+
- next: int = 0 💡 下一批拉取开始的 id
|
6581
|
+
- orderBy: str = "file_name" 💡 排序依据
|
4799
6582
|
|
4800
|
-
|
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
|
+
- ...
|
4801
6592
|
|
4802
|
-
|
4803
|
-
|
4804
|
-
|
4805
|
-
|
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" 💡 事件名称
|
4806
6600
|
|
4807
|
-
|
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
|
4808
6612
|
"""
|
4809
|
-
|
4810
|
-
|
4811
|
-
|
4812
|
-
|
4813
|
-
|
4814
|
-
|
4815
|
-
|
4816
|
-
|
4817
|
-
|
4818
|
-
|
4819
|
-
|
4820
|
-
|
4821
|
-
|
4822
|
-
|
4823
|
-
|
4824
|
-
|
4825
|
-
|
4826
|
-
|
4827
|
-
|
4828
|
-
|
4829
|
-
|
4830
|
-
|
4831
|
-
|
4832
|
-
|
4833
|
-
|
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
|
+
)
|
4834
6640
|
|
4835
6641
|
@overload
|
4836
|
-
def
|
6642
|
+
def fs_sync_log(
|
4837
6643
|
self,
|
4838
|
-
payload: dict | int
|
6644
|
+
payload: dict | int = 1,
|
4839
6645
|
/,
|
4840
6646
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4841
6647
|
*,
|
@@ -4844,9 +6650,9 @@ class P123Client(P123OpenClient):
|
|
4844
6650
|
) -> dict:
|
4845
6651
|
...
|
4846
6652
|
@overload
|
4847
|
-
def
|
6653
|
+
def fs_sync_log(
|
4848
6654
|
self,
|
4849
|
-
payload: dict | int
|
6655
|
+
payload: dict | int = 1,
|
4850
6656
|
/,
|
4851
6657
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4852
6658
|
*,
|
@@ -4854,37 +6660,40 @@ class P123Client(P123OpenClient):
|
|
4854
6660
|
**request_kwargs,
|
4855
6661
|
) -> Coroutine[Any, Any, dict]:
|
4856
6662
|
...
|
4857
|
-
def
|
6663
|
+
def fs_sync_log(
|
4858
6664
|
self,
|
4859
|
-
payload: dict | int
|
6665
|
+
payload: dict | int = 1,
|
4860
6666
|
/,
|
4861
6667
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4862
6668
|
*,
|
4863
6669
|
async_: Literal[False, True] = False,
|
4864
6670
|
**request_kwargs,
|
4865
6671
|
) -> dict | Coroutine[Any, Any, dict]:
|
4866
|
-
"""
|
6672
|
+
"""获取同步空间的操作记录
|
4867
6673
|
|
4868
|
-
GET https://www.123pan.com/api/file/
|
6674
|
+
GET https://www.123pan.com/api/restful/goapi/v1/sync-disk/file/log
|
4869
6675
|
|
4870
6676
|
:payload:
|
4871
|
-
-
|
6677
|
+
- page: int = 1 💡 第几页
|
6678
|
+
- pageSize: int = 100 💡 每页大小
|
6679
|
+
- searchData: str = <default> 💡 搜索关键字
|
4872
6680
|
"""
|
4873
|
-
if isinstance(payload,
|
4874
|
-
payload = {"
|
6681
|
+
if not isinstance(payload, dict):
|
6682
|
+
payload = {"page": payload, "pageSize": 100}
|
4875
6683
|
return self.request(
|
4876
|
-
"file/
|
6684
|
+
"restful/goapi/v1/sync-disk/file/log",
|
4877
6685
|
params=payload,
|
4878
6686
|
base_url=base_url,
|
4879
6687
|
async_=async_,
|
4880
6688
|
**request_kwargs,
|
4881
6689
|
)
|
4882
6690
|
|
4883
|
-
@overload
|
4884
|
-
def
|
6691
|
+
@overload # type: ignore
|
6692
|
+
def fs_trash(
|
4885
6693
|
self,
|
4886
|
-
payload: dict | int | str | Iterable[int | str]
|
6694
|
+
payload: dict | int | str | Iterable[int | str],
|
4887
6695
|
/,
|
6696
|
+
event: str = "intoRecycle",
|
4888
6697
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4889
6698
|
*,
|
4890
6699
|
async_: Literal[False] = False,
|
@@ -4892,51 +6701,64 @@ class P123Client(P123OpenClient):
|
|
4892
6701
|
) -> dict:
|
4893
6702
|
...
|
4894
6703
|
@overload
|
4895
|
-
def
|
6704
|
+
def fs_trash(
|
4896
6705
|
self,
|
4897
|
-
payload: dict | int | str | Iterable[int | str]
|
6706
|
+
payload: dict | int | str | Iterable[int | str],
|
4898
6707
|
/,
|
6708
|
+
event: str = "intoRecycle",
|
4899
6709
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4900
6710
|
*,
|
4901
6711
|
async_: Literal[True],
|
4902
6712
|
**request_kwargs,
|
4903
6713
|
) -> Coroutine[Any, Any, dict]:
|
4904
6714
|
...
|
4905
|
-
def
|
6715
|
+
def fs_trash(
|
4906
6716
|
self,
|
4907
|
-
payload: dict | int | str | Iterable[int | str]
|
6717
|
+
payload: dict | int | str | Iterable[int | str],
|
4908
6718
|
/,
|
6719
|
+
event: str = "intoRecycle",
|
4909
6720
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4910
6721
|
*,
|
4911
6722
|
async_: Literal[False, True] = False,
|
4912
6723
|
**request_kwargs,
|
4913
6724
|
) -> dict | Coroutine[Any, Any, dict]:
|
4914
|
-
"""
|
4915
|
-
|
4916
|
-
POST https://www.123pan.com/api/file/delete
|
6725
|
+
"""操作回收站
|
4917
6726
|
|
4918
|
-
|
4919
|
-
彻底删除文件前,文件必须要在回收站中,否则无法删除
|
6727
|
+
POST https://www.123pan.com/api/file/trash
|
4920
6728
|
|
4921
6729
|
:payload:
|
4922
|
-
-
|
6730
|
+
- fileTrashInfoList: list[File] 💡 信息可以取自 `P123Client.fs_info` 接口
|
4923
6731
|
|
4924
6732
|
.. code:: python
|
4925
6733
|
|
4926
|
-
|
4927
|
-
"FileId": int | str
|
6734
|
+
File = {
|
6735
|
+
"FileId": int | str,
|
6736
|
+
...
|
4928
6737
|
}
|
4929
6738
|
|
4930
|
-
-
|
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
|
4931
6748
|
"""
|
4932
6749
|
if isinstance(payload, (int, str)):
|
4933
|
-
payload = {"
|
6750
|
+
payload = {"fileTrashInfoList": [{"FileId": payload}]}
|
4934
6751
|
elif not isinstance(payload, dict):
|
4935
|
-
payload = {"
|
4936
|
-
payload =
|
4937
|
-
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
|
4938
6760
|
return self.request(
|
4939
|
-
"file/
|
6761
|
+
"file/trash",
|
4940
6762
|
"POST",
|
4941
6763
|
json=payload,
|
4942
6764
|
base_url=base_url,
|
@@ -4945,9 +6767,9 @@ class P123Client(P123OpenClient):
|
|
4945
6767
|
)
|
4946
6768
|
|
4947
6769
|
@overload
|
4948
|
-
def
|
6770
|
+
def fs_trash_clear(
|
4949
6771
|
self,
|
4950
|
-
payload: dict
|
6772
|
+
payload: dict = {"event": "recycleClear"},
|
4951
6773
|
/,
|
4952
6774
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4953
6775
|
*,
|
@@ -4956,9 +6778,9 @@ class P123Client(P123OpenClient):
|
|
4956
6778
|
) -> dict:
|
4957
6779
|
...
|
4958
6780
|
@overload
|
4959
|
-
def
|
6781
|
+
def fs_trash_clear(
|
4960
6782
|
self,
|
4961
|
-
payload: dict
|
6783
|
+
payload: dict = {"event": "recycleClear"},
|
4962
6784
|
/,
|
4963
6785
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4964
6786
|
*,
|
@@ -4966,26 +6788,25 @@ class P123Client(P123OpenClient):
|
|
4966
6788
|
**request_kwargs,
|
4967
6789
|
) -> Coroutine[Any, Any, dict]:
|
4968
6790
|
...
|
4969
|
-
def
|
6791
|
+
def fs_trash_clear(
|
4970
6792
|
self,
|
4971
|
-
payload: dict
|
6793
|
+
payload: dict = {"event": "recycleClear"},
|
4972
6794
|
/,
|
4973
6795
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
4974
6796
|
*,
|
4975
6797
|
async_: Literal[False, True] = False,
|
4976
6798
|
**request_kwargs,
|
4977
6799
|
) -> dict | Coroutine[Any, Any, dict]:
|
4978
|
-
"""
|
6800
|
+
"""清空回收站
|
4979
6801
|
|
4980
|
-
POST https://www.123pan.com/api/file/
|
6802
|
+
POST https://www.123pan.com/api/file/trash_delete_all
|
4981
6803
|
|
4982
6804
|
:payload:
|
4983
|
-
-
|
6805
|
+
- event: str = "recycleClear"
|
4984
6806
|
"""
|
4985
|
-
|
4986
|
-
payload = {"fileId": payload}
|
6807
|
+
payload.setdefault("event", "recycleClear")
|
4987
6808
|
return self.request(
|
4988
|
-
"file/
|
6809
|
+
"file/trash_delete_all",
|
4989
6810
|
"POST",
|
4990
6811
|
json=payload,
|
4991
6812
|
base_url=base_url,
|
@@ -4994,68 +6815,51 @@ class P123Client(P123OpenClient):
|
|
4994
6815
|
)
|
4995
6816
|
|
4996
6817
|
@overload
|
4997
|
-
|
4998
|
-
|
4999
|
-
payload: dict | int | str | Iterable[int | str] = 0,
|
5000
|
-
/,
|
6818
|
+
@staticmethod
|
6819
|
+
def fs_video_play_conf(
|
5001
6820
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6821
|
+
request: None | Callable = None,
|
5002
6822
|
*,
|
5003
6823
|
async_: Literal[False] = False,
|
5004
6824
|
**request_kwargs,
|
5005
6825
|
) -> dict:
|
5006
6826
|
...
|
5007
6827
|
@overload
|
5008
|
-
|
5009
|
-
|
5010
|
-
payload: dict | int | str | Iterable[int | str] = 0,
|
5011
|
-
/,
|
6828
|
+
@staticmethod
|
6829
|
+
def fs_video_play_conf(
|
5012
6830
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6831
|
+
request: None | Callable = None,
|
5013
6832
|
*,
|
5014
6833
|
async_: Literal[True],
|
5015
6834
|
**request_kwargs,
|
5016
6835
|
) -> Coroutine[Any, Any, dict]:
|
5017
6836
|
...
|
5018
|
-
|
5019
|
-
|
5020
|
-
payload: dict | int | str | Iterable[int | str] = 0,
|
5021
|
-
/,
|
6837
|
+
@staticmethod
|
6838
|
+
def fs_video_play_conf(
|
5022
6839
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6840
|
+
request: None | Callable = None,
|
5023
6841
|
*,
|
5024
|
-
async_: Literal[False, True] = False,
|
5025
|
-
**request_kwargs,
|
5026
|
-
) -> dict | Coroutine[Any, Any, dict]:
|
5027
|
-
"""
|
5028
|
-
|
5029
|
-
|
5030
|
-
|
5031
|
-
|
5032
|
-
|
5033
|
-
|
5034
|
-
|
5035
|
-
|
5036
|
-
|
5037
|
-
"FileId": int | str
|
5038
|
-
}
|
5039
|
-
"""
|
5040
|
-
if isinstance(payload, (int, str)):
|
5041
|
-
payload = {"fileIdList": [{"FileId": payload}]}
|
5042
|
-
elif not isinstance(payload, dict):
|
5043
|
-
payload = {"fileIdList": [{"FileId": fid} for fid in payload]}
|
5044
|
-
return self.request(
|
5045
|
-
"file/info",
|
5046
|
-
"POST",
|
5047
|
-
json=payload,
|
5048
|
-
base_url=base_url,
|
5049
|
-
async_=async_,
|
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),
|
5050
6855
|
**request_kwargs,
|
5051
6856
|
)
|
5052
6857
|
|
5053
|
-
@overload
|
5054
|
-
def
|
6858
|
+
@overload
|
6859
|
+
def fs_video_play_list(
|
5055
6860
|
self,
|
5056
6861
|
payload: dict | int | str = 0,
|
5057
6862
|
/,
|
5058
|
-
event: str = "homeListFile",
|
5059
6863
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5060
6864
|
*,
|
5061
6865
|
async_: Literal[False] = False,
|
@@ -5063,95 +6867,54 @@ class P123Client(P123OpenClient):
|
|
5063
6867
|
) -> dict:
|
5064
6868
|
...
|
5065
6869
|
@overload
|
5066
|
-
def
|
6870
|
+
def fs_video_play_list(
|
5067
6871
|
self,
|
5068
6872
|
payload: dict | int | str = 0,
|
5069
6873
|
/,
|
5070
|
-
event: str = "homeListFile",
|
5071
6874
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5072
6875
|
*,
|
5073
6876
|
async_: Literal[True],
|
5074
6877
|
**request_kwargs,
|
5075
6878
|
) -> Coroutine[Any, Any, dict]:
|
5076
6879
|
...
|
5077
|
-
def
|
6880
|
+
def fs_video_play_list(
|
5078
6881
|
self,
|
5079
6882
|
payload: dict | int | str = 0,
|
5080
6883
|
/,
|
5081
|
-
event: str = "homeListFile",
|
5082
6884
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5083
6885
|
*,
|
5084
6886
|
async_: Literal[False, True] = False,
|
5085
6887
|
**request_kwargs,
|
5086
6888
|
) -> dict | Coroutine[Any, Any, dict]:
|
5087
|
-
"""
|
5088
|
-
|
5089
|
-
GET https://www.123pan.com/api/file/list
|
6889
|
+
"""获取某个目录下的视频列表
|
5090
6890
|
|
5091
|
-
|
5092
|
-
如果返回信息中,"Next" 字段的值为 "-1",代表最后一页(无需再翻页查询)
|
6891
|
+
GET https://www.123pan.com/api/file/video/play/list
|
5093
6892
|
|
5094
6893
|
:payload:
|
5095
|
-
-
|
5096
|
-
-
|
5097
|
-
-
|
5098
|
-
- orderBy: str = "file_id" 💡 排序依据
|
5099
|
-
|
5100
|
-
- "file_id": 文件 id,也可以写作 "fileId"
|
5101
|
-
- "file_name": 文件名
|
5102
|
-
- "size": 文件大小
|
5103
|
-
- "create_at": 创建时间
|
5104
|
-
- "update_at": 更新时间
|
5105
|
-
- "share_id": 分享 id
|
5106
|
-
- ...
|
5107
|
-
|
5108
|
-
- orderDirection: "asc" | "desc" = "asc" 💡 排序顺序
|
5109
|
-
- Page: int = <default> 💡 第几页,从 1 开始,可以是 0
|
5110
|
-
- parentFileId: int | str = 0 💡 父目录 id
|
5111
|
-
- trashed: "false" | "true" = <default> 💡 是否查看回收站的文件
|
5112
|
-
- inDirectSpace: "false" | "true" = "false"
|
5113
|
-
- event: str = "homeListFile" 💡 事件名称
|
5114
|
-
|
5115
|
-
- "homeListFile": 全部文件
|
5116
|
-
- "recycleListFile": 回收站
|
5117
|
-
- "syncFileList": 同步空间
|
5118
|
-
|
5119
|
-
- operateType: int | str = <default> 💡 操作类型,如果在同步空间,则需要指定为 "SyncSpacePage"
|
5120
|
-
- SearchData: str = <default> 💡 搜索关键字(将无视 `parentFileId` 参数)
|
5121
|
-
- OnlyLookAbnormalFile: int = <default>
|
6894
|
+
- page: int = 1
|
6895
|
+
- page_size: int = 100
|
6896
|
+
- parent_file_id: int = 0
|
5122
6897
|
"""
|
5123
|
-
if isinstance(payload,
|
5124
|
-
payload = {"
|
5125
|
-
payload
|
5126
|
-
|
5127
|
-
"limit": 100,
|
5128
|
-
"next": 0,
|
5129
|
-
"orderBy": "file_id",
|
5130
|
-
"orderDirection": "asc",
|
5131
|
-
"parentFileId": 0,
|
5132
|
-
"inDirectSpace": "false",
|
5133
|
-
"event": event,
|
5134
|
-
})
|
5135
|
-
if not payload.get("trashed"):
|
5136
|
-
match payload["event"]:
|
5137
|
-
case "recycleListFile":
|
5138
|
-
payload["trashed"] = "true"
|
5139
|
-
case _:
|
5140
|
-
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)
|
5141
6902
|
return self.request(
|
5142
|
-
"file/list",
|
6903
|
+
"file/video/play/list",
|
5143
6904
|
params=payload,
|
5144
6905
|
base_url=base_url,
|
5145
6906
|
async_=async_,
|
5146
6907
|
**request_kwargs,
|
5147
6908
|
)
|
5148
6909
|
|
6910
|
+
########## Qrcode API ##########
|
6911
|
+
|
5149
6912
|
@overload
|
5150
|
-
|
5151
|
-
|
5152
|
-
payload: dict
|
6913
|
+
@staticmethod
|
6914
|
+
def login_passport(
|
6915
|
+
payload: dict,
|
5153
6916
|
/,
|
5154
|
-
|
6917
|
+
request: None | Callable = None,
|
5155
6918
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5156
6919
|
*,
|
5157
6920
|
async_: Literal[False] = False,
|
@@ -5159,211 +6922,141 @@ class P123Client(P123OpenClient):
|
|
5159
6922
|
) -> dict:
|
5160
6923
|
...
|
5161
6924
|
@overload
|
5162
|
-
|
5163
|
-
|
5164
|
-
payload: dict
|
6925
|
+
@staticmethod
|
6926
|
+
def login_passport(
|
6927
|
+
payload: dict,
|
5165
6928
|
/,
|
5166
|
-
|
6929
|
+
request: None | Callable = None,
|
5167
6930
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5168
6931
|
*,
|
5169
6932
|
async_: Literal[True],
|
5170
6933
|
**request_kwargs,
|
5171
6934
|
) -> Coroutine[Any, Any, dict]:
|
5172
6935
|
...
|
5173
|
-
|
5174
|
-
|
5175
|
-
payload: dict
|
6936
|
+
@staticmethod
|
6937
|
+
def login_passport(
|
6938
|
+
payload: dict,
|
5176
6939
|
/,
|
5177
|
-
|
6940
|
+
request: None | Callable = None,
|
5178
6941
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5179
6942
|
*,
|
5180
6943
|
async_: Literal[False, True] = False,
|
5181
6944
|
**request_kwargs,
|
5182
6945
|
) -> dict | Coroutine[Any, Any, dict]:
|
5183
|
-
"""
|
6946
|
+
"""使用账号和密码登录
|
5184
6947
|
|
5185
|
-
|
6948
|
+
POST https://www.123pan.com/api/user/sign_in
|
5186
6949
|
|
5187
6950
|
.. note::
|
5188
|
-
|
6951
|
+
获取的 token 有效期 30 天
|
5189
6952
|
|
5190
6953
|
:payload:
|
5191
|
-
-
|
5192
|
-
-
|
5193
|
-
-
|
5194
|
-
- orderBy: str = "file_id" 💡 排序依据
|
5195
|
-
|
5196
|
-
- "file_id": 文件 id,也可以写作 "fileId"
|
5197
|
-
- "file_name": 文件名
|
5198
|
-
- "size": 文件大小
|
5199
|
-
- "create_at": 创建时间
|
5200
|
-
- "update_at": 更新时间
|
5201
|
-
- "share_id": 分享 id
|
5202
|
-
- ...
|
5203
|
-
|
5204
|
-
- orderDirection: "asc" | "desc" = "asc" 💡 排序顺序
|
5205
|
-
- Page: int = 1 💡 第几页,从 1 开始
|
5206
|
-
- parentFileId: int | str = 0 💡 父目录 id
|
5207
|
-
- trashed: "false" | "true" = <default> 💡 是否查看回收站的文件
|
5208
|
-
- inDirectSpace: "false" | "true" = "false"
|
5209
|
-
- event: str = "homeListFile" 💡 事件名称
|
5210
|
-
|
5211
|
-
- "homeListFile": 全部文件
|
5212
|
-
- "recycleListFile": 回收站
|
5213
|
-
- "syncFileList": 同步空间
|
5214
|
-
|
5215
|
-
- operateType: int | str = <default> 💡 操作类型,如果在同步空间,则需要指定为 "SyncSpacePage"
|
5216
|
-
|
5217
|
-
.. note::
|
5218
|
-
这个值似乎不影响结果,所以可以忽略。我在浏览器中,看到罗列根目录为 1,搜索(指定 `SearchData`)为 2,同步空间的根目录为 3,罗列其它目录大多为 4,偶尔为 8,也可能是其它值
|
5219
|
-
|
5220
|
-
- SearchData: str = <default> 💡 搜索关键字(将无视 `parentFileId` 参数)
|
5221
|
-
- OnlyLookAbnormalFile: int = 0 💡 大概可传入 0 或 1
|
5222
|
-
- RequestSource: int = <default> 💡 浏览器中,在同步空间中为 1
|
6954
|
+
- passport: int | str 💡 手机号或邮箱
|
6955
|
+
- password: str 💡 密码
|
6956
|
+
- remember: bool = True 💡 是否记住密码(不用管)
|
5223
6957
|
"""
|
5224
|
-
|
5225
|
-
|
5226
|
-
|
5227
|
-
|
5228
|
-
"
|
5229
|
-
|
5230
|
-
"orderBy": "file_id",
|
5231
|
-
"orderDirection": "asc",
|
5232
|
-
"parentFileId": 0,
|
5233
|
-
"inDirectSpace": "false",
|
5234
|
-
"event": event,
|
5235
|
-
"OnlyLookAbnormalFile": 0,
|
5236
|
-
"Page": 1,
|
5237
|
-
})
|
5238
|
-
if not payload.get("trashed"):
|
5239
|
-
match payload["event"]:
|
5240
|
-
case "recycleListFile":
|
5241
|
-
payload["trashed"] = "true"
|
5242
|
-
case _:
|
5243
|
-
payload["trashed"] = "false"
|
5244
|
-
return self.request(
|
5245
|
-
"file/list/new",
|
5246
|
-
params=payload,
|
5247
|
-
base_url=base_url,
|
5248
|
-
async_=async_,
|
5249
|
-
**request_kwargs,
|
5250
|
-
)
|
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)
|
5251
6964
|
|
5252
|
-
@overload
|
5253
|
-
|
5254
|
-
|
5255
|
-
|
6965
|
+
@overload
|
6966
|
+
@staticmethod
|
6967
|
+
def login_qrcode_bind_wx_code(
|
6968
|
+
payload: dict,
|
5256
6969
|
/,
|
5257
|
-
|
5258
|
-
|
5259
|
-
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6970
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
6971
|
+
request: None | Callable = None,
|
5260
6972
|
*,
|
5261
6973
|
async_: Literal[False] = False,
|
5262
6974
|
**request_kwargs,
|
5263
6975
|
) -> dict:
|
5264
6976
|
...
|
5265
6977
|
@overload
|
5266
|
-
|
5267
|
-
|
5268
|
-
|
6978
|
+
@staticmethod
|
6979
|
+
def login_qrcode_bind_wx_code(
|
6980
|
+
payload: dict,
|
5269
6981
|
/,
|
5270
|
-
|
5271
|
-
|
5272
|
-
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6982
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
6983
|
+
request: None | Callable = None,
|
5273
6984
|
*,
|
5274
6985
|
async_: Literal[True],
|
5275
6986
|
**request_kwargs,
|
5276
6987
|
) -> Coroutine[Any, Any, dict]:
|
5277
6988
|
...
|
5278
|
-
|
5279
|
-
|
5280
|
-
|
6989
|
+
@staticmethod
|
6990
|
+
def login_qrcode_bind_wx_code(
|
6991
|
+
payload: dict,
|
5281
6992
|
/,
|
5282
|
-
|
5283
|
-
|
5284
|
-
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
6993
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
6994
|
+
request: None | Callable = None,
|
5285
6995
|
*,
|
5286
6996
|
async_: Literal[False, True] = False,
|
5287
6997
|
**request_kwargs,
|
5288
6998
|
) -> dict | Coroutine[Any, Any, dict]:
|
5289
|
-
"""
|
6999
|
+
"""绑定微信号
|
5290
7000
|
|
5291
|
-
|
5292
|
-
:param parent_id: 父目录 id
|
5293
|
-
:param duplicate: 处理同名:0: 复用 1: 保留两者 2: 替换
|
5294
|
-
:param async_: 是否异步
|
5295
|
-
:param request_kwargs: 其它请求参数
|
7001
|
+
POST https://login.123pan.com/api/user/qr-code/bind_wx_code
|
5296
7002
|
|
5297
|
-
:
|
7003
|
+
:payload:
|
7004
|
+
- uniID: str 💡 二维码 id
|
7005
|
+
- wxcode: str 💡 微信码
|
5298
7006
|
"""
|
5299
|
-
|
5300
|
-
if
|
5301
|
-
|
5302
|
-
|
5303
|
-
return
|
5304
|
-
|
5305
|
-
|
5306
|
-
|
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,
|
5307
7015
|
**request_kwargs,
|
5308
7016
|
)
|
5309
7017
|
|
5310
7018
|
@overload
|
5311
|
-
def
|
7019
|
+
def login_qrcode_confirm(
|
5312
7020
|
self,
|
5313
|
-
payload: dict |
|
7021
|
+
payload: dict | str,
|
5314
7022
|
/,
|
5315
|
-
|
5316
|
-
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
7023
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
5317
7024
|
*,
|
5318
7025
|
async_: Literal[False] = False,
|
5319
7026
|
**request_kwargs,
|
5320
7027
|
) -> dict:
|
5321
7028
|
...
|
5322
7029
|
@overload
|
5323
|
-
def
|
7030
|
+
def login_qrcode_confirm(
|
5324
7031
|
self,
|
5325
|
-
payload: dict |
|
7032
|
+
payload: dict | str,
|
5326
7033
|
/,
|
5327
|
-
|
5328
|
-
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
7034
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
5329
7035
|
*,
|
5330
7036
|
async_: Literal[True],
|
5331
7037
|
**request_kwargs,
|
5332
7038
|
) -> Coroutine[Any, Any, dict]:
|
5333
7039
|
...
|
5334
|
-
def
|
7040
|
+
def login_qrcode_confirm(
|
5335
7041
|
self,
|
5336
|
-
payload: dict |
|
7042
|
+
payload: dict | str,
|
5337
7043
|
/,
|
5338
|
-
|
5339
|
-
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
7044
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
5340
7045
|
*,
|
5341
7046
|
async_: Literal[False, True] = False,
|
5342
7047
|
**request_kwargs,
|
5343
7048
|
) -> dict | Coroutine[Any, Any, dict]:
|
5344
|
-
"""
|
7049
|
+
"""确认扫码登录
|
5345
7050
|
|
5346
|
-
POST https://
|
7051
|
+
POST https://login.123pan.com/api/user/qr-code/login
|
5347
7052
|
|
5348
7053
|
:payload:
|
5349
|
-
-
|
5350
|
-
|
5351
|
-
.. code:: python
|
5352
|
-
|
5353
|
-
FileID = {
|
5354
|
-
"FileId": int | str
|
5355
|
-
}
|
5356
|
-
|
5357
|
-
- parentFileId: int | str = 0
|
5358
|
-
- event: str = "fileMove"
|
7054
|
+
- uniID: str 💡 二维码 id
|
5359
7055
|
"""
|
5360
|
-
if isinstance(payload,
|
5361
|
-
payload = {"
|
5362
|
-
elif not isinstance(payload, dict):
|
5363
|
-
payload = {"fileIdList": [{"FileId": fid} for fid in payload]}
|
5364
|
-
payload = dict_to_lower_merge(payload, {"parentFileId": parent_id, "event": "fileMove"})
|
7056
|
+
if not isinstance(payload, dict):
|
7057
|
+
payload = {"uniID": payload}
|
5365
7058
|
return self.request(
|
5366
|
-
"
|
7059
|
+
"user/qr-code/login",
|
5367
7060
|
"POST",
|
5368
7061
|
json=payload,
|
5369
7062
|
base_url=base_url,
|
@@ -5372,237 +7065,221 @@ class P123Client(P123OpenClient):
|
|
5372
7065
|
)
|
5373
7066
|
|
5374
7067
|
@overload
|
5375
|
-
|
5376
|
-
|
5377
|
-
payload: dict
|
7068
|
+
@staticmethod
|
7069
|
+
def login_qrcode_deny(
|
7070
|
+
payload: dict | str,
|
5378
7071
|
/,
|
5379
|
-
base_url: str | Callable[[], str] =
|
7072
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
7073
|
+
request: None | Callable = None,
|
5380
7074
|
*,
|
5381
7075
|
async_: Literal[False] = False,
|
5382
7076
|
**request_kwargs,
|
5383
7077
|
) -> dict:
|
5384
7078
|
...
|
5385
7079
|
@overload
|
5386
|
-
|
5387
|
-
|
5388
|
-
payload: dict
|
7080
|
+
@staticmethod
|
7081
|
+
def login_qrcode_deny(
|
7082
|
+
payload: dict | str,
|
5389
7083
|
/,
|
5390
|
-
base_url: str | Callable[[], str] =
|
7084
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
7085
|
+
request: None | Callable = None,
|
5391
7086
|
*,
|
5392
7087
|
async_: Literal[True],
|
5393
7088
|
**request_kwargs,
|
5394
7089
|
) -> Coroutine[Any, Any, dict]:
|
5395
7090
|
...
|
5396
|
-
|
5397
|
-
|
5398
|
-
payload: dict
|
7091
|
+
@staticmethod
|
7092
|
+
def login_qrcode_deny(
|
7093
|
+
payload: dict | str,
|
5399
7094
|
/,
|
5400
|
-
base_url: str | Callable[[], str] =
|
7095
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
7096
|
+
request: None | Callable = None,
|
5401
7097
|
*,
|
5402
7098
|
async_: Literal[False, True] = False,
|
5403
7099
|
**request_kwargs,
|
5404
7100
|
) -> dict | Coroutine[Any, Any, dict]:
|
5405
|
-
"""
|
7101
|
+
"""更新扫码状态为:已取消(loginStatus=2)
|
5406
7102
|
|
5407
|
-
POST https://
|
7103
|
+
POST https://login.123pan.com/api/user/qr-code/deny
|
7104
|
+
|
7105
|
+
:payload:
|
7106
|
+
- uniID: str 💡 二维码 id
|
5408
7107
|
"""
|
5409
|
-
|
5410
|
-
"
|
5411
|
-
|
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",
|
5412
7117
|
json=payload,
|
5413
|
-
base_url=base_url,
|
5414
|
-
async_=async_,
|
5415
7118
|
**request_kwargs,
|
5416
7119
|
)
|
5417
7120
|
|
5418
|
-
@overload
|
5419
|
-
|
5420
|
-
|
5421
|
-
|
5422
|
-
|
5423
|
-
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,
|
5424
7126
|
*,
|
5425
7127
|
async_: Literal[False] = False,
|
5426
7128
|
**request_kwargs,
|
5427
7129
|
) -> dict:
|
5428
7130
|
...
|
5429
7131
|
@overload
|
5430
|
-
|
5431
|
-
|
5432
|
-
|
5433
|
-
|
5434
|
-
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,
|
5435
7136
|
*,
|
5436
7137
|
async_: Literal[True],
|
5437
7138
|
**request_kwargs,
|
5438
7139
|
) -> Coroutine[Any, Any, dict]:
|
5439
7140
|
...
|
5440
|
-
|
5441
|
-
|
5442
|
-
|
5443
|
-
|
5444
|
-
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,
|
5445
7145
|
*,
|
5446
7146
|
async_: Literal[False, True] = False,
|
5447
7147
|
**request_kwargs,
|
5448
7148
|
) -> dict | Coroutine[Any, Any, dict]:
|
5449
|
-
"""
|
5450
|
-
|
5451
|
-
POST https://www.123pan.com/api/file/rename
|
7149
|
+
"""产生二维码
|
5452
7150
|
|
5453
|
-
|
5454
|
-
- FileId: int | str
|
5455
|
-
- fileName: str
|
5456
|
-
- driveId: int | str = 0
|
5457
|
-
- duplicate: 0 | 1 | 2 = 0 💡 处理同名:0: 提示/忽略 1: 保留两者 2: 替换
|
5458
|
-
- event: str = "fileRename"
|
7151
|
+
GET https://login.123pan.com/api/user/qr-code/generate
|
5459
7152
|
"""
|
5460
|
-
|
5461
|
-
|
5462
|
-
|
5463
|
-
"
|
5464
|
-
|
5465
|
-
|
5466
|
-
"file/rename",
|
5467
|
-
"POST",
|
5468
|
-
json=payload,
|
5469
|
-
base_url=base_url,
|
5470
|
-
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),
|
5471
7159
|
**request_kwargs,
|
5472
7160
|
)
|
5473
7161
|
|
5474
7162
|
@overload
|
5475
|
-
|
5476
|
-
|
5477
|
-
payload: dict |
|
7163
|
+
@staticmethod
|
7164
|
+
def login_qrcode_result(
|
7165
|
+
payload: dict | str,
|
5478
7166
|
/,
|
5479
|
-
base_url: str | Callable[[], str] =
|
7167
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
7168
|
+
request: None | Callable = None,
|
5480
7169
|
*,
|
5481
7170
|
async_: Literal[False] = False,
|
5482
7171
|
**request_kwargs,
|
5483
7172
|
) -> dict:
|
5484
7173
|
...
|
5485
7174
|
@overload
|
5486
|
-
|
5487
|
-
|
5488
|
-
payload: dict |
|
7175
|
+
@staticmethod
|
7176
|
+
def login_qrcode_result(
|
7177
|
+
payload: dict | str,
|
5489
7178
|
/,
|
5490
|
-
base_url: str | Callable[[], str] =
|
7179
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
7180
|
+
request: None | Callable = None,
|
5491
7181
|
*,
|
5492
7182
|
async_: Literal[True],
|
5493
7183
|
**request_kwargs,
|
5494
7184
|
) -> Coroutine[Any, Any, dict]:
|
5495
7185
|
...
|
5496
|
-
|
5497
|
-
|
5498
|
-
payload: dict |
|
7186
|
+
@staticmethod
|
7187
|
+
def login_qrcode_result(
|
7188
|
+
payload: dict | str,
|
5499
7189
|
/,
|
5500
|
-
base_url: str | Callable[[], str] =
|
7190
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
7191
|
+
request: None | Callable = None,
|
5501
7192
|
*,
|
5502
7193
|
async_: Literal[False, True] = False,
|
5503
7194
|
**request_kwargs,
|
5504
7195
|
) -> dict | Coroutine[Any, Any, dict]:
|
5505
|
-
"""
|
7196
|
+
"""获取扫码结果
|
5506
7197
|
|
5507
|
-
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: 已失效
|
5508
7208
|
|
5509
7209
|
:payload:
|
5510
|
-
-
|
5511
|
-
- pageSize: int = 100 💡 每页大小
|
5512
|
-
- searchData: str = <default> 💡 搜索关键字
|
7210
|
+
- uniID: str 💡 二维码 id
|
5513
7211
|
"""
|
5514
7212
|
if not isinstance(payload, dict):
|
5515
|
-
payload = {"
|
5516
|
-
|
5517
|
-
|
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),
|
5518
7220
|
params=payload,
|
5519
|
-
base_url=base_url,
|
5520
|
-
async_=async_,
|
5521
7221
|
**request_kwargs,
|
5522
7222
|
)
|
5523
7223
|
|
5524
|
-
@overload
|
5525
|
-
|
5526
|
-
|
5527
|
-
payload: dict |
|
7224
|
+
@overload
|
7225
|
+
@staticmethod
|
7226
|
+
def login_qrcode_scan(
|
7227
|
+
payload: dict | str,
|
5528
7228
|
/,
|
5529
|
-
|
5530
|
-
|
7229
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
7230
|
+
request: None | Callable = None,
|
5531
7231
|
*,
|
5532
7232
|
async_: Literal[False] = False,
|
5533
7233
|
**request_kwargs,
|
5534
7234
|
) -> dict:
|
5535
7235
|
...
|
5536
7236
|
@overload
|
5537
|
-
|
5538
|
-
|
5539
|
-
payload: dict |
|
7237
|
+
@staticmethod
|
7238
|
+
def login_qrcode_scan(
|
7239
|
+
payload: dict | str,
|
5540
7240
|
/,
|
5541
|
-
|
5542
|
-
|
7241
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
7242
|
+
request: None | Callable = None,
|
5543
7243
|
*,
|
5544
7244
|
async_: Literal[True],
|
5545
7245
|
**request_kwargs,
|
5546
7246
|
) -> Coroutine[Any, Any, dict]:
|
5547
7247
|
...
|
5548
|
-
|
5549
|
-
|
5550
|
-
payload: dict |
|
7248
|
+
@staticmethod
|
7249
|
+
def login_qrcode_scan(
|
7250
|
+
payload: dict | str,
|
5551
7251
|
/,
|
5552
|
-
|
5553
|
-
|
7252
|
+
base_url: str | Callable[[], str] = DEFAULT_LOGIN_BASE_URL,
|
7253
|
+
request: None | Callable = None,
|
5554
7254
|
*,
|
5555
7255
|
async_: Literal[False, True] = False,
|
5556
7256
|
**request_kwargs,
|
5557
7257
|
) -> dict | Coroutine[Any, Any, dict]:
|
5558
|
-
"""
|
7258
|
+
"""更新扫码状态为:已扫码(loginStatus=1)
|
5559
7259
|
|
5560
|
-
POST https://
|
7260
|
+
POST https://login.123pan.com/api/user/qr-code/scan
|
5561
7261
|
|
5562
7262
|
:payload:
|
5563
|
-
-
|
5564
|
-
|
5565
|
-
.. code:: python
|
5566
|
-
|
5567
|
-
File = {
|
5568
|
-
"FileId": int | str,
|
5569
|
-
...
|
5570
|
-
}
|
5571
|
-
|
5572
|
-
- driveId: int = 0
|
5573
|
-
- event: str = "intoRecycle" 💡 事件类型
|
5574
|
-
|
5575
|
-
- "intoRecycle": 移入回收站
|
5576
|
-
- "recycleRestore": 移出回收站
|
5577
|
-
|
5578
|
-
- operation: bool = <default>
|
5579
|
-
- operatePlace: int = <default>
|
5580
|
-
- RequestSource: int = <default>
|
7263
|
+
- uniID: str 💡 二维码 id
|
7264
|
+
- scanPlatform: int = 4 💡 扫码的平台代码,微信是 4
|
5581
7265
|
"""
|
5582
|
-
if isinstance(payload,
|
5583
|
-
payload = {"
|
5584
|
-
|
5585
|
-
|
5586
|
-
|
5587
|
-
|
5588
|
-
|
5589
|
-
|
5590
|
-
|
5591
|
-
|
5592
|
-
payload["operation"] = True
|
5593
|
-
return self.request(
|
5594
|
-
"file/trash",
|
5595
|
-
"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",
|
5596
7276
|
json=payload,
|
5597
|
-
base_url=base_url,
|
5598
|
-
async_=async_,
|
5599
7277
|
**request_kwargs,
|
5600
7278
|
)
|
5601
7279
|
|
5602
7280
|
@overload
|
5603
|
-
def
|
7281
|
+
def logout(
|
5604
7282
|
self,
|
5605
|
-
payload: dict = {"event": "recycleClear"},
|
5606
7283
|
/,
|
5607
7284
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5608
7285
|
*,
|
@@ -5611,9 +7288,8 @@ class P123Client(P123OpenClient):
|
|
5611
7288
|
) -> dict:
|
5612
7289
|
...
|
5613
7290
|
@overload
|
5614
|
-
def
|
7291
|
+
def logout(
|
5615
7292
|
self,
|
5616
|
-
payload: dict = {"event": "recycleClear"},
|
5617
7293
|
/,
|
5618
7294
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5619
7295
|
*,
|
@@ -5621,32 +7297,28 @@ class P123Client(P123OpenClient):
|
|
5621
7297
|
**request_kwargs,
|
5622
7298
|
) -> Coroutine[Any, Any, dict]:
|
5623
7299
|
...
|
5624
|
-
def
|
7300
|
+
def logout(
|
5625
7301
|
self,
|
5626
|
-
payload: dict = {"event": "recycleClear"},
|
5627
7302
|
/,
|
5628
7303
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
5629
7304
|
*,
|
5630
7305
|
async_: Literal[False, True] = False,
|
5631
7306
|
**request_kwargs,
|
5632
7307
|
) -> dict | Coroutine[Any, Any, dict]:
|
5633
|
-
"""
|
5634
|
-
|
5635
|
-
POST https://www.123pan.com/api/file/trash_delete_all
|
7308
|
+
"""退出登录
|
5636
7309
|
|
5637
|
-
|
5638
|
-
- event: str = "recycleClear"
|
7310
|
+
POST https://www.123pan.com/api/user/logout
|
5639
7311
|
"""
|
5640
|
-
payload.setdefault("event", "recycleClear")
|
5641
7312
|
return self.request(
|
5642
|
-
"
|
7313
|
+
"user/logout",
|
5643
7314
|
"POST",
|
5644
|
-
json=payload,
|
5645
7315
|
base_url=base_url,
|
5646
7316
|
async_=async_,
|
5647
7317
|
**request_kwargs,
|
5648
7318
|
)
|
5649
7319
|
|
7320
|
+
########## Offline Download API ##########
|
7321
|
+
|
5650
7322
|
@overload
|
5651
7323
|
def offline_task_delete(
|
5652
7324
|
self,
|
@@ -5684,7 +7356,7 @@ class P123Client(P123OpenClient):
|
|
5684
7356
|
|
5685
7357
|
:payload:
|
5686
7358
|
- task_ids: list[int] 💡 任务 id 列表
|
5687
|
-
- status_arr: list[0|1|2] = [] 💡 状态列表:0
|
7359
|
+
- status_arr: list[ 0 | 1 | 2 | 3 | 4 ] = [] 💡 状态列表:0:进行中 1:下载失败 2:下载成功 3:重试中
|
5688
7360
|
"""
|
5689
7361
|
if isinstance(payload, int):
|
5690
7362
|
payload = {"task_ids": [payload], "status_arr": []}
|
@@ -5739,12 +7411,12 @@ class P123Client(P123OpenClient):
|
|
5739
7411
|
:payload:
|
5740
7412
|
- current_page: int = 1
|
5741
7413
|
- page_size: 100
|
5742
|
-
- 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:重试中
|
5743
7415
|
"""
|
5744
7416
|
if isinstance(payload, int):
|
5745
|
-
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]}
|
5746
7418
|
else:
|
5747
|
-
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}
|
5748
7420
|
return self.request(
|
5749
7421
|
"offline_download/task/list",
|
5750
7422
|
"POST",
|
@@ -5911,6 +7583,8 @@ class P123Client(P123OpenClient):
|
|
5911
7583
|
**request_kwargs,
|
5912
7584
|
)
|
5913
7585
|
|
7586
|
+
########## Share API ##########
|
7587
|
+
|
5914
7588
|
@overload
|
5915
7589
|
def share_cancel(
|
5916
7590
|
self,
|
@@ -6687,6 +8361,8 @@ class P123Client(P123OpenClient):
|
|
6687
8361
|
**request_kwargs,
|
6688
8362
|
)
|
6689
8363
|
|
8364
|
+
########## Upload API ##########
|
8365
|
+
|
6690
8366
|
@overload
|
6691
8367
|
def upload_auth(
|
6692
8368
|
self,
|
@@ -7410,6 +9086,8 @@ class P123Client(P123OpenClient):
|
|
7410
9086
|
)
|
7411
9087
|
return run_gen_step(gen_step, async_)
|
7412
9088
|
|
9089
|
+
########## User API ##########
|
9090
|
+
|
7413
9091
|
@overload
|
7414
9092
|
def user_device_list(
|
7415
9093
|
self,
|
@@ -7499,11 +9177,9 @@ class P123Client(P123OpenClient):
|
|
7499
9177
|
)
|
7500
9178
|
|
7501
9179
|
@overload
|
7502
|
-
|
7503
|
-
|
7504
|
-
payload: dict,
|
9180
|
+
def user_referral_info(
|
9181
|
+
self,
|
7505
9182
|
/,
|
7506
|
-
request: None | Callable = None,
|
7507
9183
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
7508
9184
|
*,
|
7509
9185
|
async_: Literal[False] = False,
|
@@ -7511,45 +9187,72 @@ class P123Client(P123OpenClient):
|
|
7511
9187
|
) -> dict:
|
7512
9188
|
...
|
7513
9189
|
@overload
|
7514
|
-
|
7515
|
-
|
7516
|
-
payload: dict,
|
9190
|
+
def user_referral_info(
|
9191
|
+
self,
|
7517
9192
|
/,
|
7518
|
-
request: None | Callable = None,
|
7519
9193
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
7520
9194
|
*,
|
7521
9195
|
async_: Literal[True],
|
7522
9196
|
**request_kwargs,
|
7523
9197
|
) -> Coroutine[Any, Any, dict]:
|
7524
9198
|
...
|
7525
|
-
|
7526
|
-
|
7527
|
-
payload: dict,
|
9199
|
+
def user_referral_info(
|
9200
|
+
self,
|
7528
9201
|
/,
|
7529
|
-
request: None | Callable = None,
|
7530
9202
|
base_url: str | Callable[[], str] = DEFAULT_BASE_URL,
|
7531
9203
|
*,
|
7532
9204
|
async_: Literal[False, True] = False,
|
7533
9205
|
**request_kwargs,
|
7534
9206
|
) -> dict | Coroutine[Any, Any, dict]:
|
7535
|
-
"""
|
9207
|
+
"""用户拉人头信息
|
7536
9208
|
|
7537
|
-
|
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
|
+
)
|
7538
9217
|
|
7539
|
-
|
7540
|
-
|
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
|
+
"""用户推送消息配置
|
7541
9247
|
|
7542
|
-
|
7543
|
-
- passport: int | str 💡 手机号或邮箱
|
7544
|
-
- password: str 💡 密码
|
7545
|
-
- remember: bool = True 💡 是否记住密码(不用管)
|
9248
|
+
GET https://www.123pan.com/b/api/restful/goapi/v1/user/report/info
|
7546
9249
|
"""
|
7547
|
-
|
7548
|
-
|
7549
|
-
|
7550
|
-
|
7551
|
-
request_kwargs
|
7552
|
-
|
9250
|
+
return self.request(
|
9251
|
+
"restful/goapi/v1/user/report/info",
|
9252
|
+
base_url=base_url,
|
9253
|
+
async_=async_,
|
9254
|
+
**request_kwargs,
|
9255
|
+
)
|
7553
9256
|
|
7554
9257
|
@overload
|
7555
9258
|
def user_use_history(
|
@@ -7599,9 +9302,31 @@ class P123Client(P123OpenClient):
|
|
7599
9302
|
**request_kwargs,
|
7600
9303
|
)
|
7601
9304
|
|
7602
|
-
|
7603
|
-
|
7604
|
-
|
7605
|
-
|
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
|
+
|
7606
9323
|
# TODO: 对于某些工具的接口封装,例如 重复文件清理
|
7607
|
-
# TODO:
|
9324
|
+
# TODO: 同步空间
|
9325
|
+
# TODO: 直链空间
|
9326
|
+
# TODO: 图床
|
9327
|
+
# TODO: 视频转码
|
9328
|
+
# TODO: 移入保险箱
|
9329
|
+
# TODO: 申诉和申诉列表
|
9330
|
+
# TODO: 歌单(以及批量加入歌单)
|
9331
|
+
# TODO: 最近查看
|
9332
|
+
# TODO: 消息通知列表和操作
|