aioqzone 1.8.3.dev1__tar.gz → 1.8.4.dev3__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.3.dev1 → aioqzone-1.8.4.dev3}/PKG-INFO +1 -1
  2. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/pyproject.toml +1 -1
  3. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/model/api/request.py +6 -3
  4. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/model/api/response.py +21 -16
  5. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/utils/regex.py +1 -1
  6. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/up/web.py +2 -7
  7. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/LICENSE +0 -0
  8. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/README.md +0 -0
  9. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/__init__.py +0 -0
  10. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/api/__init__.py +0 -0
  11. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/api/h5/__init__.py +0 -0
  12. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/api/h5/model.py +0 -0
  13. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/api/login/__init__.py +0 -0
  14. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/api/login/_base.py +0 -0
  15. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/exception.py +0 -0
  16. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/message.py +0 -0
  17. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/model/__init__.py +0 -0
  18. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/model/api/__init__.py +0 -0
  19. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/model/api/feed.py +0 -0
  20. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/model/api/profile.py +0 -0
  21. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/model/protocol/__init__.py +0 -0
  22. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/model/protocol/config.py +0 -0
  23. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/model/protocol/entity.py +0 -0
  24. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/utils/__init__.py +0 -0
  25. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/utils/entity.py +0 -0
  26. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/utils/retry.py +0 -0
  27. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/utils/time.py +0 -0
  28. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/__init__.py +0 -0
  29. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/base.py +0 -0
  30. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/constant.py +0 -0
  31. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/exception.py +0 -0
  32. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/message.py +0 -0
  33. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/py.typed +0 -0
  34. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/qr/__init__.py +0 -0
  35. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/qr/type.py +0 -0
  36. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/type.py +0 -0
  37. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/up/__init__.py +0 -0
  38. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/up/_model.py +0 -0
  39. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/up/captcha/__init__.py +0 -0
  40. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/up/captcha/_model.py +0 -0
  41. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/up/captcha/capsess.py +0 -0
  42. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/up/captcha/pil_utils.py +0 -0
  43. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/up/captcha/select/__init__.py +0 -0
  44. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/up/captcha/select/_types.py +0 -0
  45. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/up/captcha/slide/__init__.py +0 -0
  46. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/up/captcha/slide/_types.py +0 -0
  47. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/up/encrypt.py +0 -0
  48. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/up/h5.py +0 -0
  49. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/utils/encrypt.py +0 -0
  50. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/utils/iter.py +0 -0
  51. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/utils/jsjson.py +0 -0
  52. {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/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.dev1
3
+ Version: 1.8.4.dev3
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
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "aioqzone"
3
- version = "1.8.3.dev1"
3
+ version = "1.8.4.dev3"
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"
@@ -3,8 +3,7 @@ from base64 import b64encode
3
3
  from math import floor
4
4
  from time import time
5
5
 
6
- from pydantic import Base64Encoder, BaseModel, EncodedBytes, Field, field_serializer
7
- from typing_extensions import Annotated
6
+ from pydantic import BaseModel, Field, field_serializer
8
7
 
9
8
  from aioqzone.utils.time import time_ms
10
9
 
@@ -164,7 +163,7 @@ class DeleteUgcParams(QzoneRequestParams):
164
163
 
165
164
  class UploadPicParams(QzoneRequestParams):
166
165
  uin_fields = ("uin",)
167
- picture: Annotated[bytes, EncodedBytes(Base64Encoder)]
166
+ picture: bytes
168
167
  hd_height: int
169
168
  hd_width: int
170
169
  hd_quality: int = 70
@@ -180,6 +179,10 @@ class UploadPicParams(QzoneRequestParams):
180
179
  Exif_CameraModel: str = ""
181
180
  Exif_Time: str = ""
182
181
 
182
+ @field_serializer("picture", return_type=str)
183
+ def b64_picture(self, picture: t.ByteString) -> str:
184
+ return b64encode(picture).decode()
185
+
183
186
 
184
187
  class PhotosPreuploadParams(QzoneRequestParams):
185
188
  uin_fields = ("uin",)
@@ -39,7 +39,7 @@ __all__ = [
39
39
 
40
40
  class QzoneResponse(BaseModel):
41
41
  _errno_key: t.ClassVar[t.Union[str, AliasPath, AliasChoices, None]] = AliasChoices(
42
- "code", "ret", "err"
42
+ "code", "ret", "err", "error"
43
43
  )
44
44
  _msg_key: t.ClassVar[t.Union[str, AliasPath, AliasChoices, None]] = AliasChoices(
45
45
  "message", "msg"
@@ -55,18 +55,17 @@ class QzoneResponse(BaseModel):
55
55
 
56
56
  :return: Self
57
57
  """
58
- if cls._errno_key and cls._msg_key:
59
58
 
60
- class response_header(BaseModel):
61
- status: int = Field(validation_alias=cls._errno_key)
62
- message: str = Field(default="", validation_alias=cls._msg_key)
59
+ class response_header(BaseModel):
60
+ status: int = Field(default=0, validation_alias=cls._errno_key)
61
+ message: str = Field(default="", validation_alias=cls._msg_key)
63
62
 
64
- header = response_header.model_validate(obj)
65
- if header.status != 0:
66
- if header.message:
67
- raise QzoneError(header.status, header.message, robj=header)
68
- else:
69
- raise QzoneError(header.status, robj=header)
63
+ header = response_header.model_validate(obj)
64
+ if header.status != 0:
65
+ if header.message:
66
+ raise QzoneError(header.status, header.message, robj=obj)
67
+ else:
68
+ raise QzoneError(header.status, robj=obj)
70
69
 
71
70
  if cls._data_key is None:
72
71
  return cls.model_validate(obj)
@@ -208,7 +207,7 @@ class ProfilePagePesp(QzoneResponse):
208
207
  return cls(
209
208
  info=QzoneInfo.from_response_object(obj["info"]), # type: ignore
210
209
  feedpage=ProfileResp.from_response_object(obj["feedpage"]), # type: ignore
211
- qzonetoken=obj["qzonetoken"],
210
+ qzonetoken=obj["qzonetoken"], # type: ignore
212
211
  )
213
212
 
214
213
 
@@ -239,7 +238,8 @@ class DeleteUgcResp(QzoneResponse):
239
238
 
240
239
 
241
240
  class UploadPicResponse(QzoneResponse):
242
- _errno_key = None
241
+ _data_key = None
242
+
243
243
  filelen: int
244
244
  filemd5: str
245
245
 
@@ -250,7 +250,9 @@ class UploadPicResponse(QzoneResponse):
250
250
  return json_loads(m.group(1))
251
251
 
252
252
 
253
- class PicInfo(BaseModel):
253
+ class PicInfo(QzoneResponse):
254
+ _data_key = None
255
+
254
256
  pre: HttpUrl
255
257
  url: HttpUrl
256
258
  sloc: str
@@ -261,11 +263,14 @@ class PicInfo(BaseModel):
261
263
 
262
264
 
263
265
  class PhotosPreuploadResponse(QzoneResponse):
264
- _errno_key = None
266
+ _data_key = None
265
267
  photos: t.List[PicInfo] = Field(default_factory=list)
266
268
 
267
269
  @classmethod
268
270
  async def response_to_object(cls, response: ClientResponse):
269
271
  m = response_callback.search(await response.text())
270
272
  assert m
271
- return dict(photos=json_loads(m.group(1)))
273
+
274
+ picinfos = json_loads(m.group(1))
275
+ assert isinstance(picinfos, list)
276
+ return dict(photos=[PicInfo.from_response_object(info["picinfo"]) for info in picinfos])
@@ -5,7 +5,7 @@ some patterns for matching html and so on.
5
5
  import re
6
6
 
7
7
  # use this to match qzone api response
8
- response_callback = re.compile(r"callback\(\s*(\{.*\})\s*\)", re.S | re.I)
8
+ response_callback = re.compile(r"callback\(\s*([\{\[].*[\}\]])\s*\)", re.S | re.I)
9
9
  # use this to get unikey & curkey of a html
10
10
  uni_cur_key = re.compile(r'data-unikey="([^"]*)"[^d]*data-curkey="([^"]*)"')
11
11
 
@@ -104,15 +104,10 @@ class _UpHookMixin:
104
104
 
105
105
  class UpWebLogin(LoginBase[UpWebSession], _UpHookMixin):
106
106
  """
107
- .. versionchanged:: 0.12.4
108
-
109
- `TeaEncoder` is used as the default password encoder. A `legacy_encoder` paramater is added to force
110
- using the former `NodeEncoder`. It can also be configured by set :envvar:`AIOQZONE_PWDENCODER` to "node".
111
- Note that the paramater in code, i.e. `legacy_encoder`, takes precedence.
112
-
113
107
  .. versionchanged:: 0.13.0.dev1
114
108
 
115
- `TeaEncoder` is the only encoder. ``NodeEncoder`` is removed.
109
+ :class:`~qqqr.up.encrypt.TeaEncoder` is the unique :class:`~qqqr.up.encrypt.PasswdEncoder`.
110
+ ``NodeEncoder`` is removed.
116
111
  """
117
112
 
118
113
  def __init__(
File without changes
File without changes