p115client 0.0.5.10.4__py3-none-any.whl → 0.0.5.10.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- p115client/client.py +23 -3
- p115client/tool/attr.py +1 -0
- p115client/tool/iterdir.py +252 -148
- {p115client-0.0.5.10.4.dist-info → p115client-0.0.5.10.6.dist-info}/METADATA +1 -1
- {p115client-0.0.5.10.4.dist-info → p115client-0.0.5.10.6.dist-info}/RECORD +7 -7
- {p115client-0.0.5.10.4.dist-info → p115client-0.0.5.10.6.dist-info}/LICENSE +0 -0
- {p115client-0.0.5.10.4.dist-info → p115client-0.0.5.10.6.dist-info}/WHEEL +0 -0
p115client/client.py
CHANGED
@@ -1364,6 +1364,7 @@ class ClientRequestMixin:
|
|
1364
1364
|
POST https://qrcodeapi.115.com/open/deviceCodeToToken
|
1365
1365
|
|
1366
1366
|
.. admonition:: Reference
|
1367
|
+
|
1367
1368
|
https://www.yuque.com/115yun/open/shtpzfhewv5nag11#QCCVQ
|
1368
1369
|
|
1369
1370
|
:payload:
|
@@ -1415,6 +1416,7 @@ class ClientRequestMixin:
|
|
1415
1416
|
POST https://qrcodeapi.115.com/open/refreshToken
|
1416
1417
|
|
1417
1418
|
.. admonition:: Reference
|
1419
|
+
|
1418
1420
|
https://www.yuque.com/115yun/open/shtpzfhewv5nag11#ve54x
|
1419
1421
|
|
1420
1422
|
:payload:
|
@@ -1567,6 +1569,7 @@ class ClientRequestMixin:
|
|
1567
1569
|
GET https://qrcodeapi.115.com/get/status/
|
1568
1570
|
|
1569
1571
|
.. admonition:: Reference
|
1572
|
+
|
1570
1573
|
https://www.yuque.com/115yun/open/shtpzfhewv5nag11#lAsp2
|
1571
1574
|
|
1572
1575
|
:payload:
|
@@ -1653,6 +1656,7 @@ class ClientRequestMixin:
|
|
1653
1656
|
POST https://qrcodeapi.115.com/open/authDeviceCode
|
1654
1657
|
|
1655
1658
|
.. admonition:: Reference
|
1659
|
+
|
1656
1660
|
https://www.yuque.com/115yun/open/shtpzfhewv5nag11#WzRhM
|
1657
1661
|
|
1658
1662
|
.. note::
|
@@ -2464,6 +2468,7 @@ class P115OpenClient(ClientRequestMixin):
|
|
2464
2468
|
"""115 的客户端对象
|
2465
2469
|
|
2466
2470
|
.. admonition:: Reference
|
2471
|
+
|
2467
2472
|
https://www.yuque.com/115yun/open
|
2468
2473
|
|
2469
2474
|
:param app_id_or_refresh_token: 申请到的 AppID 或 refresh_token
|
@@ -2747,6 +2752,7 @@ class P115OpenClient(ClientRequestMixin):
|
|
2747
2752
|
相当于 `P115Client.download_url_app(app="chrome")`
|
2748
2753
|
|
2749
2754
|
.. admonition:: Reference
|
2755
|
+
|
2750
2756
|
https://www.yuque.com/115yun/open/um8whr91bxb5997o
|
2751
2757
|
|
2752
2758
|
:payload:
|
@@ -2810,6 +2816,7 @@ class P115OpenClient(ClientRequestMixin):
|
|
2810
2816
|
POST https://proapi.115.com/open/ufile/copy
|
2811
2817
|
|
2812
2818
|
.. admonition:: Reference
|
2819
|
+
|
2813
2820
|
https://www.yuque.com/115yun/open/lvas49ar94n47bbk
|
2814
2821
|
|
2815
2822
|
:payload:
|
@@ -2866,6 +2873,7 @@ class P115OpenClient(ClientRequestMixin):
|
|
2866
2873
|
POST https://proapi.115.com/open/ufile/delete
|
2867
2874
|
|
2868
2875
|
.. admonition:: Reference
|
2876
|
+
|
2869
2877
|
https://www.yuque.com/115yun/open/kt04fu8vcchd2fnb
|
2870
2878
|
|
2871
2879
|
:payload:
|
@@ -2909,7 +2917,7 @@ class P115OpenClient(ClientRequestMixin):
|
|
2909
2917
|
async_: Literal[False, True] = False,
|
2910
2918
|
**request_kwargs,
|
2911
2919
|
) -> dict | Coroutine[Any, Any, dict]:
|
2912
|
-
"""
|
2920
|
+
"""获取目录中的文件列表和基本信息
|
2913
2921
|
|
2914
2922
|
GET https://proapi.115.com/open/ufile/files
|
2915
2923
|
|
@@ -2917,6 +2925,7 @@ class P115OpenClient(ClientRequestMixin):
|
|
2917
2925
|
相当于 `P115Client.fs_files_app`
|
2918
2926
|
|
2919
2927
|
.. admonition:: Reference
|
2928
|
+
|
2920
2929
|
https://www.yuque.com/115yun/open/kz9ft9a7s57ep868
|
2921
2930
|
|
2922
2931
|
:payload:
|
@@ -3036,6 +3045,7 @@ class P115OpenClient(ClientRequestMixin):
|
|
3036
3045
|
相当于 `P115Client.fs_category_get_app`
|
3037
3046
|
|
3038
3047
|
.. admonition:: Reference
|
3048
|
+
|
3039
3049
|
https://www.yuque.com/115yun/open/rl8zrhe2nag21dfw
|
3040
3050
|
|
3041
3051
|
:payload:
|
@@ -3085,6 +3095,7 @@ class P115OpenClient(ClientRequestMixin):
|
|
3085
3095
|
POST https://proapi.115.com/open/folder/add
|
3086
3096
|
|
3087
3097
|
.. admonition:: Reference
|
3098
|
+
|
3088
3099
|
https://www.yuque.com/115yun/open/qur839kyx9cgxpxi
|
3089
3100
|
|
3090
3101
|
:payload:
|
@@ -3137,6 +3148,7 @@ class P115OpenClient(ClientRequestMixin):
|
|
3137
3148
|
POST https://proapi.115.com/open/ufile/move
|
3138
3149
|
|
3139
3150
|
.. admonition:: Reference
|
3151
|
+
|
3140
3152
|
https://www.yuque.com/115yun/open/vc6fhi2mrkenmav2
|
3141
3153
|
|
3142
3154
|
:payload:
|
@@ -3195,6 +3207,7 @@ class P115OpenClient(ClientRequestMixin):
|
|
3195
3207
|
相当于 `P115Client.fs_search_app2`
|
3196
3208
|
|
3197
3209
|
.. admonition:: Reference
|
3210
|
+
|
3198
3211
|
https://www.yuque.com/115yun/open/ft2yelxzopusus38
|
3199
3212
|
|
3200
3213
|
:payload:
|
@@ -3350,6 +3363,7 @@ class P115OpenClient(ClientRequestMixin):
|
|
3350
3363
|
即使文件已经被删除,也可以操作成功
|
3351
3364
|
|
3352
3365
|
.. admonition:: Reference
|
3366
|
+
|
3353
3367
|
https://www.yuque.com/115yun/open/gyrpw5a0zc4sengm
|
3354
3368
|
|
3355
3369
|
:payload:
|
@@ -3448,6 +3462,7 @@ class P115OpenClient(ClientRequestMixin):
|
|
3448
3462
|
GET https://proapi.115.com/open/rb/list
|
3449
3463
|
|
3450
3464
|
.. admonition:: Reference
|
3465
|
+
|
3451
3466
|
https://www.yuque.com/115yun/open/bg7l4328t98fwgex
|
3452
3467
|
|
3453
3468
|
:payload:
|
@@ -3497,6 +3512,7 @@ class P115OpenClient(ClientRequestMixin):
|
|
3497
3512
|
POST https://proapi.115.com/open/rb/revert
|
3498
3513
|
|
3499
3514
|
.. admonition:: Reference
|
3515
|
+
|
3500
3516
|
https://www.yuque.com/115yun/open/gq293z80a3kmxbaq
|
3501
3517
|
|
3502
3518
|
:payload:
|
@@ -3542,6 +3558,7 @@ class P115OpenClient(ClientRequestMixin):
|
|
3542
3558
|
GET https://proapi.115.com/open/upload/get_token
|
3543
3559
|
|
3544
3560
|
.. admonition:: Reference
|
3561
|
+
|
3545
3562
|
https://www.yuque.com/115yun/open/kzacvzl0g7aiyyn4
|
3546
3563
|
"""
|
3547
3564
|
api = complete_proapi("/open/upload/get_token", base_url)
|
@@ -3583,6 +3600,7 @@ class P115OpenClient(ClientRequestMixin):
|
|
3583
3600
|
POST https://proapi.115.com/open/upload/init
|
3584
3601
|
|
3585
3602
|
.. admonition:: Reference
|
3603
|
+
|
3586
3604
|
https://www.yuque.com/115yun/open/ul4mrauo5i2uza0q
|
3587
3605
|
|
3588
3606
|
:payload:
|
@@ -3641,6 +3659,7 @@ class P115OpenClient(ClientRequestMixin):
|
|
3641
3659
|
POST https://proapi.115.com/open/upload/resume
|
3642
3660
|
|
3643
3661
|
.. admonition:: Reference
|
3662
|
+
|
3644
3663
|
https://www.yuque.com/115yun/open/tzvi9sbcg59msddz
|
3645
3664
|
|
3646
3665
|
:payload:
|
@@ -4131,6 +4150,7 @@ class P115OpenClient(ClientRequestMixin):
|
|
4131
4150
|
GET https://proapi.115.com/open/user/info
|
4132
4151
|
|
4133
4152
|
.. admonition:: Reference
|
4153
|
+
|
4134
4154
|
https://www.yuque.com/115yun/open/ot1litggzxa1czww
|
4135
4155
|
"""
|
4136
4156
|
api = complete_proapi("/open/user/info", base_url)
|
@@ -9057,9 +9077,9 @@ class P115Client(P115OpenClient):
|
|
9057
9077
|
4. show_dir=0 且 cur=0(或不指定 cur)
|
9058
9078
|
|
9059
9079
|
.. hint::
|
9060
|
-
|
9080
|
+
如果不指定或者指定的 cid 不存在,则会视为 cid=0 进行处理
|
9061
9081
|
|
9062
|
-
|
9082
|
+
当指定 natsort=1 时,如果里面的数量较少时,可仅统计某个目录内的文件或目录总数,而不返回具体的文件信息
|
9063
9083
|
|
9064
9084
|
.. hint::
|
9065
9085
|
当一个 cookies 被另一个更新的登录所失效,并不意味着这个 cookies 就直接不可用了。
|
p115client/tool/attr.py
CHANGED
p115client/tool/iterdir.py
CHANGED
@@ -59,30 +59,6 @@ from .life import iter_life_behavior_once, life_show
|
|
59
59
|
from .util import posix_escape_name, share_extract_payload, unescape_115_charref
|
60
60
|
|
61
61
|
|
62
|
-
WEBAPI_BASE_URLS = (
|
63
|
-
"http://webapi.115.com",
|
64
|
-
"https://webapi.115.com",
|
65
|
-
"http://webapi.115.com",
|
66
|
-
"http://115cdn.com/webapi",
|
67
|
-
"http://webapi.115.com",
|
68
|
-
"http://115vod.com/webapi",
|
69
|
-
)
|
70
|
-
PROAPI_BASE_URLS = (
|
71
|
-
"http://proapi.115.com",
|
72
|
-
"https://proapi.115.com",
|
73
|
-
"http://proapi.115.com",
|
74
|
-
"https://proapi.115.com",
|
75
|
-
)
|
76
|
-
APS_BASE_URLS = (
|
77
|
-
"http://115cdn.com/aps",
|
78
|
-
"http://aps.115.com",
|
79
|
-
"http://115vod.com/aps",
|
80
|
-
)
|
81
|
-
|
82
|
-
_n_get_ancestors = 0
|
83
|
-
_n_get_count = 0
|
84
|
-
|
85
|
-
|
86
62
|
class DirNode(NamedTuple):
|
87
63
|
name: str
|
88
64
|
parent_id: int
|
@@ -152,7 +128,7 @@ def get_path_to_cid(
|
|
152
128
|
root_id: None | int = None,
|
153
129
|
escape: None | bool | Callable[[str], str] = True,
|
154
130
|
refresh: bool = False,
|
155
|
-
id_to_dirnode: None | dict[int, tuple[str, int] | DirNode] = None,
|
131
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
156
132
|
app: str = "web",
|
157
133
|
*,
|
158
134
|
async_: Literal[False] = False,
|
@@ -166,7 +142,7 @@ def get_path_to_cid(
|
|
166
142
|
root_id: None | int = None,
|
167
143
|
escape: None | bool | Callable[[str], str] = True,
|
168
144
|
refresh: bool = False,
|
169
|
-
id_to_dirnode: None | dict[int, tuple[str, int] | DirNode] = None,
|
145
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
170
146
|
app: str = "web",
|
171
147
|
*,
|
172
148
|
async_: Literal[True],
|
@@ -179,7 +155,7 @@ def get_path_to_cid(
|
|
179
155
|
root_id: None | int = None,
|
180
156
|
escape: None | bool | Callable[[str], str] = True,
|
181
157
|
refresh: bool = False,
|
182
|
-
id_to_dirnode: None | dict[int, tuple[str, int] | DirNode] = None,
|
158
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
183
159
|
app: str = "web",
|
184
160
|
*,
|
185
161
|
async_: Literal[False, True] = False,
|
@@ -215,14 +191,31 @@ def get_path_to_cid(
|
|
215
191
|
escape = cast(None | Callable[[str], str], escape)
|
216
192
|
if id_to_dirnode is None:
|
217
193
|
id_to_dirnode = ID_TO_DIRNODE_CACHE[client.user_id]
|
194
|
+
elif id_to_dirnode is ...:
|
195
|
+
id_to_dirnode = {}
|
218
196
|
def gen_step():
|
219
197
|
nonlocal cid
|
220
198
|
parts: list[str] = []
|
221
199
|
if cid and (refresh or cid not in id_to_dirnode):
|
222
|
-
if
|
223
|
-
resp = yield client.
|
200
|
+
if not isinstance(client, P115Client) or app == "open":
|
201
|
+
resp = yield client.fs_files_open(
|
202
|
+
{"cid": cid, "cur": 1, "nf": 1, "hide_data": 1},
|
203
|
+
async_=async_,
|
204
|
+
**request_kwargs,
|
205
|
+
)
|
206
|
+
elif app in ("", "web", "desktop", "harmony"):
|
207
|
+
resp = yield client.fs_files_aps(
|
208
|
+
{"cid": cid, "limit": 1, "nf": 1, "star": 1},
|
209
|
+
async_=async_,
|
210
|
+
**request_kwargs,
|
211
|
+
)
|
224
212
|
else:
|
225
|
-
resp = yield client.fs_files_app(
|
213
|
+
resp = yield client.fs_files_app(
|
214
|
+
{"cid": cid, "cur": 1, "nf": 1, "hide_data": 1},
|
215
|
+
app=app,
|
216
|
+
async_=async_,
|
217
|
+
**request_kwargs,
|
218
|
+
)
|
226
219
|
check_response(resp)
|
227
220
|
if cid and int(resp["path"][-1]["cid"]) != cid:
|
228
221
|
raise FileNotFoundError(ENOENT, cid)
|
@@ -252,6 +245,8 @@ def get_file_count(
|
|
252
245
|
client: str | P115Client,
|
253
246
|
cid: int = 0,
|
254
247
|
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
248
|
+
app: str = "web",
|
249
|
+
use_fs_files: bool = True,
|
255
250
|
*,
|
256
251
|
async_: Literal[False] = False,
|
257
252
|
**request_kwargs,
|
@@ -262,6 +257,8 @@ def get_file_count(
|
|
262
257
|
client: str | P115Client,
|
263
258
|
cid: int = 0,
|
264
259
|
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
260
|
+
app: str = "web",
|
261
|
+
use_fs_files: bool = True,
|
265
262
|
*,
|
266
263
|
async_: Literal[True],
|
267
264
|
**request_kwargs,
|
@@ -271,6 +268,8 @@ def get_file_count(
|
|
271
268
|
client: str | P115Client,
|
272
269
|
cid: int = 0,
|
273
270
|
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
271
|
+
app: str = "web",
|
272
|
+
use_fs_files: bool = True,
|
274
273
|
*,
|
275
274
|
async_: Literal[False, True] = False,
|
276
275
|
**request_kwargs,
|
@@ -283,6 +282,8 @@ def get_file_count(
|
|
283
282
|
:param client: 115 客户端或 cookies
|
284
283
|
:param cid: 目录 id
|
285
284
|
:param id_to_dirnode: 字典,保存 id 到对应文件的 `DirNode(name, parent_id)` 命名元组的字典
|
285
|
+
:param app: 使用某个 app (设备)的接口
|
286
|
+
:param use_fs_files: 使用 `client.fs_files`,否则使用 `client.fs_category_get`
|
286
287
|
:param async_: 是否异步
|
287
288
|
:param request_kwargs: 其它请求参数
|
288
289
|
|
@@ -292,75 +293,78 @@ def get_file_count(
|
|
292
293
|
client = P115Client(client, check_for_relogin=True)
|
293
294
|
if id_to_dirnode is None:
|
294
295
|
id_to_dirnode = ID_TO_DIRNODE_CACHE[client.user_id]
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
_n_get_count += 1
|
296
|
+
def get_resp_of_fs_files(id: int, /):
|
297
|
+
if not isinstance(client, P115Client) or app == "open":
|
298
|
+
return client.fs_files_open(
|
299
|
+
{"cid": id, "hide_data": 1, "show_dir": 0},
|
300
|
+
async_=async_,
|
301
|
+
**request_kwargs,
|
302
|
+
)
|
303
|
+
elif app in ("", "web", "desktop", "harmony"):
|
304
304
|
return client.fs_files(
|
305
|
-
{"cid":
|
306
|
-
base_url=WEBAPI_BASE_URLS[n],
|
305
|
+
{"cid": id, "limit": 1, "show_dir": 0},
|
307
306
|
async_=async_,
|
308
307
|
**request_kwargs,
|
309
308
|
)
|
310
|
-
|
311
|
-
|
312
|
-
|
309
|
+
elif app == "aps":
|
310
|
+
return client.fs_files_aps(
|
311
|
+
{"cid": id, "limit": 1, "show_dir": 0},
|
312
|
+
async_=async_,
|
313
|
+
**request_kwargs,
|
314
|
+
)
|
315
|
+
else:
|
313
316
|
return client.fs_files_app(
|
314
|
-
{"cid":
|
315
|
-
|
317
|
+
{"cid": id, "hide_data": 1, "show_dir": 0},
|
318
|
+
app=app,
|
316
319
|
async_=async_,
|
317
320
|
**request_kwargs,
|
318
321
|
)
|
319
|
-
|
320
|
-
if
|
321
|
-
|
322
|
-
|
323
|
-
{"cid": cid, "limit": 1, "show_dir": 0},
|
324
|
-
base_url=APS_BASE_URLS[n],
|
322
|
+
def get_resp_of_category_get(id: int, /):
|
323
|
+
if not isinstance(client, P115Client) or app == "open":
|
324
|
+
return client.fs_info_open(
|
325
|
+
id,
|
325
326
|
async_=async_,
|
326
327
|
**request_kwargs,
|
327
328
|
)
|
328
|
-
|
329
|
-
if n < n_webapi:
|
330
|
-
_n_get_count += 1
|
329
|
+
elif app in ("", "web", "desktop", "harmony", "aps"):
|
331
330
|
return client.fs_category_get(
|
332
|
-
|
333
|
-
|
331
|
+
id,
|
332
|
+
async_=async_,
|
333
|
+
**request_kwargs,
|
334
|
+
)
|
335
|
+
else:
|
336
|
+
return client.fs_category_get_app(
|
337
|
+
id,
|
338
|
+
app=app,
|
334
339
|
async_=async_,
|
335
340
|
**request_kwargs,
|
336
341
|
)
|
337
|
-
n -= n_webapi
|
338
|
-
_n_get_count += 1
|
339
|
-
return client.fs_category_get_app(
|
340
|
-
cid,
|
341
|
-
base_url=PROAPI_BASE_URLS[n],
|
342
|
-
async_=async_,
|
343
|
-
**request_kwargs,
|
344
|
-
)
|
345
342
|
def gen_step():
|
346
|
-
if cid
|
343
|
+
if not cid:
|
347
344
|
resp = yield client.fs_space_summury(async_=async_, **request_kwargs)
|
348
345
|
check_response(resp)
|
349
346
|
return sum(v["count"] for k, v in resp["type_summury"].items() if k.isupper())
|
350
|
-
|
351
|
-
|
352
|
-
|
353
|
-
check_response(resp)
|
354
|
-
resp["cid"] = cid
|
355
|
-
if "path" in resp:
|
347
|
+
if use_fs_files:
|
348
|
+
resp = yield get_resp_of_fs_files(cid)
|
349
|
+
check_response(resp)
|
356
350
|
if cid != int(resp["path"][-1]["cid"]):
|
351
|
+
resp["cid"] = cid
|
357
352
|
raise NotADirectoryError(ENOTDIR, resp)
|
358
353
|
if id_to_dirnode is not ...:
|
359
354
|
for info in resp["path"][1:]:
|
360
355
|
id_to_dirnode[int(info["cid"])] = DirNode(info["name"], int(info["pid"]))
|
361
356
|
return int(resp["count"])
|
362
357
|
else:
|
358
|
+
resp = yield get_resp_of_category_get(cid)
|
359
|
+
if not resp:
|
360
|
+
raise FileNotFoundError(ENOENT, cid)
|
361
|
+
if "paths" not in resp:
|
362
|
+
check_response(resp)
|
363
|
+
resp = resp["data"]
|
364
|
+
if not resp:
|
365
|
+
raise FileNotFoundError(ENOENT, cid)
|
363
366
|
if int(resp["file_category"]):
|
367
|
+
resp["cid"] = cid
|
364
368
|
raise NotADirectoryError(ENOTDIR, resp)
|
365
369
|
if id_to_dirnode is not ...:
|
366
370
|
pid = 0
|
@@ -374,8 +378,9 @@ def get_file_count(
|
|
374
378
|
@overload
|
375
379
|
def get_ancestors(
|
376
380
|
client: str | P115Client,
|
377
|
-
attr: dict,
|
381
|
+
attr: int | dict,
|
378
382
|
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
383
|
+
app: str = "web",
|
379
384
|
*,
|
380
385
|
async_: Literal[False] = False,
|
381
386
|
**request_kwargs,
|
@@ -384,8 +389,9 @@ def get_ancestors(
|
|
384
389
|
@overload
|
385
390
|
def get_ancestors(
|
386
391
|
client: str | P115Client,
|
387
|
-
attr: dict,
|
392
|
+
attr: int | dict,
|
388
393
|
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
394
|
+
app: str = "web",
|
389
395
|
*,
|
390
396
|
async_: Literal[True],
|
391
397
|
**request_kwargs,
|
@@ -393,8 +399,9 @@ def get_ancestors(
|
|
393
399
|
...
|
394
400
|
def get_ancestors(
|
395
401
|
client: str | P115Client,
|
396
|
-
attr: dict,
|
402
|
+
attr: int | dict,
|
397
403
|
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
404
|
+
app: str = "web",
|
398
405
|
*,
|
399
406
|
async_: Literal[False, True] = False,
|
400
407
|
**request_kwargs,
|
@@ -405,8 +412,9 @@ def get_ancestors(
|
|
405
412
|
我通过一些经验,搭配了多个接口的占比和参数分布,可能不够合理,以后会根据实际情况调整
|
406
413
|
|
407
414
|
:param client: 115 客户端或 cookies
|
408
|
-
:param attr:
|
415
|
+
:param attr: 待查询节点 `id` 或信息(必须有 `id`,可选有 `parent_id`)
|
409
416
|
:param id_to_dirnode: 字典,保存 id 到对应文件的 `DirNode(name, parent_id)` 命名元组的字典
|
417
|
+
:param app: 使用某个 app (设备)的接口
|
410
418
|
:param async_: 是否异步
|
411
419
|
:param request_kwargs: 其它请求参数
|
412
420
|
|
@@ -424,89 +432,168 @@ def get_ancestors(
|
|
424
432
|
client = P115Client(client, check_for_relogin=True)
|
425
433
|
if id_to_dirnode is None:
|
426
434
|
id_to_dirnode = ID_TO_DIRNODE_CACHE[client.user_id]
|
427
|
-
|
428
|
-
|
429
|
-
|
430
|
-
|
431
|
-
|
432
|
-
|
433
|
-
|
434
|
-
|
435
|
-
_n_get_ancestors += 1
|
435
|
+
def get_resp_of_fs_files(id: int, /):
|
436
|
+
if not isinstance(client, P115Client) or app == "open":
|
437
|
+
return client.fs_files_open(
|
438
|
+
{"cid": id, "cur": 1, "nf": 1, "hide_data": 1},
|
439
|
+
async_=async_,
|
440
|
+
**request_kwargs,
|
441
|
+
)
|
442
|
+
elif app in ("", "web", "desktop", "harmony"):
|
436
443
|
return client.fs_files(
|
437
|
-
{"cid":
|
438
|
-
base_url=WEBAPI_BASE_URLS[n],
|
444
|
+
{"cid": id, "limit": 1, "nf": 1, "star": 1},
|
439
445
|
async_=async_,
|
440
446
|
**request_kwargs,
|
441
447
|
)
|
442
|
-
|
443
|
-
|
444
|
-
|
448
|
+
elif app == "aps":
|
449
|
+
return client.fs_files_aps(
|
450
|
+
{"cid": id, "limit": 1, "nf": 1, "star": 1},
|
451
|
+
async_=async_,
|
452
|
+
**request_kwargs,
|
453
|
+
)
|
454
|
+
else:
|
445
455
|
return client.fs_files_app(
|
446
|
-
{"cid":
|
447
|
-
|
456
|
+
{"cid": id, "cur": 1, "nf": 1, "hide_data": 1},
|
457
|
+
app=app,
|
448
458
|
async_=async_,
|
449
459
|
**request_kwargs,
|
450
460
|
)
|
451
|
-
|
452
|
-
if
|
453
|
-
|
454
|
-
|
455
|
-
{"cid": attr["parent_id"], "limit": 1},
|
456
|
-
base_url=APS_BASE_URLS[n],
|
461
|
+
def get_resp_of_category_get(id: int, /):
|
462
|
+
if not isinstance(client, P115Client) or app == "open":
|
463
|
+
return client.fs_info_open(
|
464
|
+
id,
|
457
465
|
async_=async_,
|
458
466
|
**request_kwargs,
|
459
467
|
)
|
460
|
-
|
461
|
-
_n_get_ancestors = 0
|
462
|
-
return get_resp()
|
463
|
-
n -= n_apsapi
|
464
|
-
if n < n_webapi:
|
465
|
-
_n_get_ancestors += 1
|
468
|
+
elif app in ("", "web", "desktop", "harmony", "aps"):
|
466
469
|
return client.fs_category_get(
|
467
|
-
|
468
|
-
|
470
|
+
id,
|
471
|
+
async_=async_,
|
472
|
+
**request_kwargs,
|
473
|
+
)
|
474
|
+
else:
|
475
|
+
return client.fs_category_get_app(
|
476
|
+
id,
|
477
|
+
app=app,
|
469
478
|
async_=async_,
|
470
479
|
**request_kwargs,
|
471
480
|
)
|
472
|
-
n -= n_webapi
|
473
|
-
_n_get_ancestors += 1
|
474
|
-
return client.fs_category_get_app(
|
475
|
-
attr["id"],
|
476
|
-
base_url=PROAPI_BASE_URLS[n],
|
477
|
-
async_=async_,
|
478
|
-
**request_kwargs,
|
479
|
-
)
|
480
481
|
def gen_step():
|
481
|
-
if not attr["parent_id"]:
|
482
|
-
return [{"id": 0, "parent_id": 0, "name": ""}]
|
483
|
-
resp = yield get_resp()
|
484
|
-
if not resp:
|
485
|
-
raise FileNotFoundError(ENOENT, attr)
|
486
|
-
check_response(resp)
|
487
|
-
resp["attr"] = attr
|
488
482
|
ancestors: list[dict] = [{"id": 0, "parent_id": 0, "name": ""}]
|
489
483
|
add_ancestor = ancestors.append
|
490
484
|
pid = 0
|
491
|
-
|
492
|
-
|
493
|
-
|
494
|
-
|
495
|
-
|
496
|
-
|
497
|
-
|
498
|
-
|
499
|
-
|
485
|
+
is_completed = False
|
486
|
+
if isinstance(attr, dict):
|
487
|
+
fid = cast(int, attr["id"])
|
488
|
+
if not fid:
|
489
|
+
return ancestors
|
490
|
+
is_dir: None | bool = attr.get("is_dir") or attr.get("is_directory")
|
491
|
+
if is_dir is None:
|
492
|
+
if "parent_id" in attr:
|
493
|
+
cid = cast(int, attr["parent_id"])
|
494
|
+
resp = yield get_resp_of_fs_files(cid)
|
495
|
+
if cid != int(resp["path"][-1]["cid"]):
|
496
|
+
resp["attr"] = attr
|
497
|
+
raise FileNotFoundError(ENOENT, resp)
|
498
|
+
for info in resp["path"][1:]:
|
499
|
+
add_ancestor({
|
500
|
+
"parent_id": pid,
|
501
|
+
"id": (pid := int(info["cid"])),
|
502
|
+
"name": info["name"],
|
503
|
+
})
|
504
|
+
if id_to_dirnode is not ...:
|
505
|
+
for ans in ancestors[1:]:
|
506
|
+
id_to_dirnode[ans["id"]] = DirNode(ans["name"], ans["parent_id"])
|
507
|
+
if "name" in attr:
|
508
|
+
name = attr["name"]
|
509
|
+
is_dir = bool(attr.get("is_dir"))
|
510
|
+
else:
|
511
|
+
resp = yield client.fs_file_skim(attr["id"], async_=async_, **request_kwargs)
|
512
|
+
check_response(resp)
|
513
|
+
name = unescape_115_charref(resp["data"]["file_name"])
|
514
|
+
is_dir = not resp["data"]["sha1"]
|
515
|
+
ans = {"id": fid, "parent_id": pid, "name": name}
|
516
|
+
add_ancestor(ans)
|
517
|
+
if is_dir and id_to_dirnode is not ...:
|
518
|
+
id_to_dirnode[ans["id"]] = DirNode(ans["name"], ans["parent_id"])
|
519
|
+
is_completed = True
|
520
|
+
elif is_dir:
|
521
|
+
resp = yield get_resp_of_fs_files(fid)
|
522
|
+
if fid != int(resp["path"][-1]["cid"]):
|
523
|
+
resp["attr"] = attr
|
524
|
+
raise FileNotFoundError(ENOENT, resp)
|
525
|
+
for info in resp["path"][1:]:
|
526
|
+
add_ancestor({
|
527
|
+
"parent_id": pid,
|
528
|
+
"id": (pid := int(info["cid"])),
|
529
|
+
"name": info["name"],
|
530
|
+
})
|
531
|
+
if id_to_dirnode is not ...:
|
532
|
+
for ans in ancestors[1:]:
|
533
|
+
id_to_dirnode[ans["id"]] = DirNode(ans["name"], ans["parent_id"])
|
534
|
+
is_completed = True
|
535
|
+
else:
|
536
|
+
resp = yield get_resp_of_category_get(fid)
|
537
|
+
if not resp:
|
538
|
+
raise FileNotFoundError(ENOENT, attr)
|
539
|
+
if "paths" not in resp:
|
540
|
+
check_response(resp)
|
541
|
+
resp = resp["data"]
|
542
|
+
if not resp:
|
543
|
+
raise FileNotFoundError(ENOENT, attr)
|
544
|
+
for info in resp["paths"]:
|
545
|
+
add_ancestor({
|
546
|
+
"parent_id": pid,
|
547
|
+
"id": (pid := int(info["file_id"])),
|
548
|
+
"name": info["file_name"],
|
549
|
+
})
|
550
|
+
if id_to_dirnode is not ...:
|
551
|
+
for ans in ancestors[1:]:
|
552
|
+
id_to_dirnode[ans["id"]] = DirNode(ans["name"], ans["parent_id"])
|
553
|
+
ans = {"id": fid, "parent_id": pid, "name": resp["file_name"]}
|
554
|
+
add_ancestor(ans)
|
555
|
+
if not resp.get("sha1") and id_to_dirnode is not ...:
|
556
|
+
id_to_dirnode[ans["id"]] = DirNode(ans["name"], ans["parent_id"])
|
557
|
+
is_completed = True
|
500
558
|
else:
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
506
|
-
|
507
|
-
|
508
|
-
|
509
|
-
|
559
|
+
fid = attr
|
560
|
+
if not is_completed:
|
561
|
+
if not fid:
|
562
|
+
return ancestors
|
563
|
+
resp = yield get_resp_of_fs_files(fid)
|
564
|
+
check_response(resp)
|
565
|
+
if fid == int(resp["path"][-1]["cid"]):
|
566
|
+
for info in resp["path"][1:]:
|
567
|
+
add_ancestor({
|
568
|
+
"parent_id": pid,
|
569
|
+
"id": (pid := int(info["cid"])),
|
570
|
+
"name": info["name"],
|
571
|
+
})
|
572
|
+
if id_to_dirnode is not ...:
|
573
|
+
for ans in ancestors[1:]:
|
574
|
+
id_to_dirnode[ans["id"]] = DirNode(ans["name"], ans["parent_id"])
|
575
|
+
else:
|
576
|
+
resp = yield get_resp_of_category_get(fid)
|
577
|
+
if not resp:
|
578
|
+
raise FileNotFoundError(ENOENT, fid)
|
579
|
+
if "paths" not in resp:
|
580
|
+
check_response(resp)
|
581
|
+
resp = resp["data"]
|
582
|
+
if not resp:
|
583
|
+
raise FileNotFoundError(ENOENT, fid)
|
584
|
+
for info in resp["paths"]:
|
585
|
+
add_ancestor({
|
586
|
+
"parent_id": pid,
|
587
|
+
"id": (pid := int(info["file_id"])),
|
588
|
+
"name": info["file_name"],
|
589
|
+
})
|
590
|
+
if id_to_dirnode is not ...:
|
591
|
+
for ans in ancestors[1:]:
|
592
|
+
id_to_dirnode[ans["id"]] = DirNode(ans["name"], ans["parent_id"])
|
593
|
+
ans = {"id": fid, "parent_id": pid, "name": resp["file_name"]}
|
594
|
+
add_ancestor(ans)
|
595
|
+
if not resp.get("sha1") and id_to_dirnode is not ...:
|
596
|
+
id_to_dirnode[ans["id"]] = DirNode(ans["name"], ans["parent_id"])
|
510
597
|
return ancestors
|
511
598
|
return run_gen_step(gen_step, async_=async_)
|
512
599
|
|
@@ -516,7 +603,7 @@ def get_ancestors_to_cid(
|
|
516
603
|
client: str | P115Client,
|
517
604
|
cid: int = 0,
|
518
605
|
refresh: bool = False,
|
519
|
-
id_to_dirnode: None
|
606
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
520
607
|
app: str = "web",
|
521
608
|
*,
|
522
609
|
async_: Literal[False] = False,
|
@@ -528,7 +615,7 @@ def get_ancestors_to_cid(
|
|
528
615
|
client: str | P115Client,
|
529
616
|
cid: int = 0,
|
530
617
|
refresh: bool = False,
|
531
|
-
id_to_dirnode: None
|
618
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
532
619
|
app: str = "web",
|
533
620
|
*,
|
534
621
|
async_: Literal[True],
|
@@ -539,7 +626,7 @@ def get_ancestors_to_cid(
|
|
539
626
|
client: str | P115Client,
|
540
627
|
cid: int = 0,
|
541
628
|
refresh: bool = False,
|
542
|
-
id_to_dirnode: None
|
629
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
543
630
|
app: str = "web",
|
544
631
|
*,
|
545
632
|
async_: Literal[False, True] = False,
|
@@ -569,14 +656,31 @@ def get_ancestors_to_cid(
|
|
569
656
|
client = P115Client(client, check_for_relogin=True)
|
570
657
|
if id_to_dirnode is None:
|
571
658
|
id_to_dirnode = ID_TO_DIRNODE_CACHE[client.user_id]
|
659
|
+
elif id_to_dirnode is ...:
|
660
|
+
id_to_dirnode = {}
|
572
661
|
def gen_step():
|
573
662
|
nonlocal cid
|
574
663
|
parts: list[dict] = []
|
575
664
|
if cid and (refresh or cid not in id_to_dirnode):
|
576
|
-
if
|
577
|
-
resp = yield client.
|
665
|
+
if not isinstance(client, P115Client) or app == "open":
|
666
|
+
resp = yield client.fs_files_open(
|
667
|
+
{"cid": cid, "cur": 1, "nf": 1, "hide_data": 1},
|
668
|
+
async_=async_,
|
669
|
+
**request_kwargs,
|
670
|
+
)
|
671
|
+
elif app in ("", "web", "desktop", "harmony"):
|
672
|
+
resp = yield client.fs_files_aps(
|
673
|
+
{"cid": cid, "limit": 1, "nf": 1, "star": 1},
|
674
|
+
async_=async_,
|
675
|
+
**request_kwargs,
|
676
|
+
)
|
578
677
|
else:
|
579
|
-
resp = yield client.fs_files_app(
|
678
|
+
resp = yield client.fs_files_app(
|
679
|
+
{"cid": cid, "cur": 1, "nf": 1, "hide_data": 1},
|
680
|
+
app=app,
|
681
|
+
async_=async_,
|
682
|
+
**request_kwargs,
|
683
|
+
)
|
580
684
|
check_response(resp)
|
581
685
|
if cid and int(resp["path"][-1]["cid"]) != cid:
|
582
686
|
raise FileNotFoundError(ENOENT, cid)
|
@@ -605,7 +709,7 @@ def get_id_to_path(
|
|
605
709
|
ensure_file: None | bool = None,
|
606
710
|
is_posixpath: bool = False,
|
607
711
|
refresh: bool = False,
|
608
|
-
id_to_dirnode: None | dict[int, tuple[str, int] | DirNode] = None,
|
712
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
609
713
|
app: str = "web",
|
610
714
|
dont_use_getid: bool = False,
|
611
715
|
*,
|
@@ -621,7 +725,7 @@ def get_id_to_path(
|
|
621
725
|
ensure_file: None | bool = None,
|
622
726
|
is_posixpath: bool = False,
|
623
727
|
refresh: bool = False,
|
624
|
-
id_to_dirnode: None | dict[int, tuple[str, int] | DirNode] = None,
|
728
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
625
729
|
app: str = "web",
|
626
730
|
dont_use_getid: bool = False,
|
627
731
|
*,
|
@@ -636,7 +740,7 @@ def get_id_to_path(
|
|
636
740
|
ensure_file: None | bool = None,
|
637
741
|
is_posixpath: bool = False,
|
638
742
|
refresh: bool = False,
|
639
|
-
id_to_dirnode: None | dict[int, tuple[str, int] | DirNode] = None,
|
743
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
640
744
|
app: str = "web",
|
641
745
|
dont_use_getid: bool = False,
|
642
746
|
*,
|
@@ -1,18 +1,18 @@
|
|
1
1
|
LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
|
2
2
|
p115client/__init__.py,sha256=1mx7njuAlqcuEWONTjSiiGnXyyNyqOcJyNX1FMHqQ-4,214
|
3
3
|
p115client/_upload.py,sha256=DOckFLU_P7Fl0BNu_0-2od6pPsCnzroYY6zZE5_EMnM,30735
|
4
|
-
p115client/client.py,sha256=
|
4
|
+
p115client/client.py,sha256=rNLeQTbQp861Vs6L-OfEXh6ykM-NvfycwaCZJiOx91E,727374
|
5
5
|
p115client/const.py,sha256=AMyL3QZ172f_RaEkfh27DQxwbkXvPhqfeBWHWTrvSLY,7754
|
6
6
|
p115client/exception.py,sha256=kQMI7lwkFIC_tRuj1HT8zqi5HGzz6fTxgK7B1aKrNTI,3447
|
7
7
|
p115client/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
8
|
p115client/tool/__init__.py,sha256=NjT9rroMhLwKI7UlpSCksSsnB3GexXzxvhfunNWzjY0,386
|
9
|
-
p115client/tool/attr.py,sha256=
|
9
|
+
p115client/tool/attr.py,sha256=9xN99lgFxE-48nqiIOSuuo3R0D9lcvuJvcRbJzPKKiw,2883
|
10
10
|
p115client/tool/download.py,sha256=3zoxkLPf4Jya-wYowZJmZR65sR3GWNWNmnevKrrgvQY,60509
|
11
11
|
p115client/tool/edit.py,sha256=eRlR1UZMpfGnoetpqSAAx5bPBOEiSlx7HPkpOSs5agk,17739
|
12
12
|
p115client/tool/export_dir.py,sha256=iMnKtnESi8HKvW9WhIvOdEoMXSBpAnhFlGeyKXHpQbE,24545
|
13
13
|
p115client/tool/fs_files.py,sha256=jY57L4nhB9t-2kT_1j3mdiwOdPZKsimN3eN5mUJAqMI,15745
|
14
14
|
p115client/tool/history.py,sha256=2S26BH7uBNfVHlbYFNy-aNOLMcM-HrlR7TLHAZacUJI,7458
|
15
|
-
p115client/tool/iterdir.py,sha256=
|
15
|
+
p115client/tool/iterdir.py,sha256=bg59xHMxSuPEAqlmEhF6IBvbSW8piKbfrb6QYtAixa0,197797
|
16
16
|
p115client/tool/life.py,sha256=X6Bp0GYKwnZeWlttE2DIVw5iOCXM5QzIkM6Zuj24c5Y,17323
|
17
17
|
p115client/tool/pool.py,sha256=K-ALC-JEwik3DYCr5Eckok15oQnHRe6yznKIuJ9jyyM,13953
|
18
18
|
p115client/tool/request.py,sha256=rjXuQwRganE5Z-4rfgnyPFjE4jzdQSLdIs9s0cIDshU,7043
|
@@ -20,7 +20,7 @@ p115client/tool/upload.py,sha256=qK1OQYxP-Faq2eMDhc5sBXJiSr8m8EZ_gb0O_iA2TrI,159
|
|
20
20
|
p115client/tool/util.py,sha256=0o9TrXdoPcljgxDDRdxRon41bq1OjuUYCWsR0XLfmPo,3357
|
21
21
|
p115client/tool/xys.py,sha256=WMTisCyN4eYyv4A14yYOpjud2mBhQvBcUHOp6pJUQeA,10140
|
22
22
|
p115client/type.py,sha256=7kOp98uLaYqcTTCgCrb3DRcl8ukMpn7ibsnVvtw2nG8,6250
|
23
|
-
p115client-0.0.5.10.
|
24
|
-
p115client-0.0.5.10.
|
25
|
-
p115client-0.0.5.10.
|
26
|
-
p115client-0.0.5.10.
|
23
|
+
p115client-0.0.5.10.6.dist-info/LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
|
24
|
+
p115client-0.0.5.10.6.dist-info/METADATA,sha256=Uahbt1F8XXlWu3VG5PvJps8OsInLt78coGPwhSI1RgI,8276
|
25
|
+
p115client-0.0.5.10.6.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
26
|
+
p115client-0.0.5.10.6.dist-info/RECORD,,
|
File without changes
|
File without changes
|