aioqzone 1.9.8.dev1__tar.gz → 1.9.9.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.9.8.dev1 → aioqzone-1.9.9.dev1}/PKG-INFO +1 -1
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/pyproject.toml +1 -1
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/aioqzone/api/h5/model.py +26 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/aioqzone/model/api/__init__.py +13 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/aioqzone/model/api/request.py +17 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/aioqzone/model/api/response.py +116 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/README.md +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/aioqzone/__init__.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/aioqzone/api/__init__.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/aioqzone/api/h5/__init__.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/aioqzone/api/login/__init__.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/aioqzone/api/login/_base.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/aioqzone/exception.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/aioqzone/message.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/aioqzone/model/__init__.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/aioqzone/model/api/feed.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/aioqzone/model/api/profile.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/aioqzone/model/protocol/__init__.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/aioqzone/model/protocol/config.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/aioqzone/model/protocol/entity.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/aioqzone/utils/__init__.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/aioqzone/utils/entity.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/aioqzone/utils/regex.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/aioqzone/utils/retry.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/aioqzone/utils/time.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/qqqr/__init__.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/qqqr/base.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/qqqr/constant.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/qqqr/exception.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/qqqr/message.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/qqqr/py.typed +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/qqqr/qr/__init__.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/qqqr/qr/type.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/qqqr/type.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/qqqr/up/__init__.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/qqqr/up/_model.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/qqqr/up/captcha/__init__.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/qqqr/up/captcha/_model.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/qqqr/up/captcha/capsess.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/qqqr/up/captcha/click/__init__.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/qqqr/up/captcha/click/_types.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/qqqr/up/captcha/pil_utils.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/qqqr/up/captcha/select/__init__.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/qqqr/up/captcha/select/_types.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/qqqr/up/captcha/slide/__init__.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/qqqr/up/captcha/slide/_types.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/qqqr/up/encrypt.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/qqqr/up/h5.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/qqqr/up/web.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/qqqr/utils/encrypt.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/qqqr/utils/iter.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/qqqr/utils/jsjson.py +0 -0
- {aioqzone-1.9.8.dev1 → aioqzone-1.9.9.dev1}/src/qqqr/utils/net.py +0 -0
|
@@ -410,3 +410,29 @@ class QzoneH5API:
|
|
|
410
410
|
params=SetTopParams.model_validate(locals()),
|
|
411
411
|
)
|
|
412
412
|
)
|
|
413
|
+
|
|
414
|
+
async def get_visitor(self, page: int = 1) -> VisitorResp:
|
|
415
|
+
"""Get today / total visitor count.
|
|
416
|
+
|
|
417
|
+
:param page: page number
|
|
418
|
+
|
|
419
|
+
.. note::
|
|
420
|
+
|
|
421
|
+
Contributed by hexadecimal233.
|
|
422
|
+
"""
|
|
423
|
+
return await self.call(VisitorApi(params=VisitorParams.model_validate(locals())))
|
|
424
|
+
|
|
425
|
+
async def get_message_board(
|
|
426
|
+
self, hostUin: int, num: int = 10, start: int = 0
|
|
427
|
+
) -> MessageBoardResp:
|
|
428
|
+
"""Get message board messages.
|
|
429
|
+
|
|
430
|
+
:param hostUin: QQ of the profile owner
|
|
431
|
+
:param num: number of messages to fetch
|
|
432
|
+
:param start: start offset
|
|
433
|
+
|
|
434
|
+
.. note::
|
|
435
|
+
|
|
436
|
+
Contributed by hexadecimal233.
|
|
437
|
+
"""
|
|
438
|
+
return await self.call(MessageBoardApi(params=MessageBoardParams.model_validate(locals())))
|
|
@@ -197,3 +197,16 @@ class SetTopApi(QzoneApi[SetTopParams, SingleReturnResp]):
|
|
|
197
197
|
http_method: t.ClassVar[TyHttpMethod] = "POST"
|
|
198
198
|
host: t.ClassVar[str] = "user.qzone.qq.com"
|
|
199
199
|
path: t.ClassVar[str] = "proxy/domain/ic2.qzone.qq.com/cgi-bin/feeds/cgi_settopfeed"
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
class VisitorApi(QzoneApi[VisitorParams, VisitorResp]):
|
|
203
|
+
response: t.ClassVar = VisitorResp
|
|
204
|
+
http_method: t.ClassVar[TyHttpMethod] = "GET"
|
|
205
|
+
path: t.ClassVar[str] = "/proxy/domain/g.qzone.qq.com/cgi-bin/friendshow/cgi_get_visitor_more"
|
|
206
|
+
|
|
207
|
+
|
|
208
|
+
class MessageBoardApi(QzoneApi[MessageBoardParams, MessageBoardResp]):
|
|
209
|
+
response: t.ClassVar = MessageBoardResp
|
|
210
|
+
http_method: t.ClassVar[TyHttpMethod] = "GET"
|
|
211
|
+
host: t.ClassVar[str] = "https://user.qzone.qq.com"
|
|
212
|
+
path: t.ClassVar[str] = "/proxy/domain/m.qzone.qq.com/cgi-bin/new/get_msgb"
|
|
@@ -39,6 +39,8 @@ __all__ = [
|
|
|
39
39
|
"UgcRight",
|
|
40
40
|
"PhotoData",
|
|
41
41
|
"SetTopParams",
|
|
42
|
+
"VisitorParams",
|
|
43
|
+
"MessageBoardParams",
|
|
42
44
|
]
|
|
43
45
|
|
|
44
46
|
|
|
@@ -320,3 +322,18 @@ class SetTopParams(QzoneRequestParams):
|
|
|
320
322
|
@field_serializer("set_top", return_type=str)
|
|
321
323
|
def serialize_set_top(self, set_top: bool) -> str:
|
|
322
324
|
return "set" if set_top else "cancel"
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
class VisitorParams(QzoneRequestParams):
|
|
328
|
+
uin_fields = ("uin",)
|
|
329
|
+
mask: int = 7
|
|
330
|
+
page: int = 1
|
|
331
|
+
fupdate: int = 1
|
|
332
|
+
clear: int = 1
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
class MessageBoardParams(QzoneRequestParams):
|
|
336
|
+
uin_fields = ("uin",)
|
|
337
|
+
hostUin: int
|
|
338
|
+
num: int = 10
|
|
339
|
+
start: int = 0
|
|
@@ -15,6 +15,7 @@ from pydantic import (
|
|
|
15
15
|
AliasChoices,
|
|
16
16
|
AliasPath,
|
|
17
17
|
BaseModel,
|
|
18
|
+
ConfigDict,
|
|
18
19
|
Field,
|
|
19
20
|
HttpUrl,
|
|
20
21
|
TypeAdapter,
|
|
@@ -55,6 +56,14 @@ __all__ = [
|
|
|
55
56
|
"PicInfo",
|
|
56
57
|
"ProfileFeedData",
|
|
57
58
|
"AvatarResponse",
|
|
59
|
+
"VisitorResp",
|
|
60
|
+
"VisitorUser",
|
|
61
|
+
"VisitorItem",
|
|
62
|
+
"ShuoshuoSnapshot",
|
|
63
|
+
"ReplyItem",
|
|
64
|
+
"CommentListItem",
|
|
65
|
+
"AuthorInfo",
|
|
66
|
+
"MessageBoardResp",
|
|
58
67
|
]
|
|
59
68
|
|
|
60
69
|
validate_strdict = TypeAdapter(StrDict).validate_python
|
|
@@ -361,3 +370,110 @@ class AvatarResponse(QzoneResponse):
|
|
|
361
370
|
@classmethod
|
|
362
371
|
async def response_to_object(cls, response: ClientResponse) -> "StrDict":
|
|
363
372
|
return {"avatar": await response.content.read()}
|
|
373
|
+
|
|
374
|
+
|
|
375
|
+
class VisitorUser(BaseModel):
|
|
376
|
+
uin: int
|
|
377
|
+
src: int
|
|
378
|
+
platform_src: int
|
|
379
|
+
service_src: int
|
|
380
|
+
time: int
|
|
381
|
+
hide_from: int
|
|
382
|
+
is_hide_visit: int
|
|
383
|
+
name: str
|
|
384
|
+
yellow: int = -1
|
|
385
|
+
supervip: int = 0
|
|
386
|
+
|
|
387
|
+
|
|
388
|
+
class ShuoshuoSnapshot(BaseModel):
|
|
389
|
+
model_config = ConfigDict(union_mode="left_to_right")
|
|
390
|
+
|
|
391
|
+
id: str
|
|
392
|
+
src: int
|
|
393
|
+
platform_src: int
|
|
394
|
+
service_src: int
|
|
395
|
+
vtime: int
|
|
396
|
+
url: t.Union[HttpUrl, str]
|
|
397
|
+
imgsrc: t.Union[HttpUrl, str]
|
|
398
|
+
name: str
|
|
399
|
+
|
|
400
|
+
|
|
401
|
+
class VisitorItem(BaseModel):
|
|
402
|
+
uin: int
|
|
403
|
+
src: int
|
|
404
|
+
platform_src: int
|
|
405
|
+
service_src: int
|
|
406
|
+
time: int
|
|
407
|
+
hide_from: int
|
|
408
|
+
is_hide_visit: int
|
|
409
|
+
name: str
|
|
410
|
+
yellow: int = -1
|
|
411
|
+
supervip: int = 0
|
|
412
|
+
uins: t.List[VisitorUser] = []
|
|
413
|
+
shuoshuoes: t.List[ShuoshuoSnapshot] = []
|
|
414
|
+
|
|
415
|
+
|
|
416
|
+
class VisitorResp(QzoneResponse):
|
|
417
|
+
Ishost: int = 0
|
|
418
|
+
page: int = 1
|
|
419
|
+
totalpage: int = 1
|
|
420
|
+
todaycount: int = 0
|
|
421
|
+
totalcount: int = 0
|
|
422
|
+
noright_todaycount: int = 0
|
|
423
|
+
noright_totalcount: int = 0
|
|
424
|
+
items: t.List[VisitorItem] = []
|
|
425
|
+
|
|
426
|
+
@classmethod
|
|
427
|
+
async def response_to_object(cls, response: ClientResponse) -> StrDict:
|
|
428
|
+
m = response_callback.search(await response.text())
|
|
429
|
+
if not m:
|
|
430
|
+
raise TryAgain("VisitorResp: callback not found")
|
|
431
|
+
return validate_strdict(json_loads(m.group(1)))
|
|
432
|
+
|
|
433
|
+
|
|
434
|
+
class ReplyItem(BaseModel):
|
|
435
|
+
content: str
|
|
436
|
+
uin: int
|
|
437
|
+
time: int
|
|
438
|
+
nick: str
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
class CommentListItem(BaseModel):
|
|
442
|
+
id: str
|
|
443
|
+
secret: int
|
|
444
|
+
pasterid: str
|
|
445
|
+
bmp: str
|
|
446
|
+
pubtime: str
|
|
447
|
+
modifytime: int
|
|
448
|
+
effect: int
|
|
449
|
+
type: int
|
|
450
|
+
|
|
451
|
+
uin: t.Optional[int] = None
|
|
452
|
+
nickname: t.Optional[str] = None
|
|
453
|
+
capacity: t.Optional[int] = None
|
|
454
|
+
htmlContent: t.Optional[str] = None
|
|
455
|
+
ubbContent: t.Optional[str] = None
|
|
456
|
+
signature: t.Optional[str] = None
|
|
457
|
+
replyList: t.Optional[t.List[ReplyItem]] = Field(default_factory=list)
|
|
458
|
+
|
|
459
|
+
|
|
460
|
+
class AuthorInfo(BaseModel):
|
|
461
|
+
msg: str = ""
|
|
462
|
+
htmlMsg: str = ""
|
|
463
|
+
sign: str = ""
|
|
464
|
+
|
|
465
|
+
|
|
466
|
+
class MessageBoardResp(QzoneResponse):
|
|
467
|
+
auditNum: t.Optional[int] = None
|
|
468
|
+
auditON: t.Optional[int] = None
|
|
469
|
+
|
|
470
|
+
total: int
|
|
471
|
+
authorInfo: AuthorInfo = Field(default_factory=AuthorInfo)
|
|
472
|
+
commentList: t.List[CommentListItem] = Field(default_factory=list)
|
|
473
|
+
|
|
474
|
+
@classmethod
|
|
475
|
+
async def response_to_object(cls, response: ClientResponse) -> StrDict:
|
|
476
|
+
m = response_callback.search(await response.text())
|
|
477
|
+
if not m:
|
|
478
|
+
raise TryAgain("MessageBoardResp: callback not found")
|
|
479
|
+
return validate_strdict(json_loads(m.group(1)))
|
|
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
|
|
File without changes
|