p115client 0.0.5.8.7__py3-none-any.whl → 0.0.5.9__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 +10 -6
- p115client/tool/__init__.py +1 -1
- p115client/tool/history.py +224 -0
- p115client/tool/life.py +7 -13
- {p115client-0.0.5.8.7.dist-info → p115client-0.0.5.9.dist-info}/METADATA +1 -1
- {p115client-0.0.5.8.7.dist-info → p115client-0.0.5.9.dist-info}/RECORD +8 -7
- {p115client-0.0.5.8.7.dist-info → p115client-0.0.5.9.dist-info}/LICENSE +0 -0
- {p115client-0.0.5.8.7.dist-info → p115client-0.0.5.9.dist-info}/WHEEL +0 -0
p115client/client.py
CHANGED
@@ -375,8 +375,9 @@ def check_response(resp: dict | Awaitable[dict], /) -> dict | Coroutine[Any, Any
|
|
375
375
|
raise FileNotFoundError(ENOENT, resp)
|
376
376
|
# {"state": false, "errno": 20018, "error": "文件不存在或已删除。"}
|
377
377
|
# {"state": false, "errno": 50015, "error": "文件不存在或已删除。"}
|
378
|
+
# {"state": false, "errno": 90008, "error": "文件(夹)不存在或已经删除。"}
|
378
379
|
# {"state": false, "errno": 430004, "error": "文件(夹)不存在或已删除。"}
|
379
|
-
case 20018 | 50015 | 430004:
|
380
|
+
case 20018 | 50015 | 90008 | 430004:
|
380
381
|
raise FileNotFoundError(ENOENT, resp)
|
381
382
|
# {"state": false, "errno": 20020, "error": "后缀名不正确,请重新输入"}
|
382
383
|
case 20020:
|
@@ -393,9 +394,6 @@ def check_response(resp: dict | Awaitable[dict], /) -> dict | Coroutine[Any, Any
|
|
393
394
|
# {"state": false, "errno": 50003, "error": "很抱歉,该文件提取码不存在。"}
|
394
395
|
case 50003:
|
395
396
|
raise FileNotFoundError(ENOENT, resp)
|
396
|
-
# {"state": false, "errno": 90008, "error": "文件(夹)不存在或已经删除。"}
|
397
|
-
case 90008:
|
398
|
-
raise FileNotFoundError(ENOENT, resp)
|
399
397
|
# {"state": false, "errno": 91002, "error": "不能将文件复制到自身或其子目录下。"}
|
400
398
|
case 91002:
|
401
399
|
raise NotSupportedError(ENOTSUP, resp)
|
@@ -462,6 +460,12 @@ def check_response(resp: dict | Awaitable[dict], /) -> dict | Coroutine[Any, Any
|
|
462
460
|
raise IsADirectoryError(EISDIR, resp)
|
463
461
|
case 70005 | 70008:
|
464
462
|
raise FileNotFoundError(ENOENT, resp)
|
463
|
+
elif "error" in resp:
|
464
|
+
match resp["error"]:
|
465
|
+
case "目录不存在或已转移":
|
466
|
+
raise FileNotFoundError(ENOENT, resp)
|
467
|
+
case "更新的数据为空":
|
468
|
+
raise OperationalError(EINVAL, resp)
|
465
469
|
raise P115OSError(EIO, resp)
|
466
470
|
if isinstance(resp, dict):
|
467
471
|
return check(resp)
|
@@ -14179,7 +14183,7 @@ class P115Client(P115OpenClient):
|
|
14179
14183
|
- type: str = "" 💡 操作类型,若不指定则是全部
|
14180
14184
|
|
14181
14185
|
- "upload_image_file": 1 💡 上传图片
|
14182
|
-
- "upload_file": 2 💡
|
14186
|
+
- "upload_file": 2 💡 上传文件或目录(不包括图片)
|
14183
14187
|
- "star_image": 3 💡 给图片设置星标
|
14184
14188
|
- "star_file": 4 💡 给文件或目录设置星标(不包括图片)
|
14185
14189
|
- "move_image_file": 5 💡 移动图片
|
@@ -14250,7 +14254,7 @@ class P115Client(P115OpenClient):
|
|
14250
14254
|
- type: str = "" 💡 操作类型
|
14251
14255
|
|
14252
14256
|
- "upload_image_file": 1 💡 上传图片
|
14253
|
-
- "upload_file": 2 💡
|
14257
|
+
- "upload_file": 2 💡 上传文件或目录(不包括图片)
|
14254
14258
|
- "star_image": 3 💡 给图片设置星标
|
14255
14259
|
- "star_file": 4 💡 给文件或目录设置星标(不包括图片)
|
14256
14260
|
- "move_image_file": 5 💡 移动图片
|
p115client/tool/__init__.py
CHANGED
@@ -7,10 +7,10 @@ from .download import *
|
|
7
7
|
from .edit import *
|
8
8
|
from .export_dir import *
|
9
9
|
from .fs_files import *
|
10
|
+
from .history import *
|
10
11
|
from .iterdir import *
|
11
12
|
from .life import *
|
12
13
|
from .pool import *
|
13
14
|
from .request import *
|
14
15
|
from .upload import *
|
15
16
|
from .xys import *
|
16
|
-
|
@@ -0,0 +1,224 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
__author__ = "ChenyangGao <https://chenyanggao.github.io>"
|
5
|
+
__all__ = ["iter_history_list_once", "iter_history_list"]
|
6
|
+
__doc__ = "这个模块提供了一些和 115 的历史记录有关的函数"
|
7
|
+
|
8
|
+
from asyncio import sleep as async_sleep
|
9
|
+
from collections.abc import AsyncIterator, Iterator
|
10
|
+
from functools import partial
|
11
|
+
from itertools import cycle
|
12
|
+
from time import time, sleep
|
13
|
+
from typing import overload, Literal
|
14
|
+
|
15
|
+
from iterutils import run_gen_step_iter, with_iter_next, Yield
|
16
|
+
from p115client import check_response, P115Client
|
17
|
+
|
18
|
+
|
19
|
+
@overload
|
20
|
+
def iter_history_list_once(
|
21
|
+
client: str | P115Client,
|
22
|
+
from_time: int | float = 0,
|
23
|
+
from_id: int = 0,
|
24
|
+
type: int | str = 0,
|
25
|
+
first_batch_size = 0,
|
26
|
+
app: str = "web",
|
27
|
+
cooldown: int | float = 0,
|
28
|
+
*,
|
29
|
+
async_: Literal[False] = False,
|
30
|
+
**request_kwargs,
|
31
|
+
) -> Iterator[dict]:
|
32
|
+
...
|
33
|
+
@overload
|
34
|
+
def iter_history_list_once(
|
35
|
+
client: str | P115Client,
|
36
|
+
from_time: int | float = 0,
|
37
|
+
from_id: int = 0,
|
38
|
+
type: int | str = 0,
|
39
|
+
first_batch_size = 0,
|
40
|
+
app: str = "web",
|
41
|
+
cooldown: int | float = 0,
|
42
|
+
*,
|
43
|
+
async_: Literal[True],
|
44
|
+
**request_kwargs,
|
45
|
+
) -> AsyncIterator[dict]:
|
46
|
+
...
|
47
|
+
def iter_history_list_once(
|
48
|
+
client: str | P115Client,
|
49
|
+
from_time: int | float = 0,
|
50
|
+
from_id: int = 0,
|
51
|
+
type: int | str = 0,
|
52
|
+
first_batch_size = 0,
|
53
|
+
app: str = "web",
|
54
|
+
cooldown: int | float = 0,
|
55
|
+
*,
|
56
|
+
async_: Literal[False, True] = False,
|
57
|
+
**request_kwargs,
|
58
|
+
) -> AsyncIterator[dict] | Iterator[dict]:
|
59
|
+
"""拉取一组 115 的历史记录
|
60
|
+
|
61
|
+
:param client: 115 客户端或 cookies
|
62
|
+
:param from_time: 开始时间(含),若为 0 则从当前时间开始,若小于 0 则从最早开始
|
63
|
+
:param from_id: 开始的事件 id (不含)
|
64
|
+
:param type: 拉取指定类型的历史记录(??表示还未搞清楚),多个用逗号 "," 隔开
|
65
|
+
|
66
|
+
- 全部: 0
|
67
|
+
- ??: 1
|
68
|
+
- 离线下载: 2
|
69
|
+
- 播放视频: 3
|
70
|
+
- 上传: 4
|
71
|
+
- ??: 5
|
72
|
+
- ??: 6
|
73
|
+
- 接收: 7
|
74
|
+
- 移动: 8
|
75
|
+
|
76
|
+
:param first_batch_size: 首批的拉取数目
|
77
|
+
:param app: 使用某个 app (设备)的接口
|
78
|
+
:param cooldown: 冷却时间,大于 0 时,两次接口调用之间至少间隔这么多秒
|
79
|
+
:param async_: 是否异步
|
80
|
+
:param request_kwargs: 其它请求参数
|
81
|
+
|
82
|
+
:return: 迭代器,产生 115 的历史记录数据字典
|
83
|
+
"""
|
84
|
+
if isinstance(client, str):
|
85
|
+
client = P115Client(client, check_for_relogin=True)
|
86
|
+
if app in ("", "web", "desktop", "harmony"):
|
87
|
+
history_list = partial(client.fs_history_list, **request_kwargs)
|
88
|
+
else:
|
89
|
+
request_kwargs.setdefault("base_url", cycle(("http://proapi.115.com", "https://proapi.115.com")).__next__)
|
90
|
+
history_list = partial(client.fs_history_list_app, app=app, **request_kwargs)
|
91
|
+
if first_batch_size <= 0:
|
92
|
+
first_batch_size = 64 if from_time or from_id else 1150
|
93
|
+
def gen_step():
|
94
|
+
payload = {"type": type, "limit": first_batch_size, "offset": 0}
|
95
|
+
seen: set[int] = set()
|
96
|
+
seen_add = seen.add
|
97
|
+
ts_last_call = time()
|
98
|
+
resp = yield history_list(payload, async_=async_)
|
99
|
+
events = check_response(resp)["data"]["list"]
|
100
|
+
payload["limit"] = 1150
|
101
|
+
offset = 0
|
102
|
+
while events:
|
103
|
+
for event in events:
|
104
|
+
event_id = int(event["id"])
|
105
|
+
if from_id and event_id <= from_id or from_time and int(event["update_time"]) < from_time:
|
106
|
+
return
|
107
|
+
if event_id not in seen:
|
108
|
+
yield Yield(event, identity=True)
|
109
|
+
seen_add(event_id)
|
110
|
+
offset += len(events)
|
111
|
+
if offset >= int(resp["data"]["total"]):
|
112
|
+
return
|
113
|
+
payload["offset"] = offset
|
114
|
+
if cooldown > 0 and (delta := ts_last_call + cooldown - time()) > 0:
|
115
|
+
if async_:
|
116
|
+
yield async_sleep(delta)
|
117
|
+
else:
|
118
|
+
sleep(delta)
|
119
|
+
ts_last_call = time()
|
120
|
+
resp = yield history_list(payload, async_=async_)
|
121
|
+
events = check_response(resp)["data"]["list"]
|
122
|
+
return run_gen_step_iter(gen_step, async_=async_)
|
123
|
+
|
124
|
+
|
125
|
+
@overload
|
126
|
+
def iter_history_list(
|
127
|
+
client: str | P115Client,
|
128
|
+
from_time: int | float = 0,
|
129
|
+
from_id: int = 0,
|
130
|
+
type: int | str = 0,
|
131
|
+
app: str = "web",
|
132
|
+
cooldown: int | float = 0,
|
133
|
+
interval: int | float = 0,
|
134
|
+
*,
|
135
|
+
async_: Literal[False] = False,
|
136
|
+
**request_kwargs,
|
137
|
+
) -> Iterator[dict]:
|
138
|
+
...
|
139
|
+
@overload
|
140
|
+
def iter_history_list(
|
141
|
+
client: str | P115Client,
|
142
|
+
from_time: int | float = 0,
|
143
|
+
from_id: int = 0,
|
144
|
+
type: int | str = 0,
|
145
|
+
app: str = "web",
|
146
|
+
cooldown: int | float = 0,
|
147
|
+
interval: int | float = 0,
|
148
|
+
*,
|
149
|
+
async_: Literal[True],
|
150
|
+
**request_kwargs,
|
151
|
+
) -> AsyncIterator[dict]:
|
152
|
+
...
|
153
|
+
def iter_history_list(
|
154
|
+
client: str | P115Client,
|
155
|
+
from_time: int | float = 0,
|
156
|
+
from_id: int = 0,
|
157
|
+
type: int | str = 0,
|
158
|
+
app: str = "web",
|
159
|
+
cooldown: int | float = 0,
|
160
|
+
interval: int | float = 0,
|
161
|
+
*,
|
162
|
+
async_: Literal[False, True] = False,
|
163
|
+
**request_kwargs,
|
164
|
+
) -> AsyncIterator[dict] | Iterator[dict]:
|
165
|
+
"""持续拉取 115 的历史记录
|
166
|
+
|
167
|
+
:param client: 115 客户端或 cookies
|
168
|
+
:param from_time: 开始时间(含),若为 0 则从当前时间开始,若小于 0 则从最早开始
|
169
|
+
:param from_id: 开始的事件 id (不含)
|
170
|
+
:param type: 拉取指定类型的历史记录(??表示还未搞清楚),多个用逗号 "," 隔开
|
171
|
+
|
172
|
+
- 全部: 0
|
173
|
+
- ??: 1
|
174
|
+
- 离线下载: 2
|
175
|
+
- 播放视频: 3
|
176
|
+
- 上传: 4
|
177
|
+
- ??: 5
|
178
|
+
- ??: 6
|
179
|
+
- 接收: 7
|
180
|
+
- 移动: 8
|
181
|
+
|
182
|
+
:param cooldown: 冷却时间,大于 0 时,两次接口调用之间至少间隔这么多秒
|
183
|
+
:param interval: 两个批量拉取之间的睡眠时间间隔,如果小于等于 0,则不睡眠
|
184
|
+
:param app: 使用某个 app (设备)的接口
|
185
|
+
:param async_: 是否异步
|
186
|
+
:param request_kwargs: 其它请求参数
|
187
|
+
|
188
|
+
:return: 迭代器,产生 115 的历史记录数据字典
|
189
|
+
"""
|
190
|
+
if isinstance(client, str):
|
191
|
+
client = P115Client(client, check_for_relogin=True)
|
192
|
+
def gen_step():
|
193
|
+
nonlocal from_time, from_id
|
194
|
+
if from_time == 0:
|
195
|
+
from_time = time()
|
196
|
+
first_loop = True
|
197
|
+
while True:
|
198
|
+
if first_loop:
|
199
|
+
first_loop = False
|
200
|
+
elif interval > 0:
|
201
|
+
if async_:
|
202
|
+
yield async_sleep(interval)
|
203
|
+
else:
|
204
|
+
sleep(interval)
|
205
|
+
with with_iter_next(iter_history_list_once(
|
206
|
+
client,
|
207
|
+
from_time,
|
208
|
+
from_id,
|
209
|
+
type=type,
|
210
|
+
app=app,
|
211
|
+
cooldown=cooldown,
|
212
|
+
async_=async_,
|
213
|
+
**request_kwargs,
|
214
|
+
)) as get_next:
|
215
|
+
sub_first_loop = True
|
216
|
+
while True:
|
217
|
+
event = yield get_next
|
218
|
+
if sub_first_loop:
|
219
|
+
from_id = int(event["id"])
|
220
|
+
from_time = int(event["update_time"])
|
221
|
+
sub_first_loop = False
|
222
|
+
yield Yield(event, identity=True)
|
223
|
+
return run_gen_step_iter(gen_step, async_=async_)
|
224
|
+
|
p115client/tool/life.py
CHANGED
@@ -15,7 +15,7 @@ from itertools import count, cycle
|
|
15
15
|
from time import time, sleep
|
16
16
|
from typing import overload, Any, Final, Literal
|
17
17
|
|
18
|
-
from iterutils import run_gen_step_iter, Yield
|
18
|
+
from iterutils import run_gen_step_iter, with_iter_next, Yield
|
19
19
|
from p115client import check_response, P115Client
|
20
20
|
|
21
21
|
|
@@ -357,7 +357,7 @@ def iter_life_behavior(
|
|
357
357
|
yield async_sleep(interval)
|
358
358
|
else:
|
359
359
|
sleep(interval)
|
360
|
-
|
360
|
+
with with_iter_next(iter_life_behavior_once(
|
361
361
|
client,
|
362
362
|
from_time,
|
363
363
|
from_id,
|
@@ -366,11 +366,10 @@ def iter_life_behavior(
|
|
366
366
|
cooldown=cooldown,
|
367
367
|
async_=async_,
|
368
368
|
**request_kwargs,
|
369
|
-
)
|
370
|
-
try:
|
369
|
+
)) as get_next:
|
371
370
|
sub_first_loop = True
|
372
371
|
while True:
|
373
|
-
event =
|
372
|
+
event = yield get_next
|
374
373
|
if sub_first_loop:
|
375
374
|
from_id = int(event["id"])
|
376
375
|
from_time = int(event["update_time"])
|
@@ -378,8 +377,6 @@ def iter_life_behavior(
|
|
378
377
|
if not type and ignore_types and event["type"] in ignore_types:
|
379
378
|
continue
|
380
379
|
yield Yield(event, identity=True)
|
381
|
-
except (StopIteration, StopAsyncIteration):
|
382
|
-
pass
|
383
380
|
return run_gen_step_iter(gen_step, async_=async_)
|
384
381
|
|
385
382
|
|
@@ -451,7 +448,7 @@ def iter_life_behavior_list(
|
|
451
448
|
while True:
|
452
449
|
ls: list[dict] = []
|
453
450
|
push = ls.append
|
454
|
-
|
451
|
+
with with_iter_next(iter_life_behavior_once(
|
455
452
|
client,
|
456
453
|
from_time,
|
457
454
|
from_id,
|
@@ -460,11 +457,10 @@ def iter_life_behavior_list(
|
|
460
457
|
cooldown=cooldown,
|
461
458
|
async_=async_,
|
462
459
|
**request_kwargs,
|
463
|
-
)
|
464
|
-
try:
|
460
|
+
)) as get_next:
|
465
461
|
first_loop = True
|
466
462
|
while True:
|
467
|
-
event =
|
463
|
+
event = yield get_next
|
468
464
|
if first_loop:
|
469
465
|
from_id = int(event["id"])
|
470
466
|
from_time = int(event["update_time"])
|
@@ -472,8 +468,6 @@ def iter_life_behavior_list(
|
|
472
468
|
if not type and ignore_types and event["type"] in ignore_types:
|
473
469
|
continue
|
474
470
|
push(event)
|
475
|
-
except (StopIteration, StopAsyncIteration):
|
476
|
-
pass
|
477
471
|
yield Yield(ls, identity=True)
|
478
472
|
return run_gen_step_iter(gen_step, async_=async_)
|
479
473
|
|
@@ -1,23 +1,24 @@
|
|
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=u_DqD-BKA0CkkQJ8hD-5CF4itke9TZBiuH4lcv1HW9g,718310
|
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
|
-
p115client/tool/__init__.py,sha256=
|
8
|
+
p115client/tool/__init__.py,sha256=x1x4yt3Ylim5CbFO4M-Fu62Gd99pUFpb3-5ssL6l-_Y,346
|
9
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/history.py,sha256=2S26BH7uBNfVHlbYFNy-aNOLMcM-HrlR7TLHAZacUJI,7458
|
13
14
|
p115client/tool/iterdir.py,sha256=T6bsD8A896nHgVxKYu2dkIo-5Az2svL4iLm2uHQWyHg,187517
|
14
|
-
p115client/tool/life.py,sha256=
|
15
|
+
p115client/tool/life.py,sha256=9ncoB2dNibhgOjPb9mHr873fCZmb65ZeteVLH4Tsujc,17330
|
15
16
|
p115client/tool/pool.py,sha256=vM5ItMxELtT7_bvbmdhwWj81rQ0zyaj3uPMny4KDw_E,9757
|
16
17
|
p115client/tool/request.py,sha256=SWsezW9EYZGS3R-TbZxMG-8bN3YWJ0-GzgvKlvRBSCM,7042
|
17
18
|
p115client/tool/upload.py,sha256=qK1OQYxP-Faq2eMDhc5sBXJiSr8m8EZ_gb0O_iA2TrI,15915
|
18
19
|
p115client/tool/xys.py,sha256=n89n9OLBXx6t20L61wJgfrP6V4jW3sHgyaQNBLdUwUQ,3578
|
19
20
|
p115client/type.py,sha256=e4g9URQBE23XN2dGomldj8wC6NlDWBBSVC5Bmd8giBc,5993
|
20
|
-
p115client-0.0.5.
|
21
|
-
p115client-0.0.5.
|
22
|
-
p115client-0.0.5.
|
23
|
-
p115client-0.0.5.
|
21
|
+
p115client-0.0.5.9.dist-info/LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
|
22
|
+
p115client-0.0.5.9.dist-info/METADATA,sha256=LV4l0DZSTHATMpfLGnhETKs6RYrYXEfnSHB02Nqodj8,8231
|
23
|
+
p115client-0.0.5.9.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
24
|
+
p115client-0.0.5.9.dist-info/RECORD,,
|
File without changes
|
File without changes
|