p115client 0.0.5.8.7__tar.gz → 0.0.5.9.1__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.8.7 → p115client-0.0.5.9.1}/PKG-INFO +1 -1
- {p115client-0.0.5.8.7 → p115client-0.0.5.9.1}/p115client/client.py +238 -126
- {p115client-0.0.5.8.7 → p115client-0.0.5.9.1}/p115client/tool/__init__.py +1 -1
- p115client-0.0.5.9.1/p115client/tool/history.py +224 -0
- {p115client-0.0.5.8.7 → p115client-0.0.5.9.1}/p115client/tool/life.py +7 -13
- p115client-0.0.5.9.1/p115client/tool/pool.py +399 -0
- {p115client-0.0.5.8.7 → p115client-0.0.5.9.1}/pyproject.toml +1 -1
- p115client-0.0.5.8.7/p115client/tool/pool.py +0 -284
- {p115client-0.0.5.8.7 → p115client-0.0.5.9.1}/LICENSE +0 -0
- {p115client-0.0.5.8.7 → p115client-0.0.5.9.1}/p115client/__init__.py +0 -0
- {p115client-0.0.5.8.7 → p115client-0.0.5.9.1}/p115client/_upload.py +0 -0
- {p115client-0.0.5.8.7 → p115client-0.0.5.9.1}/p115client/const.py +0 -0
- {p115client-0.0.5.8.7 → p115client-0.0.5.9.1}/p115client/exception.py +0 -0
- {p115client-0.0.5.8.7 → p115client-0.0.5.9.1}/p115client/py.typed +0 -0
- {p115client-0.0.5.8.7 → p115client-0.0.5.9.1}/p115client/tool/download.py +0 -0
- {p115client-0.0.5.8.7 → p115client-0.0.5.9.1}/p115client/tool/edit.py +0 -0
- {p115client-0.0.5.8.7 → p115client-0.0.5.9.1}/p115client/tool/export_dir.py +0 -0
- {p115client-0.0.5.8.7 → p115client-0.0.5.9.1}/p115client/tool/fs_files.py +0 -0
- {p115client-0.0.5.8.7 → p115client-0.0.5.9.1}/p115client/tool/iterdir.py +0 -0
- {p115client-0.0.5.8.7 → p115client-0.0.5.9.1}/p115client/tool/request.py +0 -0
- {p115client-0.0.5.8.7 → p115client-0.0.5.9.1}/p115client/tool/upload.py +0 -0
- {p115client-0.0.5.8.7 → p115client-0.0.5.9.1}/p115client/tool/xys.py +0 -0
- {p115client-0.0.5.8.7 → p115client-0.0.5.9.1}/p115client/type.py +0 -0
- {p115client-0.0.5.8.7 → p115client-0.0.5.9.1}/readme.md +0 -0
@@ -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)
|
@@ -935,6 +939,19 @@ class IgnoreCaseDict[V](dict[str, V]):
|
|
935
939
|
if kwargs:
|
936
940
|
update(((k.lower(), v) for k, v in kwargs.items()))
|
937
941
|
|
942
|
+
def merge(self, *args, **kwargs):
|
943
|
+
setdefault = super().setdefault
|
944
|
+
for arg in args:
|
945
|
+
if not arg:
|
946
|
+
continue
|
947
|
+
if isinstance(arg, Mapping):
|
948
|
+
arg = items(arg)
|
949
|
+
for k, v in arg:
|
950
|
+
setdefault(k, v)
|
951
|
+
if kwargs:
|
952
|
+
for k, v in kwargs.items():
|
953
|
+
setdefault(k, v)
|
954
|
+
|
938
955
|
|
939
956
|
class ClientRequestMixin:
|
940
957
|
|
@@ -1768,7 +1785,7 @@ class ClientRequestMixin:
|
|
1768
1785
|
|
1769
1786
|
@overload
|
1770
1787
|
@classmethod
|
1771
|
-
def
|
1788
|
+
def login_with_app_id(
|
1772
1789
|
cls,
|
1773
1790
|
/,
|
1774
1791
|
app_id: int | str = 100195993,
|
@@ -1780,7 +1797,7 @@ class ClientRequestMixin:
|
|
1780
1797
|
...
|
1781
1798
|
@overload
|
1782
1799
|
@classmethod
|
1783
|
-
def
|
1800
|
+
def login_with_app_id(
|
1784
1801
|
cls,
|
1785
1802
|
/,
|
1786
1803
|
app_id: int | str = 100195993,
|
@@ -1791,7 +1808,7 @@ class ClientRequestMixin:
|
|
1791
1808
|
) -> Coroutine[Any, Any, dict]:
|
1792
1809
|
...
|
1793
1810
|
@classmethod
|
1794
|
-
def
|
1811
|
+
def login_with_app_id(
|
1795
1812
|
cls,
|
1796
1813
|
/,
|
1797
1814
|
app_id: int | str = 100195993,
|
@@ -2438,7 +2455,7 @@ class P115OpenClient(ClientRequestMixin):
|
|
2438
2455
|
)
|
2439
2456
|
else:
|
2440
2457
|
app_id = self.app_id = app_id_or_refresh_token
|
2441
|
-
resp = yield self.
|
2458
|
+
resp = yield self.login_with_app_id(
|
2442
2459
|
app_id,
|
2443
2460
|
console_qrcode=console_qrcode,
|
2444
2461
|
async_=async_,
|
@@ -4259,22 +4276,14 @@ class P115Client(P115OpenClient):
|
|
4259
4276
|
) -> None | str:
|
4260
4277
|
cookies_path = self.__dict__.get("cookies_path")
|
4261
4278
|
if not cookies_path:
|
4262
|
-
return None
|
4263
|
-
cookies_mtime_old = self.__dict__.get("cookies_mtime", 0)
|
4264
|
-
try:
|
4265
|
-
cookies_mtime = cookies_path.stat().st_mtime
|
4266
|
-
except OSError:
|
4267
|
-
cookies_mtime = 0
|
4268
|
-
if cookies_mtime_old >= cookies_mtime:
|
4269
4279
|
return self.cookies_str
|
4270
4280
|
try:
|
4271
4281
|
with cookies_path.open("rb") as f:
|
4272
4282
|
cookies = str(f.read(), encoding)
|
4273
4283
|
setattr(self, "cookies", cookies)
|
4274
|
-
self.cookies_mtime = cookies_mtime
|
4275
4284
|
return cookies
|
4276
4285
|
except OSError:
|
4277
|
-
return
|
4286
|
+
return self.cookies_str
|
4278
4287
|
|
4279
4288
|
def _write_cookies(
|
4280
4289
|
self,
|
@@ -4289,10 +4298,6 @@ class P115Client(P115OpenClient):
|
|
4289
4298
|
cookies_bytes = bytes(cookies, encoding)
|
4290
4299
|
with cookies_path.open("wb") as f:
|
4291
4300
|
f.write(cookies_bytes)
|
4292
|
-
try:
|
4293
|
-
self.cookies_mtime = cookies_path.stat().st_mtime
|
4294
|
-
except OSError:
|
4295
|
-
self.cookies_mtime = 0
|
4296
4301
|
|
4297
4302
|
@overload # type: ignore
|
4298
4303
|
@classmethod
|
@@ -4759,6 +4764,8 @@ class P115Client(P115OpenClient):
|
|
4759
4764
|
def login_without_app(
|
4760
4765
|
self,
|
4761
4766
|
/,
|
4767
|
+
show_warning: bool = False,
|
4768
|
+
*,
|
4762
4769
|
async_: Literal[False] = False,
|
4763
4770
|
**request_kwargs,
|
4764
4771
|
) -> str:
|
@@ -4767,6 +4774,8 @@ class P115Client(P115OpenClient):
|
|
4767
4774
|
def login_without_app(
|
4768
4775
|
self,
|
4769
4776
|
/,
|
4777
|
+
show_warning: bool = False,
|
4778
|
+
*,
|
4770
4779
|
async_: Literal[True],
|
4771
4780
|
**request_kwargs,
|
4772
4781
|
) -> Coroutine[Any, Any, str]:
|
@@ -4774,29 +4783,93 @@ class P115Client(P115OpenClient):
|
|
4774
4783
|
def login_without_app(
|
4775
4784
|
self,
|
4776
4785
|
/,
|
4786
|
+
show_warning: bool = False,
|
4787
|
+
*,
|
4777
4788
|
async_: Literal[False, True] = False,
|
4778
4789
|
**request_kwargs,
|
4779
4790
|
) -> str | Coroutine[Any, Any, str]:
|
4780
4791
|
"""执行一次自动扫登录二维码,但不绑定设备,返回扫码的 uid,可用于之后绑定设备
|
4792
|
+
|
4793
|
+
:param show_warning: 是否显示提示信息
|
4794
|
+
:param async_: 是否异步
|
4795
|
+
:param request_kwargs: 其它请求参数
|
4796
|
+
|
4797
|
+
:return: 二维码的 uid
|
4781
4798
|
"""
|
4782
4799
|
def gen_step():
|
4783
4800
|
uid = check_response((yield self.login_qrcode_token(
|
4784
4801
|
async_=async_,
|
4785
4802
|
**request_kwargs,
|
4786
4803
|
)))["data"]["uid"]
|
4787
|
-
|
4804
|
+
resp = yield self.login_qrcode_scan(
|
4788
4805
|
uid,
|
4789
4806
|
async_=async_,
|
4790
4807
|
**request_kwargs,
|
4791
|
-
)
|
4792
|
-
check_response(
|
4808
|
+
)
|
4809
|
+
check_response(resp)
|
4810
|
+
if show_warning:
|
4811
|
+
warn(f"qrcode scanned: {resp}", category=P115Warning)
|
4812
|
+
resp = yield self.login_qrcode_scan_confirm(
|
4793
4813
|
uid,
|
4794
4814
|
async_=async_,
|
4795
4815
|
**request_kwargs,
|
4796
|
-
)
|
4816
|
+
)
|
4817
|
+
check_response(resp)
|
4797
4818
|
return uid
|
4798
4819
|
return run_gen_step(gen_step, async_=async_)
|
4799
4820
|
|
4821
|
+
@overload
|
4822
|
+
def login_with_open(
|
4823
|
+
self,
|
4824
|
+
/,
|
4825
|
+
app_id: int | str = 100195993,
|
4826
|
+
*,
|
4827
|
+
show_warning: bool = False,
|
4828
|
+
async_: Literal[False] = False,
|
4829
|
+
**request_kwargs,
|
4830
|
+
) -> dict:
|
4831
|
+
...
|
4832
|
+
@overload
|
4833
|
+
def login_with_open(
|
4834
|
+
self,
|
4835
|
+
/,
|
4836
|
+
app_id: int | str = 100195993,
|
4837
|
+
*,
|
4838
|
+
show_warning: bool = False,
|
4839
|
+
async_: Literal[True],
|
4840
|
+
**request_kwargs,
|
4841
|
+
) -> Coroutine[Any, Any, dict]:
|
4842
|
+
...
|
4843
|
+
def login_with_open(
|
4844
|
+
self,
|
4845
|
+
/,
|
4846
|
+
app_id: int | str = 100195993,
|
4847
|
+
*,
|
4848
|
+
show_warning: bool = False,
|
4849
|
+
async_: Literal[False, True] = False,
|
4850
|
+
**request_kwargs,
|
4851
|
+
) -> dict | Coroutine[Any, Any, dict]:
|
4852
|
+
"""登录某个开放接口应用
|
4853
|
+
|
4854
|
+
:param app_id: AppID
|
4855
|
+
:param show_warning: 是否显示提示信息
|
4856
|
+
:param async_: 是否异步
|
4857
|
+
:param request_kwargs: 其它请求参数
|
4858
|
+
|
4859
|
+
:return: 接口返回值
|
4860
|
+
"""
|
4861
|
+
def gen_step():
|
4862
|
+
resp = yield self.login_qrcode_token_open(app_id, async_=async_, **request_kwargs)
|
4863
|
+
login_uid = check_response(resp)["data"]["uid"]
|
4864
|
+
resp = yield self.login_qrcode_scan(login_uid, async_=async_, **request_kwargs)
|
4865
|
+
check_response(resp)
|
4866
|
+
if show_warning:
|
4867
|
+
warn(f"qrcode scanned: {resp}", category=P115Warning)
|
4868
|
+
resp = yield self.login_qrcode_scan_confirm(login_uid, async_=async_, **request_kwargs)
|
4869
|
+
check_response(resp)
|
4870
|
+
return self.login_qrcode_access_token_open(login_uid, async_=async_, **request_kwargs)
|
4871
|
+
return run_gen_step(gen_step, async_=async_)
|
4872
|
+
|
4800
4873
|
@overload
|
4801
4874
|
def login_another_app(
|
4802
4875
|
self,
|
@@ -4804,6 +4877,7 @@ class P115Client(P115OpenClient):
|
|
4804
4877
|
app: None | str = None,
|
4805
4878
|
replace: bool | Self = False,
|
4806
4879
|
check_for_relogin: bool | Callable[[BaseException], bool | int] = False,
|
4880
|
+
show_warning: bool = False,
|
4807
4881
|
*,
|
4808
4882
|
async_: Literal[False] = False,
|
4809
4883
|
**request_kwargs,
|
@@ -4816,6 +4890,7 @@ class P115Client(P115OpenClient):
|
|
4816
4890
|
app: None | str = None,
|
4817
4891
|
replace: bool | Self = False,
|
4818
4892
|
check_for_relogin: bool | Callable[[BaseException], bool | int] = False,
|
4893
|
+
show_warning: bool = False,
|
4819
4894
|
*,
|
4820
4895
|
async_: Literal[True],
|
4821
4896
|
**request_kwargs,
|
@@ -4827,6 +4902,7 @@ class P115Client(P115OpenClient):
|
|
4827
4902
|
app: None | str = None,
|
4828
4903
|
replace: bool | Self = False,
|
4829
4904
|
check_for_relogin: bool | Callable[[BaseException], bool | int] = False,
|
4905
|
+
show_warning: bool = False,
|
4830
4906
|
*,
|
4831
4907
|
async_: Literal[False, True] = False,
|
4832
4908
|
**request_kwargs,
|
@@ -4841,8 +4917,8 @@ class P115Client(P115OpenClient):
|
|
4841
4917
|
:param app: 要登录的 app,如果为 None,则用当前登录设备,如果无当前登录设备,则报错
|
4842
4918
|
:param replace: 替换某个 client 对象的 cookie
|
4843
4919
|
|
4844
|
-
- 如果为 P115Client,
|
4845
|
-
- 如果为 True
|
4920
|
+
- 如果为 P115Client, 则更新到此对象
|
4921
|
+
- 如果为 True,则更新到 `self`
|
4846
4922
|
- 如果为 False,否则返回新的 `P115Client` 对象
|
4847
4923
|
|
4848
4924
|
:param check_for_relogin: 网页请求抛出异常时,判断是否要重新登录并重试
|
@@ -4851,9 +4927,12 @@ class P115Client(P115OpenClient):
|
|
4851
4927
|
- 如果为 True,则自动通过判断 HTTP 响应码为 405 时重新登录并重试
|
4852
4928
|
- 如果为 collections.abc.Callable,则调用以判断,当返回值为 bool 类型且值为 True,或者值为 405 时重新登录,然后循环此流程,直到成功或不可重试
|
4853
4929
|
|
4930
|
+
:param show_warning: 是否显示提示信息
|
4854
4931
|
:param async_: 是否异步
|
4855
4932
|
:param request_kwargs: 其它请求参数
|
4856
4933
|
|
4934
|
+
:return: 客户端实例
|
4935
|
+
|
4857
4936
|
-----
|
4858
4937
|
|
4859
4938
|
:设备列表如下:
|
@@ -4914,7 +4993,12 @@ class P115Client(P115OpenClient):
|
|
4914
4993
|
nonlocal app
|
4915
4994
|
if not app and isinstance(replace, P115Client):
|
4916
4995
|
app = yield replace.login_app(async_=True)
|
4917
|
-
resp = yield self.login_with_app(
|
4996
|
+
resp = yield self.login_with_app(
|
4997
|
+
app,
|
4998
|
+
show_warning=show_warning,
|
4999
|
+
async_=async_,
|
5000
|
+
**request_kwargs,
|
5001
|
+
)
|
4918
5002
|
cookies = check_response(resp)["data"]["cookie"]
|
4919
5003
|
ssoent = self.login_ssoent
|
4920
5004
|
if isinstance(replace, P115Client):
|
@@ -4937,6 +5021,7 @@ class P115Client(P115OpenClient):
|
|
4937
5021
|
app_id: int | str = 100195993,
|
4938
5022
|
*,
|
4939
5023
|
replace: Literal[True] | Self,
|
5024
|
+
show_warning: bool = False,
|
4940
5025
|
async_: Literal[False] = False,
|
4941
5026
|
**request_kwargs,
|
4942
5027
|
) -> Self:
|
@@ -4948,6 +5033,7 @@ class P115Client(P115OpenClient):
|
|
4948
5033
|
app_id: int | str = 100195993,
|
4949
5034
|
*,
|
4950
5035
|
replace: Literal[True] | Self,
|
5036
|
+
show_warning: bool = False,
|
4951
5037
|
async_: Literal[True],
|
4952
5038
|
**request_kwargs,
|
4953
5039
|
) -> Coroutine[Any, Any, Self]:
|
@@ -4959,6 +5045,7 @@ class P115Client(P115OpenClient):
|
|
4959
5045
|
app_id: int | str = 100195993,
|
4960
5046
|
*,
|
4961
5047
|
replace: Literal[False] = False,
|
5048
|
+
show_warning: bool = False,
|
4962
5049
|
async_: Literal[False] = False,
|
4963
5050
|
**request_kwargs,
|
4964
5051
|
) -> P115OpenClient:
|
@@ -4970,6 +5057,7 @@ class P115Client(P115OpenClient):
|
|
4970
5057
|
app_id: int | str = 100195993,
|
4971
5058
|
*,
|
4972
5059
|
replace: Literal[False] = False,
|
5060
|
+
show_warning: bool = False,
|
4973
5061
|
async_: Literal[True],
|
4974
5062
|
**request_kwargs,
|
4975
5063
|
) -> Coroutine[Any, Any, P115OpenClient]:
|
@@ -4980,23 +5068,33 @@ class P115Client(P115OpenClient):
|
|
4980
5068
|
app_id: int | str = 100195993,
|
4981
5069
|
*,
|
4982
5070
|
replace: bool | Self = False,
|
5071
|
+
show_warning: bool = False,
|
4983
5072
|
async_: Literal[False, True] = False,
|
4984
5073
|
**request_kwargs,
|
4985
5074
|
) -> P115OpenClient | Coroutine[Any, Any, P115OpenClient] | Self | Coroutine[Any, Any, Self]:
|
4986
5075
|
"""登录某个开放接口应用
|
4987
5076
|
|
4988
5077
|
:param app_id: AppID
|
5078
|
+
:param replace: 替换某个 client 对象的 `access_token` 和 `refresh_token`
|
5079
|
+
|
5080
|
+
- 如果为 P115Client, 则更新到此对象
|
5081
|
+
- 如果为 True,则更新到 `self`
|
5082
|
+
- 如果为 False,否则返回新的 `P115Client` 对象
|
5083
|
+
|
5084
|
+
:param show_warning: 是否显示提示信息
|
4989
5085
|
:param async_: 是否异步
|
4990
5086
|
:param request_kwargs: 其它请求参数
|
5087
|
+
|
5088
|
+
:return: 客户端实例
|
4991
5089
|
"""
|
4992
5090
|
def gen_step():
|
4993
|
-
resp = yield self.
|
4994
|
-
|
4995
|
-
|
4996
|
-
|
4997
|
-
|
4998
|
-
|
4999
|
-
data = resp["data"]
|
5091
|
+
resp = yield self.login_with_open(
|
5092
|
+
app_id,
|
5093
|
+
show_warning=show_warning,
|
5094
|
+
async_=async_,
|
5095
|
+
**request_kwargs,
|
5096
|
+
)
|
5097
|
+
data = check_response(resp)["data"]
|
5000
5098
|
if replace is False:
|
5001
5099
|
inst: P115OpenClient | Self = P115OpenClient.from_token(data["access_token"], data["refresh_token"])
|
5002
5100
|
else:
|
@@ -5171,9 +5269,10 @@ class P115Client(P115OpenClient):
|
|
5171
5269
|
params = None,
|
5172
5270
|
data = None,
|
5173
5271
|
*,
|
5272
|
+
check: bool = False,
|
5174
5273
|
ecdh_encrypt: bool = False,
|
5175
|
-
|
5176
|
-
|
5274
|
+
fetch_cert_headers: None | Callable[..., Mapping] | Callable[..., Awaitable[Mapping]] = None,
|
5275
|
+
revert_cert_headers: None | Callable[[Mapping], Any] = None,
|
5177
5276
|
async_: Literal[False, True] = False,
|
5178
5277
|
request: None | Callable[[Unpack[RequestKeywords]], Any] = None,
|
5179
5278
|
**request_kwargs,
|
@@ -5183,9 +5282,10 @@ class P115Client(P115OpenClient):
|
|
5183
5282
|
:param url: HTTP 的请求链接
|
5184
5283
|
:param method: HTTP 的请求方法
|
5185
5284
|
:param params: 查询参数
|
5285
|
+
:param check: 是否用 `check_response` 函数检查返回值
|
5186
5286
|
:param ecdh_encrypt: 使用 ecdh 算法进行加密(返回值也要解密)
|
5187
|
-
:param
|
5188
|
-
:param
|
5287
|
+
:param fetch_cert_headers: 调用以获取认证信息头
|
5288
|
+
:param revert_cert_headers: 调用以退还认证信息头
|
5189
5289
|
:param async_: 说明 `request` 是同步调用还是异步调用
|
5190
5290
|
:param request: HTTP 请求调用,如果为 None,则默认用 httpx 执行请求
|
5191
5291
|
如果传入调用,则必须至少能接受以下几个关键词参数:
|
@@ -5261,18 +5361,39 @@ class P115Client(P115OpenClient):
|
|
5261
5361
|
url = "http://webapi.115.com" + url
|
5262
5362
|
if params:
|
5263
5363
|
url = make_url(url, params)
|
5364
|
+
is_open_api = url.startswith("https://proapi.115.com/open/")
|
5365
|
+
headers = IgnoreCaseDict(request_kwargs.get("headers") or {})
|
5366
|
+
request_kwargs["headers"] = headers
|
5367
|
+
check_for_relogin = self.check_for_relogin
|
5368
|
+
need_to_check = callable(check_for_relogin)
|
5369
|
+
if need_to_check and fetch_cert_headers is None:
|
5370
|
+
if is_open_api:
|
5371
|
+
need_to_check = "authorization" not in headers
|
5372
|
+
else:
|
5373
|
+
need_to_check = "cookie" not in headers
|
5374
|
+
need_fetch_cert_first = False
|
5375
|
+
if fetch_cert_headers is not None:
|
5376
|
+
fetch_cert_headers_argcount = argcount(fetch_cert_headers)
|
5377
|
+
if async_:
|
5378
|
+
fetch_cert_headers = ensure_async(fetch_cert_headers)
|
5379
|
+
if fetch_cert_headers_argcount:
|
5380
|
+
fetch_cert_headers = partial(fetch_cert_headers, async_)
|
5381
|
+
if revert_cert_headers is not None and async_:
|
5382
|
+
revert_cert_headers = ensure_async(revert_cert_headers)
|
5383
|
+
if is_open_api:
|
5384
|
+
need_fetch_cert_first = "authorization" not in headers
|
5385
|
+
else:
|
5386
|
+
need_fetch_cert_first = "cookie" not in headers
|
5264
5387
|
if request is None:
|
5265
5388
|
request_kwargs["session"] = self.async_session if async_ else self.session
|
5266
5389
|
request_kwargs["async_"] = async_
|
5267
|
-
headers: IgnoreCaseDict[str] = IgnoreCaseDict()
|
5268
5390
|
request = get_default_request()
|
5269
5391
|
else:
|
5270
|
-
headers
|
5271
|
-
|
5272
|
-
|
5392
|
+
headers.merge(self.headers)
|
5393
|
+
if is_open_api:
|
5394
|
+
headers["cookie"] = ""
|
5273
5395
|
if m := CRE_API_match(url):
|
5274
5396
|
headers["host"] = m.expand(r"\1.api.115.com")
|
5275
|
-
request_kwargs["headers"] = headers
|
5276
5397
|
if ecdh_encrypt:
|
5277
5398
|
url = make_url(url, _default_k_ec)
|
5278
5399
|
if data:
|
@@ -5284,112 +5405,103 @@ class P115Client(P115OpenClient):
|
|
5284
5405
|
elif data is not None:
|
5285
5406
|
request_kwargs["data"] = data
|
5286
5407
|
request_kwargs.setdefault("parse", default_parse)
|
5287
|
-
use_cookies = not url.startswith("https://proapi.115.com/open/")
|
5288
|
-
if not use_cookies:
|
5289
|
-
headers["cookie"] = ""
|
5290
5408
|
def gen_step():
|
5409
|
+
cert_headers: None | Mapping = None
|
5410
|
+
if need_fetch_cert_first:
|
5411
|
+
cert_headers = yield fetch_cert_headers
|
5412
|
+
headers.update(cert_headers)
|
5291
5413
|
if async_:
|
5292
5414
|
lock: Lock | AsyncLock = self.request_alock
|
5293
5415
|
else:
|
5294
5416
|
lock = self.request_lock
|
5295
|
-
|
5296
|
-
|
5297
|
-
|
5298
|
-
|
5299
|
-
|
5300
|
-
|
5417
|
+
if is_open_api:
|
5418
|
+
if "authorization" not in headers:
|
5419
|
+
yield lock.acquire
|
5420
|
+
try:
|
5421
|
+
yield self.login_another_open(
|
5422
|
+
async_=async_, # type: ignore
|
5423
|
+
)
|
5424
|
+
finally:
|
5425
|
+
lock.release()
|
5426
|
+
elif "cookie" not in headers:
|
5427
|
+
headers["cookie"] = self.cookies_str
|
5301
5428
|
for i in count(0):
|
5302
|
-
exc = None
|
5303
5429
|
try:
|
5304
|
-
if
|
5305
|
-
if
|
5306
|
-
|
5307
|
-
cookies_old = headers["cookie"] = self.cookies_str
|
5430
|
+
if need_fetch_cert_first is None:
|
5431
|
+
if is_open_api:
|
5432
|
+
cert: str = headers["authorization"]
|
5308
5433
|
else:
|
5309
|
-
|
5310
|
-
|
5311
|
-
|
5312
|
-
|
5313
|
-
|
5314
|
-
|
5315
|
-
|
5316
|
-
resp = yield partial(request, url=url, method=method, **request_kwargs)
|
5317
|
-
return resp
|
5434
|
+
cert = headers["cookie"]
|
5435
|
+
resp = yield partial(
|
5436
|
+
cast(Callable, request),
|
5437
|
+
url=url,
|
5438
|
+
method=method,
|
5439
|
+
**request_kwargs,
|
5440
|
+
)
|
5318
5441
|
except BaseException as e:
|
5319
|
-
|
5320
|
-
if
|
5321
|
-
|
5322
|
-
|
5323
|
-
|
5324
|
-
|
5325
|
-
|
5326
|
-
|
5327
|
-
|
5328
|
-
continue
|
5442
|
+
is_auth_error = isinstance(e, (AuthenticationError, LoginError))
|
5443
|
+
if (
|
5444
|
+
cert_headers is not None and
|
5445
|
+
revert_cert_headers is not None and
|
5446
|
+
not is_auth_error and
|
5447
|
+
get_status_code(e) != 405
|
5448
|
+
):
|
5449
|
+
yield partial(revert_cert_headers, cert_headers)
|
5450
|
+
if not need_to_check:
|
5329
5451
|
raise
|
5330
5452
|
res = yield partial(cast(Callable, check_for_relogin), e)
|
5331
5453
|
if not res if isinstance(res, bool) else res != 405:
|
5332
5454
|
raise
|
5333
|
-
if
|
5334
|
-
|
5335
|
-
|
5336
|
-
|
5337
|
-
if not cookies_equal(cookies, cookies_old):
|
5338
|
-
continue
|
5339
|
-
cookies_mtime = getattr(self, "cookies_mtime", 0)
|
5455
|
+
if fetch_cert_headers is not None:
|
5456
|
+
cert_headers = yield fetch_cert_headers
|
5457
|
+
headers.update(cert_headers)
|
5458
|
+
elif is_open_api:
|
5340
5459
|
yield lock.acquire
|
5341
5460
|
try:
|
5342
|
-
|
5343
|
-
|
5344
|
-
if
|
5345
|
-
|
5346
|
-
|
5347
|
-
|
5348
|
-
|
5349
|
-
|
5350
|
-
|
5351
|
-
|
5352
|
-
|
5353
|
-
warn(f"relogin to refresh cookies: UID={uid!r} app={self.login_app()!r}", category=P115Warning)
|
5354
|
-
yield self.login_another_app(
|
5355
|
-
replace=True,
|
5356
|
-
async_=async_, # type: ignore
|
5357
|
-
)
|
5461
|
+
if cert != self.access_token:
|
5462
|
+
continue
|
5463
|
+
if i or is_auth_error:
|
5464
|
+
raise
|
5465
|
+
app_id = getattr(self, "app_id", 100195993)
|
5466
|
+
yield self.login_another_open(
|
5467
|
+
app_id,
|
5468
|
+
replace=True,
|
5469
|
+
async_=async_, # type: ignore
|
5470
|
+
)
|
5471
|
+
warn(f"relogin to refresh token: {app_id=}", category=P115Warning)
|
5358
5472
|
finally:
|
5359
5473
|
lock.release()
|
5360
5474
|
else:
|
5361
|
-
access_token = self.access_token
|
5362
5475
|
yield lock.acquire
|
5363
5476
|
try:
|
5364
|
-
|
5365
|
-
|
5366
|
-
|
5367
|
-
|
5368
|
-
|
5369
|
-
|
5477
|
+
cookies_new: str = self.cookies_str
|
5478
|
+
if cookies_equal(cert, cookies_new):
|
5479
|
+
if self.__dict__.get("cookies_path"):
|
5480
|
+
cookies_new = self._read_cookies() or ""
|
5481
|
+
if not cookies_equal(cert, cookies_new):
|
5482
|
+
headers["cookie"] = cookies_new
|
5483
|
+
continue
|
5484
|
+
if i or is_auth_error:
|
5485
|
+
raise
|
5486
|
+
m = CRE_COOKIES_UID_search(cert)
|
5487
|
+
uid = "" if m is None else m[0]
|
5488
|
+
if not uid:
|
5489
|
+
raise
|
5490
|
+
warn(f"relogin to refresh cookies: UID={uid!r} app={self.login_app()!r}", category=P115Warning)
|
5491
|
+
yield self.login_another_app(
|
5370
5492
|
replace=True,
|
5371
5493
|
async_=async_, # type: ignore
|
5372
5494
|
)
|
5373
|
-
warn(f"relogin to refresh token: {app_id=}", category=P115Warning)
|
5374
5495
|
else:
|
5375
|
-
|
5376
|
-
async_=async_, # type: ignore
|
5377
|
-
)
|
5378
|
-
check_response(resp)
|
5379
|
-
warn("relogin to refresh token (using refresh_token)", category=P115Warning)
|
5496
|
+
headers["cookie"] = cookies_new
|
5380
5497
|
finally:
|
5381
5498
|
lock.release()
|
5382
|
-
|
5383
|
-
if
|
5384
|
-
|
5385
|
-
|
5386
|
-
|
5387
|
-
|
5388
|
-
get_status_code(exc) == 405
|
5389
|
-
)
|
5390
|
-
)
|
5391
|
-
):
|
5392
|
-
yield partial(revert_cookies, cookies_)
|
5499
|
+
else:
|
5500
|
+
if cert_headers is not None and revert_cert_headers is not None:
|
5501
|
+
yield partial(revert_cert_headers, cert_headers)
|
5502
|
+
if check and isinstance(resp, dict):
|
5503
|
+
check_response(resp)
|
5504
|
+
return resp
|
5393
5505
|
return run_gen_step(gen_step, async_=async_)
|
5394
5506
|
|
5395
5507
|
########## Activity API ##########
|
@@ -14179,7 +14291,7 @@ class P115Client(P115OpenClient):
|
|
14179
14291
|
- type: str = "" 💡 操作类型,若不指定则是全部
|
14180
14292
|
|
14181
14293
|
- "upload_image_file": 1 💡 上传图片
|
14182
|
-
- "upload_file": 2 💡
|
14294
|
+
- "upload_file": 2 💡 上传文件或目录(不包括图片)
|
14183
14295
|
- "star_image": 3 💡 给图片设置星标
|
14184
14296
|
- "star_file": 4 💡 给文件或目录设置星标(不包括图片)
|
14185
14297
|
- "move_image_file": 5 💡 移动图片
|
@@ -14250,7 +14362,7 @@ class P115Client(P115OpenClient):
|
|
14250
14362
|
- type: str = "" 💡 操作类型
|
14251
14363
|
|
14252
14364
|
- "upload_image_file": 1 💡 上传图片
|
14253
|
-
- "upload_file": 2 💡
|
14365
|
+
- "upload_file": 2 💡 上传文件或目录(不包括图片)
|
14254
14366
|
- "star_image": 3 💡 给图片设置星标
|
14255
14367
|
- "star_file": 4 💡 给文件或目录设置星标(不包括图片)
|
14256
14368
|
- "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
|
-
|