aioqzone 1.8.0.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.
Files changed (52) hide show
  1. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/PKG-INFO +4 -6
  2. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/pyproject.toml +3 -5
  3. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/api/h5/model.py +1 -1
  4. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/api/login/__init__.py +1 -0
  5. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/model/protocol/config.py +9 -2
  6. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/up/captcha/__init__.py +9 -2
  7. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/up/captcha/capsess.py +4 -2
  8. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/up/web.py +4 -1
  9. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/LICENSE +0 -0
  10. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/README.md +0 -0
  11. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/__init__.py +0 -0
  12. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/api/__init__.py +0 -0
  13. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/api/h5/__init__.py +0 -0
  14. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/api/login/_base.py +0 -0
  15. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/exception.py +0 -0
  16. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/message.py +0 -0
  17. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/model/__init__.py +0 -0
  18. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/model/api/__init__.py +0 -0
  19. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/model/api/feed.py +0 -0
  20. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/model/api/profile.py +0 -0
  21. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/model/api/request.py +0 -0
  22. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/model/api/response.py +0 -0
  23. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/model/protocol/__init__.py +0 -0
  24. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/model/protocol/entity.py +0 -0
  25. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/utils/__init__.py +0 -0
  26. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/utils/entity.py +0 -0
  27. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/utils/regex.py +0 -0
  28. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/utils/retry.py +0 -0
  29. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/aioqzone/utils/time.py +0 -0
  30. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/__init__.py +0 -0
  31. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/base.py +0 -0
  32. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/constant.py +0 -0
  33. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/exception.py +0 -0
  34. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/message.py +0 -0
  35. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/py.typed +0 -0
  36. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/qr/__init__.py +0 -0
  37. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/qr/type.py +0 -0
  38. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/type.py +0 -0
  39. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/up/__init__.py +0 -0
  40. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/up/_model.py +0 -0
  41. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/up/captcha/_model.py +0 -0
  42. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/up/captcha/pil_utils.py +0 -0
  43. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/up/captcha/select/__init__.py +0 -0
  44. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/up/captcha/select/_types.py +0 -0
  45. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/up/captcha/slide/__init__.py +0 -0
  46. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/up/captcha/slide/_types.py +0 -0
  47. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/up/encrypt.py +0 -0
  48. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/up/h5.py +0 -0
  49. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/utils/encrypt.py +0 -0
  50. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/utils/iter.py +0 -0
  51. {aioqzone-1.8.0.dev1 → aioqzone-1.8.2.dev1}/src/qqqr/utils/jsjson.py +0 -0
  52. {aioqzone-1.8.0.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.0.dev1
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
@@ -19,17 +19,15 @@ Classifier: Programming Language :: Python :: 3.11
19
19
  Classifier: Programming Language :: Python :: 3.12
20
20
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
21
  Classifier: Typing :: Typed
22
- Provides-Extra: captcha
22
+ Provides-Extra: slide-captcha
23
23
  Requires-Dist: aiohttp (>=3.8.5,<4.0.0)
24
- Requires-Dist: cssselect (>=1.1.0,<2.0.0)
25
24
  Requires-Dist: exceptiongroup (>=1.1.1,<2.0.0)
26
- Requires-Dist: lxml (>=4.9.1,<5.0.0)
27
25
  Requires-Dist: pillow (>=10.0.1,<11.0.0)
28
- Requires-Dist: pychaosvm (>=0.3.2,<0.4.0)
26
+ Requires-Dist: pychaosvm (>=0.3.4,<0.4.0)
29
27
  Requires-Dist: pydantic (>=2.0.3,<3.0.0)
30
28
  Requires-Dist: pydantic-settings (>=2.0.2,<3.0.0)
31
29
  Requires-Dist: rsa (>=4.8,<5.0)
32
- Requires-Dist: slide-tc (>=0.1.1,<0.2.0) ; extra == "captcha"
30
+ Requires-Dist: slide-tc (>=0.1.1,<0.2.0) ; extra == "slide-captcha"
33
31
  Requires-Dist: tenacity (>=8.2.3,<9.0.0)
34
32
  Requires-Dist: tylisten (>=2.1.3,<3.0.0)
35
33
  Project-URL: Bug Tracker, https://github.com/aioqzone/aioqzone/issues
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "aioqzone"
3
- version = "1.8.0.dev1"
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"
@@ -32,17 +32,15 @@ aiohttp = "^3.8.5"
32
32
  pydantic = "^2.0.3"
33
33
  pydantic-settings = "^2.0.2"
34
34
  rsa = "^4.8"
35
- lxml = "^4.9.1"
36
- cssselect = "^1.1.0"
37
35
  tenacity = "^8.2.3"
38
36
  exceptiongroup = "^1.1.1"
39
37
  tylisten = "^2.1.3"
40
38
  pillow = "^10.0.1"
41
- pychaosvm = { version = "~0.3.2", source = "aioqzone-index" }
39
+ pychaosvm = { version = "~0.3.4", source = "aioqzone-index" }
42
40
  slide-tc = {version = "~0.1.1", optional = true, source = "aioqzone-index" }
43
41
 
44
42
  [tool.poetry.extras]
45
- captcha = ["slide-tc"]
43
+ slide-captcha = ["slide-tc"]
46
44
 
47
45
  # dependency groups
48
46
  [tool.poetry.group.test]
@@ -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
- from typing import Literal, Union
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__(self, client: ClientAdapter, appid: int, xlogin_url: str):
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(self, client: ClientAdapter, ua: t.Optional[str] = None):
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(self.client, self.app.appid, str(self.login_page_url))
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