aioqzone 1.9.5.dev4__tar.gz → 1.9.6.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 (137) hide show
  1. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/PKG-INFO +20 -18
  2. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/README.md +5 -3
  3. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/pyproject.toml +13 -13
  4. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/aioqzone/api/h5/model.py +13 -1
  5. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/aioqzone/model/api/__init__.py +7 -0
  6. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/aioqzone/model/api/feed.py +2 -2
  7. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/aioqzone/model/api/profile.py +14 -17
  8. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/aioqzone/model/api/request.py +13 -1
  9. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/aioqzone/model/api/response.py +9 -9
  10. aioqzone-1.9.5.dev4/.github/dependabot.yml +0 -13
  11. aioqzone-1.9.5.dev4/.github/workflows/auto-pr.yml +0 -37
  12. aioqzone-1.9.5.dev4/.github/workflows/build.yml +0 -36
  13. aioqzone-1.9.5.dev4/.github/workflows/codeql-analysis.yml +0 -59
  14. aioqzone-1.9.5.dev4/.github/workflows/sphinx.yml +0 -69
  15. aioqzone-1.9.5.dev4/.github/workflows/test.yml +0 -52
  16. aioqzone-1.9.5.dev4/.gitignore +0 -28
  17. aioqzone-1.9.5.dev4/.pre-commit-config.yaml +0 -37
  18. aioqzone-1.9.5.dev4/CONTRIBUTING.md +0 -9
  19. aioqzone-1.9.5.dev4/LICENSE +0 -661
  20. aioqzone-1.9.5.dev4/README_en.md +0 -84
  21. aioqzone-1.9.5.dev4/cliff.toml +0 -59
  22. aioqzone-1.9.5.dev4/doc/source/_static/penguin-blob.webp +0 -0
  23. aioqzone-1.9.5.dev4/doc/source/_static/teaencoder.ts +0 -145
  24. aioqzone-1.9.5.dev4/doc/source/aioqzone/api/h5.rst +0 -5
  25. aioqzone-1.9.5.dev4/doc/source/aioqzone/api/index.rst +0 -8
  26. aioqzone-1.9.5.dev4/doc/source/aioqzone/api/login.rst +0 -16
  27. aioqzone-1.9.5.dev4/doc/source/aioqzone/exception.rst +0 -6
  28. aioqzone-1.9.5.dev4/doc/source/aioqzone/index.rst +0 -12
  29. aioqzone-1.9.5.dev4/doc/source/aioqzone/messages.rst +0 -30
  30. aioqzone-1.9.5.dev4/doc/source/aioqzone/model/api.rst +0 -23
  31. aioqzone-1.9.5.dev4/doc/source/aioqzone/model/index.rst +0 -8
  32. aioqzone-1.9.5.dev4/doc/source/aioqzone/model/protocol.rst +0 -26
  33. aioqzone-1.9.5.dev4/doc/source/aioqzone/reference.rst +0 -29
  34. aioqzone-1.9.5.dev4/doc/source/conf.py +0 -79
  35. aioqzone-1.9.5.dev4/doc/source/disclaimers.rst +0 -49
  36. aioqzone-1.9.5.dev4/doc/source/index.rst +0 -37
  37. aioqzone-1.9.5.dev4/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/api/h5.po +0 -255
  38. aioqzone-1.9.5.dev4/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/api/index.po +0 -22
  39. aioqzone-1.9.5.dev4/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/api/login.po +0 -234
  40. aioqzone-1.9.5.dev4/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/api/web.po +0 -488
  41. aioqzone-1.9.5.dev4/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/exception.po +0 -52
  42. aioqzone-1.9.5.dev4/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/index.po +0 -22
  43. aioqzone-1.9.5.dev4/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/messages.po +0 -226
  44. aioqzone-1.9.5.dev4/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/model/api.po +0 -835
  45. aioqzone-1.9.5.dev4/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/model/index.po +0 -24
  46. aioqzone-1.9.5.dev4/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/model/protocol.po +0 -227
  47. aioqzone-1.9.5.dev4/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/model/response.po +0 -1023
  48. aioqzone-1.9.5.dev4/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/reference.po +0 -78
  49. aioqzone-1.9.5.dev4/doc/source/locale/zh_CN/LC_MESSAGES/disclaimers.po +0 -171
  50. aioqzone-1.9.5.dev4/doc/source/locale/zh_CN/LC_MESSAGES/index.po +0 -74
  51. aioqzone-1.9.5.dev4/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/base.po +0 -75
  52. aioqzone-1.9.5.dev4/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/exception.po +0 -78
  53. aioqzone-1.9.5.dev4/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/index.po +0 -61
  54. aioqzone-1.9.5.dev4/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/jsjson.po +0 -134
  55. aioqzone-1.9.5.dev4/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/qr/index.po +0 -22
  56. aioqzone-1.9.5.dev4/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/qr/login.po +0 -257
  57. aioqzone-1.9.5.dev4/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/qr/type.po +0 -70
  58. aioqzone-1.9.5.dev4/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/up/captcha/capsess.po +0 -32
  59. aioqzone-1.9.5.dev4/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/up/captcha/captcha.po +0 -166
  60. aioqzone-1.9.5.dev4/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/up/captcha/index.po +0 -108
  61. aioqzone-1.9.5.dev4/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/up/captcha/jigsaw.po +0 -204
  62. aioqzone-1.9.5.dev4/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/up/encrypt.po +0 -43
  63. aioqzone-1.9.5.dev4/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/up/index.po +0 -26
  64. aioqzone-1.9.5.dev4/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/up/login.po +0 -101
  65. aioqzone-1.9.5.dev4/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/up/type.po +0 -433
  66. aioqzone-1.9.5.dev4/doc/source/locale/zh_CN/LC_MESSAGES/reference.po +0 -77
  67. aioqzone-1.9.5.dev4/doc/source/qqqr/base.rst +0 -7
  68. aioqzone-1.9.5.dev4/doc/source/qqqr/exception.rst +0 -6
  69. aioqzone-1.9.5.dev4/doc/source/qqqr/index.rst +0 -46
  70. aioqzone-1.9.5.dev4/doc/source/qqqr/jsjson.rst +0 -7
  71. aioqzone-1.9.5.dev4/doc/source/qqqr/qr/index.rst +0 -8
  72. aioqzone-1.9.5.dev4/doc/source/qqqr/qr/login.rst +0 -14
  73. aioqzone-1.9.5.dev4/doc/source/qqqr/qr/type.rst +0 -8
  74. aioqzone-1.9.5.dev4/doc/source/qqqr/up/captcha/capsess.rst +0 -14
  75. aioqzone-1.9.5.dev4/doc/source/qqqr/up/captcha/captcha.rst +0 -10
  76. aioqzone-1.9.5.dev4/doc/source/qqqr/up/captcha/index.rst +0 -69
  77. aioqzone-1.9.5.dev4/doc/source/qqqr/up/encrypt.rst +0 -5
  78. aioqzone-1.9.5.dev4/doc/source/qqqr/up/index.rst +0 -19
  79. aioqzone-1.9.5.dev4/doc/source/qqqr/up/login.rst +0 -12
  80. aioqzone-1.9.5.dev4/doc/source/qqqr/up/type.rst +0 -8
  81. aioqzone-1.9.5.dev4/test/api/__init__.py +0 -0
  82. aioqzone-1.9.5.dev4/test/api/conftest.py +0 -55
  83. aioqzone-1.9.5.dev4/test/api/test_h5.py +0 -134
  84. aioqzone-1.9.5.dev4/test/api/test_loginman.py +0 -136
  85. aioqzone-1.9.5.dev4/test/conftest.py +0 -30
  86. aioqzone-1.9.5.dev4/test/login_logic/__init__.py +0 -0
  87. aioqzone-1.9.5.dev4/test/login_logic/test_captcha.py +0 -108
  88. aioqzone-1.9.5.dev4/test/login_logic/test_qr.py +0 -83
  89. aioqzone-1.9.5.dev4/test/login_logic/test_up.py +0 -102
  90. aioqzone-1.9.5.dev4/test/utils/test_entity.py +0 -37
  91. aioqzone-1.9.5.dev4/test/utils/test_json.py +0 -35
  92. aioqzone-1.9.5.dev4/test/utils/test_time.py +0 -11
  93. aioqzone-1.9.5.dev4/uv.lock +0 -2016
  94. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/aioqzone/__init__.py +0 -0
  95. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/aioqzone/api/__init__.py +0 -0
  96. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/aioqzone/api/h5/__init__.py +0 -0
  97. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/aioqzone/api/login/__init__.py +0 -0
  98. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/aioqzone/api/login/_base.py +0 -0
  99. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/aioqzone/exception.py +0 -0
  100. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/aioqzone/message.py +0 -0
  101. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/aioqzone/model/__init__.py +0 -0
  102. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/aioqzone/model/protocol/__init__.py +0 -0
  103. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/aioqzone/model/protocol/config.py +0 -0
  104. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/aioqzone/model/protocol/entity.py +0 -0
  105. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/aioqzone/utils/__init__.py +0 -0
  106. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/aioqzone/utils/entity.py +0 -0
  107. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/aioqzone/utils/regex.py +0 -0
  108. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/aioqzone/utils/retry.py +0 -0
  109. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/aioqzone/utils/time.py +0 -0
  110. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/qqqr/__init__.py +0 -0
  111. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/qqqr/base.py +0 -0
  112. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/qqqr/constant.py +0 -0
  113. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/qqqr/exception.py +0 -0
  114. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/qqqr/message.py +0 -0
  115. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/qqqr/py.typed +0 -0
  116. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/qqqr/qr/__init__.py +0 -0
  117. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/qqqr/qr/type.py +0 -0
  118. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/qqqr/type.py +0 -0
  119. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/qqqr/up/__init__.py +0 -0
  120. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/qqqr/up/_model.py +0 -0
  121. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/qqqr/up/captcha/__init__.py +0 -0
  122. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/qqqr/up/captcha/_model.py +0 -0
  123. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/qqqr/up/captcha/capsess.py +0 -0
  124. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/qqqr/up/captcha/click/__init__.py +0 -0
  125. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/qqqr/up/captcha/click/_types.py +0 -0
  126. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/qqqr/up/captcha/pil_utils.py +0 -0
  127. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/qqqr/up/captcha/select/__init__.py +0 -0
  128. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/qqqr/up/captcha/select/_types.py +0 -0
  129. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/qqqr/up/captcha/slide/__init__.py +0 -0
  130. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/qqqr/up/captcha/slide/_types.py +0 -0
  131. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/qqqr/up/encrypt.py +0 -0
  132. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/qqqr/up/h5.py +0 -0
  133. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/qqqr/up/web.py +0 -0
  134. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/qqqr/utils/encrypt.py +0 -0
  135. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/qqqr/utils/iter.py +0 -0
  136. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/qqqr/utils/jsjson.py +0 -0
  137. {aioqzone-1.9.5.dev4 → aioqzone-1.9.6.dev1}/src/qqqr/utils/net.py +0 -0
@@ -1,32 +1,32 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aioqzone
3
- Version: 1.9.5.dev4
3
+ Version: 1.9.6.dev1
4
4
  Summary: A Python wrapper for Qzone login and H5 APIs.
5
- Project-URL: Homepage, https://github.com/aioqzone/aioqzone
6
- Project-URL: Repository, https://github.com/aioqzone/aioqzone
7
- Project-URL: Documentation, https://aioqzone.github.io/aioqzone
8
- Project-URL: Bug Tracker, https://github.com/aioqzone/aioqzone/issues
9
- Project-URL: Discussion, https://t.me/aioqzone_chatroom
5
+ Keywords: qzone-api,autologin,asyncio-spider
10
6
  Author: aioqzone
11
- Maintainer-email: JamzumSum <22952836+JamzumSum@users.noreply.github.com>
12
7
  License-Expression: AGPL-3.0
13
- License-File: LICENSE
14
- Keywords: asyncio-spider,autologin,qzone-api
15
8
  Classifier: Development Status :: 4 - Beta
16
9
  Classifier: Intended Audience :: Developers
17
10
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
18
11
  Classifier: Typing :: Typed
19
- Requires-Python: >=3.9
20
12
  Requires-Dist: aiohttp>=3.9.0
21
- Requires-Dist: pillow>=10.1.0
22
- Requires-Dist: pychaosvm~=0.4.3
13
+ Requires-Dist: pydantic>=2.12
23
14
  Requires-Dist: pydantic-settings>=2.9.0
24
- Requires-Dist: pydantic>=2.11.4
25
15
  Requires-Dist: rsa>=4.9.1
26
- Requires-Dist: tenacity<10.0.0,>=8.2.3
16
+ Requires-Dist: tenacity>=8.2.3,<10.0.0
27
17
  Requires-Dist: tylisten>=2.2.1
18
+ Requires-Dist: pillow>=11.3.0
19
+ Requires-Dist: pychaosvm~=0.5.4
20
+ Requires-Dist: slide-tc~=0.1.3 ; extra == 'slide-captcha'
21
+ Maintainer: JamzumSum
22
+ Maintainer-email: JamzumSum <22952836+JamzumSum@users.noreply.github.com>
23
+ Requires-Python: >=3.10
24
+ Project-URL: Bug Tracker, https://github.com/aioqzone/aioqzone/issues
25
+ Project-URL: Discussion, https://t.me/aioqzone_chatroom
26
+ Project-URL: Documentation, https://aioqzone.github.io/aioqzone
27
+ Project-URL: Homepage, https://github.com/aioqzone/aioqzone
28
+ Project-URL: Repository, https://github.com/aioqzone/aioqzone
28
29
  Provides-Extra: slide-captcha
29
- Requires-Dist: slide-tc~=0.1.1; extra == 'slide-captcha'
30
30
  Description-Content-Type: text/markdown
31
31
 
32
32
  # aioqzone
@@ -52,14 +52,14 @@ aioqzone封装了一些Qzone接口。
52
52
 
53
53
  - [x] [二维码登录](src/qqqr/qr/)
54
54
  - [x] [密码登录](src/qqqr/up/) (受限)
55
- - [x] [通过滑动验证码](src/qqqr/up/captcha/slide)
55
+ - [x] [通过滑动验证码](src/qqqr/up/captcha/slide) ([slide-tc][slide-tc])
56
56
  - [x] [解析图片选择验证码](src/qqqr/up/captcha/select)
57
57
  - [ ] [通过网络环境检测][pychaosvm]
58
58
  - [x] 爬取HTML说说
59
59
  - [x] 爬取说说详细内容
60
60
  - [x] 点赞/取消赞
61
- - [x] 发布(仅文字)/修改/删除说说
62
- - [x] 发评论
61
+ - [x] 发布/修改/删除说说(图文)
62
+ - [x] 发评论/删评论(图文)
63
63
 
64
64
  ### 为什么选择 aioqzone
65
65
 
@@ -72,6 +72,7 @@ aioqzone封装了一些Qzone接口。
72
72
  __在做了:__
73
73
 
74
74
  - [ ] 完善的测试覆盖
75
+ - [x] [示例代码](https://aioqzone.github.io/aioqzone/examples.html)
75
76
 
76
77
  ## 包描述
77
78
 
@@ -114,5 +115,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
114
115
  [home]: https://github.com/aioqzone/aioqzone "Python wrapper for Qzone web login and Qzone http api"
115
116
  [aioqzone-feed]: https://github.com/aioqzone/aioqzone-feed "aioqzone plugin providing higher level api for processing feed"
116
117
  [pychaosvm]: https://github.com/aioqzone/pychaosvm "A Python envirionment for Tencent ChaosVM."
118
+ [slide-tc]: https://github.com/aioqzone/slide-tc "An aioqzone plugin for solving slide captcha."
117
119
  [pypi]: https://pypi.org/project/aioqzone
118
120
  [org]: https://github.com/aioqzone
@@ -21,14 +21,14 @@ aioqzone封装了一些Qzone接口。
21
21
 
22
22
  - [x] [二维码登录](src/qqqr/qr/)
23
23
  - [x] [密码登录](src/qqqr/up/) (受限)
24
- - [x] [通过滑动验证码](src/qqqr/up/captcha/slide)
24
+ - [x] [通过滑动验证码](src/qqqr/up/captcha/slide) ([slide-tc][slide-tc])
25
25
  - [x] [解析图片选择验证码](src/qqqr/up/captcha/select)
26
26
  - [ ] [通过网络环境检测][pychaosvm]
27
27
  - [x] 爬取HTML说说
28
28
  - [x] 爬取说说详细内容
29
29
  - [x] 点赞/取消赞
30
- - [x] 发布(仅文字)/修改/删除说说
31
- - [x] 发评论
30
+ - [x] 发布/修改/删除说说(图文)
31
+ - [x] 发评论/删评论(图文)
32
32
 
33
33
  ### 为什么选择 aioqzone
34
34
 
@@ -41,6 +41,7 @@ aioqzone封装了一些Qzone接口。
41
41
  __在做了:__
42
42
 
43
43
  - [ ] 完善的测试覆盖
44
+ - [x] [示例代码](https://aioqzone.github.io/aioqzone/examples.html)
44
45
 
45
46
  ## 包描述
46
47
 
@@ -83,5 +84,6 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
83
84
  [home]: https://github.com/aioqzone/aioqzone "Python wrapper for Qzone web login and Qzone http api"
84
85
  [aioqzone-feed]: https://github.com/aioqzone/aioqzone-feed "aioqzone plugin providing higher level api for processing feed"
85
86
  [pychaosvm]: https://github.com/aioqzone/pychaosvm "A Python envirionment for Tencent ChaosVM."
87
+ [slide-tc]: https://github.com/aioqzone/slide-tc "An aioqzone plugin for solving slide captcha."
86
88
  [pypi]: https://pypi.org/project/aioqzone
87
89
  [org]: https://github.com/aioqzone
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "aioqzone"
3
- version = "1.9.5.dev4"
3
+ version = "1.9.6.dev1"
4
4
  description = "A Python wrapper for Qzone login and H5 APIs."
5
5
  authors = [{ name = "aioqzone" }]
6
6
  maintainers = [
@@ -8,7 +8,7 @@ maintainers = [
8
8
  ]
9
9
  license = "AGPL-3.0"
10
10
  readme = "README.md"
11
- requires-python = ">=3.9"
11
+ requires-python = ">=3.10"
12
12
  keywords = ["qzone-api", "autologin", "asyncio-spider"]
13
13
  classifiers = [
14
14
  "Development Status :: 4 - Beta",
@@ -19,14 +19,14 @@ classifiers = [
19
19
 
20
20
  dependencies = [
21
21
  "aiohttp>=3.9.0",
22
- "pydantic>=2.11.4",
22
+ "pydantic>=2.12",
23
23
  "pydantic-settings>=2.9.0",
24
24
  "rsa>=4.9.1",
25
25
  "tenacity>=8.2.3,<10.0.0",
26
26
  # "exceptiongroup>=1.1.1",
27
27
  "tylisten>=2.2.1",
28
- "pillow>=10.1.0",
29
- "pychaosvm~=0.4.3",
28
+ "pillow>=11.3.0",
29
+ "pychaosvm~=0.5.4",
30
30
  ]
31
31
 
32
32
  [project.urls]
@@ -40,16 +40,17 @@ Documentation = "https://aioqzone.github.io/aioqzone"
40
40
  test = ["pytest>=8.2.0", "pytest-asyncio>=1.1,<1.3"]
41
41
  dev = ["pre-commit", "ruff"]
42
42
  doc = [
43
- "Sphinx>=7.0.1; python_version>='3.9' and python_version<'3.11'",
43
+ "Sphinx>=7.0.1; python_version>='3.10' and python_version<'3.11'",
44
44
  "Sphinx>=8.2.0; python_version>='3.11'",
45
45
  "autodoc-pydantic>=2.0.1",
46
46
  "sphinx-autodoc-typehints>=1.19.5",
47
47
  "furo",
48
48
  "sphinx-intl",
49
+ "sphinx-inline-tabs",
49
50
  ]
50
51
 
51
52
  [project.optional-dependencies]
52
- slide-captcha = ["slide-tc~=0.1.1"]
53
+ slide-captcha = ["slide-tc~=0.1.3"]
53
54
 
54
55
  [tool.uv]
55
56
  prerelease = "if-necessary-or-explicit"
@@ -63,12 +64,11 @@ name = "aioqzone-index"
63
64
  url = "https://aioqzone.github.io/aioqzone-index/simple/"
64
65
 
65
66
  [build-system]
66
- requires = ["hatchling"]
67
- build-backend = "hatchling.build"
67
+ requires = ["uv_build"]
68
+ build-backend = "uv_build"
68
69
 
69
- [tool.hatch.build.targets.wheel]
70
- skip-excluded-dirs = true
71
- packages = ["src/aioqzone", "src/qqqr"]
70
+ [tool.uv.build-backend]
71
+ module-name = ["aioqzone", "qqqr"]
72
72
 
73
73
  [tool.pytest.ini_options]
74
74
  pythonpath = "src"
@@ -86,6 +86,6 @@ ignore = [
86
86
  ]
87
87
 
88
88
  [tool.pyright]
89
- pythonVersion = "3.9"
89
+ pythonVersion = "3.10"
90
90
  pythonPlatform = "All"
91
91
  reportIncompatibleVariableOverride = "information"
@@ -291,7 +291,7 @@ class QzoneH5API:
291
291
  .. versionchanged:: 1.8.5
292
292
 
293
293
  In version <= 1.8.4, user is responsible for compressing a image and this api
294
- encode the :obj:`picture` with Base64 and send it to Qzone _ASIS_.
294
+ encode the :obj:`picture` with Base64 and send it to Qzone *ASIS* .
295
295
 
296
296
  Since version 1.8.5, we recognize a compressed image by :obj:`width` and :obj:`height`
297
297
  parameters. If :obj:`width` and :obj:`height` is provided, this API will keep the former
@@ -356,3 +356,15 @@ class QzoneH5API:
356
356
  params=AvatarParams.model_validate(locals()),
357
357
  ),
358
358
  )
359
+
360
+ async def set_top_feed(self, fid: str, set_top: bool = True) -> None:
361
+ """Set or unset a feed to top.
362
+
363
+ :param fid: :term:`fid`
364
+ :param set_top: whether to set top, default to `True`
365
+ """
366
+ await self.call(
367
+ SetTopApi(
368
+ params=SetTopParams.model_validate(locals()),
369
+ )
370
+ )
@@ -146,3 +146,10 @@ class AvatarApi(QzoneApi[AvatarParams, AvatarResponse]):
146
146
  http_method: t.ClassVar[TyHttpMethod] = "GET"
147
147
  host: t.ClassVar[str] = "https://qlogo2.store.qq.com"
148
148
  path: t.ClassVar[str] = "/qzone/{hostuin}/{hostuin}/{size}"
149
+
150
+
151
+ class SetTopApi(QzoneApi[SetTopParams, SingleReturnResp]):
152
+ response: t.ClassVar = SingleReturnResp
153
+ http_method: t.ClassVar[TyHttpMethod] = "POST"
154
+ host: t.ClassVar[str] = "user.qzone.qq.com"
155
+ path: t.ClassVar[str] = "proxy/domain/ic2.qzone.qq.com/cgi-bin/feeds/cgi_settopfeed"
@@ -41,9 +41,9 @@ class ContentCommon(BaseModel):
41
41
 
42
42
 
43
43
  class FeedCommon(ContentCommon):
44
- ugckey: str
44
+ ugckey: str = ""
45
45
  """an underscore-joined string including `uin`, `appid`, `ugcrightkey`"""
46
- ugcrightkey: str
46
+ ugcrightkey: str = ""
47
47
  """an identifier, for most 311 feeds, it equals to cellid (fid)."""
48
48
  right_info: RightInfo = Field(default_factory=RightInfo)
49
49
  wup_feeds_type: int = 0
@@ -4,20 +4,27 @@ Qzone uses different feed schemes for ``/mqzone/profile``. This module patches :
4
4
 
5
5
  import typing as t
6
6
 
7
- from pydantic import AliasPath, BaseModel, Field, HttpUrl, field_validator, model_validator
7
+ from pydantic import (
8
+ AliasPath,
9
+ BaseModel,
10
+ Field,
11
+ HttpUrl,
12
+ field_validator,
13
+ model_validator,
14
+ )
8
15
 
9
16
  from .feed import (
10
17
  CommentItem,
11
18
  FeedComment,
12
- FeedCommon,
13
19
  FeedOperation,
14
20
  FeedPic,
15
21
  FeedSummary,
22
+ FeedVideo,
23
+ HasCommon,
16
24
  HasFid,
17
25
  HasSummary,
18
26
  LikeInfo,
19
27
  PhotoUrls,
20
- RightInfo,
21
28
  Share,
22
29
  UserInfo,
23
30
  Visitor,
@@ -39,20 +46,9 @@ class QzoneProfile(BaseModel):
39
46
  is_concerned: bool = False
40
47
  is_special: int
41
48
 
42
-
43
- class ProfileFeedCommon(FeedCommon):
44
- ugckey: str = ""
45
- ugcrightkey: str = ""
46
- right_info: RightInfo = Field(default_factory=RightInfo)
47
- wup_feeds_type: int = 0
48
-
49
-
50
- class HasCommon(BaseModel):
51
- common: ProfileFeedCommon = Field(validation_alias="comm")
52
-
53
- @property
54
- def abstime(self):
55
- return self.common.time
49
+ vip: int = 0
50
+ viplevel: int = 0
51
+ viptype: int = 0
56
52
 
57
53
 
58
54
  class ProfilePicData(BaseModel):
@@ -68,6 +64,7 @@ class ProfileFeedPic(FeedPic):
68
64
 
69
65
  class HasMedia(BaseModel):
70
66
  pic: t.Optional[ProfileFeedPic] = None
67
+ video: t.Optional[FeedVideo] = None
71
68
 
72
69
 
73
70
  class ProfileLikeInfo(LikeInfo):
@@ -5,7 +5,7 @@ from math import floor
5
5
  from os import PathLike
6
6
  from time import time
7
7
 
8
- from pydantic import BaseModel, Field, HttpUrl, field_serializer, field_validator
8
+ from pydantic import BaseModel, Field, HttpUrl, field_serializer
9
9
  from typing_extensions import Buffer
10
10
 
11
11
  from aioqzone.utils.time import time_ms
@@ -31,6 +31,7 @@ __all__ = [
31
31
  "PhotosPreuploadParams",
32
32
  "UgcRight",
33
33
  "PhotoData",
34
+ "SetTopParams",
34
35
  ]
35
36
 
36
37
 
@@ -292,3 +293,14 @@ class PhotosPreuploadParams(QzoneRequestParams):
292
293
  class AvatarParams(QzoneRequestParams):
293
294
  hostuin: int
294
295
  size: t.Literal[100, 640] = 100
296
+
297
+
298
+ class SetTopParams(QzoneRequestParams):
299
+ fid: str = Field(validation_alias="key")
300
+ set_top: bool = Field(serialization_alias="act")
301
+
302
+ need_change: int = 0
303
+
304
+ @field_serializer("set_top", return_type=str)
305
+ def serialize_set_top(self, set_top: bool) -> str:
306
+ return "set" if set_top else "cancel"
@@ -144,7 +144,7 @@ class IndexPageResp(FeedPageResp):
144
144
  if not scripts:
145
145
  raise TryAgain("script tag not found")
146
146
 
147
- texts: t.List[str] = [s.text for s in scripts]
147
+ texts: t.List[str] = [s.text for s in scripts if s.text]
148
148
  script = firstn(texts, lambda s: "shine0callback" in s)
149
149
  if not script:
150
150
  raise TryAgain("data script not found")
@@ -174,11 +174,11 @@ class QzoneStatistic(BaseModel):
174
174
 
175
175
 
176
176
  class QzoneInfo(QzoneResponse):
177
- count: QzoneStatistic
177
+ count: QzoneStatistic = Field(default_factory=QzoneStatistic)
178
178
  cover: HttpUrl = Field(validation_alias=AliasPath("coverinfo", 0, "cover"))
179
- is_friend: bool
180
- is_hide: int
181
- limit: int
179
+ is_friend: bool = False
180
+ is_hide: int = 0
181
+ limit: int = 0
182
182
  profile: QzoneProfile
183
183
 
184
184
 
@@ -188,7 +188,7 @@ class ProfilePagePesp(QzoneResponse):
188
188
  qzonetoken: str
189
189
 
190
190
  @classmethod
191
- async def response_to_object(cls, response: ClientResponse):
191
+ async def response_to_object(cls, response: ClientResponse) -> StrDict:
192
192
  html = await response.text()
193
193
  scripts: t.List[HtmlElement] = document_fromstring(html).xpath(
194
194
  'body/script[@type="application/javascript"]'
@@ -196,7 +196,7 @@ class ProfilePagePesp(QzoneResponse):
196
196
  if not scripts:
197
197
  raise TryAgain("ProfilePageResponse: script tag not found")
198
198
 
199
- texts: t.List[str] = [s.text for s in scripts]
199
+ texts: t.List[str] = [s.text for s in scripts if s.text]
200
200
  script = firstn(texts, lambda s: "shine0callback" in s)
201
201
  if not script:
202
202
  raise TryAgain("ProfilePageResponse: script tag not found")
@@ -255,7 +255,7 @@ class AddCommentLegacyResp(QzoneResponse):
255
255
  scripts: t.List[HtmlElement] = document_fromstring(html).xpath(
256
256
  'body/script[@type="text/javascript"]'
257
257
  )
258
- texts: t.List[str] = [s.text for s in scripts]
258
+ texts: t.List[str] = [s.text for s in scripts if s.text]
259
259
  script = firstn(texts, lambda s: "frameElement.callback" in s)
260
260
  if not script:
261
261
  raise TryAgain("AddCommentLegacyResponse: script tag not found")
@@ -274,7 +274,7 @@ class DeleteCommentResp(QzoneResponse):
274
274
  scripts: t.List[HtmlElement] = document_fromstring(html).xpath(
275
275
  'body/script[@type="text/javascript"]'
276
276
  )
277
- texts: t.List[str] = [s.text for s in scripts]
277
+ texts: t.List[str] = [s.text for s in scripts if s.text]
278
278
  script = firstn(texts, lambda s: "frameElement.callback" in s)
279
279
  if not script:
280
280
  raise TryAgain("DeleteCommentResponse: script tag not found")
@@ -1,13 +0,0 @@
1
- version: 2
2
- updates:
3
- # Maintain dependencies for GitHub Actions
4
- - package-ecosystem: github-actions
5
- directory: "/"
6
- schedule:
7
- interval: weekly
8
- day: saturday
9
-
10
- - package-ecosystem: uv
11
- directory: "/"
12
- schedule:
13
- interval: daily
@@ -1,37 +0,0 @@
1
- name: Auto PR
2
-
3
- on:
4
- push:
5
- branches:
6
- - dev
7
- - dev/**
8
-
9
- concurrency:
10
- group: ci-${{ github.ref_name }}
11
- cancel-in-progress: true
12
-
13
- env:
14
- target: beta
15
-
16
- jobs:
17
- pr:
18
- name: Open or Edit PR
19
- runs-on: ubuntu-latest
20
- if: "!startsWith(github.event.head_commit.message, '@no-pr')"
21
- permissions:
22
- pull-requests: write
23
- steps:
24
- - uses: actions/checkout@v5
25
- with:
26
- fetch-depth: 0
27
-
28
- - uses: JamzumSum/actions/pr-changelog@master
29
- id: git-cliff
30
- with:
31
- start: ${{ env.target }}
32
-
33
- - name: Push Changelog to PR
34
- uses: JamzumSum/actions/push-pr-body@master
35
- with:
36
- base-branch: ${{ env.target }}
37
- body: ${{ steps.git-cliff.outputs.changelog }}
@@ -1,36 +0,0 @@
1
- # This workflow will install Python dependencies, build and publish this repo to PyPI.
2
-
3
- name: Publish to PyPI
4
-
5
- on:
6
- workflow_dispatch:
7
- pull_request:
8
- types:
9
- - closed
10
- branches:
11
- - "release"
12
- - "release/**"
13
- - "beta"
14
- - "beta/**"
15
-
16
- jobs:
17
- build:
18
- runs-on: ubuntu-latest
19
- if: |
20
- github.event_name == 'workflow_dispatch' ||
21
- contains(github.event.pull_request.labels.*.name, 'release')
22
- steps:
23
- #----------------------------------------------
24
- # check-out repo and set-up python
25
- #----------------------------------------------
26
- - uses: actions/checkout@v5
27
- - uses: astral-sh/setup-uv@v6
28
- #----------------------------------------------
29
- # -------- Build and release ---------
30
- #----------------------------------------------
31
- - name: Build dist and Publish to PyPI
32
- env:
33
- UV_PUBLISH_PASSWORD: ${{ secrets.PYPI_TOKEN }}
34
- run: |
35
- uv build --no-sources
36
- uv publish --username __token__
@@ -1,59 +0,0 @@
1
- # For most projects, this workflow file will not need changing; you simply need
2
- # to commit it to your repository.
3
- #
4
- # You may wish to alter this file to override the set of languages analyzed,
5
- # or to provide custom queries or build logic.
6
- #
7
- # ******** NOTE ********
8
- # We have attempted to detect the languages in your repository. Please check
9
- # the `language` matrix defined below to confirm you have the correct set of
10
- # supported CodeQL languages.
11
- #
12
- name: "CodeQL"
13
-
14
- on:
15
- pull_request:
16
- # The branches below must be a subset of the branches above
17
- branches: [ beta ]
18
- paths:
19
- - "*.py"
20
- schedule:
21
- - cron: '31 23 * * 0/2'
22
-
23
- jobs:
24
- analyze:
25
- name: Analyze
26
- runs-on: ubuntu-latest
27
- permissions:
28
- actions: read
29
- contents: read
30
- security-events: write
31
-
32
- strategy:
33
- fail-fast: false
34
- matrix:
35
- language: [ 'python' ]
36
- # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
37
- # Learn more about CodeQL language support at https://git.io/codeql-language-support
38
-
39
- steps:
40
- - name: Checkout repository
41
- uses: actions/checkout@v5
42
-
43
- # Initializes the CodeQL tools for scanning.
44
- - name: Initialize CodeQL
45
- uses: github/codeql-action/init@v3
46
- with:
47
- languages: ${{ matrix.language }}
48
- # If you wish to specify custom queries, you can do so here or in a config file.
49
- # By default, queries listed here will override any specified in a config file.
50
- # Prefix the list here with "+" to use these queries and those in the config file.
51
- # queries: ./path/to/local/query, your-org/your-repo/queries@main
52
-
53
- - name: Perform CodeQL Analysis
54
- uses: github/codeql-action/analyze@v3
55
-
56
-
57
- concurrency:
58
- group: codeql-${{ github.ref_name }}
59
- cancel-in-progress: true
@@ -1,69 +0,0 @@
1
- name: Sphinx Build and Deploy
2
-
3
- on:
4
- pull_request:
5
- types:
6
- - review_requested
7
- branches:
8
- - beta
9
- push:
10
- branches:
11
- - beta
12
- paths:
13
- - doc/**
14
- - .github/workflows/sphinx.yml
15
-
16
- concurrency:
17
- group: pages
18
- cancel-in-progress: true
19
-
20
- jobs:
21
- sphinx-build:
22
- runs-on: ubuntu-latest
23
- permissions:
24
- contents: read
25
- steps:
26
- - uses: actions/checkout@v5
27
- - uses: actions/configure-pages@v5
28
- - uses: astral-sh/setup-uv@v6
29
- with:
30
- activate-environment: true
31
-
32
- - name: Install Library and Build HTML
33
- run: |
34
- echo "::group::Install Library"
35
- uv sync --no-default-groups --group doc
36
- echo "::endgroup::"
37
-
38
- echo "::group::Build HTML"
39
- uv run sphinx-build doc/source doc/build/html -D release=$(uv version --short)
40
- echo "::endgroup::"
41
-
42
- - name: Fix permissions
43
- run: |
44
- chmod -c -R +rX "doc/build/html/" | while read line; do
45
- echo "::warning title=Invalid file permissions automatically fixed::$line"
46
- done
47
-
48
- - name: Upload artifact
49
- if: github.event_name == 'push'
50
- uses: actions/upload-pages-artifact@v4
51
- with:
52
- path: doc/build/html
53
-
54
- deploy:
55
- if: github.event_name == 'push'
56
- environment:
57
- name: github-pages
58
- url: ${{ steps.deployment.outputs.page_url }}
59
- permissions:
60
- pages: write
61
- id-token: write
62
- runs-on: ubuntu-latest
63
- needs: sphinx-build
64
- outputs:
65
- page_url: ${{ steps.deployment.outputs.page_url }}
66
- steps:
67
- - name: Deploy to GitHub Pages
68
- id: deployment
69
- uses: actions/deploy-pages@v4
@@ -1,52 +0,0 @@
1
- # install dependency and current package
2
- name: Test Poetry Project
3
-
4
- on:
5
- pull_request:
6
- types:
7
- - review_requested
8
- branches:
9
- - beta
10
- - release
11
-
12
- concurrency:
13
- group: test-${{ github.ref_name }}
14
- cancel-in-progress: true
15
-
16
- jobs:
17
- install-test:
18
- runs-on: ubuntu-latest
19
- strategy:
20
- matrix:
21
- python-version: ["3.13", "3.11", "3.10", "3.9"]
22
- steps:
23
- #----------------------------------------------
24
- # check-out repo and set-up python
25
- #----------------------------------------------
26
- - uses: actions/checkout@v5
27
- - uses: astral-sh/setup-uv@v6
28
- with:
29
- python-version: ${{ matrix.python-version }}
30
- activate-environment: true
31
- enable-cache: true
32
-
33
- - name: Install and Test
34
- env:
35
- TEST_UIN: ${{ secrets.TEST_UIN }}
36
- TEST_PASSWORD: ${{ secrets.TEST_PASSWORD }}
37
- run: |
38
- echo "::group::Install Basic Dependencies"
39
- uv sync --no-default-groups --group test
40
- echo "::endgroup::"
41
-
42
- echo "::group::pytest outputs"
43
- uv run pytest test --log-cli-level=WARNING
44
- echo "::endgroup::"
45
-
46
- - name: Request Changes
47
- env:
48
- GH_TOKEN: ${{ secrets.COMMENT_PAT }} # the reviewer PAT
49
- run: |
50
- if [[ $GH_TOKEN != "" ]]; then
51
- gh pr review ${{ github.event.pull_request.number }} -r -b "Some test(s) failed."
52
- fi