aioqzone 1.9.5.dev4__tar.gz → 1.9.5.dev6__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 (139) hide show
  1. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/.github/workflows/sphinx.yml +8 -5
  2. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/.pre-commit-config.yaml +3 -3
  3. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/PKG-INFO +6 -4
  4. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/README.md +5 -3
  5. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/README_en.md +6 -4
  6. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/conf.py +2 -0
  7. aioqzone-1.9.5.dev6/doc/source/examples.rst +327 -0
  8. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/index.rst +1 -0
  9. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/api/h5.po +113 -19
  10. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/api/login.po +56 -40
  11. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/model/api.po +249 -51
  12. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/model/protocol.po +10 -5
  13. aioqzone-1.9.5.dev6/doc/source/locale/zh_CN/LC_MESSAGES/examples.po +232 -0
  14. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/jsjson.po +39 -16
  15. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/qr/type.po +16 -13
  16. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/up/type.po +45 -25
  17. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/pyproject.toml +2 -1
  18. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/api/h5/model.py +1 -1
  19. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/model/api/feed.py +2 -2
  20. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/model/api/profile.py +14 -17
  21. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/model/api/response.py +4 -4
  22. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/uv.lock +17 -1
  23. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/.github/dependabot.yml +0 -0
  24. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/.github/workflows/auto-pr.yml +0 -0
  25. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/.github/workflows/build.yml +0 -0
  26. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/.github/workflows/codeql-analysis.yml +0 -0
  27. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/.github/workflows/test.yml +0 -0
  28. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/.gitignore +0 -0
  29. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/CONTRIBUTING.md +0 -0
  30. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/LICENSE +0 -0
  31. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/cliff.toml +0 -0
  32. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/_static/penguin-blob.webp +0 -0
  33. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/_static/teaencoder.ts +0 -0
  34. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/aioqzone/api/h5.rst +0 -0
  35. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/aioqzone/api/index.rst +0 -0
  36. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/aioqzone/api/login.rst +0 -0
  37. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/aioqzone/exception.rst +0 -0
  38. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/aioqzone/index.rst +0 -0
  39. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/aioqzone/messages.rst +0 -0
  40. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/aioqzone/model/api.rst +0 -0
  41. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/aioqzone/model/index.rst +0 -0
  42. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/aioqzone/model/protocol.rst +0 -0
  43. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/aioqzone/reference.rst +0 -0
  44. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/disclaimers.rst +0 -0
  45. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/api/index.po +0 -0
  46. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/api/web.po +0 -0
  47. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/exception.po +0 -0
  48. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/index.po +0 -0
  49. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/messages.po +0 -0
  50. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/model/index.po +0 -0
  51. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/model/response.po +0 -0
  52. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/reference.po +0 -0
  53. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/disclaimers.po +0 -0
  54. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/index.po +0 -0
  55. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/base.po +0 -0
  56. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/exception.po +0 -0
  57. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/index.po +0 -0
  58. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/qr/index.po +0 -0
  59. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/qr/login.po +0 -0
  60. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/up/captcha/capsess.po +0 -0
  61. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/up/captcha/captcha.po +0 -0
  62. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/up/captcha/index.po +0 -0
  63. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/up/captcha/jigsaw.po +0 -0
  64. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/up/encrypt.po +0 -0
  65. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/up/index.po +0 -0
  66. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/up/login.po +0 -0
  67. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/reference.po +0 -0
  68. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/qqqr/base.rst +0 -0
  69. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/qqqr/exception.rst +0 -0
  70. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/qqqr/index.rst +0 -0
  71. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/qqqr/jsjson.rst +0 -0
  72. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/qqqr/qr/index.rst +0 -0
  73. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/qqqr/qr/login.rst +0 -0
  74. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/qqqr/qr/type.rst +0 -0
  75. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/qqqr/up/captcha/capsess.rst +0 -0
  76. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/qqqr/up/captcha/captcha.rst +0 -0
  77. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/qqqr/up/captcha/index.rst +0 -0
  78. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/qqqr/up/encrypt.rst +0 -0
  79. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/qqqr/up/index.rst +0 -0
  80. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/qqqr/up/login.rst +0 -0
  81. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/qqqr/up/type.rst +0 -0
  82. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/__init__.py +0 -0
  83. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/api/__init__.py +0 -0
  84. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/api/h5/__init__.py +0 -0
  85. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/api/login/__init__.py +0 -0
  86. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/api/login/_base.py +0 -0
  87. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/exception.py +0 -0
  88. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/message.py +0 -0
  89. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/model/__init__.py +0 -0
  90. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/model/api/__init__.py +0 -0
  91. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/model/api/request.py +0 -0
  92. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/model/protocol/__init__.py +0 -0
  93. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/model/protocol/config.py +0 -0
  94. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/model/protocol/entity.py +0 -0
  95. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/utils/__init__.py +0 -0
  96. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/utils/entity.py +0 -0
  97. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/utils/regex.py +0 -0
  98. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/utils/retry.py +0 -0
  99. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/utils/time.py +0 -0
  100. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/__init__.py +0 -0
  101. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/base.py +0 -0
  102. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/constant.py +0 -0
  103. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/exception.py +0 -0
  104. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/message.py +0 -0
  105. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/py.typed +0 -0
  106. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/qr/__init__.py +0 -0
  107. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/qr/type.py +0 -0
  108. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/type.py +0 -0
  109. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/up/__init__.py +0 -0
  110. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/up/_model.py +0 -0
  111. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/up/captcha/__init__.py +0 -0
  112. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/up/captcha/_model.py +0 -0
  113. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/up/captcha/capsess.py +0 -0
  114. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/up/captcha/click/__init__.py +0 -0
  115. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/up/captcha/click/_types.py +0 -0
  116. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/up/captcha/pil_utils.py +0 -0
  117. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/up/captcha/select/__init__.py +0 -0
  118. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/up/captcha/select/_types.py +0 -0
  119. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/up/captcha/slide/__init__.py +0 -0
  120. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/up/captcha/slide/_types.py +0 -0
  121. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/up/encrypt.py +0 -0
  122. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/up/h5.py +0 -0
  123. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/up/web.py +0 -0
  124. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/utils/encrypt.py +0 -0
  125. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/utils/iter.py +0 -0
  126. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/utils/jsjson.py +0 -0
  127. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/utils/net.py +0 -0
  128. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/test/api/__init__.py +0 -0
  129. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/test/api/conftest.py +0 -0
  130. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/test/api/test_h5.py +0 -0
  131. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/test/api/test_loginman.py +0 -0
  132. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/test/conftest.py +0 -0
  133. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/test/login_logic/__init__.py +0 -0
  134. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/test/login_logic/test_captcha.py +0 -0
  135. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/test/login_logic/test_qr.py +0 -0
  136. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/test/login_logic/test_up.py +0 -0
  137. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/test/utils/test_entity.py +0 -0
  138. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/test/utils/test_json.py +0 -0
  139. {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/test/utils/test_time.py +0 -0
@@ -1,12 +1,11 @@
1
1
  name: Sphinx Build and Deploy
2
2
 
3
3
  on:
4
+ workflow_dispatch:
4
5
  pull_request:
5
6
  types:
6
7
  - review_requested
7
- branches:
8
- - beta
9
- push:
8
+ - closed
10
9
  branches:
11
10
  - beta
12
11
  paths:
@@ -46,13 +45,17 @@ jobs:
46
45
  done
47
46
 
48
47
  - name: Upload artifact
49
- if: github.event_name == 'push'
48
+ if: |
49
+ github.event_name == 'workflow_dispatch' ||
50
+ (github.event_name == 'pull_request' && github.event.action == 'closed')
50
51
  uses: actions/upload-pages-artifact@v4
51
52
  with:
52
53
  path: doc/build/html
53
54
 
54
55
  deploy:
55
- if: github.event_name == 'push'
56
+ if: |
57
+ github.event_name == 'workflow_dispatch' ||
58
+ (github.event_name == 'pull_request' && github.event.action == 'closed')
56
59
  environment:
57
60
  name: github-pages
58
61
  url: ${{ steps.deployment.outputs.page_url }}
@@ -17,19 +17,19 @@ repos:
17
17
  hooks:
18
18
  - id: isort
19
19
  name: sort imports
20
- entry: uv run ruff check --select I --fix
20
+ entry: uv run --active ruff check --select I --fix
21
21
  pass_filenames: false
22
22
  language: system
23
23
  types: [python]
24
24
  - id: black
25
25
  name: format
26
- entry: uv run ruff format
26
+ entry: uv run --active ruff format
27
27
  pass_filenames: false
28
28
  language: system
29
29
  types: [python]
30
30
  - id: pytest
31
31
  name: pytest-check
32
- entry: uv run pytest test
32
+ entry: uv run --active pytest test
33
33
  language: system
34
34
  pass_filenames: false
35
35
  types: [python, toml]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aioqzone
3
- Version: 1.9.5.dev4
3
+ Version: 1.9.5.dev6
4
4
  Summary: A Python wrapper for Qzone login and H5 APIs.
5
5
  Project-URL: Homepage, https://github.com/aioqzone/aioqzone
6
6
  Project-URL: Repository, https://github.com/aioqzone/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
@@ -18,14 +18,14 @@ English | [简体中文](README.md)
18
18
 
19
19
  - [x] [QR login](src/qqqr/qr/)
20
20
  - [x] [password login](src/qqqr/up/) (limited)
21
- - [x] [solve slide captcha](src/qqqr/up/captcha/slide)
21
+ - [x] [solve slide captcha](src/qqqr/up/captcha/slide) ([slide-tc][slide-tc])
22
22
  - [x] [parse select captcha](src/qqqr/up/captcha/select)
23
23
  - [ ] [pass network environment verification][pychaosvm]
24
24
  - [x] get complete html feeds
25
25
  - [x] get feed details
26
26
  - [x] like/unlike app
27
- - [x] publish/update/delete text feeds
28
- - [x] add comment
27
+ - [x] publish/update/delete feeds (w/ photos)
28
+ - [x] add/delete comment (w/ photos)
29
29
 
30
30
  ### Why using this package?
31
31
 
@@ -38,6 +38,7 @@ English | [简体中文](README.md)
38
38
  __Working On:__
39
39
 
40
40
  - [ ] test coverage
41
+ - [x] [example snippets](https://aioqzone.github.io/aioqzone/examples.html)
41
42
 
42
43
  ## Description
43
44
 
@@ -81,4 +82,5 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
81
82
  [home]: https://github.com/aioqzone/aioqzone "Python wrapper for Qzone web login and Qzone http api"
82
83
  [aioqzone-feed]: https://github.com/aioqzone/aioqzone-feed "aioqzone plugin providing higher level api for processing feed"
83
84
  [pychaosvm]: https://github.com/aioqzone/pychaosvm "A Python envirionment for Tencent ChaosVM."
84
- [pypi]: https://pypi.org/project/aioqzone
85
+ [pypi]: https://pypi.org[slide-tc]: https://github.com/aioqzone/slide-tc "An aioqzone plugin for solving slide captcha."
86
+ /project/aioqzone
@@ -36,6 +36,8 @@ extensions = [
36
36
  "sphinx.ext.autodoc",
37
37
  "sphinx_autodoc_typehints",
38
38
  "sphinx.ext.githubpages",
39
+ "sphinx_inline_tabs",
40
+ "sphinx.ext.todo",
39
41
  ]
40
42
 
41
43
  # Add any paths that contain templates here, relative to this directory.
@@ -0,0 +1,327 @@
1
+ ============================
2
+ Examples
3
+ ============================
4
+
5
+ This page provides a collection of examples of aioqzone usage.
6
+
7
+ Login
8
+ ============================
9
+
10
+ .. tab:: QR code login
11
+
12
+ .. code-block:: python
13
+
14
+ from aioqzone.api import QrLoginConfig, QrLoginManager
15
+ from qqqr.utils.net import ClientAdapter
16
+
17
+ with ClientAdapter() as client:
18
+ mgr = QrLoginManager(client, config=QrLoginConfig(uin=env.uin))
19
+
20
+ User-Agent is automatically set when login.
21
+
22
+ .. tab:: uin-password login
23
+
24
+ .. code-block:: python
25
+
26
+ from aioqzone.api import UpLoginConfig, UpLoginManager
27
+ from qqqr.utils.net import ClientAdapter
28
+
29
+ with ClientAdapter() as client:
30
+ mgr = UpLoginManager(
31
+ client,
32
+ config=UpLoginConfig.model_validate(
33
+ dict(uin=env.uin, pwd=env.password, fake_ip="8.8.8.8")
34
+ ),
35
+ )
36
+
37
+ User-Agent is automatically set when login.
38
+
39
+ .. tab:: external cookie login
40
+
41
+ You can surely disable auto login and use external cookie:
42
+
43
+ .. code-block:: python
44
+
45
+ import json
46
+ from os import environ
47
+
48
+ from aioqzone.api.login import ConstLoginMan
49
+ from qqqr.utils.net import ClientAdapter
50
+
51
+ with open("your_external_cookie.json") as f:
52
+ cookie = json.load(f)
53
+ with ClientAdapter() as client:
54
+ mgr = ConstLoginMan(cookie)
55
+
56
+ User-Agent is **NOT** automatically set, remember to change it:
57
+
58
+ .. code-block:: python
59
+
60
+ from qqqr.utils.net import ClientAdapter
61
+ from qqqr.utils.net import use_mobile_ua
62
+
63
+ with ClientAdapter() as client:
64
+ use_mobile_ua(client)
65
+
66
+ ...
67
+
68
+ If you'd like to use external cookie with auto login, just assign cookie dict to login manager:
69
+
70
+ .. code-block:: python
71
+
72
+ import json
73
+ from os import environ
74
+
75
+ from aioqzone.api.login import QrLoginManager
76
+ from qqqr.utils.net import ClientAdapter
77
+
78
+ with open("your_external_cookie.json") as f:
79
+ cookie = json.load(f)
80
+ with ClientAdapter() as client:
81
+ mgr = QrLoginManager(client, config=QrLoginConfig(uin=env.uin))
82
+ mgr.cookie = cookie # assign external cookie to login manager
83
+
84
+ Receiving Messages from Login Manager
85
+ ----------------------------------------------
86
+
87
+ .. seealso:: :doc:`/aioqzone/messages`
88
+
89
+ You can receive QR code image from QR code login manager:
90
+
91
+ .. code-block:: python
92
+
93
+ import io
94
+
95
+ from PIL import Image as image
96
+
97
+ man = QrLoginManager(client, config=QrLoginConfig(uin=env.uin))
98
+ man.qr_fetched.add_impl(
99
+ lambda png, times, qr_renew=False: image.open(io.BytesIO(png)).show() if png else None
100
+ )
101
+
102
+ .. todo:: other messages
103
+
104
+ Create Qzone H5 API
105
+ ============================
106
+
107
+ .. tab:: QR code login
108
+
109
+ .. code-block:: python
110
+
111
+ from aioqzone.api import QzoneH5Api
112
+ from aioqzone.api.login import QrLoginManager
113
+ from qqqr.utils.net import ClientAdapter
114
+
115
+ with ClientAdapter() as client:
116
+ mgr = QrLoginManager(client, config=QrLoginConfig(uin=env.uin))
117
+ api = QzoneH5Api(client, mgr)
118
+
119
+ .. tab:: uin-password login
120
+
121
+ .. code-block:: python
122
+
123
+ from aioqzone.api import UpLoginConfig, UpLoginManager
124
+ from qqqr.utils.net import ClientAdapter
125
+
126
+ with ClientAdapter() as client:
127
+ mgr = UpLoginManager(
128
+ client,
129
+ config=UpLoginConfig.model_validate(
130
+ dict(uin=env.uin, pwd=env.password, fake_ip="8.8.8.8")
131
+ ),
132
+ )
133
+ api = QzoneH5Api(client, mgr)
134
+
135
+ fetch feed flow
136
+ =========================================
137
+
138
+ .. tab:: from self index page
139
+
140
+ .. code-block:: python
141
+
142
+ feed_flow = await api.index()
143
+
144
+ .. tab:: from specific profile page
145
+
146
+ .. code-block:: python
147
+
148
+ feed_flow = await api.profile(uin=123456789)
149
+
150
+ Fetching (self) feed flow is a preliminary step for most operations, as it gets ``qzonetoken`` from Qzone server,
151
+ which is used in most operations.
152
+
153
+ fetch next page of feed flow
154
+ =========================================
155
+
156
+ As feed flow is paginated, you can fetch next page of feed flow:
157
+
158
+ .. tab:: self index page
159
+
160
+ .. code-block:: python
161
+
162
+ attach_info = None
163
+ while True:
164
+ resp = await api.get_active_feeds(attach_info=attach_info)
165
+ attach_info = resp.attach_info
166
+ if not resp.has_more:
167
+ break
168
+
169
+ .. tab:: specific profile page
170
+
171
+ .. code-block:: python
172
+
173
+ attach_info = None
174
+ while True:
175
+ resp = await api.get_feeds(uin=123456789, attach_info=attach_info)
176
+ attach_info = resp.attach_info
177
+ if not resp.has_more:
178
+ break
179
+
180
+ .. seealso::
181
+
182
+ `aioqzone-feed <https://github.com/aioqzone/aioqzone-feed>`_ provides a high-level
183
+ interface for fetching feed flow.
184
+
185
+ fetch avatar from uin
186
+ =========================================
187
+
188
+ This is a no-login API, you can fetch avatar without login state.
189
+
190
+ .. code-block:: python
191
+
192
+ size = 100 # avatar size, can be 100, 640
193
+ resp = await api.avatar(123456789, size)
194
+ with open("out/avatar.png", "wb") as f:
195
+ f.write(resp.avatar)
196
+
197
+ upload photo
198
+ =========================================
199
+
200
+ Uploading photo is a two-step process. The first is :meth:`QzoneH5API.upload_pic`, which should
201
+ be called per-image. The response is file length and md5. The second is `:meth:`QzoneH5API.preupload_photos` ,
202
+ which is called once for multiple images, and the response is a list of :class:`PicInfo`, including
203
+ image url, image id, etc.
204
+
205
+ .. code-block:: python
206
+
207
+ import asyncio
208
+
209
+ images = ["image_a.jpg", "image_b.jpg", "image_c.jpg"]
210
+ hashes = await asyncio.gather(
211
+ *map(api.upload_pic, images)
212
+ )
213
+ pic_infos = await api.preupload_photos(hashes)
214
+
215
+ .. hint::
216
+
217
+ You can specify quality of uploaded image by setting ``quality`` parameter of :meth:`QzoneH5API.upload_pic`.
218
+
219
+ Mood operation
220
+ =========================
221
+
222
+ upload mood
223
+ -------------------------
224
+
225
+ .. code-block:: python
226
+
227
+ from aioqzone.model import UgcRight
228
+
229
+ MOOD_TEXT = "Hello, world!"
230
+ picinfo = [...] # list of PicInfo, can be empty
231
+ feed = await api.publish_mood(
232
+ MOOD_TEXT, photos=picinfo, sync_weibo=False, ugc_right=UgcRight.self
233
+ )
234
+
235
+ .. hint::
236
+
237
+ You can specify mood visibility by setting ``ugc_right`` parameter of :meth:`QzoneH5API.publish_mood` .
238
+
239
+ delete mood
240
+ -------------------------
241
+
242
+ .. code-block:: python
243
+
244
+ # get appid from fetch feed. common appid of mood without sharing is 311.
245
+ delete_response = await api.delete_ugc(feed.fid, appid)
246
+
247
+ get mood detail
248
+ -------------------------
249
+
250
+ .. code-block:: python
251
+
252
+ # fetching feed
253
+ feed_flow = await api.get_active_feeds()
254
+ feed_dict = {i.fid: i for i in feed_flow.vFeeds}
255
+ fetched_feed = feed_dict[feed.fid]
256
+
257
+ detail = await api.shuoshuo(
258
+ fetched_feed.fid, fetched_feed.userinfo.uin, fetched_feed.common.appid
259
+ )
260
+
261
+ like/unlike mood
262
+ =========================
263
+
264
+ .. code-block:: python
265
+
266
+ from aioqzone.model import LikeData
267
+
268
+ # get appid, curkey and unikey from fetch feed
269
+ # common appid of mood without sharing is 311.
270
+
271
+ # for feeds without forward, curkey and unikey are the same.
272
+ # you can construct them by host uin and fid:
273
+ # unikey = LikeData.persudo_unikey(appid, hostuin, feed.fid)
274
+
275
+ await api.internal_dolike_app(appid, unikey, curkey=unikey, like=True) # like
276
+ await api.internal_dolike_app(appid, unikey, curkey=unikey, like=False) # unlike
277
+
278
+ mood comment
279
+ =========================
280
+
281
+ add comment
282
+ -------------------------
283
+
284
+ .. tab:: w/o picture
285
+
286
+ .. code-block:: python
287
+
288
+ COMMENT_TEXT = "Nice mood!"
289
+ comment = await api.add_comment(
290
+ hostuin, feed.fid, appid, COMMENT_TEXT, busi_param=fetched_feed.operation.busi_param
291
+ )
292
+
293
+ .. tip:: ``busi_param`` is optional, but recommended.
294
+
295
+ .. tab:: w/ picture
296
+
297
+ .. code-block:: python
298
+
299
+ COMMENT_TEXT = "Nice mood!"
300
+ picinfo = [...] # list of PicInfo
301
+ comment_pic = await api.add_comment(
302
+ hostuin, feed.fid, appid, COMMENT_TEXT, [i.url for i in picinfo]
303
+ )
304
+
305
+ .. attention::
306
+
307
+ Picture comment uses legacy html Qzone API, which has a html response.
308
+ Currently ``commentId`` cannot be parsed from the response.
309
+
310
+ delete comment
311
+ -------------------------
312
+
313
+ .. code-block:: python
314
+
315
+ await api.delete_comment(ownuin, fetched_feed.topicId, comment.commentid)
316
+
317
+ check feed update
318
+ ============================
319
+
320
+ .. admonition:: Speculation
321
+
322
+ Call this api every 5 minutes might keep your login cookie alive within one day (or several days).
323
+ Otherwise the login state will expire in several hours.
324
+
325
+ .. code-block:: python
326
+
327
+ await api.mfeeds_get_count()
@@ -18,6 +18,7 @@ aioqzone provides python interface to
18
18
 
19
19
  aioqzone/index
20
20
  qqqr/index
21
+ examples
21
22
 
22
23
  .. toctree::
23
24
  :caption: Links