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.
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/PKG-INFO +1 -1
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/pyproject.toml +1 -1
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/model/api/request.py +6 -3
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/model/api/response.py +21 -16
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/utils/regex.py +1 -1
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/up/web.py +2 -7
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/LICENSE +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/README.md +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/__init__.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/api/__init__.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/api/h5/__init__.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/api/h5/model.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/api/login/__init__.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/api/login/_base.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/exception.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/message.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/model/__init__.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/model/api/__init__.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/model/api/feed.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/model/api/profile.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/model/protocol/__init__.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/model/protocol/config.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/model/protocol/entity.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/utils/__init__.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/utils/entity.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/utils/retry.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/aioqzone/utils/time.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/__init__.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/base.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/constant.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/exception.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/message.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/py.typed +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/qr/__init__.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/qr/type.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/type.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/up/__init__.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/up/_model.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/up/captcha/__init__.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/up/captcha/_model.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/up/captcha/capsess.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/up/captcha/pil_utils.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/up/captcha/select/__init__.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/up/captcha/select/_types.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/up/captcha/slide/__init__.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/up/captcha/slide/_types.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/up/encrypt.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/up/h5.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/utils/encrypt.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/utils/iter.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/utils/jsjson.py +0 -0
- {aioqzone-1.8.3.dev1 → aioqzone-1.8.4.dev3}/src/qqqr/utils/net.py +0 -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
|
|
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:
|
|
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
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
-
|
|
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*(\{
|
|
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
|
-
|
|
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
|
|
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
|