p115client 0.0.5.11.10.2__tar.gz → 0.0.5.11.11__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.
- {p115client-0.0.5.11.10.2 → p115client-0.0.5.11.11}/PKG-INFO +1 -1
- {p115client-0.0.5.11.10.2 → p115client-0.0.5.11.11}/p115client/client.py +10 -6
- {p115client-0.0.5.11.10.2 → p115client-0.0.5.11.11}/p115client/tool/__init__.py +1 -0
- p115client-0.0.5.11.11/p115client/tool/offline.py +164 -0
- {p115client-0.0.5.11.10.2 → p115client-0.0.5.11.11}/pyproject.toml +1 -1
- {p115client-0.0.5.11.10.2 → p115client-0.0.5.11.11}/LICENSE +0 -0
- {p115client-0.0.5.11.10.2 → p115client-0.0.5.11.11}/p115client/__init__.py +0 -0
- {p115client-0.0.5.11.10.2 → p115client-0.0.5.11.11}/p115client/_upload.py +0 -0
- {p115client-0.0.5.11.10.2 → p115client-0.0.5.11.11}/p115client/const.py +0 -0
- {p115client-0.0.5.11.10.2 → p115client-0.0.5.11.11}/p115client/exception.py +0 -0
- {p115client-0.0.5.11.10.2 → p115client-0.0.5.11.11}/p115client/py.typed +0 -0
- {p115client-0.0.5.11.10.2 → p115client-0.0.5.11.11}/p115client/tool/attr.py +0 -0
- {p115client-0.0.5.11.10.2 → p115client-0.0.5.11.11}/p115client/tool/auth.py +0 -0
- {p115client-0.0.5.11.10.2 → p115client-0.0.5.11.11}/p115client/tool/download.py +0 -0
- {p115client-0.0.5.11.10.2 → p115client-0.0.5.11.11}/p115client/tool/edit.py +0 -0
- {p115client-0.0.5.11.10.2 → p115client-0.0.5.11.11}/p115client/tool/export_dir.py +0 -0
- {p115client-0.0.5.11.10.2 → p115client-0.0.5.11.11}/p115client/tool/fs_files.py +0 -0
- {p115client-0.0.5.11.10.2 → p115client-0.0.5.11.11}/p115client/tool/history.py +0 -0
- {p115client-0.0.5.11.10.2 → p115client-0.0.5.11.11}/p115client/tool/iterdir.py +0 -0
- {p115client-0.0.5.11.10.2 → p115client-0.0.5.11.11}/p115client/tool/life.py +0 -0
- {p115client-0.0.5.11.10.2 → p115client-0.0.5.11.11}/p115client/tool/pool.py +0 -0
- {p115client-0.0.5.11.10.2 → p115client-0.0.5.11.11}/p115client/tool/request.py +0 -0
- {p115client-0.0.5.11.10.2 → p115client-0.0.5.11.11}/p115client/tool/upload.py +0 -0
- {p115client-0.0.5.11.10.2 → p115client-0.0.5.11.11}/p115client/tool/util.py +0 -0
- {p115client-0.0.5.11.10.2 → p115client-0.0.5.11.11}/p115client/tool/xys.py +0 -0
- {p115client-0.0.5.11.10.2 → p115client-0.0.5.11.11}/p115client/type.py +0 -0
- {p115client-0.0.5.11.10.2 → p115client-0.0.5.11.11}/readme.md +0 -0
@@ -377,6 +377,9 @@ def check_response(resp: dict | Awaitable[dict], /) -> dict | Coroutine[Any, Any
|
|
377
377
|
# {"state": false, "errno": 911, "error": "请验证账号"}
|
378
378
|
case 911:
|
379
379
|
raise AuthenticationError(errno.EAUTH, resp)
|
380
|
+
# {"state": false, "errno": 10004, "error": "错误的链接"}
|
381
|
+
case 10004:
|
382
|
+
raise OperationalError(errno.EINVAL, resp)
|
380
383
|
# {"state": false, "errno": 20001, "error": "目录名称不能为空"}
|
381
384
|
case 20001:
|
382
385
|
raise OperationalError(errno.EINVAL, resp)
|
@@ -3180,8 +3183,8 @@ class P115OpenClient(ClientRequestMixin):
|
|
3180
3183
|
- `c`: 允许同时打开次数,如果为 0,则是无限次数
|
3181
3184
|
- `f`: 请求时要求携带请求头
|
3182
3185
|
- 如果为空,则无要求
|
3183
|
-
- 如果为 1,则需要
|
3184
|
-
- 如果为 3,则需要
|
3186
|
+
- 如果为 1,则需要 user-agent(和请求直链时的一致)
|
3187
|
+
- 如果为 3,则需要 user-agent(和请求直链时的一致) 和 Cookie(由请求直链时的响应所返回的 Set-Cookie 响应头)
|
3185
3188
|
|
3186
3189
|
:param pickcode: 提取码
|
3187
3190
|
:param strict: 如果为 True,当目标是目录时,会抛出 IsADirectoryError 异常
|
@@ -7857,8 +7860,8 @@ class P115Client(P115OpenClient):
|
|
7857
7860
|
- `c`: 允许同时打开次数,如果为 0,则是无限次数
|
7858
7861
|
- `f`: 请求时要求携带请求头
|
7859
7862
|
- 如果为空,则无要求
|
7860
|
-
- 如果为 1,则需要
|
7861
|
-
- 如果为 3,则需要
|
7863
|
+
- 如果为 1,则需要 user-agent(和请求直链时的一致)
|
7864
|
+
- 如果为 3,则需要 user-agent(和请求直链时的一致) 和 Cookie(由请求直链时的响应所返回的 Set-Cookie 响应头)
|
7862
7865
|
|
7863
7866
|
:param pickcode: 提取码
|
7864
7867
|
:param strict: 如果为 True,当目标是目录时,会抛出 IsADirectoryError 异常
|
@@ -18043,6 +18046,7 @@ class P115Client(P115OpenClient):
|
|
18043
18046
|
POST https://lixian.115.com/lixianssp/?ac=add_task_urls
|
18044
18047
|
|
18045
18048
|
:payload:
|
18049
|
+
- url: str 💡 链接,支持HTTP、HTTPS、FTP、磁力链和电驴链接
|
18046
18050
|
- url[0]: str 💡 链接,支持HTTP、HTTPS、FTP、磁力链和电驴链接
|
18047
18051
|
- url[1]: str
|
18048
18052
|
- ...
|
@@ -18052,7 +18056,7 @@ class P115Client(P115OpenClient):
|
|
18052
18056
|
if isinstance(payload, str):
|
18053
18057
|
payload = payload.strip("\n").split("\n")
|
18054
18058
|
if not isinstance(payload, dict):
|
18055
|
-
payload = {f"url[{i}]": url for i, url in enumerate(payload)}
|
18059
|
+
payload = {f"url[{i}]": url for i, url in enumerate(payload) if url}
|
18056
18060
|
if not payload:
|
18057
18061
|
raise ValueError("no `url` specified")
|
18058
18062
|
return self._offline_post(payload, "add_task_urls", use_web_api=use_web_api, async_=async_, **request_kwargs)
|
@@ -21021,7 +21025,7 @@ class P115Client(P115OpenClient):
|
|
21021
21025
|
request_kwargs.update(make_upload_payload(data))
|
21022
21026
|
request_kwargs["headers"] = {
|
21023
21027
|
**(request_kwargs.get("headers") or {}),
|
21024
|
-
"
|
21028
|
+
"content-type": "application/x-www-form-urlencoded",
|
21025
21029
|
"user-agent": "Mozilla/5.0 115disk/99.99.99.99 115Browser/99.99.99.99 115wangpan_android/99.99.99.99",
|
21026
21030
|
}
|
21027
21031
|
request_kwargs.setdefault("parse", parse_upload_init_response)
|
@@ -0,0 +1,164 @@
|
|
1
|
+
#!/usr/bin/env python3
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
__author__ = "ChenyangGao <https://chenyanggao.github.io>"
|
5
|
+
__all__ = ["offline_iter", "offline_restart_iter"]
|
6
|
+
__doc__ = "这个模块提供了一些和离线下载有关的函数"
|
7
|
+
|
8
|
+
from asyncio import sleep as async_sleep
|
9
|
+
from collections.abc import AsyncIterator, Callable, Iterable, Iterator
|
10
|
+
from itertools import count
|
11
|
+
from time import sleep, time
|
12
|
+
from typing import overload, Literal
|
13
|
+
|
14
|
+
from iterutils import run_gen_step_iter, with_iter_next, Yield, YieldFrom
|
15
|
+
from p115client import check_response, P115Client, P115OpenClient
|
16
|
+
|
17
|
+
|
18
|
+
@overload
|
19
|
+
def offline_iter(
|
20
|
+
client: str | P115Client | P115OpenClient,
|
21
|
+
/,
|
22
|
+
page_start: int = 1,
|
23
|
+
page_stop: int = -1,
|
24
|
+
cooldown: float = 0,
|
25
|
+
use_open_api: bool = False,
|
26
|
+
*,
|
27
|
+
async_: Literal[False] = False,
|
28
|
+
**request_kwargs,
|
29
|
+
) -> Iterator[dict]:
|
30
|
+
...
|
31
|
+
@overload
|
32
|
+
def offline_iter(
|
33
|
+
client: str | P115Client | P115OpenClient,
|
34
|
+
/,
|
35
|
+
page_start: int = 1,
|
36
|
+
page_stop: int = -1,
|
37
|
+
cooldown: float = 0,
|
38
|
+
use_open_api: bool = False,
|
39
|
+
*,
|
40
|
+
async_: Literal[True],
|
41
|
+
**request_kwargs,
|
42
|
+
) -> AsyncIterator[dict]:
|
43
|
+
...
|
44
|
+
def offline_iter(
|
45
|
+
client: str | P115Client | P115OpenClient,
|
46
|
+
/,
|
47
|
+
page_start: int = 1,
|
48
|
+
page_stop: int = -1,
|
49
|
+
cooldown: float = 0,
|
50
|
+
use_open_api: bool = False,
|
51
|
+
*,
|
52
|
+
async_: Literal[False, True] = False,
|
53
|
+
**request_kwargs,
|
54
|
+
) -> Iterator[dict] | AsyncIterator[dict]:
|
55
|
+
"""遍历任务列表,获取任务信息
|
56
|
+
|
57
|
+
:param client: 115 客户端或 cookies
|
58
|
+
:param page_start: 开始页数
|
59
|
+
:param page_stop: 结束页数(不含),如果 <= 0,则不限
|
60
|
+
:param cooldown: 接口调用冷却时间,单位:秒
|
61
|
+
:param use_open_api: 是否使用 open api
|
62
|
+
:param async_: 是否异步
|
63
|
+
:param request_kwargs: 其它请求参数
|
64
|
+
|
65
|
+
:return: 迭代器,返回任务信息
|
66
|
+
"""
|
67
|
+
if isinstance(client, str):
|
68
|
+
client = P115Client(client, check_for_relogin=True)
|
69
|
+
if page_start < 1:
|
70
|
+
page_start = 1
|
71
|
+
if page_stop > 0:
|
72
|
+
pages: Iterable[int] = range(page_start, page_stop)
|
73
|
+
else:
|
74
|
+
pages = count(page_start)
|
75
|
+
if not isinstance(client, P115Client):
|
76
|
+
use_open_api = True
|
77
|
+
def gen_step():
|
78
|
+
if use_open_api:
|
79
|
+
offline_list = client.offline_list_open
|
80
|
+
else:
|
81
|
+
offline_list = client.offline_list
|
82
|
+
if cooldown > 0:
|
83
|
+
do_sleep = async_sleep if async_ else sleep
|
84
|
+
last_t: float = 0
|
85
|
+
for page in pages:
|
86
|
+
if last_t and (diff := last_t + cooldown - time()) > 0:
|
87
|
+
yield do_sleep(diff)
|
88
|
+
last_t = time()
|
89
|
+
resp = yield offline_list(page, async_=async_, **request_kwargs)
|
90
|
+
check_response(resp)
|
91
|
+
if use_open_api:
|
92
|
+
resp = resp["data"]
|
93
|
+
tasks = resp["tasks"]
|
94
|
+
if not tasks:
|
95
|
+
break
|
96
|
+
yield YieldFrom(resp["tasks"])
|
97
|
+
if len(tasks) < 30 or page >= resp["page_count"]:
|
98
|
+
break
|
99
|
+
return run_gen_step_iter(gen_step, async_=async_)
|
100
|
+
|
101
|
+
|
102
|
+
@overload
|
103
|
+
def offline_restart_iter(
|
104
|
+
client: str | P115Client,
|
105
|
+
/,
|
106
|
+
predicate: None | Callable[[dict], bool] = None,
|
107
|
+
*,
|
108
|
+
async_: Literal[False] = False,
|
109
|
+
**request_kwargs,
|
110
|
+
) -> Iterator[dict]:
|
111
|
+
...
|
112
|
+
@overload
|
113
|
+
def offline_restart_iter(
|
114
|
+
client: str | P115Client,
|
115
|
+
/,
|
116
|
+
predicate: None | Callable[[dict], bool] = None,
|
117
|
+
*,
|
118
|
+
async_: Literal[True],
|
119
|
+
**request_kwargs,
|
120
|
+
) -> AsyncIterator[dict]:
|
121
|
+
...
|
122
|
+
def offline_restart_iter(
|
123
|
+
client: str | P115Client,
|
124
|
+
/,
|
125
|
+
predicate: None | Callable[[dict], bool] = None,
|
126
|
+
*,
|
127
|
+
async_: Literal[False, True] = False,
|
128
|
+
**request_kwargs,
|
129
|
+
) -> Iterator[dict] | AsyncIterator[dict]:
|
130
|
+
"""重试任务:重试那些因为空间不足而转存失败的任务
|
131
|
+
|
132
|
+
:param client: 115 客户端或 cookies
|
133
|
+
:param predicate: 断言,用于筛选
|
134
|
+
:param async_: 是否异步
|
135
|
+
:param request_kwargs: 其它请求参数
|
136
|
+
|
137
|
+
:return: 迭代器,逐个任务返回执行重试后的响应
|
138
|
+
"""
|
139
|
+
if isinstance(client, str):
|
140
|
+
client = P115Client(client, check_for_relogin=True)
|
141
|
+
def gen_step():
|
142
|
+
left_no_space: list[dict] = []
|
143
|
+
add_task = left_no_space.append
|
144
|
+
with with_iter_next(offline_iter(
|
145
|
+
client,
|
146
|
+
async_=async_,
|
147
|
+
**request_kwargs,
|
148
|
+
)) as do_next:
|
149
|
+
while True:
|
150
|
+
task = yield do_next()
|
151
|
+
if task["move"] == -1:
|
152
|
+
add_task(task)
|
153
|
+
elif task["status"] == 2:
|
154
|
+
break
|
155
|
+
for task in filter(predicate, left_no_space):
|
156
|
+
resp = yield client.offline_restart(
|
157
|
+
task["info_hash"],
|
158
|
+
async_=async_,
|
159
|
+
**request_kwargs,
|
160
|
+
)
|
161
|
+
resp["task"] = task
|
162
|
+
yield Yield(resp)
|
163
|
+
return run_gen_step_iter(gen_step, async_=async_)
|
164
|
+
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|