p123client 0.0.6__py3-none-any.whl → 0.0.6.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- p123client/client.py +213 -73
- p123client/tool/__init__.py +4 -3
- {p123client-0.0.6.dist-info → p123client-0.0.6.1.dist-info}/METADATA +1 -1
- p123client-0.0.6.1.dist-info/RECORD +12 -0
- p123client-0.0.6.dist-info/RECORD +0 -12
- {p123client-0.0.6.dist-info → p123client-0.0.6.1.dist-info}/LICENSE +0 -0
- {p123client-0.0.6.dist-info → p123client-0.0.6.1.dist-info}/WHEEL +0 -0
p123client/client.py
CHANGED
@@ -6,8 +6,8 @@ from __future__ import annotations
|
|
6
6
|
__all__ = ["check_response", "P123OpenClient", "P123Client"]
|
7
7
|
|
8
8
|
from collections.abc import (
|
9
|
-
AsyncIterable, Awaitable, Buffer, Callable, Coroutine,
|
10
|
-
Iterable, Iterator, Mapping, MutableMapping,
|
9
|
+
AsyncIterable, Awaitable, Buffer, Callable, Coroutine,
|
10
|
+
ItemsView, Iterable, Iterator, Mapping, MutableMapping,
|
11
11
|
)
|
12
12
|
from errno import EIO, EISDIR, ENOENT
|
13
13
|
from functools import partial
|
@@ -17,7 +17,6 @@ from inspect import isawaitable
|
|
17
17
|
from itertools import chain
|
18
18
|
from os import fsdecode, fstat, PathLike
|
19
19
|
from os.path import basename
|
20
|
-
from platform import system
|
21
20
|
from re import compile as re_compile
|
22
21
|
from tempfile import TemporaryFile
|
23
22
|
from typing import cast, overload, Any, Literal
|
@@ -40,18 +39,6 @@ from yarl import URL
|
|
40
39
|
from .exception import P123OSError, P123BrokenUpload
|
41
40
|
|
42
41
|
|
43
|
-
# 当前的系统平台
|
44
|
-
SYS_PLATFORM = system()
|
45
|
-
# 替换表,用于半角转全角,包括了 Windows 中不允许出现在文件名中的字符
|
46
|
-
match SYS_PLATFORM:
|
47
|
-
case "Windows":
|
48
|
-
NAME_TANSTAB_FULLWIDH = {c: chr(c+65248) for c in b"\\/:*?|><"}
|
49
|
-
case "Darwin":
|
50
|
-
NAME_TANSTAB_FULLWIDH = {ord("/"): ":", ord(":"): ":"}
|
51
|
-
case _:
|
52
|
-
NAME_TANSTAB_FULLWIDH = {ord("/"): "/"}
|
53
|
-
# 查找大写字母(除了左边第 1 个)
|
54
|
-
CRE_UPPER_ALPHABET_sub = re_compile("(?<!^)[A-Z]").sub
|
55
42
|
# 默认使用的域名
|
56
43
|
DEFAULT_BASE_URL = "https://www.123pan.com/b"
|
57
44
|
DEFAULT_LOGIN_BASE_URL = "https://login.123pan.com"
|
@@ -120,6 +107,14 @@ def dict_to_lower_merge[K, V](
|
|
120
107
|
return m
|
121
108
|
|
122
109
|
|
110
|
+
def escape_filename(
|
111
|
+
s: str,
|
112
|
+
/,
|
113
|
+
table: dict[int, int | str] = {c: chr(c+65248) for c in b'"\\/:*?|><'}, # type: ignore
|
114
|
+
) -> str:
|
115
|
+
return s.translate(table)
|
116
|
+
|
117
|
+
|
123
118
|
def items[K, V](
|
124
119
|
m: Mapping[K, V] | Iterable[tuple[K, V]],
|
125
120
|
/,
|
@@ -710,6 +705,143 @@ class P123OpenClient:
|
|
710
705
|
})
|
711
706
|
return self.request(api, params=payload, async_=async_, **request_kwargs)
|
712
707
|
|
708
|
+
@overload
|
709
|
+
def dlink_m3u8(
|
710
|
+
self,
|
711
|
+
payload: dict | int | str,
|
712
|
+
/,
|
713
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
714
|
+
*,
|
715
|
+
async_: Literal[False] = False,
|
716
|
+
**request_kwargs,
|
717
|
+
) -> dict:
|
718
|
+
...
|
719
|
+
@overload
|
720
|
+
def dlink_m3u8(
|
721
|
+
self,
|
722
|
+
payload: dict | int | str,
|
723
|
+
/,
|
724
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
725
|
+
*,
|
726
|
+
async_: Literal[True],
|
727
|
+
**request_kwargs,
|
728
|
+
) -> Coroutine[Any, Any, dict]:
|
729
|
+
...
|
730
|
+
def dlink_m3u8(
|
731
|
+
self,
|
732
|
+
payload: dict | int | str,
|
733
|
+
/,
|
734
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
735
|
+
*,
|
736
|
+
async_: Literal[False, True] = False,
|
737
|
+
**request_kwargs,
|
738
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
739
|
+
"""获取直链转码链接
|
740
|
+
|
741
|
+
GET https://open-api.123pan.com/api/v1/direct-link/get/m3u8
|
742
|
+
|
743
|
+
:payload:
|
744
|
+
- fileID: int 💡 文件 id
|
745
|
+
"""
|
746
|
+
api = complete_url("/api/v1/direct-link/get/m3u8", base_url)
|
747
|
+
if not isinstance(payload, dict):
|
748
|
+
payload = {"fileID": payload}
|
749
|
+
return self.request(api, params=payload, async_=async_, **request_kwargs)
|
750
|
+
|
751
|
+
@overload
|
752
|
+
def dlink_transcode(
|
753
|
+
self,
|
754
|
+
payload: dict | int | str | Iterable[int | str],
|
755
|
+
/,
|
756
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
757
|
+
*,
|
758
|
+
async_: Literal[False] = False,
|
759
|
+
**request_kwargs,
|
760
|
+
) -> dict:
|
761
|
+
...
|
762
|
+
@overload
|
763
|
+
def dlink_transcode(
|
764
|
+
self,
|
765
|
+
payload: dict | int | str | Iterable[int | str],
|
766
|
+
/,
|
767
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
768
|
+
*,
|
769
|
+
async_: Literal[True],
|
770
|
+
**request_kwargs,
|
771
|
+
) -> Coroutine[Any, Any, dict]:
|
772
|
+
...
|
773
|
+
def dlink_transcode(
|
774
|
+
self,
|
775
|
+
payload: dict | int | str | Iterable[int | str],
|
776
|
+
/,
|
777
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
778
|
+
*,
|
779
|
+
async_: Literal[False, True] = False,
|
780
|
+
**request_kwargs,
|
781
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
782
|
+
"""发起直链转码
|
783
|
+
|
784
|
+
POST https://open-api.123pan.com/api/v1/direct-link/doTranscode
|
785
|
+
|
786
|
+
:payload:
|
787
|
+
- ids: list[int] 💡 视频文件 id 列表
|
788
|
+
"""
|
789
|
+
api = complete_url("/api/v1/direct-link/doTranscode", base_url)
|
790
|
+
if not isinstance(payload, dict):
|
791
|
+
if isinstance(payload, (int, str)):
|
792
|
+
payload = [payload]
|
793
|
+
elif not isinstance(payload, (tuple, list)):
|
794
|
+
payload = list(payload)
|
795
|
+
payload = {"ids": payload}
|
796
|
+
return self.request(api, "POST", json=payload, async_=async_, **request_kwargs)
|
797
|
+
|
798
|
+
@overload
|
799
|
+
def dlink_transcode_query(
|
800
|
+
self,
|
801
|
+
payload: dict | int | str | Iterable[int | str],
|
802
|
+
/,
|
803
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
804
|
+
*,
|
805
|
+
async_: Literal[False] = False,
|
806
|
+
**request_kwargs,
|
807
|
+
) -> dict:
|
808
|
+
...
|
809
|
+
@overload
|
810
|
+
def dlink_transcode_query(
|
811
|
+
self,
|
812
|
+
payload: dict | int | str | Iterable[int | str],
|
813
|
+
/,
|
814
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
815
|
+
*,
|
816
|
+
async_: Literal[True],
|
817
|
+
**request_kwargs,
|
818
|
+
) -> Coroutine[Any, Any, dict]:
|
819
|
+
...
|
820
|
+
def dlink_transcode_query(
|
821
|
+
self,
|
822
|
+
payload: dict | int | str | Iterable[int | str],
|
823
|
+
/,
|
824
|
+
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
825
|
+
*,
|
826
|
+
async_: Literal[False, True] = False,
|
827
|
+
**request_kwargs,
|
828
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
829
|
+
"""查询直链转码进度
|
830
|
+
|
831
|
+
POST https://open-api.123pan.com/api/v1/direct-link/queryTranscode
|
832
|
+
|
833
|
+
:payload:
|
834
|
+
- ids: str 💡 视频文件 id 列表
|
835
|
+
"""
|
836
|
+
api = complete_url("/api/v1/direct-link/queryTranscode", base_url)
|
837
|
+
if not isinstance(payload, dict):
|
838
|
+
if isinstance(payload, (int, str)):
|
839
|
+
payload = [payload]
|
840
|
+
elif not isinstance(payload, (tuple, list)):
|
841
|
+
payload = list(payload)
|
842
|
+
payload = {"ids": payload}
|
843
|
+
return self.request(api, "POST", json=payload, async_=async_, **request_kwargs)
|
844
|
+
|
713
845
|
@overload
|
714
846
|
def dlink_url(
|
715
847
|
self,
|
@@ -751,7 +883,7 @@ class P123OpenClient:
|
|
751
883
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/tdxfsmtemp4gu4o2
|
752
884
|
|
753
885
|
:payload:
|
754
|
-
- fileID: int 💡
|
886
|
+
- fileID: int 💡 文件 id
|
755
887
|
"""
|
756
888
|
api = complete_url("/api/v1/direct-link/url", base_url)
|
757
889
|
if not isinstance(payload, dict):
|
@@ -1596,7 +1728,7 @@ class P123OpenClient:
|
|
1596
1728
|
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/trahy3lmds4o0i3r
|
1597
1729
|
|
1598
1730
|
:payload:
|
1599
|
-
- fileIDs: list[int] 💡 文件 id
|
1731
|
+
- fileIDs: list[int] 💡 文件 id 列表
|
1600
1732
|
- toParentFileID: int = 0 💡 要移动到的目标目录 id,默认为根目录
|
1601
1733
|
- sourceType: int = 1 💡 复制来源:1:云盘
|
1602
1734
|
- type: int = 1 💡 业务类型,固定为 1
|
@@ -1770,7 +1902,7 @@ class P123OpenClient:
|
|
1770
1902
|
return self.request(api, "POST", json=payload, async_=async_, **request_kwargs)
|
1771
1903
|
|
1772
1904
|
@overload
|
1773
|
-
def
|
1905
|
+
def oss_detail(
|
1774
1906
|
self,
|
1775
1907
|
payload: dict | int | str,
|
1776
1908
|
/,
|
@@ -1781,7 +1913,7 @@ class P123OpenClient:
|
|
1781
1913
|
) -> dict:
|
1782
1914
|
...
|
1783
1915
|
@overload
|
1784
|
-
def
|
1916
|
+
def oss_detail(
|
1785
1917
|
self,
|
1786
1918
|
payload: dict | int | str,
|
1787
1919
|
/,
|
@@ -1791,7 +1923,7 @@ class P123OpenClient:
|
|
1791
1923
|
**request_kwargs,
|
1792
1924
|
) -> Coroutine[Any, Any, dict]:
|
1793
1925
|
...
|
1794
|
-
def
|
1926
|
+
def oss_detail(
|
1795
1927
|
self,
|
1796
1928
|
payload: dict | int | str,
|
1797
1929
|
/,
|
@@ -2144,7 +2276,7 @@ class P123OpenClient:
|
|
2144
2276
|
|
2145
2277
|
:payload:
|
2146
2278
|
- filename: str 💡 文件名
|
2147
|
-
- duplicate: 0 | 1 | 2 = 0 💡 处理同名:0:
|
2279
|
+
- duplicate: 0 | 1 | 2 = 0 💡 处理同名:0: 跳过/报错 1: 保留/后缀编号 2: 替换/覆盖
|
2148
2280
|
- etag: str 💡 文件 md5
|
2149
2281
|
- parentFileID: int = 0 💡 父目录 id,默认为根目录
|
2150
2282
|
- size: int 💡 文件大小,单位:字节
|
@@ -2163,7 +2295,9 @@ class P123OpenClient:
|
|
2163
2295
|
}
|
2164
2296
|
"""
|
2165
2297
|
api = complete_url("/upload/v1/oss/file/create", base_url)
|
2166
|
-
payload = dict_to_lower_merge(payload,
|
2298
|
+
payload = dict_to_lower_merge(payload, type=1)
|
2299
|
+
if not payload.get("duplicate"):
|
2300
|
+
payload.pop("duplicate", None)
|
2167
2301
|
return self.request(api, "POST", json=payload, async_=async_, **request_kwargs)
|
2168
2302
|
|
2169
2303
|
@overload
|
@@ -2437,7 +2571,7 @@ class P123OpenClient:
|
|
2437
2571
|
"""上传文件
|
2438
2572
|
|
2439
2573
|
.. note::
|
2440
|
-
|
2574
|
+
如果文件名中包含字符 "\\/:*?|><,则转换为对应的全角字符
|
2441
2575
|
|
2442
2576
|
.. admonition:: Reference
|
2443
2577
|
/API列表/图床/上传图片/💡上传流程说明
|
@@ -2571,7 +2705,7 @@ class P123OpenClient:
|
|
2571
2705
|
file_name = getattr(file, "name", "")
|
2572
2706
|
file_name = basename(file_name)
|
2573
2707
|
if file_name:
|
2574
|
-
file_name = file_name
|
2708
|
+
file_name = escape_filename(file_name)
|
2575
2709
|
else:
|
2576
2710
|
file_name = str(uuid4())
|
2577
2711
|
if file_size < 0:
|
@@ -2726,7 +2860,7 @@ class P123OpenClient:
|
|
2726
2860
|
:payload:
|
2727
2861
|
- fileIDList: str 💡 分享文件 id 列表,最多 100 个,用逗号,分隔连接
|
2728
2862
|
- shareExpire: 0 | 1 | 7 | 30 = 0 💡 分享链接有效期天数,0 为永久
|
2729
|
-
- shareName: str 💡 分享链接名称,须小于 35 个字符且不能包含特殊字符
|
2863
|
+
- shareName: str 💡 分享链接名称,须小于 35 个字符且不能包含特殊字符 "\\/:*?|><
|
2730
2864
|
- sharePwd: str = "" 💡 设置分享链接提取码
|
2731
2865
|
- trafficLimit: int = <default> 💡 免登陆限制流量,单位:字节
|
2732
2866
|
- trafficLimitSwitch: 1 | 2 = <default> 💡 免登录流量限制开关:1:关闭 2:打开
|
@@ -2781,7 +2915,7 @@ class P123OpenClient:
|
|
2781
2915
|
- isReward: 0 | 1 = 0 💡 是否开启打赏
|
2782
2916
|
- payAmount: int = 1 💡 金额,从 1 到 99,单位:元
|
2783
2917
|
- resourceDesc: str = "" 💡 资源描述
|
2784
|
-
- shareName: str 💡 分享链接名称,须小于 35 个字符且不能包含特殊字符
|
2918
|
+
- shareName: str 💡 分享链接名称,须小于 35 个字符且不能包含特殊字符 "\\/:*?|><
|
2785
2919
|
"""
|
2786
2920
|
api = complete_url("/api/v1/share/content-payment/create", base_url)
|
2787
2921
|
payload = dict_to_lower_merge(payload, {"payAmount": 1, "isReward": 0, "resourceDesc": ""})
|
@@ -2991,9 +3125,9 @@ class P123OpenClient:
|
|
2991
3125
|
return self.request(api, "POST", json=payload, async_=async_, **request_kwargs)
|
2992
3126
|
|
2993
3127
|
@overload
|
2994
|
-
def
|
3128
|
+
def transcode_download_all(
|
2995
3129
|
self,
|
2996
|
-
payload: dict,
|
3130
|
+
payload: dict | int | str,
|
2997
3131
|
/,
|
2998
3132
|
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
2999
3133
|
*,
|
@@ -3002,9 +3136,9 @@ class P123OpenClient:
|
|
3002
3136
|
) -> dict:
|
3003
3137
|
...
|
3004
3138
|
@overload
|
3005
|
-
def
|
3139
|
+
def transcode_download_all(
|
3006
3140
|
self,
|
3007
|
-
payload: dict,
|
3141
|
+
payload: dict | int | str,
|
3008
3142
|
/,
|
3009
3143
|
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
3010
3144
|
*,
|
@@ -3012,37 +3146,41 @@ class P123OpenClient:
|
|
3012
3146
|
**request_kwargs,
|
3013
3147
|
) -> Coroutine[Any, Any, dict]:
|
3014
3148
|
...
|
3015
|
-
def
|
3149
|
+
def transcode_download_all(
|
3016
3150
|
self,
|
3017
|
-
payload: dict,
|
3151
|
+
payload: dict | int | str,
|
3018
3152
|
/,
|
3019
3153
|
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
3020
3154
|
*,
|
3021
3155
|
async_: Literal[False, True] = False,
|
3022
3156
|
**request_kwargs,
|
3023
3157
|
) -> dict | Coroutine[Any, Any, dict]:
|
3024
|
-
"""
|
3158
|
+
"""某个视频全部转码文件下载
|
3025
3159
|
|
3026
|
-
POST https://open-api.123pan.com/api/v1/transcode/
|
3160
|
+
POST https://open-api.123pan.com/api/v1/transcode/file/download/all
|
3161
|
+
|
3162
|
+
.. attention::
|
3163
|
+
该接口需要轮询去查询结果,建议 10s 一次
|
3027
3164
|
|
3028
3165
|
.. admonition:: Reference
|
3029
|
-
/API
|
3166
|
+
/API列表/视频转码/视频文件下载/某个视频全部转码文件下载
|
3030
3167
|
|
3031
|
-
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/
|
3168
|
+
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/yb7hrb0x2gym7xic
|
3032
3169
|
|
3033
3170
|
:payload:
|
3034
|
-
- fileId: int
|
3035
|
-
-
|
3036
|
-
- type: int 💡 文件类型:1:m3u8 2:ts
|
3037
|
-
- tsName: str 💡 下载 ts 文件时必须要指定名称,请参考查询某个视频的转码结果
|
3171
|
+
- fileId: int 💡 文件 id
|
3172
|
+
- zipName: str = f"转码{file_id}.zip" 💡 下载 zip 文件的名字
|
3038
3173
|
"""
|
3039
|
-
api = complete_url("/api/v1/transcode/
|
3174
|
+
api = complete_url("/api/v1/transcode/file/download/all", base_url)
|
3175
|
+
if not isinstance(payload, dict):
|
3176
|
+
payload = {"fileId": payload}
|
3177
|
+
payload = dict_to_lower_merge(payload, zipName=f"转码{payload.get('fileid', '')}.zip")
|
3040
3178
|
return self.request(api, "POST", json=payload, async_=async_, **request_kwargs)
|
3041
3179
|
|
3042
3180
|
@overload
|
3043
|
-
def
|
3181
|
+
def transcode_m3u8_ts_download(
|
3044
3182
|
self,
|
3045
|
-
payload: dict
|
3183
|
+
payload: dict,
|
3046
3184
|
/,
|
3047
3185
|
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
3048
3186
|
*,
|
@@ -3051,9 +3189,9 @@ class P123OpenClient:
|
|
3051
3189
|
) -> dict:
|
3052
3190
|
...
|
3053
3191
|
@overload
|
3054
|
-
def
|
3192
|
+
def transcode_m3u8_ts_download(
|
3055
3193
|
self,
|
3056
|
-
payload: dict
|
3194
|
+
payload: dict,
|
3057
3195
|
/,
|
3058
3196
|
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
3059
3197
|
*,
|
@@ -3061,35 +3199,31 @@ class P123OpenClient:
|
|
3061
3199
|
**request_kwargs,
|
3062
3200
|
) -> Coroutine[Any, Any, dict]:
|
3063
3201
|
...
|
3064
|
-
def
|
3202
|
+
def transcode_m3u8_ts_download(
|
3065
3203
|
self,
|
3066
|
-
payload: dict
|
3204
|
+
payload: dict,
|
3067
3205
|
/,
|
3068
3206
|
base_url: str | Callable[[], str] = DEFAULT_OPEN_BASE_URL,
|
3069
3207
|
*,
|
3070
3208
|
async_: Literal[False, True] = False,
|
3071
3209
|
**request_kwargs,
|
3072
3210
|
) -> dict | Coroutine[Any, Any, dict]:
|
3073
|
-
"""
|
3074
|
-
|
3075
|
-
POST https://open-api.123pan.com/api/v1/transcode/file/download/all
|
3211
|
+
"""单个转码文件下载(m3u8或ts)
|
3076
3212
|
|
3077
|
-
|
3078
|
-
该接口需要轮询去查询结果,建议 10s 一次
|
3213
|
+
POST https://open-api.123pan.com/api/v1/transcode/m3u8_ts/download
|
3079
3214
|
|
3080
3215
|
.. admonition:: Reference
|
3081
|
-
/API
|
3216
|
+
/API列表/视频转码/视频文件下载/单个转码文件下载(m3u8或ts)
|
3082
3217
|
|
3083
|
-
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/
|
3218
|
+
https://123yunpan.yuque.com/org-wiki-123yunpan-muaork/cr6ced/yf97p60yyzb8mzbr
|
3084
3219
|
|
3085
3220
|
:payload:
|
3086
|
-
- fileId: int
|
3087
|
-
-
|
3221
|
+
- fileId: int 💡 文件 id
|
3222
|
+
- resolution: str 💡 分辨率
|
3223
|
+
- type: int 💡 文件类型:1:m3u8 2:ts
|
3224
|
+
- tsName: str 💡 下载 ts 文件时必须要指定名称,请参考查询某个视频的转码结果
|
3088
3225
|
"""
|
3089
|
-
api = complete_url("/api/v1/transcode/
|
3090
|
-
if not isinstance(payload, dict):
|
3091
|
-
payload = {"fileId": payload}
|
3092
|
-
payload = dict_to_lower_merge(payload, zipName=f"转码{payload.get('fileid', '')}.zip")
|
3226
|
+
api = complete_url("/api/v1/transcode/m3u8_ts/download", base_url)
|
3093
3227
|
return self.request(api, "POST", json=payload, async_=async_, **request_kwargs)
|
3094
3228
|
|
3095
3229
|
@overload
|
@@ -3486,7 +3620,7 @@ class P123OpenClient:
|
|
3486
3620
|
:payload:
|
3487
3621
|
- containDir: "false" | "true" = "false" 💡 上传文件是否包含路径
|
3488
3622
|
- filename: str 💡 文件名,但 `containDir` 为 "true" 时,视为路径
|
3489
|
-
- duplicate: 0 | 1 | 2 = 0 💡 处理同名:0:
|
3623
|
+
- duplicate: 0 | 1 | 2 = 0 💡 处理同名:0: 跳过/报错 1: 保留/后缀编号 2: 替换/覆盖
|
3490
3624
|
- etag: str 💡 文件 md5
|
3491
3625
|
- parentFileID: int = 0 💡 父目录 id,根目录是 0
|
3492
3626
|
- size: int 💡 文件大小,单位:字节
|
@@ -3505,10 +3639,11 @@ class P123OpenClient:
|
|
3505
3639
|
"""
|
3506
3640
|
api = complete_url("/upload/v1/file/create", base_url)
|
3507
3641
|
payload = dict_to_lower_merge(payload, {
|
3508
|
-
"duplicate": 0,
|
3509
3642
|
"parentFileId": 0,
|
3510
3643
|
"containDir": "false",
|
3511
3644
|
})
|
3645
|
+
if not payload.get("duplicate"):
|
3646
|
+
payload.pop("duplicate", None)
|
3512
3647
|
return self.request(api, "POST", json=payload, async_=async_, **request_kwargs)
|
3513
3648
|
|
3514
3649
|
@overload
|
@@ -3788,7 +3923,7 @@ class P123OpenClient:
|
|
3788
3923
|
"""上传文件
|
3789
3924
|
|
3790
3925
|
.. note::
|
3791
|
-
|
3926
|
+
如果文件名中包含字符 "\\/:*?|><,则转换为对应的全角字符
|
3792
3927
|
|
3793
3928
|
.. admonition:: Reference
|
3794
3929
|
/API列表/文件管理/上传/v1/💡上传流程说明
|
@@ -3926,7 +4061,7 @@ class P123OpenClient:
|
|
3926
4061
|
file_name = getattr(file, "name", "")
|
3927
4062
|
file_name = basename(file_name)
|
3928
4063
|
if file_name:
|
3929
|
-
file_name = file_name
|
4064
|
+
file_name = escape_filename(file_name)
|
3930
4065
|
else:
|
3931
4066
|
file_name = str(uuid4())
|
3932
4067
|
if file_size < 0:
|
@@ -4099,6 +4234,9 @@ class P123OpenClient:
|
|
4099
4234
|
dlink_disable_open = dlink_disable
|
4100
4235
|
dlink_enable_open = dlink_enable
|
4101
4236
|
dlink_log_open = dlink_log
|
4237
|
+
dlink_m3u8_open = dlink_m3u8
|
4238
|
+
dlink_transcode_open = dlink_transcode
|
4239
|
+
dlink_transcode_query_open = dlink_transcode_query
|
4102
4240
|
dlink_url_open = dlink_url
|
4103
4241
|
download_info_open = download_info
|
4104
4242
|
fs_delete_open = fs_delete
|
@@ -4118,7 +4256,7 @@ class P123OpenClient:
|
|
4118
4256
|
oss_copy_fail_open = oss_copy_fail
|
4119
4257
|
oss_copy_process_open = oss_copy_process
|
4120
4258
|
oss_delete_open = oss_delete
|
4121
|
-
|
4259
|
+
oss_detail_open = oss_detail
|
4122
4260
|
oss_list_open = oss_list
|
4123
4261
|
oss_mkdir_open = oss_mkdir
|
4124
4262
|
oss_move_open = oss_move
|
@@ -4137,7 +4275,7 @@ class P123OpenClient:
|
|
4137
4275
|
transcode_delete_open = transcode_delete
|
4138
4276
|
transcode_download_open = transcode_download
|
4139
4277
|
transcode_download_all_open = transcode_download_all
|
4140
|
-
|
4278
|
+
transcode_m3u8_ts_download_open = transcode_m3u8_ts_download
|
4141
4279
|
transcode_info_open = transcode_info
|
4142
4280
|
transcode_list_open = transcode_list
|
4143
4281
|
transcode_record_open = transcode_record
|
@@ -5894,7 +6032,8 @@ class P123Client(P123OpenClient):
|
|
5894
6032
|
def to_snake_case(
|
5895
6033
|
payload: dict[str, Any],
|
5896
6034
|
/,
|
5897
|
-
|
6035
|
+
*,
|
6036
|
+
_map = {
|
5898
6037
|
"sharekey": "share_key",
|
5899
6038
|
"sharepwd": "share_pwd",
|
5900
6039
|
"filelist": "file_list",
|
@@ -5903,15 +6042,16 @@ class P123Client(P123OpenClient):
|
|
5903
6042
|
"parentfileid": "parent_file_id",
|
5904
6043
|
"driveid": "drive_id",
|
5905
6044
|
"currentlevel": "current_level",
|
5906
|
-
},
|
6045
|
+
}.get,
|
6046
|
+
_sub = re_compile("(?<!^)[A-Z]").sub,
|
5907
6047
|
):
|
5908
6048
|
d: dict[str, Any] = {}
|
5909
6049
|
for k, v in payload.items():
|
5910
6050
|
if "_" in k:
|
5911
6051
|
d[k.lower()] = v
|
5912
|
-
elif k2 :=
|
6052
|
+
elif k2 := _map(k.lower()):
|
5913
6053
|
d[k2] = v
|
5914
|
-
elif (k2 :=
|
6054
|
+
elif (k2 := _sub(r"_\g<0>", k)) != k:
|
5915
6055
|
d[k2.lower()] = v
|
5916
6056
|
else:
|
5917
6057
|
d[k] = v
|
@@ -6610,7 +6750,7 @@ class P123Client(P123OpenClient):
|
|
6610
6750
|
"""上传文件
|
6611
6751
|
|
6612
6752
|
.. note::
|
6613
|
-
|
6753
|
+
如果文件名中包含字符 "\\/:*?|><,则转换为对应的全角字符
|
6614
6754
|
|
6615
6755
|
:param file: 待上传的文件
|
6616
6756
|
|
@@ -6737,7 +6877,7 @@ class P123Client(P123OpenClient):
|
|
6737
6877
|
file_name = getattr(file, "name", "")
|
6738
6878
|
file_name = basename(file_name)
|
6739
6879
|
if file_name:
|
6740
|
-
file_name = file_name
|
6880
|
+
file_name = escape_filename(file_name)
|
6741
6881
|
else:
|
6742
6882
|
file_name = str(uuid4())
|
6743
6883
|
if file_size < 0:
|
@@ -6967,7 +7107,7 @@ class P123Client(P123OpenClient):
|
|
6967
7107
|
file_name = getattr(file, "name", "")
|
6968
7108
|
file_name = basename(file_name)
|
6969
7109
|
if file_name:
|
6970
|
-
file_name = file_name
|
7110
|
+
file_name = escape_filename(file_name)
|
6971
7111
|
if not file_name:
|
6972
7112
|
file_name = str(uuid4())
|
6973
7113
|
if file_size < 0:
|
p123client/tool/__init__.py
CHANGED
@@ -302,7 +302,8 @@ def _iterdir(
|
|
302
302
|
if interval > 0:
|
303
303
|
last_ts = time()
|
304
304
|
check_response(resp)
|
305
|
-
|
305
|
+
info_list = resp["data"]["InfoList"]
|
306
|
+
for info in info_list:
|
306
307
|
is_dir = info["is_dir"] = bool(info["Type"])
|
307
308
|
fid = info["id"] = int(info["FileId"])
|
308
309
|
info["parent_id"] = parent_id
|
@@ -328,8 +329,8 @@ def _iterdir(
|
|
328
329
|
if is_dir and (max_depth < 0 or depth < max_depth):
|
329
330
|
put((depth, fid, relpath + "/"))
|
330
331
|
if (
|
331
|
-
not
|
332
|
-
len(
|
332
|
+
not info_list or
|
333
|
+
len(info_list) < page_size or
|
333
334
|
resp["data"]["Next"] == "-1"
|
334
335
|
):
|
335
336
|
break
|
@@ -0,0 +1,12 @@
|
|
1
|
+
LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
|
2
|
+
p123client/__init__.py,sha256=gfUum-q3f_XuXOk2HpArDAIxAlscZm8Fau1kiNkNFpg,214
|
3
|
+
p123client/client.py,sha256=T0PcrNCgbFBRIoFXt6iVYjDCS2FSStadAeaFwb_q-hw,244302
|
4
|
+
p123client/const.py,sha256=T17OzPQrnIG6w_Hzjc8TF_fFMKa-hQMSn1gff8pVcBc,56
|
5
|
+
p123client/exception.py,sha256=d2PN6mRJuw6SXNiTOBfjZQ6qfInAvkERkcbx4PQ-7vA,1369
|
6
|
+
p123client/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
7
|
+
p123client/tool/__init__.py,sha256=P67eusj4p7O6VyOgRrSJEspI3nTM7mLFySyw55bsOtA,16657
|
8
|
+
p123client/type.py,sha256=T17OzPQrnIG6w_Hzjc8TF_fFMKa-hQMSn1gff8pVcBc,56
|
9
|
+
p123client-0.0.6.1.dist-info/LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
|
10
|
+
p123client-0.0.6.1.dist-info/METADATA,sha256=2aec3rDPgFBC4UI1QErD4RBR7W76VvblXCZsuELbjlk,8869
|
11
|
+
p123client-0.0.6.1.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
12
|
+
p123client-0.0.6.1.dist-info/RECORD,,
|
@@ -1,12 +0,0 @@
|
|
1
|
-
LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
|
2
|
-
p123client/__init__.py,sha256=gfUum-q3f_XuXOk2HpArDAIxAlscZm8Fau1kiNkNFpg,214
|
3
|
-
p123client/client.py,sha256=Vo1QbNuDdNQBrrjXJki1n5IXFxoYd0QsK4R2eL5-Wxg,240077
|
4
|
-
p123client/const.py,sha256=T17OzPQrnIG6w_Hzjc8TF_fFMKa-hQMSn1gff8pVcBc,56
|
5
|
-
p123client/exception.py,sha256=d2PN6mRJuw6SXNiTOBfjZQ6qfInAvkERkcbx4PQ-7vA,1369
|
6
|
-
p123client/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
7
|
-
p123client/tool/__init__.py,sha256=zlKMg_ETifq4pFsbmqAS_BqU-fuqrYWbCs_HD4Vra6o,16649
|
8
|
-
p123client/type.py,sha256=T17OzPQrnIG6w_Hzjc8TF_fFMKa-hQMSn1gff8pVcBc,56
|
9
|
-
p123client-0.0.6.dist-info/LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
|
10
|
-
p123client-0.0.6.dist-info/METADATA,sha256=7JhGIxHwVQHzN9dc2fWzTFDkZCVBq6RXZWxfLmpeZo0,8867
|
11
|
-
p123client-0.0.6.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
12
|
-
p123client-0.0.6.dist-info/RECORD,,
|
File without changes
|
File without changes
|