p115client 0.0.5.8.5__py3-none-any.whl → 0.0.5.8.7__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 +34 -14
- p115client/tool/download.py +28 -25
- p115client/tool/iterdir.py +101 -6
- {p115client-0.0.5.8.5.dist-info → p115client-0.0.5.8.7.dist-info}/METADATA +1 -1
- {p115client-0.0.5.8.5.dist-info → p115client-0.0.5.8.7.dist-info}/RECORD +7 -7
- {p115client-0.0.5.8.5.dist-info → p115client-0.0.5.8.7.dist-info}/LICENSE +0 -0
- {p115client-0.0.5.8.5.dist-info → p115client-0.0.5.8.7.dist-info}/WHEEL +0 -0
p115client/client.py
CHANGED
@@ -1022,6 +1022,12 @@ class ClientRequestMixin:
|
|
1022
1022
|
for cookie in cookies:
|
1023
1023
|
set_cookie(create_cookie("", cookie))
|
1024
1024
|
|
1025
|
+
@cookies.deleter
|
1026
|
+
def cookies(self, /):
|
1027
|
+
"""请求所用的 Cookies 对象(同步和异步共用)
|
1028
|
+
"""
|
1029
|
+
self.cookies = None
|
1030
|
+
|
1025
1031
|
@property
|
1026
1032
|
def cookiejar(self, /) -> CookieJar:
|
1027
1033
|
"""请求所用的 CookieJar 对象(同步和异步共用)
|
@@ -1765,7 +1771,7 @@ class ClientRequestMixin:
|
|
1765
1771
|
def login_with_open(
|
1766
1772
|
cls,
|
1767
1773
|
/,
|
1768
|
-
app_id: int | str,
|
1774
|
+
app_id: int | str = 100195993,
|
1769
1775
|
console_qrcode: bool = True,
|
1770
1776
|
*,
|
1771
1777
|
async_: Literal[False] = False,
|
@@ -1777,7 +1783,7 @@ class ClientRequestMixin:
|
|
1777
1783
|
def login_with_open(
|
1778
1784
|
cls,
|
1779
1785
|
/,
|
1780
|
-
app_id: int | str,
|
1786
|
+
app_id: int | str = 100195993,
|
1781
1787
|
console_qrcode: bool = True,
|
1782
1788
|
*,
|
1783
1789
|
async_: Literal[True],
|
@@ -1788,7 +1794,7 @@ class ClientRequestMixin:
|
|
1788
1794
|
def login_with_open(
|
1789
1795
|
cls,
|
1790
1796
|
/,
|
1791
|
-
app_id: int | str,
|
1797
|
+
app_id: int | str = 100195993,
|
1792
1798
|
console_qrcode: bool = True,
|
1793
1799
|
*,
|
1794
1800
|
async_: Literal[False, True] = False,
|
@@ -2458,7 +2464,7 @@ class P115OpenClient(ClientRequestMixin):
|
|
2458
2464
|
|
2459
2465
|
@access_token.setter
|
2460
2466
|
def access_token(self, token, /):
|
2461
|
-
self.headers["
|
2467
|
+
self.headers["authorization"] = "Bearer " + token
|
2462
2468
|
self.__dict__["access_token"] = token
|
2463
2469
|
|
2464
2470
|
@property
|
@@ -2470,6 +2476,11 @@ class P115OpenClient(ClientRequestMixin):
|
|
2470
2476
|
token = self.__dict__["upload_token"] = resp["data"]
|
2471
2477
|
return token
|
2472
2478
|
|
2479
|
+
@locked_cacheproperty
|
2480
|
+
def user_id(self, /) -> int:
|
2481
|
+
resp = check_response(self.user_info_open())
|
2482
|
+
return int(resp["data"]["user_id"])
|
2483
|
+
|
2473
2484
|
@overload
|
2474
2485
|
def refresh_access_token(
|
2475
2486
|
self,
|
@@ -4220,11 +4231,20 @@ class P115Client(P115OpenClient):
|
|
4220
4231
|
if not cookies_equal(cookies_old, cookies_new):
|
4221
4232
|
self._write_cookies(cookies_new)
|
4222
4233
|
|
4234
|
+
@cookies.deleter
|
4235
|
+
def cookies(self, /):
|
4236
|
+
"""请求所用的 Cookies 对象(同步和异步共用)
|
4237
|
+
"""
|
4238
|
+
self.cookies = None
|
4239
|
+
|
4223
4240
|
@locked_cacheproperty
|
4224
4241
|
def user_id(self, /) -> int:
|
4225
4242
|
cookie_uid = self.cookies.get("UID")
|
4226
4243
|
if cookie_uid:
|
4227
4244
|
return int(cookie_uid.split("_")[0])
|
4245
|
+
elif "authorization" in self.headers:
|
4246
|
+
resp = check_response(self.user_info_open())
|
4247
|
+
return int(resp["data"]["user_id"])
|
4228
4248
|
else:
|
4229
4249
|
return 0
|
4230
4250
|
|
@@ -4914,9 +4934,9 @@ class P115Client(P115OpenClient):
|
|
4914
4934
|
def login_another_open(
|
4915
4935
|
self,
|
4916
4936
|
/,
|
4917
|
-
app_id: int | str,
|
4918
|
-
replace: Literal[True] | Self,
|
4937
|
+
app_id: int | str = 100195993,
|
4919
4938
|
*,
|
4939
|
+
replace: Literal[True] | Self,
|
4920
4940
|
async_: Literal[False] = False,
|
4921
4941
|
**request_kwargs,
|
4922
4942
|
) -> Self:
|
@@ -4925,9 +4945,9 @@ class P115Client(P115OpenClient):
|
|
4925
4945
|
def login_another_open(
|
4926
4946
|
self,
|
4927
4947
|
/,
|
4928
|
-
app_id: int | str,
|
4929
|
-
replace: Literal[True] | Self,
|
4948
|
+
app_id: int | str = 100195993,
|
4930
4949
|
*,
|
4950
|
+
replace: Literal[True] | Self,
|
4931
4951
|
async_: Literal[True],
|
4932
4952
|
**request_kwargs,
|
4933
4953
|
) -> Coroutine[Any, Any, Self]:
|
@@ -4936,9 +4956,9 @@ class P115Client(P115OpenClient):
|
|
4936
4956
|
def login_another_open(
|
4937
4957
|
self,
|
4938
4958
|
/,
|
4939
|
-
app_id: int | str,
|
4940
|
-
replace: Literal[False] = False,
|
4959
|
+
app_id: int | str = 100195993,
|
4941
4960
|
*,
|
4961
|
+
replace: Literal[False] = False,
|
4942
4962
|
async_: Literal[False] = False,
|
4943
4963
|
**request_kwargs,
|
4944
4964
|
) -> P115OpenClient:
|
@@ -4947,9 +4967,9 @@ class P115Client(P115OpenClient):
|
|
4947
4967
|
def login_another_open(
|
4948
4968
|
self,
|
4949
4969
|
/,
|
4950
|
-
app_id: int | str,
|
4951
|
-
replace: Literal[False] = False,
|
4970
|
+
app_id: int | str = 100195993,
|
4952
4971
|
*,
|
4972
|
+
replace: Literal[False] = False,
|
4953
4973
|
async_: Literal[True],
|
4954
4974
|
**request_kwargs,
|
4955
4975
|
) -> Coroutine[Any, Any, P115OpenClient]:
|
@@ -4957,9 +4977,9 @@ class P115Client(P115OpenClient):
|
|
4957
4977
|
def login_another_open(
|
4958
4978
|
self,
|
4959
4979
|
/,
|
4960
|
-
app_id: int | str,
|
4961
|
-
replace: bool | Self = False,
|
4980
|
+
app_id: int | str = 100195993,
|
4962
4981
|
*,
|
4982
|
+
replace: bool | Self = False,
|
4963
4983
|
async_: Literal[False, True] = False,
|
4964
4984
|
**request_kwargs,
|
4965
4985
|
) -> P115OpenClient | Coroutine[Any, Any, P115OpenClient] | Self | Coroutine[Any, Any, Self]:
|
p115client/tool/download.py
CHANGED
@@ -25,6 +25,7 @@ from shutil import rmtree
|
|
25
25
|
from threading import Lock
|
26
26
|
from time import time
|
27
27
|
from typing import cast, overload, Any, Final, Literal, TypedDict
|
28
|
+
from types import EllipsisType
|
28
29
|
from urllib.parse import quote, urlsplit
|
29
30
|
from urllib.request import urlopen, Request
|
30
31
|
from uuid import uuid4
|
@@ -257,7 +258,7 @@ def iter_files_with_url(
|
|
257
258
|
use_star: None | bool = False,
|
258
259
|
escape: None | bool | Callable[[str], str] = True,
|
259
260
|
normalize_attr: Callable[[dict], dict] = normalize_attr,
|
260
|
-
id_to_dirnode: None | dict[int, tuple[str, int] | DirNode] = None,
|
261
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
261
262
|
app: str = "web",
|
262
263
|
raise_for_changed_count: bool = False,
|
263
264
|
user_agent: str = "",
|
@@ -278,7 +279,7 @@ def iter_files_with_url(
|
|
278
279
|
use_star: None | bool = False,
|
279
280
|
escape: None | bool | Callable[[str], str] = True,
|
280
281
|
normalize_attr: Callable[[dict], dict] = normalize_attr,
|
281
|
-
id_to_dirnode: None | dict[int, tuple[str, int] | DirNode] = None,
|
282
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
282
283
|
app: str = "web",
|
283
284
|
raise_for_changed_count: bool = False,
|
284
285
|
user_agent: str = "",
|
@@ -298,7 +299,7 @@ def iter_files_with_url(
|
|
298
299
|
use_star: None | bool = False,
|
299
300
|
escape: None | bool | Callable[[str], str] = True,
|
300
301
|
normalize_attr: Callable[[dict], dict] = normalize_attr,
|
301
|
-
id_to_dirnode: None | dict[int, tuple[str, int] | DirNode] = None,
|
302
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
302
303
|
app: str = "web",
|
303
304
|
raise_for_changed_count: bool = False,
|
304
305
|
user_agent: str = "",
|
@@ -423,7 +424,7 @@ def iter_images_with_url(
|
|
423
424
|
use_star: None | bool = False,
|
424
425
|
escape: None | bool | Callable[[str], str] = True,
|
425
426
|
normalize_attr: Callable[[dict], dict] = normalize_attr,
|
426
|
-
id_to_dirnode: None | dict[int, tuple[str, int] | DirNode] = None,
|
427
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
427
428
|
app: str = "web",
|
428
429
|
raise_for_changed_count: bool = False,
|
429
430
|
*,
|
@@ -442,7 +443,7 @@ def iter_images_with_url(
|
|
442
443
|
use_star: None | bool = False,
|
443
444
|
escape: None | bool | Callable[[str], str] = True,
|
444
445
|
normalize_attr: Callable[[dict], dict] = normalize_attr,
|
445
|
-
id_to_dirnode: None | dict[int, tuple[str, int] | DirNode] = None,
|
446
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
446
447
|
app: str = "web",
|
447
448
|
raise_for_changed_count: bool = False,
|
448
449
|
*,
|
@@ -460,7 +461,7 @@ def iter_images_with_url(
|
|
460
461
|
use_star: None | bool = False,
|
461
462
|
escape: None | bool | Callable[[str], str] = True,
|
462
463
|
normalize_attr: Callable[[dict], dict] = normalize_attr,
|
463
|
-
id_to_dirnode: None | dict[int, tuple[str, int] | DirNode] = None,
|
464
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
464
465
|
app: str = "web",
|
465
466
|
raise_for_changed_count: bool = False,
|
466
467
|
*,
|
@@ -578,7 +579,7 @@ def iter_subtitles_with_url(
|
|
578
579
|
use_star: None | bool = False,
|
579
580
|
escape: None | bool | Callable[[str], str] = True,
|
580
581
|
normalize_attr: Callable[[dict], dict] = normalize_attr,
|
581
|
-
id_to_dirnode: None | dict[int, tuple[str, int] | DirNode] = None,
|
582
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
582
583
|
app: str = "web",
|
583
584
|
raise_for_changed_count: bool = False,
|
584
585
|
*,
|
@@ -597,7 +598,7 @@ def iter_subtitles_with_url(
|
|
597
598
|
use_star: None | bool = False,
|
598
599
|
escape: None | bool | Callable[[str], str] = True,
|
599
600
|
normalize_attr: Callable[[dict], dict] = normalize_attr,
|
600
|
-
id_to_dirnode: None | dict[int, tuple[str, int] | DirNode] = None,
|
601
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
601
602
|
app: str = "web",
|
602
603
|
raise_for_changed_count: bool = False,
|
603
604
|
*,
|
@@ -615,7 +616,7 @@ def iter_subtitles_with_url(
|
|
615
616
|
use_star: None | bool = False,
|
616
617
|
escape: None | bool | Callable[[str], str] = True,
|
617
618
|
normalize_attr: Callable[[dict], dict] = normalize_attr,
|
618
|
-
id_to_dirnode: None | dict[int, tuple[str, int] | DirNode] = None,
|
619
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
619
620
|
app: str = "web",
|
620
621
|
raise_for_changed_count: bool = False,
|
621
622
|
*,
|
@@ -855,7 +856,7 @@ def make_strm(
|
|
855
856
|
suffix: str = "",
|
856
857
|
type: Literal[1, 2, 3, 4, 5, 6, 7, 99] = 4,
|
857
858
|
max_workers: None | int = None,
|
858
|
-
id_to_dirnode: None | dict[int, tuple[str, int] | DirNode] = None,
|
859
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
859
860
|
path_already: bool = False,
|
860
861
|
app: str = "android",
|
861
862
|
fs_files_cooldown: int | float = 0.5,
|
@@ -881,7 +882,7 @@ def make_strm(
|
|
881
882
|
suffix: str = "",
|
882
883
|
type: Literal[1, 2, 3, 4, 5, 6, 7, 99] = 4,
|
883
884
|
max_workers: None | int = None,
|
884
|
-
id_to_dirnode: None | dict[int, tuple[str, int] | DirNode] = None,
|
885
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
885
886
|
path_already: bool = False,
|
886
887
|
app: str = "android",
|
887
888
|
fs_files_cooldown: int | float = 0.5,
|
@@ -906,7 +907,7 @@ def make_strm(
|
|
906
907
|
suffix: str = "",
|
907
908
|
type: Literal[1, 2, 3, 4, 5, 6, 7, 99] = 4,
|
908
909
|
max_workers: None | int = None,
|
909
|
-
id_to_dirnode: None | dict[int, tuple[str, int] | DirNode] = None,
|
910
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
910
911
|
path_already: bool = False,
|
911
912
|
app: str = "android",
|
912
913
|
fs_files_cooldown: int | float = 0.5,
|
@@ -1170,40 +1171,36 @@ def iter_download_nodes(
|
|
1170
1171
|
method = client.download_files
|
1171
1172
|
else:
|
1172
1173
|
method = client.download_folders
|
1174
|
+
get_nodes = partial(method, async_=async_, **{"base_url": get_base_url, **request_kwargs})
|
1173
1175
|
if max_workers == 1:
|
1174
1176
|
def gen_step(pickcode):
|
1175
1177
|
if isinstance(pickcode, int):
|
1176
1178
|
resp = yield client.fs_file_skim(pickcode, async_=async_, **request_kwargs)
|
1177
1179
|
check_response(resp)
|
1178
1180
|
pickcode = resp["data"][0]["pick_code"]
|
1179
|
-
request_kwargs.setdefault("base_url", get_base_url)
|
1180
1181
|
for i in count(1):
|
1181
1182
|
payload = {"pickcode": pickcode, "page": i}
|
1182
|
-
resp = yield
|
1183
|
+
resp = yield get_nodes(payload)
|
1183
1184
|
check_response(resp)
|
1184
1185
|
data = resp["data"]
|
1185
1186
|
yield YieldFrom(data["list"], identity=True)
|
1186
1187
|
if not data["has_next_page"]:
|
1187
1188
|
break
|
1188
1189
|
else:
|
1190
|
+
max_page = 0
|
1189
1191
|
get_next_page = count(1).__next__
|
1190
1192
|
if async_:
|
1191
1193
|
q: Any = AsyncQueue()
|
1192
1194
|
else:
|
1193
1195
|
q = SimpleQueue()
|
1194
1196
|
get, put = q.get, q.put_nowait
|
1195
|
-
max_page = 0
|
1196
1197
|
def request(pickcode):
|
1197
1198
|
nonlocal max_page
|
1198
1199
|
while True:
|
1199
1200
|
page = get_next_page()
|
1200
1201
|
if max_page and page > max_page:
|
1201
1202
|
return
|
1202
|
-
resp: dict = yield
|
1203
|
-
{"pickcode": pickcode, "page": page},
|
1204
|
-
async_=async_, # type: ignore
|
1205
|
-
**request_kwargs,
|
1206
|
-
)
|
1203
|
+
resp: dict = yield get_nodes({"pickcode": pickcode, "page": page})
|
1207
1204
|
try:
|
1208
1205
|
check_response(resp)
|
1209
1206
|
except BaseException as e:
|
@@ -1214,7 +1211,9 @@ def iter_download_nodes(
|
|
1214
1211
|
if not data["has_next_page"]:
|
1215
1212
|
max_page = page
|
1216
1213
|
def gen_step(pickcode):
|
1217
|
-
nonlocal max_workers
|
1214
|
+
nonlocal max_workers, max_page, get_next_page
|
1215
|
+
max_page = 0
|
1216
|
+
get_next_page = count(1).__next__
|
1218
1217
|
if async_:
|
1219
1218
|
if max_workers is None or max_workers <= 0:
|
1220
1219
|
max_workers = 20
|
@@ -1239,7 +1238,6 @@ def iter_download_nodes(
|
|
1239
1238
|
)
|
1240
1239
|
check_response(resp)
|
1241
1240
|
pickcode = resp["data"][0]["pick_code"]
|
1242
|
-
request_kwargs.setdefault("base_url", cycle(("http://proapi.115.com", "https://proapi.115.com")).__next__)
|
1243
1241
|
try:
|
1244
1242
|
sentinel = object()
|
1245
1243
|
countdown: Callable
|
@@ -1282,6 +1280,11 @@ def iter_download_nodes(
|
|
1282
1280
|
)) as get_next:
|
1283
1281
|
while True:
|
1284
1282
|
attr = yield get_next
|
1283
|
+
if not files:
|
1284
|
+
yield Yield(
|
1285
|
+
{"fid": str(attr["id"]), "pid": "0", "fn": attr["name"]},
|
1286
|
+
identity=True,
|
1287
|
+
)
|
1285
1288
|
yield YieldFrom(
|
1286
1289
|
run_gen_step_iter(gen_step(attr["pickcode"]), async_=async_),
|
1287
1290
|
identity=True,
|
@@ -1293,7 +1296,7 @@ def iter_download_nodes(
|
|
1293
1296
|
def iter_download_files(
|
1294
1297
|
client: str | P115Client,
|
1295
1298
|
cid: int = 0,
|
1296
|
-
id_to_dirnode: None | dict[int, tuple[str, int] | DirNode] = None,
|
1299
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
1297
1300
|
escape: None | bool | Callable[[str], str] = True,
|
1298
1301
|
with_ancestors: bool = True,
|
1299
1302
|
max_workers: None | int = None,
|
@@ -1307,7 +1310,7 @@ def iter_download_files(
|
|
1307
1310
|
def iter_download_files(
|
1308
1311
|
client: str | P115Client,
|
1309
1312
|
cid: int = 0,
|
1310
|
-
id_to_dirnode: None | dict[int, tuple[str, int] | DirNode] = None,
|
1313
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
1311
1314
|
escape: None | bool | Callable[[str], str] = True,
|
1312
1315
|
with_ancestors: bool = True,
|
1313
1316
|
max_workers: None | int = None,
|
@@ -1320,7 +1323,7 @@ def iter_download_files(
|
|
1320
1323
|
def iter_download_files(
|
1321
1324
|
client: str | P115Client,
|
1322
1325
|
cid: int = 0,
|
1323
|
-
id_to_dirnode: None | dict[int, tuple[str, int] | DirNode] = None,
|
1326
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
1324
1327
|
escape: None | bool | Callable[[str], str] = True,
|
1325
1328
|
with_ancestors: bool = True,
|
1326
1329
|
max_workers: None | int = None,
|
p115client/tool/iterdir.py
CHANGED
@@ -8,9 +8,9 @@ __all__ = [
|
|
8
8
|
"get_ancestors_to_cid", "get_id_to_path", "get_id_to_sha1", "get_id_to_pickcode",
|
9
9
|
"iter_nodes_skim", "iter_stared_dirs_raw", "iter_stared_dirs", "ensure_attr_path",
|
10
10
|
"ensure_attr_path_by_category_get", "iterdir_raw", "iterdir", "iterdir_limited",
|
11
|
-
"iter_files_raw", "iter_files", "traverse_files", "
|
12
|
-
"
|
13
|
-
"iter_selected_nodes_by_pickcode", "iter_selected_nodes_using_category_get",
|
11
|
+
"iter_files_raw", "iter_files", "traverse_files", "iter_dirs", "iter_dupfiles",
|
12
|
+
"iter_image_files", "share_extract_payload", "share_iterdir", "share_iter_files",
|
13
|
+
"iter_selected_nodes", "iter_selected_nodes_by_pickcode", "iter_selected_nodes_using_category_get",
|
14
14
|
"iter_selected_nodes_using_edit", "iter_selected_nodes_using_star_event",
|
15
15
|
"iter_selected_dirs_using_star", "iter_files_with_dirname", "iter_files_with_path",
|
16
16
|
"iter_files_with_path_by_export_dir", "iter_parents_3_level", "iter_dir_nodes",
|
@@ -41,9 +41,9 @@ from weakref import WeakValueDictionary
|
|
41
41
|
from asynctools import async_chain, async_filter, async_map, to_list
|
42
42
|
from concurrenttools import run_as_thread, taskgroup_map, threadpool_map
|
43
43
|
from iterutils import (
|
44
|
-
bfs_gen, chunked, async_foreach, ensure_aiter, foreach,
|
45
|
-
iter_unique, run_gen_step, run_gen_step_iter, through,
|
46
|
-
with_iter_next, Yield, YieldFrom,
|
44
|
+
as_gen_step, bfs_gen, chunked, async_foreach, ensure_aiter, foreach,
|
45
|
+
flatten, iter_unique, run_gen_step, run_gen_step_iter, through,
|
46
|
+
async_through, with_iter_next, Yield, YieldFrom,
|
47
47
|
)
|
48
48
|
from iter_collect import iter_keyed_dups, SupportsLT
|
49
49
|
from orjson import loads
|
@@ -2789,6 +2789,101 @@ def traverse_files(
|
|
2789
2789
|
return run_gen_step_iter(gen_step, async_=async_)
|
2790
2790
|
|
2791
2791
|
|
2792
|
+
@overload
|
2793
|
+
def iter_dirs(
|
2794
|
+
client: str | P115Client,
|
2795
|
+
cid: int | str = 0,
|
2796
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
2797
|
+
with_pickcode: bool = False,
|
2798
|
+
max_workers: None | int = None,
|
2799
|
+
*,
|
2800
|
+
async_: Literal[False] = False,
|
2801
|
+
**request_kwargs,
|
2802
|
+
) -> Iterator[dict]:
|
2803
|
+
...
|
2804
|
+
@overload
|
2805
|
+
def iter_dirs(
|
2806
|
+
client: str | P115Client,
|
2807
|
+
cid: int | str = 0,
|
2808
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
2809
|
+
with_pickcode: bool = False,
|
2810
|
+
max_workers: None | int = None,
|
2811
|
+
*,
|
2812
|
+
async_: Literal[True],
|
2813
|
+
**request_kwargs,
|
2814
|
+
) -> AsyncIterator[dict]:
|
2815
|
+
...
|
2816
|
+
def iter_dirs(
|
2817
|
+
client: str | P115Client,
|
2818
|
+
cid: int | str = 0,
|
2819
|
+
id_to_dirnode: None | EllipsisType | dict[int, tuple[str, int] | DirNode] = None,
|
2820
|
+
with_pickcode: bool = False,
|
2821
|
+
max_workers: None | int = None,
|
2822
|
+
*,
|
2823
|
+
async_: Literal[False, True] = False,
|
2824
|
+
**request_kwargs,
|
2825
|
+
) -> Iterator[dict] | AsyncIterator[dict]:
|
2826
|
+
"""遍历目录树,获取目录信息
|
2827
|
+
|
2828
|
+
:param client: 115 客户端或 cookies
|
2829
|
+
:param cid: 目录 id(如果是 int) 或者 pickcode(如果是 str)
|
2830
|
+
:param id_to_dirnode: 字典,保存 id 到对应文件的 `DirNode(name, parent_id)` 命名元组的字典
|
2831
|
+
:param with_pickcode: 是否需要包含提取码
|
2832
|
+
:param max_workers: 最大并发数
|
2833
|
+
:param async_: 是否异步
|
2834
|
+
:param request_kwargs: 其它请求参数
|
2835
|
+
|
2836
|
+
:return: 迭代器,返回此目录内的(仅目录)文件信息
|
2837
|
+
"""
|
2838
|
+
from .download import iter_download_nodes
|
2839
|
+
if isinstance(client, str):
|
2840
|
+
client = P115Client(client, check_for_relogin=True)
|
2841
|
+
if id_to_dirnode is None:
|
2842
|
+
id_to_dirnode = ID_TO_DIRNODE_CACHE[client.user_id]
|
2843
|
+
it = iter_download_nodes(
|
2844
|
+
client,
|
2845
|
+
cid,
|
2846
|
+
files=False,
|
2847
|
+
max_workers=max_workers,
|
2848
|
+
async_=async_, # type: ignore
|
2849
|
+
**request_kwargs,
|
2850
|
+
)
|
2851
|
+
do_map: Callable = async_map if async_ else map
|
2852
|
+
def project(info: dict, /) -> dict:
|
2853
|
+
attr = {"id": int(info["fid"]), "parent_id": int(info["pid"]), "name": info["fn"]}
|
2854
|
+
if id_to_dirnode is not ...:
|
2855
|
+
id_to_dirnode[attr["id"]] = DirNode(attr["name"], attr["parent_id"])
|
2856
|
+
return attr
|
2857
|
+
it = do_map(project, it)
|
2858
|
+
if with_pickcode:
|
2859
|
+
file_skim = client.fs_file_skim
|
2860
|
+
@as_gen_step(async_=async_)
|
2861
|
+
def batch_load_pickcode(batch: Sequence[dict], /):
|
2862
|
+
resp = yield file_skim(
|
2863
|
+
(a["id"] for a in batch),
|
2864
|
+
method="POST",
|
2865
|
+
async_=async_,
|
2866
|
+
**request_kwargs,
|
2867
|
+
)
|
2868
|
+
check_response(resp)
|
2869
|
+
maps = {int(a["file_id"]): a["pick_code"] for a in resp["data"]}
|
2870
|
+
for attr in batch:
|
2871
|
+
attr["pickcode"] = maps[attr["id"]]
|
2872
|
+
return batch
|
2873
|
+
def gen_step(iterable):
|
2874
|
+
batch_map = taskgroup_map if async_ else threadpool_map
|
2875
|
+
with with_iter_next(batch_map(
|
2876
|
+
batch_load_pickcode,
|
2877
|
+
chunked(iterable, 3000),
|
2878
|
+
max_workers=max_workers,
|
2879
|
+
)) as get_next:
|
2880
|
+
while True:
|
2881
|
+
batch = yield get_next
|
2882
|
+
yield YieldFrom(batch, identity=True)
|
2883
|
+
it = run_gen_step_iter(gen_step(it), async_=async_)
|
2884
|
+
return it
|
2885
|
+
|
2886
|
+
|
2792
2887
|
@overload
|
2793
2888
|
def iter_dupfiles[K](
|
2794
2889
|
client: str | P115Client,
|
@@ -1,23 +1,23 @@
|
|
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=GhLFoGzmZunVqMajS6xZZqs5k-I_2sR9LQlP102MFjE,718070
|
5
5
|
p115client/const.py,sha256=maIZfJAiUuEnXIKc8TMAyW_UboDUJPwYpPS8LjPFp_U,4321
|
6
6
|
p115client/exception.py,sha256=Ugjr__aSlYRDYwoOz7273ngV-gFX2z-ohsJmCba8nnQ,2657
|
7
7
|
p115client/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
8
8
|
p115client/tool/__init__.py,sha256=2YrKoAcFYOuqu2nUBoPVhxMOseAvcLE_LcnbZV11UKw,324
|
9
|
-
p115client/tool/download.py,sha256=
|
9
|
+
p115client/tool/download.py,sha256=DneVsbryn4d47RkS62ghF5Xz8vkDq6U0n2hj1W5g4iY,61176
|
10
10
|
p115client/tool/edit.py,sha256=3hQ5J3hHQx4yNsGcWSechBYAvZRSQUxfXLXuqXiDKmk,17789
|
11
11
|
p115client/tool/export_dir.py,sha256=iMnKtnESi8HKvW9WhIvOdEoMXSBpAnhFlGeyKXHpQbE,24545
|
12
12
|
p115client/tool/fs_files.py,sha256=hkezLKrtTAGPDkPxwq6jMrm8s2-unHZQBR7cDvh41qs,16027
|
13
|
-
p115client/tool/iterdir.py,sha256=
|
13
|
+
p115client/tool/iterdir.py,sha256=T6bsD8A896nHgVxKYu2dkIo-5Az2svL4iLm2uHQWyHg,187517
|
14
14
|
p115client/tool/life.py,sha256=SJ1dAvRYCWTUz1gPrCWv-_G1Rq5yPfxDgY7KT-2UP4A,17528
|
15
15
|
p115client/tool/pool.py,sha256=vM5ItMxELtT7_bvbmdhwWj81rQ0zyaj3uPMny4KDw_E,9757
|
16
16
|
p115client/tool/request.py,sha256=SWsezW9EYZGS3R-TbZxMG-8bN3YWJ0-GzgvKlvRBSCM,7042
|
17
17
|
p115client/tool/upload.py,sha256=qK1OQYxP-Faq2eMDhc5sBXJiSr8m8EZ_gb0O_iA2TrI,15915
|
18
18
|
p115client/tool/xys.py,sha256=n89n9OLBXx6t20L61wJgfrP6V4jW3sHgyaQNBLdUwUQ,3578
|
19
19
|
p115client/type.py,sha256=e4g9URQBE23XN2dGomldj8wC6NlDWBBSVC5Bmd8giBc,5993
|
20
|
-
p115client-0.0.5.8.
|
21
|
-
p115client-0.0.5.8.
|
22
|
-
p115client-0.0.5.8.
|
23
|
-
p115client-0.0.5.8.
|
20
|
+
p115client-0.0.5.8.7.dist-info/LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
|
21
|
+
p115client-0.0.5.8.7.dist-info/METADATA,sha256=v74Y9_1ZIk2j2CvMT-9q4RIUDH1FqsRnYCSbqt2ZifU,8233
|
22
|
+
p115client-0.0.5.8.7.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
23
|
+
p115client-0.0.5.8.7.dist-info/RECORD,,
|
File without changes
|
File without changes
|