p115client 0.0.5.8.7__py3-none-any.whl → 0.0.5.9.1__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 +238 -126
- p115client/tool/__init__.py +1 -1
- p115client/tool/history.py +224 -0
- p115client/tool/life.py +7 -13
- p115client/tool/pool.py +216 -101
- {p115client-0.0.5.8.7.dist-info → p115client-0.0.5.9.1.dist-info}/METADATA +1 -1
- {p115client-0.0.5.8.7.dist-info → p115client-0.0.5.9.1.dist-info}/RECORD +9 -8
- {p115client-0.0.5.8.7.dist-info → p115client-0.0.5.9.1.dist-info}/LICENSE +0 -0
- {p115client-0.0.5.8.7.dist-info → p115client-0.0.5.9.1.dist-info}/WHEEL +0 -0
p115client/tool/pool.py
CHANGED
@@ -1,25 +1,54 @@
|
|
1
1
|
#!/usr/bin/env python3
|
2
2
|
# encoding: utf-8
|
3
3
|
|
4
|
+
from __future__ import annotations
|
5
|
+
|
4
6
|
__author__ = "ChenyangGao <https://chenyanggao.github.io>"
|
5
7
|
__all__ = [
|
6
|
-
"
|
7
|
-
"
|
8
|
+
"generate_auth_factory", "generate_cookies_factory", "generate_client_factory",
|
9
|
+
"auth_pool", "cookies_pool", "client_pool", "call_wrap_with_pool",
|
8
10
|
]
|
9
11
|
__doc__ = "这个模块提供了一些和 cookies 池有关的函数"
|
10
12
|
|
11
13
|
from asyncio import Lock as AsyncLock
|
12
|
-
from collections import
|
13
|
-
from
|
14
|
-
from
|
14
|
+
from collections.abc import Callable, Iterable
|
15
|
+
from functools import partial, total_ordering, update_wrapper
|
16
|
+
from heapq import heappop, heappush, heapify
|
17
|
+
from itertools import cycle, repeat
|
18
|
+
from math import inf, isinf
|
15
19
|
from threading import Lock
|
16
20
|
from time import time
|
17
|
-
from typing import Any
|
21
|
+
from typing import cast, Any
|
18
22
|
|
19
23
|
from iterutils import run_gen_step
|
20
24
|
from p115client import check_response, P115Client
|
21
|
-
from p115client.
|
22
|
-
|
25
|
+
from p115client.exception import P115OSError, AuthenticationError, LoginError
|
26
|
+
|
27
|
+
|
28
|
+
@total_ordering
|
29
|
+
class ComparedWithID[T]:
|
30
|
+
value: T
|
31
|
+
|
32
|
+
def __new__(cls, value: T | ComparedWithID[T], /):
|
33
|
+
if isinstance(value, ComparedWithID):
|
34
|
+
return value
|
35
|
+
else:
|
36
|
+
self = super().__new__(cls)
|
37
|
+
self.value = value
|
38
|
+
return self
|
39
|
+
|
40
|
+
def __eq__(self, other, /) -> bool:
|
41
|
+
if isinstance(other, ComparedWithID):
|
42
|
+
return id(self) == id(other.value)
|
43
|
+
return id(self) == id(other)
|
44
|
+
|
45
|
+
def __lt__(self, other, /) -> bool:
|
46
|
+
if isinstance(other, ComparedWithID):
|
47
|
+
return id(self) < id(other.value)
|
48
|
+
return id(self) < id(other)
|
49
|
+
|
50
|
+
def __repr__(self, /) -> str:
|
51
|
+
return f"{type(self).__qualname__}({self.value!r})"
|
23
52
|
|
24
53
|
|
25
54
|
def get_status(e: BaseException, /) -> None | int:
|
@@ -48,107 +77,171 @@ def is_timeouterror(exc: Exception) -> bool:
|
|
48
77
|
return False
|
49
78
|
|
50
79
|
|
51
|
-
def
|
80
|
+
def generate_auth_factory(
|
52
81
|
client: str | P115Client,
|
53
|
-
|
82
|
+
app_ids: Iterable[int] = range(100195123, 100196659, 2),
|
54
83
|
**request_kwargs,
|
55
84
|
) -> Callable:
|
56
|
-
"""利用一个已登录设备的 cookies
|
85
|
+
"""利用一个已登录设备的 cookies,产生若干开放应用的 access_token
|
57
86
|
|
58
87
|
:param client: 115 客户端或 cookies
|
59
|
-
:param
|
88
|
+
:param app_ids: 一组开放应用的 AppID
|
60
89
|
:param request_kwargs: 其它请求参数
|
61
90
|
|
62
|
-
:return:
|
91
|
+
:return: 函数,调用以返回一个字典,包含 authorization 请求头
|
63
92
|
"""
|
64
93
|
if isinstance(client, str):
|
65
94
|
client = P115Client(client, check_for_relogin=True)
|
66
|
-
|
67
|
-
|
68
|
-
raise ValueError("same login device will cause conflicts")
|
69
|
-
else:
|
70
|
-
app = "tv" if client.login_ssoent == "R2" else "alipaymini"
|
71
|
-
login = client.login_with_app
|
95
|
+
login = client.login_with_open
|
96
|
+
get_app_id = cycle(app_ids).__next__
|
72
97
|
def make_cookies(async_: bool = False):
|
73
|
-
def
|
98
|
+
def gen_step():
|
74
99
|
while True:
|
100
|
+
app_id = get_app_id()
|
75
101
|
try:
|
76
|
-
resp = yield login(
|
102
|
+
resp = yield login(
|
103
|
+
get_app_id(),
|
104
|
+
async_=async_, # type: ignore
|
105
|
+
**request_kwargs,
|
106
|
+
)
|
77
107
|
except Exception as e:
|
78
108
|
if not is_timeouterror(e):
|
79
109
|
raise
|
80
110
|
check_response(resp)
|
81
|
-
return
|
82
|
-
|
111
|
+
return {
|
112
|
+
"authorization": "Bearer " + resp["data"]["access_token"],
|
113
|
+
"app_id": str(app_id),
|
114
|
+
}
|
115
|
+
return run_gen_step(gen_step, async_=async_)
|
83
116
|
return make_cookies
|
84
117
|
|
85
118
|
|
86
|
-
def
|
119
|
+
def generate_cookies_factory(
|
87
120
|
client: str | P115Client,
|
88
|
-
app: str = "",
|
121
|
+
app: str | Iterable[str] = "",
|
89
122
|
**request_kwargs,
|
90
123
|
) -> Callable:
|
91
|
-
"""利用一个已登录设备的
|
124
|
+
"""利用一个已登录设备的 cookies,产生另一个设备的若干 cookies
|
92
125
|
|
93
126
|
:param client: 115 客户端或 cookies
|
94
|
-
:param app: 自动扫码后绑定的 app
|
127
|
+
:param app: 自动扫码后绑定的 app(多个则传入一组 app 的可迭代对象)
|
95
128
|
:param request_kwargs: 其它请求参数
|
96
129
|
|
97
|
-
:return:
|
130
|
+
:return: 函数,调用以返回一个字典,包含 cookie 请求头
|
98
131
|
"""
|
99
132
|
if isinstance(client, str):
|
100
133
|
client = P115Client(client, check_for_relogin=True)
|
101
|
-
if app:
|
102
|
-
if
|
103
|
-
|
134
|
+
if isinstance(app, str):
|
135
|
+
if app:
|
136
|
+
if app == client.login_app():
|
137
|
+
raise ValueError(f"same login device (app={app!r}) will cause conflicts")
|
138
|
+
else:
|
139
|
+
app = "tv" if client.login_ssoent == "R2" else "alipaymini"
|
140
|
+
get_app = repeat(app).__next__
|
104
141
|
else:
|
105
|
-
app =
|
106
|
-
|
107
|
-
|
108
|
-
|
142
|
+
app = tuple(app)
|
143
|
+
if client.login_app() in app:
|
144
|
+
raise ValueError(f"same login device (app={app!r}) will cause conflicts")
|
145
|
+
elif not app:
|
146
|
+
app = "tv" if client.login_ssoent == "R2" else "alipaymini"
|
147
|
+
get_app = repeat(app).__next__
|
148
|
+
else:
|
149
|
+
get_app = cycle(app).__next__
|
150
|
+
login = client.login_with_app
|
151
|
+
def make_cookies(async_: bool = False):
|
152
|
+
def gen_step():
|
109
153
|
while True:
|
154
|
+
app = get_app()
|
110
155
|
try:
|
111
|
-
|
156
|
+
resp = yield login(
|
157
|
+
app,
|
158
|
+
async_=async_, # type: ignore
|
159
|
+
**request_kwargs,
|
160
|
+
)
|
112
161
|
except Exception as e:
|
113
162
|
if not is_timeouterror(e):
|
114
163
|
raise
|
115
|
-
|
164
|
+
check_response(resp)
|
165
|
+
return {
|
166
|
+
"cookie": "; ".join(f"{k}={v}" for k, v in resp["data"]["cookie"].items()),
|
167
|
+
"app": app,
|
168
|
+
}
|
169
|
+
return run_gen_step(gen_step, async_=async_)
|
170
|
+
return make_cookies
|
171
|
+
|
172
|
+
|
173
|
+
def generate_client_factory(
|
174
|
+
client: str | P115Client,
|
175
|
+
app: str | Iterable[str] = "",
|
176
|
+
**request_kwargs,
|
177
|
+
) -> Callable:
|
178
|
+
"""利用一个已登录设备的 client,产生另一个设备的若干 client
|
179
|
+
|
180
|
+
:param client: 115 客户端或 cookies
|
181
|
+
:param app: 自动扫码后绑定的 app(多个则传入一组 app 的可迭代对象)
|
182
|
+
:param request_kwargs: 其它请求参数
|
183
|
+
|
184
|
+
:return: 函数,调用以返回一个 client
|
185
|
+
"""
|
186
|
+
cls = type(client)
|
187
|
+
call = generate_cookies_factory(client, app, **request_kwargs)
|
188
|
+
def make_client(async_: bool = False):
|
189
|
+
def gen_step():
|
190
|
+
headers = yield call(async_=async_)
|
191
|
+
return cls(headers["cookie"])
|
192
|
+
return run_gen_step(gen_step, async_=async_)
|
116
193
|
return make_client
|
117
194
|
|
118
195
|
|
119
|
-
def make_pool(
|
196
|
+
def make_pool[T](
|
120
197
|
generate_factory: Callable,
|
121
|
-
|
198
|
+
heap: None | list[tuple[float, T | ComparedWithID[T]]] = None,
|
122
199
|
cooldown_time: int | float = 1,
|
200
|
+
live_time: int | float = inf,
|
123
201
|
lock: bool = True,
|
124
202
|
**request_kwargs,
|
125
203
|
) -> Callable:
|
126
|
-
"""
|
204
|
+
"""创建池
|
127
205
|
|
128
206
|
:param generate_factory: 产生值的工厂函数
|
129
|
-
:param
|
130
|
-
:param cooldown_time:
|
207
|
+
:param heap: 最小堆,可以包含一组初始值,各是一个元组,包含(上一次获取时刻, 值)
|
208
|
+
:param cooldown_time: 值的冷却时间
|
209
|
+
:param live_time: 值的存活时间,默认是无穷大
|
131
210
|
:param lock: 是否需要锁
|
132
211
|
:param request_kwargs: 其它请求参数
|
133
212
|
|
134
213
|
:return: 返回一个函数,调用后返回一个元组,包含 值 和 一个调用以在完成后把 值 返还池中
|
135
214
|
"""
|
136
215
|
generate = generate_factory(**request_kwargs)
|
137
|
-
|
138
|
-
|
216
|
+
if heap is None:
|
217
|
+
heap_: list[tuple[float, ComparedWithID[T]]] = []
|
218
|
+
else:
|
219
|
+
for i, (a, b) in enumerate(heap):
|
220
|
+
heap[i] = (a, ComparedWithID(b))
|
221
|
+
heapify(heap)
|
222
|
+
heap_ = heap # type: ignore
|
139
223
|
def get_value(async_: bool = False):
|
140
224
|
def call():
|
141
|
-
|
142
|
-
if
|
143
|
-
|
144
|
-
|
145
|
-
|
225
|
+
now = time()
|
226
|
+
if not isinf(live_time):
|
227
|
+
watermark = now - live_time
|
228
|
+
while heap_:
|
229
|
+
if heap_[0][0] > watermark:
|
230
|
+
break
|
231
|
+
heappop(heap_)
|
232
|
+
if heap_ and heap_[0][0] + cooldown_time <= now:
|
233
|
+
_, val = heappop(heap_)
|
234
|
+
value = val.value
|
146
235
|
else:
|
147
|
-
|
148
|
-
|
236
|
+
if async_:
|
237
|
+
value = yield generate(async_=True)
|
238
|
+
else:
|
239
|
+
value = generate()
|
240
|
+
val = ComparedWithID(value)
|
241
|
+
return value, partial(heappush, heap_, (time(), val))
|
149
242
|
return run_gen_step(call, async_=async_)
|
150
243
|
if not lock:
|
151
|
-
setattr(get_value, "
|
244
|
+
setattr(get_value, "heap", heap_)
|
152
245
|
return get_value
|
153
246
|
lock_sync = Lock()
|
154
247
|
lock_async = AsyncLock()
|
@@ -163,35 +256,71 @@ def make_pool(
|
|
163
256
|
with lock_sync:
|
164
257
|
return get_value()
|
165
258
|
return locked_get_value
|
166
|
-
setattr(locked_get_value, "
|
259
|
+
setattr(locked_get_value, "heap", heap_)
|
167
260
|
return locked_get_value
|
168
261
|
|
169
262
|
|
263
|
+
def auth_pool(
|
264
|
+
client: str | P115Client,
|
265
|
+
app_ids: Iterable[int] = range(100195123, 100196659, 2),
|
266
|
+
heap: None | list[tuple[float, dict | ComparedWithID[dict]]] = None,
|
267
|
+
cooldown_time: int | float = 1,
|
268
|
+
live_time: int | float = 7000,
|
269
|
+
lock: bool = False,
|
270
|
+
**request_kwargs,
|
271
|
+
) -> Callable:
|
272
|
+
"""authorization 请求头池
|
273
|
+
|
274
|
+
:param client: 115 客户端或 cookies
|
275
|
+
:param app_ids: 一组开放应用的 AppID
|
276
|
+
:param heap: 最小堆,可以包含一组初始值,各是一个元组,包含(上一次获取时刻, 值)
|
277
|
+
:param cooldown_time: 值的冷却时间
|
278
|
+
:param live_time: 值的存活时间,默认是无穷大
|
279
|
+
:param lock: 锁,如果不需要锁,传入 False
|
280
|
+
:param request_kwargs: 其它请求参数
|
281
|
+
|
282
|
+
:return: 返回一个函数,调用后返回一个元组,包含值 和 一个调用(以在完成后把值返还池中)
|
283
|
+
"""
|
284
|
+
return make_pool(
|
285
|
+
generate_auth_factory,
|
286
|
+
client=client,
|
287
|
+
app_ids=app_ids,
|
288
|
+
heap=heap,
|
289
|
+
cooldown_time=cooldown_time,
|
290
|
+
live_time=live_time,
|
291
|
+
lock=lock,
|
292
|
+
**request_kwargs,
|
293
|
+
)
|
294
|
+
|
295
|
+
|
170
296
|
def cookies_pool(
|
171
297
|
client: str | P115Client,
|
172
|
-
app:
|
173
|
-
|
298
|
+
app: str | Iterable[str] = "",
|
299
|
+
heap: None | list[tuple[float, dict | ComparedWithID[dict]]] = None,
|
174
300
|
cooldown_time: int | float = 1,
|
301
|
+
live_time: int | float = inf,
|
175
302
|
lock: bool = False,
|
176
303
|
**request_kwargs,
|
177
304
|
) -> Callable:
|
178
|
-
"""
|
305
|
+
"""cookie 请求头池
|
179
306
|
|
180
307
|
:param client: 115 客户端或 cookies
|
181
|
-
:param app: 自动扫码后绑定的 app
|
182
|
-
:param
|
183
|
-
:param cooldown_time:
|
308
|
+
:param app: 自动扫码后绑定的 app(多个则传入一组 app 的可迭代对象)
|
309
|
+
:param heap: 最小堆,可以包含一组初始值,各是一个元组,包含(上一次获取时刻, 值)
|
310
|
+
:param cooldown_time: 值的冷却时间
|
311
|
+
:param live_time: 值的存活时间,默认是无穷大
|
184
312
|
:param lock: 锁,如果不需要锁,传入 False
|
185
313
|
:param request_kwargs: 其它请求参数
|
186
314
|
|
187
|
-
:return:
|
315
|
+
:return: 返回一个函数,调用后返回一个元组,包含值 和 一个调用(以在完成后把值返还池中)
|
188
316
|
"""
|
189
317
|
return make_pool(
|
190
318
|
generate_cookies_factory,
|
191
319
|
client=client,
|
192
320
|
app=app,
|
193
|
-
|
321
|
+
heap=heap,
|
194
322
|
cooldown_time=cooldown_time,
|
323
|
+
live_time=live_time,
|
195
324
|
lock=lock,
|
196
325
|
**request_kwargs,
|
197
326
|
)
|
@@ -199,84 +328,70 @@ def cookies_pool(
|
|
199
328
|
|
200
329
|
def client_pool(
|
201
330
|
client: str | P115Client,
|
202
|
-
app:
|
203
|
-
|
331
|
+
app: str | Iterable[str] = "",
|
332
|
+
heap: None | list[tuple[float, P115Client | ComparedWithID[P115Client]]] = None,
|
204
333
|
cooldown_time: int | float = 1,
|
334
|
+
live_time: int | float = inf,
|
205
335
|
lock: bool = False,
|
206
336
|
**request_kwargs,
|
207
337
|
) -> Callable:
|
208
338
|
"""client 池
|
209
339
|
|
210
340
|
:param client: 115 客户端或 cookies
|
211
|
-
:param app: 自动扫码后绑定的 app
|
212
|
-
:param
|
213
|
-
:param cooldown_time:
|
341
|
+
:param app: 自动扫码后绑定的 app(多个则传入一组 app 的可迭代对象)
|
342
|
+
:param heap: 最小堆,可以包含一组初始值,各是一个元组,包含(上一次获取时刻, 值)
|
343
|
+
:param cooldown_time: 值的冷却时间
|
344
|
+
:param live_time: 值的存活时间,默认是无穷大
|
214
345
|
:param lock: 锁,如果不需要锁,传入 False
|
215
346
|
:param request_kwargs: 其它请求参数
|
216
347
|
|
217
|
-
:return:
|
348
|
+
:return: 返回一个函数,调用后返回一个元组,包含值 和 一个调用(以在完成后把值返还池中)
|
218
349
|
"""
|
219
350
|
return make_pool(
|
220
351
|
generate_client_factory,
|
221
352
|
client=client,
|
222
353
|
app=app,
|
223
|
-
|
354
|
+
heap=heap,
|
224
355
|
cooldown_time=cooldown_time,
|
356
|
+
live_time=live_time,
|
225
357
|
lock=lock,
|
226
358
|
**request_kwargs,
|
227
359
|
)
|
228
360
|
|
229
361
|
|
230
|
-
def
|
231
|
-
|
232
|
-
/,
|
233
|
-
func: Callable = P115Client("").fs_files,
|
234
|
-
check: bool | Callable = True,
|
235
|
-
base_url_seq: None | Sequence = None,
|
236
|
-
) -> Callable:
|
237
|
-
"""包装函数,使得用 cookies 池执行请求
|
362
|
+
def call_wrap_with_pool(get_cert_headers: Callable, /, func: Callable) -> Callable:
|
363
|
+
"""包装函数,用认证信息请求头的分发池执行请求
|
238
364
|
|
239
|
-
:param
|
365
|
+
:param get_cert_headers: 获取认证信息的请求头的函数
|
240
366
|
:param func: 执行请求的函数
|
241
367
|
"""
|
242
368
|
def wrapper(*args, headers=None, async_: bool = False, **kwds):
|
243
|
-
def
|
369
|
+
def gen_step():
|
244
370
|
nonlocal headers
|
245
|
-
if async_:
|
246
|
-
cookies, revert = yield get_cookies(async_=True)
|
247
|
-
else:
|
248
|
-
cookies, revert = get_cookies()
|
249
|
-
if "base_url" not in kwds and base_url_seq:
|
250
|
-
kwds["base_url"] = base_url_seq[int(cookies.rpartition("=")[-1]) % len(base_url_seq)]
|
251
371
|
while True:
|
372
|
+
if async_:
|
373
|
+
cert_headers, revert = yield get_cert_headers(async_=True)
|
374
|
+
else:
|
375
|
+
cert_headers, revert = get_cert_headers()
|
252
376
|
if headers:
|
253
|
-
headers = dict(headers,
|
377
|
+
headers = dict(headers, **cert_headers)
|
254
378
|
else:
|
255
|
-
headers =
|
379
|
+
headers = cert_headers
|
256
380
|
try:
|
257
381
|
if async_:
|
258
382
|
resp = yield func(*args, headers=headers, async_=True, **kwds)
|
259
383
|
else:
|
260
384
|
resp = func(*args, headers=headers, **kwds)
|
261
|
-
if
|
262
|
-
|
263
|
-
check_response(resp)
|
264
|
-
else:
|
265
|
-
check(resp)
|
266
|
-
revert()
|
385
|
+
if not isinstance(resp, dict) or resp.get("errno") != 40101004:
|
386
|
+
revert()
|
267
387
|
return resp
|
268
388
|
except BaseException as e:
|
269
389
|
if isinstance(e, P115OSError) and e.args[1].get("errno") == 40101004:
|
270
390
|
raise
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
cookies, revert = get_cookies()
|
276
|
-
continue
|
277
|
-
revert()
|
278
|
-
raise
|
279
|
-
return run_gen_step(call, async_=async_)
|
391
|
+
if not isinstance(e, (AuthenticationError, LoginError)) and get_status(e) != 405:
|
392
|
+
revert()
|
393
|
+
raise
|
394
|
+
return run_gen_step(gen_step, async_=async_)
|
280
395
|
return update_wrapper(wrapper, func)
|
281
396
|
|
282
397
|
# TODO: 需要完整的类型签名
|
@@ -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=XsOy9BVOqu2jof7rGIMUldVZSiuQNAku379kIiZPr-E,721350
|
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/pool.py,sha256=
|
15
|
+
p115client/tool/life.py,sha256=9ncoB2dNibhgOjPb9mHr873fCZmb65ZeteVLH4Tsujc,17330
|
16
|
+
p115client/tool/pool.py,sha256=_3eFHTHW5Bhs17AwF8awitE4n1UuvFGIkZUZ-saJ7zQ,14233
|
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.1.dist-info/LICENSE,sha256=o5242_N2TgDsWwFhPn7yr8YJNF7XsJM5NxUMtcT97bc,1100
|
22
|
+
p115client-0.0.5.9.1.dist-info/METADATA,sha256=_NxUFNOa5O4B2Ek-NsKRlEFhR-sWQ5OUZT8G2Xe1nFY,8233
|
23
|
+
p115client-0.0.5.9.1.dist-info/WHEEL,sha256=Nq82e9rUAnEjt98J6MlVmMCZb-t9cYE2Ir1kpBmnWfs,88
|
24
|
+
p115client-0.0.5.9.1.dist-info/RECORD,,
|
File without changes
|
File without changes
|