aioqzone 1.8.1.dev1__tar.gz → 1.8.2.dev1__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.
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/PKG-INFO +2 -2
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/pyproject.toml +2 -2
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/api/h5/model.py +1 -1
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/api/login/__init__.py +1 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/model/protocol/config.py +9 -2
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/up/captcha/__init__.py +9 -2
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/up/captcha/capsess.py +4 -2
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/up/web.py +4 -1
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/LICENSE +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/README.md +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/__init__.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/api/__init__.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/api/h5/__init__.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/api/login/_base.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/exception.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/message.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/model/__init__.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/model/api/__init__.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/model/api/feed.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/model/api/profile.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/model/api/request.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/model/api/response.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/model/protocol/__init__.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/model/protocol/entity.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/utils/__init__.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/utils/entity.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/utils/regex.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/utils/retry.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/utils/time.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/__init__.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/base.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/constant.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/exception.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/message.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/py.typed +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/qr/__init__.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/qr/type.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/type.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/up/__init__.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/up/_model.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/up/captcha/_model.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/up/captcha/pil_utils.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/up/captcha/select/__init__.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/up/captcha/select/_types.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/up/captcha/slide/__init__.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/up/captcha/slide/_types.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/up/encrypt.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/up/h5.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/utils/encrypt.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/utils/iter.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/utils/jsjson.py +0 -0
- {aioqzone-1.8.1.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/utils/net.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: aioqzone
|
|
3
|
-
Version: 1.8.
|
|
3
|
+
Version: 1.8.2.dev1
|
|
4
4
|
Summary: A Python wrapper for Qzone login and H5 APIs.
|
|
5
5
|
Home-page: https://github.com/aioqzone/aioqzone
|
|
6
6
|
License: AGPL-3.0
|
|
@@ -23,7 +23,7 @@ Provides-Extra: slide-captcha
|
|
|
23
23
|
Requires-Dist: aiohttp (>=3.8.5,<4.0.0)
|
|
24
24
|
Requires-Dist: exceptiongroup (>=1.1.1,<2.0.0)
|
|
25
25
|
Requires-Dist: pillow (>=10.0.1,<11.0.0)
|
|
26
|
-
Requires-Dist: pychaosvm (>=0.3.
|
|
26
|
+
Requires-Dist: pychaosvm (>=0.3.4,<0.4.0)
|
|
27
27
|
Requires-Dist: pydantic (>=2.0.3,<3.0.0)
|
|
28
28
|
Requires-Dist: pydantic-settings (>=2.0.2,<3.0.0)
|
|
29
29
|
Requires-Dist: rsa (>=4.8,<5.0)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "aioqzone"
|
|
3
|
-
version = "1.8.
|
|
3
|
+
version = "1.8.2.dev1"
|
|
4
4
|
description = "A Python wrapper for Qzone login and H5 APIs."
|
|
5
5
|
authors = ["aioqzone <zzzzss990315@gmail.com>"]
|
|
6
6
|
license = "AGPL-3.0"
|
|
@@ -36,7 +36,7 @@ tenacity = "^8.2.3"
|
|
|
36
36
|
exceptiongroup = "^1.1.1"
|
|
37
37
|
tylisten = "^2.1.3"
|
|
38
38
|
pillow = "^10.0.1"
|
|
39
|
-
pychaosvm = { version = "~0.3.
|
|
39
|
+
pychaosvm = { version = "~0.3.4", source = "aioqzone-index" }
|
|
40
40
|
slide-tc = {version = "~0.1.1", optional = true, source = "aioqzone-index" }
|
|
41
41
|
|
|
42
42
|
[tool.poetry.extras]
|
|
@@ -61,7 +61,7 @@ class QzoneH5API:
|
|
|
61
61
|
async for attempt in self._relogin_retry:
|
|
62
62
|
with attempt:
|
|
63
63
|
if (gtk := self.login.gtk) == 0:
|
|
64
|
-
raise TryAgain
|
|
64
|
+
raise TryAgain("no login state")
|
|
65
65
|
if api.attach_token:
|
|
66
66
|
params["g_tk"] = gtk
|
|
67
67
|
hostuin: int = getattr(api.params, "hostuin", self.login.uin)
|
|
@@ -118,6 +118,7 @@ class UpLoginManager(Loginable):
|
|
|
118
118
|
client=self.client,
|
|
119
119
|
uin=self.config.uin,
|
|
120
120
|
pwd=self.config.pwd.get_secret_value(),
|
|
121
|
+
fake_ip=self.config.fake_ip and str(self.config.fake_ip),
|
|
121
122
|
h5=enable,
|
|
122
123
|
)
|
|
123
124
|
self.sms_code_input = self.uplogin.sms_code_input
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
|
|
1
|
+
import typing as t
|
|
2
|
+
from ipaddress import IPv4Address
|
|
2
3
|
|
|
3
|
-
from pydantic import Field, SecretStr
|
|
4
|
+
from pydantic import AnyUrl, Field, SecretStr
|
|
4
5
|
from pydantic_settings import BaseSettings
|
|
5
6
|
|
|
6
7
|
|
|
@@ -13,6 +14,12 @@ class UpLoginConfig(LoginConfig):
|
|
|
13
14
|
pwd: SecretStr = Field(default="")
|
|
14
15
|
"""User password."""
|
|
15
16
|
|
|
17
|
+
fake_ip: t.Optional[IPv4Address] = None
|
|
18
|
+
"""Fake IP used when collecting network environment.
|
|
19
|
+
|
|
20
|
+
.. versionadded:: 1.8.2
|
|
21
|
+
"""
|
|
22
|
+
|
|
16
23
|
|
|
17
24
|
class QrLoginConfig(LoginConfig):
|
|
18
25
|
max_refresh_times: int = 6
|
|
@@ -52,7 +52,13 @@ class Captcha(_CaptchaHookMixin):
|
|
|
52
52
|
solve_select_captcha: solve_select_captcha.TyInst
|
|
53
53
|
solve_slide_captcha: solve_slide_captcha.TyInst
|
|
54
54
|
|
|
55
|
-
def __init__(
|
|
55
|
+
def __init__(
|
|
56
|
+
self,
|
|
57
|
+
client: ClientAdapter,
|
|
58
|
+
appid: int,
|
|
59
|
+
xlogin_url: str,
|
|
60
|
+
fake_ip: t.Optional[str] = None,
|
|
61
|
+
):
|
|
56
62
|
"""
|
|
57
63
|
:param client: network client
|
|
58
64
|
:param appid: Specify the appid of the application
|
|
@@ -64,6 +70,7 @@ class Captcha(_CaptchaHookMixin):
|
|
|
64
70
|
self.appid = appid
|
|
65
71
|
self.xlogin_url = xlogin_url
|
|
66
72
|
self.client.headers["Referer"] = "https://xui.ptlogin2.qq.com/"
|
|
73
|
+
self.fake_ip = fake_ip
|
|
67
74
|
|
|
68
75
|
@property
|
|
69
76
|
def base64_ua(self):
|
|
@@ -149,7 +156,7 @@ class Captcha(_CaptchaHookMixin):
|
|
|
149
156
|
return await sess.solve_captcha()
|
|
150
157
|
|
|
151
158
|
async def get_tdc_collect(client: ClientAdapter) -> str:
|
|
152
|
-
await sess.get_tdc(client)
|
|
159
|
+
await sess.get_tdc(client, ip=self.fake_ip)
|
|
153
160
|
return unquote(str(sess.tdc.getData(None, True)))
|
|
154
161
|
|
|
155
162
|
ans, collect, _ = await asyncio.gather(
|
|
@@ -70,7 +70,9 @@ class BaseTcaptchaSession(ABC):
|
|
|
70
70
|
def _vmslide_js_url(self):
|
|
71
71
|
raise NotImplementedError
|
|
72
72
|
|
|
73
|
-
async def get_tdc(
|
|
73
|
+
async def get_tdc(
|
|
74
|
+
self, client: ClientAdapter, ua: t.Optional[str] = None, ip: t.Optional[str] = None
|
|
75
|
+
):
|
|
74
76
|
"""
|
|
75
77
|
.. note:: If :obj:`.mouse_track` should be set, set it before calling this method.
|
|
76
78
|
"""
|
|
@@ -80,7 +82,7 @@ class BaseTcaptchaSession(ABC):
|
|
|
80
82
|
r.raise_for_status()
|
|
81
83
|
self.tdc = prepare(
|
|
82
84
|
await r.text("utf8"),
|
|
83
|
-
ip=self.prehandle.uip,
|
|
85
|
+
ip=ip or self.prehandle.uip,
|
|
84
86
|
ua=ua or client.headers["User-Agent"],
|
|
85
87
|
mouse_track=await self.mouse_track,
|
|
86
88
|
)
|
|
@@ -123,11 +123,14 @@ class UpWebLogin(LoginBase[UpWebSession], _UpHookMixin):
|
|
|
123
123
|
app: t.Optional[APPID] = None,
|
|
124
124
|
proxy: t.Optional[Proxy] = None,
|
|
125
125
|
info: t.Optional[PT_QR_APP] = None,
|
|
126
|
+
fake_ip: t.Optional[str] = None,
|
|
126
127
|
):
|
|
127
128
|
super().__init__(client, uin=uin, h5=h5, app=app, proxy=proxy, info=info)
|
|
128
129
|
self.pwd = pwd
|
|
129
130
|
self.pwder = TeaEncoder(pwd)
|
|
130
|
-
self.captcha = Captcha(
|
|
131
|
+
self.captcha = Captcha(
|
|
132
|
+
self.client, self.app.appid, str(self.login_page_url), fake_ip=fake_ip
|
|
133
|
+
)
|
|
131
134
|
|
|
132
135
|
async def new(self):
|
|
133
136
|
"""Create a :class:`UpWebSession`. This will call `check` api of Qzone, and receive result
|
|
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
|
|
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
|