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.
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/.github/workflows/sphinx.yml +8 -5
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/.pre-commit-config.yaml +3 -3
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/PKG-INFO +6 -4
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/README.md +5 -3
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/README_en.md +6 -4
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/conf.py +2 -0
- aioqzone-1.9.5.dev6/doc/source/examples.rst +327 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/index.rst +1 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/api/h5.po +113 -19
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/api/login.po +56 -40
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/model/api.po +249 -51
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/model/protocol.po +10 -5
- aioqzone-1.9.5.dev6/doc/source/locale/zh_CN/LC_MESSAGES/examples.po +232 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/jsjson.po +39 -16
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/qr/type.po +16 -13
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/up/type.po +45 -25
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/pyproject.toml +2 -1
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/api/h5/model.py +1 -1
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/model/api/feed.py +2 -2
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/model/api/profile.py +14 -17
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/model/api/response.py +4 -4
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/uv.lock +17 -1
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/.github/dependabot.yml +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/.github/workflows/auto-pr.yml +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/.github/workflows/build.yml +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/.github/workflows/codeql-analysis.yml +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/.github/workflows/test.yml +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/.gitignore +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/CONTRIBUTING.md +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/LICENSE +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/cliff.toml +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/_static/penguin-blob.webp +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/_static/teaencoder.ts +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/aioqzone/api/h5.rst +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/aioqzone/api/index.rst +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/aioqzone/api/login.rst +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/aioqzone/exception.rst +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/aioqzone/index.rst +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/aioqzone/messages.rst +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/aioqzone/model/api.rst +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/aioqzone/model/index.rst +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/aioqzone/model/protocol.rst +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/aioqzone/reference.rst +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/disclaimers.rst +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/api/index.po +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/api/web.po +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/exception.po +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/index.po +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/messages.po +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/model/index.po +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/model/response.po +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/aioqzone/reference.po +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/disclaimers.po +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/index.po +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/base.po +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/exception.po +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/index.po +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/qr/index.po +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/qr/login.po +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/up/captcha/capsess.po +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/up/captcha/captcha.po +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/up/captcha/index.po +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/up/captcha/jigsaw.po +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/up/encrypt.po +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/up/index.po +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/qqqr/up/login.po +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/locale/zh_CN/LC_MESSAGES/reference.po +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/qqqr/base.rst +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/qqqr/exception.rst +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/qqqr/index.rst +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/qqqr/jsjson.rst +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/qqqr/qr/index.rst +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/qqqr/qr/login.rst +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/qqqr/qr/type.rst +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/qqqr/up/captcha/capsess.rst +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/qqqr/up/captcha/captcha.rst +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/qqqr/up/captcha/index.rst +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/qqqr/up/encrypt.rst +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/qqqr/up/index.rst +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/qqqr/up/login.rst +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/doc/source/qqqr/up/type.rst +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/__init__.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/api/__init__.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/api/h5/__init__.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/api/login/__init__.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/api/login/_base.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/exception.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/message.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/model/__init__.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/model/api/__init__.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/model/api/request.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/model/protocol/__init__.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/model/protocol/config.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/model/protocol/entity.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/utils/__init__.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/utils/entity.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/utils/regex.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/utils/retry.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/aioqzone/utils/time.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/__init__.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/base.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/constant.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/exception.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/message.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/py.typed +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/qr/__init__.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/qr/type.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/type.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/up/__init__.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/up/_model.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/up/captcha/__init__.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/up/captcha/_model.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/up/captcha/capsess.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/up/captcha/click/__init__.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/up/captcha/click/_types.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/up/captcha/pil_utils.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/up/captcha/select/__init__.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/up/captcha/select/_types.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/up/captcha/slide/__init__.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/up/captcha/slide/_types.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/up/encrypt.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/up/h5.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/up/web.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/utils/encrypt.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/utils/iter.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/utils/jsjson.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/src/qqqr/utils/net.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/test/api/__init__.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/test/api/conftest.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/test/api/test_h5.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/test/api/test_loginman.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/test/conftest.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/test/login_logic/__init__.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/test/login_logic/test_captcha.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/test/login_logic/test_qr.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/test/login_logic/test_up.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/test/utils/test_entity.py +0 -0
- {aioqzone-1.9.5.dev4 → aioqzone-1.9.5.dev6}/test/utils/test_json.py +0 -0
- {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
|
-
|
|
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:
|
|
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:
|
|
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.
|
|
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
|
|
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/
|
|
85
|
+
[pypi]: https://pypi.org[slide-tc]: https://github.com/aioqzone/slide-tc "An aioqzone plugin for solving slide captcha."
|
|
86
|
+
/project/aioqzone
|
|
@@ -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()
|