p115client 0.0.5.8.7__tar.gz → 0.0.5.9__tar.gz

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.
Files changed (23) hide show
  1. {p115client-0.0.5.8.7 → p115client-0.0.5.9}/PKG-INFO +1 -1
  2. {p115client-0.0.5.8.7 → p115client-0.0.5.9}/p115client/client.py +10 -6
  3. {p115client-0.0.5.8.7 → p115client-0.0.5.9}/p115client/tool/__init__.py +1 -1
  4. p115client-0.0.5.9/p115client/tool/history.py +224 -0
  5. {p115client-0.0.5.8.7 → p115client-0.0.5.9}/p115client/tool/life.py +7 -13
  6. {p115client-0.0.5.8.7 → p115client-0.0.5.9}/pyproject.toml +1 -1
  7. {p115client-0.0.5.8.7 → p115client-0.0.5.9}/LICENSE +0 -0
  8. {p115client-0.0.5.8.7 → p115client-0.0.5.9}/p115client/__init__.py +0 -0
  9. {p115client-0.0.5.8.7 → p115client-0.0.5.9}/p115client/_upload.py +0 -0
  10. {p115client-0.0.5.8.7 → p115client-0.0.5.9}/p115client/const.py +0 -0
  11. {p115client-0.0.5.8.7 → p115client-0.0.5.9}/p115client/exception.py +0 -0
  12. {p115client-0.0.5.8.7 → p115client-0.0.5.9}/p115client/py.typed +0 -0
  13. {p115client-0.0.5.8.7 → p115client-0.0.5.9}/p115client/tool/download.py +0 -0
  14. {p115client-0.0.5.8.7 → p115client-0.0.5.9}/p115client/tool/edit.py +0 -0
  15. {p115client-0.0.5.8.7 → p115client-0.0.5.9}/p115client/tool/export_dir.py +0 -0
  16. {p115client-0.0.5.8.7 → p115client-0.0.5.9}/p115client/tool/fs_files.py +0 -0
  17. {p115client-0.0.5.8.7 → p115client-0.0.5.9}/p115client/tool/iterdir.py +0 -0
  18. {p115client-0.0.5.8.7 → p115client-0.0.5.9}/p115client/tool/pool.py +0 -0
  19. {p115client-0.0.5.8.7 → p115client-0.0.5.9}/p115client/tool/request.py +0 -0
  20. {p115client-0.0.5.8.7 → p115client-0.0.5.9}/p115client/tool/upload.py +0 -0
  21. {p115client-0.0.5.8.7 → p115client-0.0.5.9}/p115client/tool/xys.py +0 -0
  22. {p115client-0.0.5.8.7 → p115client-0.0.5.9}/p115client/type.py +0 -0
  23. {p115client-0.0.5.8.7 → p115client-0.0.5.9}/readme.md +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: p115client
3
- Version: 0.0.5.8.7
3
+ Version: 0.0.5.9
4
4
  Summary: Python 115 webdisk client.
5
5
  Home-page: https://github.com/ChenyangGao/p115client
6
6
  License: MIT
@@ -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 💡 移动图片
@@ -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
+
@@ -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
- it = iter_life_behavior_once(
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 = (yield anext(it)) if async_ else next(it) # type: ignore
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
- it = iter_life_behavior_once(
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 = (yield anext(it)) if async_ else next(it) # type: ignore
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,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "p115client"
3
- version = "0.0.5.8.7"
3
+ version = "0.0.5.9"
4
4
  description = "Python 115 webdisk client."
5
5
  authors = ["ChenyangGao <wosiwujm@gmail.com>"]
6
6
  license = "MIT"
File without changes
File without changes