huimei 0.1.0__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.
- huimei-0.1.0/PKG-INFO +134 -0
- huimei-0.1.0/README.md +98 -0
- huimei-0.1.0/huimei.egg-info/PKG-INFO +134 -0
- huimei-0.1.0/huimei.egg-info/SOURCES.txt +41 -0
- huimei-0.1.0/huimei.egg-info/dependency_links.txt +1 -0
- huimei-0.1.0/huimei.egg-info/entry_points.txt +3 -0
- huimei-0.1.0/huimei.egg-info/requires.txt +14 -0
- huimei-0.1.0/huimei.egg-info/top_level.txt +1 -0
- huimei-0.1.0/huimei_cli/__init__.py +2 -0
- huimei-0.1.0/huimei_cli/api_client.py +105 -0
- huimei-0.1.0/huimei_cli/auth.py +72 -0
- huimei-0.1.0/huimei_cli/commands/__init__.py +1 -0
- huimei-0.1.0/huimei_cli/commands/account_cmd.py +106 -0
- huimei-0.1.0/huimei_cli/commands/auth_cmd.py +67 -0
- huimei-0.1.0/huimei_cli/commands/publish_cmd.py +119 -0
- huimei-0.1.0/huimei_cli/config.py +72 -0
- huimei-0.1.0/huimei_cli/engine/__init__.py +0 -0
- huimei-0.1.0/huimei_cli/engine/browser.py +83 -0
- huimei-0.1.0/huimei_cli/engine/output.py +55 -0
- huimei-0.1.0/huimei_cli/engine/router.py +72 -0
- huimei-0.1.0/huimei_cli/engine/session.py +111 -0
- huimei-0.1.0/huimei_cli/main.py +102 -0
- huimei-0.1.0/huimei_cli/mcp_server.py +150 -0
- huimei-0.1.0/huimei_cli/platforms/__init__.py +0 -0
- huimei-0.1.0/huimei_cli/platforms/registry/__init__.py +6 -0
- huimei-0.1.0/huimei_cli/platforms/registry/_template.py +122 -0
- huimei-0.1.0/huimei_cli/platforms/registry/baijiahao.py +37 -0
- huimei-0.1.0/huimei_cli/platforms/registry/bilibili.py +97 -0
- huimei-0.1.0/huimei_cli/platforms/registry/douyin.py +9 -0
- huimei-0.1.0/huimei_cli/platforms/registry/ks.py +25 -0
- huimei-0.1.0/huimei_cli/platforms/registry/sample.py +79 -0
- huimei-0.1.0/huimei_cli/platforms/registry/tencent.py +25 -0
- huimei-0.1.0/huimei_cli/platforms/registry/tk.py +25 -0
- huimei-0.1.0/huimei_cli/platforms/registry/toutiao.py +72 -0
- huimei-0.1.0/huimei_cli/platforms/registry/weibo.py +164 -0
- huimei-0.1.0/huimei_cli/platforms/registry/weixingongzhonghao.py +48 -0
- huimei-0.1.0/huimei_cli/platforms/registry/xhs.py +73 -0
- huimei-0.1.0/huimei_cli/platforms/registry/zhihu.py +25 -0
- huimei-0.1.0/pyproject.toml +57 -0
- huimei-0.1.0/setup.cfg +4 -0
- huimei-0.1.0/tests/test_cli.py +24 -0
- huimei-0.1.0/tests/test_core.py +126 -0
- huimei-0.1.0/tests/test_mcp.py +41 -0
huimei-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: huimei
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Multi-platform social media automation CLI — publish to Douyin, XHS, Bilibili, Weibo and 8+ platforms from your terminal
|
|
5
|
+
Author: HuiMei Team
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/huimei-engine/huimei-cli
|
|
8
|
+
Project-URL: Repository, https://codeup.aliyun.com/6832d8ec9c32f0e37238744f/huimei-cli
|
|
9
|
+
Keywords: social-media,automation,cli,douyin,bilibili,xiaohongshu,playwright,cross-posting,marketing
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Internet
|
|
20
|
+
Classifier: Topic :: Multimedia
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
Requires-Dist: typer>=0.12.0
|
|
24
|
+
Requires-Dist: httpx>=0.27.0
|
|
25
|
+
Requires-Dist: rich>=13.0.0
|
|
26
|
+
Requires-Dist: playwright>=1.40.0
|
|
27
|
+
Requires-Dist: pydantic>=2.0.0
|
|
28
|
+
Requires-Dist: pycryptodome>=3.20.0
|
|
29
|
+
Requires-Dist: keyring>=25.0.0
|
|
30
|
+
Requires-Dist: mcp>=1.0.0
|
|
31
|
+
Provides-Extra: dev
|
|
32
|
+
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
33
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
|
|
34
|
+
Requires-Dist: build; extra == "dev"
|
|
35
|
+
Requires-Dist: twine; extra == "dev"
|
|
36
|
+
|
|
37
|
+
# 慧媒引擎 CLI (huimei)
|
|
38
|
+
|
|
39
|
+
多平台社媒自动化发布工具 — 一个命令发布到抖音/快手/B站/小红书/微博等11个平台。
|
|
40
|
+
|
|
41
|
+
## 安装
|
|
42
|
+
|
|
43
|
+
### 方式1: pip (推荐)
|
|
44
|
+
```bash
|
|
45
|
+
pip install huimei
|
|
46
|
+
playwright install chromium
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### 方式2: pipx (隔离环境)
|
|
50
|
+
```bash
|
|
51
|
+
pipx install huimei
|
|
52
|
+
playwright install chromium
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 方式3: 一键脚本
|
|
56
|
+
```bash
|
|
57
|
+
curl -fsSL https://raw.githubusercontent.com/huimei-engine/huimei-cli/main/install.sh | bash
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## 快速开始
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# 登录
|
|
64
|
+
huimei login
|
|
65
|
+
|
|
66
|
+
# 查看支持的平台
|
|
67
|
+
huimei platforms
|
|
68
|
+
|
|
69
|
+
# 查看已绑定账号
|
|
70
|
+
huimei account list
|
|
71
|
+
|
|
72
|
+
# 查看状态
|
|
73
|
+
huimei status
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## AI Agent 集成 (MCP Server)
|
|
77
|
+
|
|
78
|
+
huimei 内置 MCP Server,可供 Claude Code / Hermes / OpenCode 等 AI Agent 直接调用:
|
|
79
|
+
|
|
80
|
+
### Claude Code 配置
|
|
81
|
+
```json
|
|
82
|
+
{
|
|
83
|
+
"mcpServers": {
|
|
84
|
+
"huimei": {
|
|
85
|
+
"command": "huimei-mcp-server",
|
|
86
|
+
"args": []
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Hermes Agent 配置
|
|
93
|
+
```yaml
|
|
94
|
+
mcp_servers:
|
|
95
|
+
huimei:
|
|
96
|
+
command: huimei-mcp-server
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### 可用工具
|
|
100
|
+
|
|
101
|
+
| 工具 | 说明 |
|
|
102
|
+
|------|------|
|
|
103
|
+
| `huimei_login` | 登录账号 |
|
|
104
|
+
| `huimei_status` | 查看状态 |
|
|
105
|
+
| `huimei_logout` | 登出 |
|
|
106
|
+
| `huimei_platforms` | 列出支持平台 |
|
|
107
|
+
| `huimei_accounts` | 列出绑定账号 |
|
|
108
|
+
| `huimei_publish` | 创建发布任务 |
|
|
109
|
+
|
|
110
|
+
## 架构
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
CLI (本地) ──HTTP──► Java后端 (云端)
|
|
114
|
+
│ │
|
|
115
|
+
├─ Playwright ├─ 账号管理
|
|
116
|
+
├─ Cookie本地存储 ├─ 任务调度
|
|
117
|
+
└─ 住宅IP执行 └─ 订阅计费
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
CLI 是后端的远程执行器(手臂),所有业务决策由后端(大脑)做出。
|
|
121
|
+
|
|
122
|
+
## 开发
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
git clone <repo>
|
|
126
|
+
cd huimei-cli
|
|
127
|
+
python -m venv .venv && source .venv/bin/activate
|
|
128
|
+
pip install -e ".[dev]"
|
|
129
|
+
pytest
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## License
|
|
133
|
+
|
|
134
|
+
MIT
|
huimei-0.1.0/README.md
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# 慧媒引擎 CLI (huimei)
|
|
2
|
+
|
|
3
|
+
多平台社媒自动化发布工具 — 一个命令发布到抖音/快手/B站/小红书/微博等11个平台。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
### 方式1: pip (推荐)
|
|
8
|
+
```bash
|
|
9
|
+
pip install huimei
|
|
10
|
+
playwright install chromium
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### 方式2: pipx (隔离环境)
|
|
14
|
+
```bash
|
|
15
|
+
pipx install huimei
|
|
16
|
+
playwright install chromium
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### 方式3: 一键脚本
|
|
20
|
+
```bash
|
|
21
|
+
curl -fsSL https://raw.githubusercontent.com/huimei-engine/huimei-cli/main/install.sh | bash
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## 快速开始
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# 登录
|
|
28
|
+
huimei login
|
|
29
|
+
|
|
30
|
+
# 查看支持的平台
|
|
31
|
+
huimei platforms
|
|
32
|
+
|
|
33
|
+
# 查看已绑定账号
|
|
34
|
+
huimei account list
|
|
35
|
+
|
|
36
|
+
# 查看状态
|
|
37
|
+
huimei status
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## AI Agent 集成 (MCP Server)
|
|
41
|
+
|
|
42
|
+
huimei 内置 MCP Server,可供 Claude Code / Hermes / OpenCode 等 AI Agent 直接调用:
|
|
43
|
+
|
|
44
|
+
### Claude Code 配置
|
|
45
|
+
```json
|
|
46
|
+
{
|
|
47
|
+
"mcpServers": {
|
|
48
|
+
"huimei": {
|
|
49
|
+
"command": "huimei-mcp-server",
|
|
50
|
+
"args": []
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
### Hermes Agent 配置
|
|
57
|
+
```yaml
|
|
58
|
+
mcp_servers:
|
|
59
|
+
huimei:
|
|
60
|
+
command: huimei-mcp-server
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### 可用工具
|
|
64
|
+
|
|
65
|
+
| 工具 | 说明 |
|
|
66
|
+
|------|------|
|
|
67
|
+
| `huimei_login` | 登录账号 |
|
|
68
|
+
| `huimei_status` | 查看状态 |
|
|
69
|
+
| `huimei_logout` | 登出 |
|
|
70
|
+
| `huimei_platforms` | 列出支持平台 |
|
|
71
|
+
| `huimei_accounts` | 列出绑定账号 |
|
|
72
|
+
| `huimei_publish` | 创建发布任务 |
|
|
73
|
+
|
|
74
|
+
## 架构
|
|
75
|
+
|
|
76
|
+
```
|
|
77
|
+
CLI (本地) ──HTTP──► Java后端 (云端)
|
|
78
|
+
│ │
|
|
79
|
+
├─ Playwright ├─ 账号管理
|
|
80
|
+
├─ Cookie本地存储 ├─ 任务调度
|
|
81
|
+
└─ 住宅IP执行 └─ 订阅计费
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
CLI 是后端的远程执行器(手臂),所有业务决策由后端(大脑)做出。
|
|
85
|
+
|
|
86
|
+
## 开发
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
git clone <repo>
|
|
90
|
+
cd huimei-cli
|
|
91
|
+
python -m venv .venv && source .venv/bin/activate
|
|
92
|
+
pip install -e ".[dev]"
|
|
93
|
+
pytest
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## License
|
|
97
|
+
|
|
98
|
+
MIT
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: huimei
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Multi-platform social media automation CLI — publish to Douyin, XHS, Bilibili, Weibo and 8+ platforms from your terminal
|
|
5
|
+
Author: HuiMei Team
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/huimei-engine/huimei-cli
|
|
8
|
+
Project-URL: Repository, https://codeup.aliyun.com/6832d8ec9c32f0e37238744f/huimei-cli
|
|
9
|
+
Keywords: social-media,automation,cli,douyin,bilibili,xiaohongshu,playwright,cross-posting,marketing
|
|
10
|
+
Classifier: Development Status :: 3 - Alpha
|
|
11
|
+
Classifier: Environment :: Console
|
|
12
|
+
Classifier: Intended Audience :: End Users/Desktop
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Operating System :: OS Independent
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Internet
|
|
20
|
+
Classifier: Topic :: Multimedia
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Description-Content-Type: text/markdown
|
|
23
|
+
Requires-Dist: typer>=0.12.0
|
|
24
|
+
Requires-Dist: httpx>=0.27.0
|
|
25
|
+
Requires-Dist: rich>=13.0.0
|
|
26
|
+
Requires-Dist: playwright>=1.40.0
|
|
27
|
+
Requires-Dist: pydantic>=2.0.0
|
|
28
|
+
Requires-Dist: pycryptodome>=3.20.0
|
|
29
|
+
Requires-Dist: keyring>=25.0.0
|
|
30
|
+
Requires-Dist: mcp>=1.0.0
|
|
31
|
+
Provides-Extra: dev
|
|
32
|
+
Requires-Dist: pytest>=8.0.0; extra == "dev"
|
|
33
|
+
Requires-Dist: pytest-asyncio>=0.23.0; extra == "dev"
|
|
34
|
+
Requires-Dist: build; extra == "dev"
|
|
35
|
+
Requires-Dist: twine; extra == "dev"
|
|
36
|
+
|
|
37
|
+
# 慧媒引擎 CLI (huimei)
|
|
38
|
+
|
|
39
|
+
多平台社媒自动化发布工具 — 一个命令发布到抖音/快手/B站/小红书/微博等11个平台。
|
|
40
|
+
|
|
41
|
+
## 安装
|
|
42
|
+
|
|
43
|
+
### 方式1: pip (推荐)
|
|
44
|
+
```bash
|
|
45
|
+
pip install huimei
|
|
46
|
+
playwright install chromium
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### 方式2: pipx (隔离环境)
|
|
50
|
+
```bash
|
|
51
|
+
pipx install huimei
|
|
52
|
+
playwright install chromium
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 方式3: 一键脚本
|
|
56
|
+
```bash
|
|
57
|
+
curl -fsSL https://raw.githubusercontent.com/huimei-engine/huimei-cli/main/install.sh | bash
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## 快速开始
|
|
61
|
+
|
|
62
|
+
```bash
|
|
63
|
+
# 登录
|
|
64
|
+
huimei login
|
|
65
|
+
|
|
66
|
+
# 查看支持的平台
|
|
67
|
+
huimei platforms
|
|
68
|
+
|
|
69
|
+
# 查看已绑定账号
|
|
70
|
+
huimei account list
|
|
71
|
+
|
|
72
|
+
# 查看状态
|
|
73
|
+
huimei status
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## AI Agent 集成 (MCP Server)
|
|
77
|
+
|
|
78
|
+
huimei 内置 MCP Server,可供 Claude Code / Hermes / OpenCode 等 AI Agent 直接调用:
|
|
79
|
+
|
|
80
|
+
### Claude Code 配置
|
|
81
|
+
```json
|
|
82
|
+
{
|
|
83
|
+
"mcpServers": {
|
|
84
|
+
"huimei": {
|
|
85
|
+
"command": "huimei-mcp-server",
|
|
86
|
+
"args": []
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### Hermes Agent 配置
|
|
93
|
+
```yaml
|
|
94
|
+
mcp_servers:
|
|
95
|
+
huimei:
|
|
96
|
+
command: huimei-mcp-server
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### 可用工具
|
|
100
|
+
|
|
101
|
+
| 工具 | 说明 |
|
|
102
|
+
|------|------|
|
|
103
|
+
| `huimei_login` | 登录账号 |
|
|
104
|
+
| `huimei_status` | 查看状态 |
|
|
105
|
+
| `huimei_logout` | 登出 |
|
|
106
|
+
| `huimei_platforms` | 列出支持平台 |
|
|
107
|
+
| `huimei_accounts` | 列出绑定账号 |
|
|
108
|
+
| `huimei_publish` | 创建发布任务 |
|
|
109
|
+
|
|
110
|
+
## 架构
|
|
111
|
+
|
|
112
|
+
```
|
|
113
|
+
CLI (本地) ──HTTP──► Java后端 (云端)
|
|
114
|
+
│ │
|
|
115
|
+
├─ Playwright ├─ 账号管理
|
|
116
|
+
├─ Cookie本地存储 ├─ 任务调度
|
|
117
|
+
└─ 住宅IP执行 └─ 订阅计费
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
CLI 是后端的远程执行器(手臂),所有业务决策由后端(大脑)做出。
|
|
121
|
+
|
|
122
|
+
## 开发
|
|
123
|
+
|
|
124
|
+
```bash
|
|
125
|
+
git clone <repo>
|
|
126
|
+
cd huimei-cli
|
|
127
|
+
python -m venv .venv && source .venv/bin/activate
|
|
128
|
+
pip install -e ".[dev]"
|
|
129
|
+
pytest
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
## License
|
|
133
|
+
|
|
134
|
+
MIT
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
huimei.egg-info/PKG-INFO
|
|
4
|
+
huimei.egg-info/SOURCES.txt
|
|
5
|
+
huimei.egg-info/dependency_links.txt
|
|
6
|
+
huimei.egg-info/entry_points.txt
|
|
7
|
+
huimei.egg-info/requires.txt
|
|
8
|
+
huimei.egg-info/top_level.txt
|
|
9
|
+
huimei_cli/__init__.py
|
|
10
|
+
huimei_cli/api_client.py
|
|
11
|
+
huimei_cli/auth.py
|
|
12
|
+
huimei_cli/config.py
|
|
13
|
+
huimei_cli/main.py
|
|
14
|
+
huimei_cli/mcp_server.py
|
|
15
|
+
huimei_cli/commands/__init__.py
|
|
16
|
+
huimei_cli/commands/account_cmd.py
|
|
17
|
+
huimei_cli/commands/auth_cmd.py
|
|
18
|
+
huimei_cli/commands/publish_cmd.py
|
|
19
|
+
huimei_cli/engine/__init__.py
|
|
20
|
+
huimei_cli/engine/browser.py
|
|
21
|
+
huimei_cli/engine/output.py
|
|
22
|
+
huimei_cli/engine/router.py
|
|
23
|
+
huimei_cli/engine/session.py
|
|
24
|
+
huimei_cli/platforms/__init__.py
|
|
25
|
+
huimei_cli/platforms/registry/__init__.py
|
|
26
|
+
huimei_cli/platforms/registry/_template.py
|
|
27
|
+
huimei_cli/platforms/registry/baijiahao.py
|
|
28
|
+
huimei_cli/platforms/registry/bilibili.py
|
|
29
|
+
huimei_cli/platforms/registry/douyin.py
|
|
30
|
+
huimei_cli/platforms/registry/ks.py
|
|
31
|
+
huimei_cli/platforms/registry/sample.py
|
|
32
|
+
huimei_cli/platforms/registry/tencent.py
|
|
33
|
+
huimei_cli/platforms/registry/tk.py
|
|
34
|
+
huimei_cli/platforms/registry/toutiao.py
|
|
35
|
+
huimei_cli/platforms/registry/weibo.py
|
|
36
|
+
huimei_cli/platforms/registry/weixingongzhonghao.py
|
|
37
|
+
huimei_cli/platforms/registry/xhs.py
|
|
38
|
+
huimei_cli/platforms/registry/zhihu.py
|
|
39
|
+
tests/test_cli.py
|
|
40
|
+
tests/test_core.py
|
|
41
|
+
tests/test_mcp.py
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
huimei_cli
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"""慧媒引擎 Backend API Client"""
|
|
2
|
+
import httpx
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
class ApiError(Exception):
|
|
6
|
+
"""API request error with status code and message."""
|
|
7
|
+
def __init__(self, code: int, message: str):
|
|
8
|
+
self.code = code
|
|
9
|
+
self.message = message
|
|
10
|
+
super().__init__(f"[{code}] {message}")
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
class ApiClient:
|
|
14
|
+
"""Synchronous HTTP client for huimei-engine backend API."""
|
|
15
|
+
|
|
16
|
+
def __init__(self, server_url: str, token: str | None = None, timeout: float = 30.0):
|
|
17
|
+
self.base_url = server_url.rstrip("/")
|
|
18
|
+
self.token = token
|
|
19
|
+
self.timeout = timeout
|
|
20
|
+
|
|
21
|
+
def _headers(self) -> dict:
|
|
22
|
+
headers = {"Content-Type": "application/json"}
|
|
23
|
+
if self.token:
|
|
24
|
+
headers["Authorization"] = f"Bearer {self.token}"
|
|
25
|
+
return headers
|
|
26
|
+
|
|
27
|
+
def _request(self, method: str, path: str, **kwargs) -> dict:
|
|
28
|
+
url = f"{self.base_url}{path}"
|
|
29
|
+
try:
|
|
30
|
+
resp = httpx.request(
|
|
31
|
+
method, url,
|
|
32
|
+
headers=self._headers(),
|
|
33
|
+
timeout=self.timeout,
|
|
34
|
+
**kwargs,
|
|
35
|
+
)
|
|
36
|
+
except httpx.HTTPError as e:
|
|
37
|
+
raise ApiError(0, f"Request failed: {e}") from e
|
|
38
|
+
|
|
39
|
+
if resp.status_code != 200:
|
|
40
|
+
raise ApiError(resp.status_code, f"HTTP {resp.status_code}: {resp.text[:200]}")
|
|
41
|
+
|
|
42
|
+
body = resp.json()
|
|
43
|
+
code = body.get("code", -1)
|
|
44
|
+
if code != 200:
|
|
45
|
+
raise ApiError(code, body.get("message", "Unknown error"))
|
|
46
|
+
return body.get("data")
|
|
47
|
+
|
|
48
|
+
def _get(self, path: str, **params) -> dict:
|
|
49
|
+
return self._request("GET", path, params=params or None)
|
|
50
|
+
|
|
51
|
+
def _post(self, path: str, data: dict = None) -> dict:
|
|
52
|
+
return self._request("POST", path, json=data)
|
|
53
|
+
|
|
54
|
+
def _put(self, path: str, data: dict = None) -> dict:
|
|
55
|
+
return self._request("PUT", path, json=data)
|
|
56
|
+
|
|
57
|
+
# ── Auth ──────────────────────────────────────────────
|
|
58
|
+
|
|
59
|
+
def login(self, username: str, password: str) -> dict:
|
|
60
|
+
"""Login and store JWT token. Returns user/token data."""
|
|
61
|
+
result = self._post("/api/v1/auth/login", {
|
|
62
|
+
"username": username,
|
|
63
|
+
"password": password,
|
|
64
|
+
})
|
|
65
|
+
if result and "token" in result:
|
|
66
|
+
self.token = result["token"]
|
|
67
|
+
return result
|
|
68
|
+
|
|
69
|
+
# ── Subscription ──────────────────────────────────────
|
|
70
|
+
|
|
71
|
+
def get_subscription_info(self) -> dict:
|
|
72
|
+
"""Get current subscription/plan info."""
|
|
73
|
+
return self._get("/api/v1/subscription/current")
|
|
74
|
+
|
|
75
|
+
# ── Accounts & Platforms ──────────────────────────────
|
|
76
|
+
|
|
77
|
+
def get_accounts(self) -> list:
|
|
78
|
+
"""List all bound social media accounts."""
|
|
79
|
+
return self._get("/api/v1/accounts")
|
|
80
|
+
|
|
81
|
+
def get_platforms(self) -> list:
|
|
82
|
+
"""List all supported platforms."""
|
|
83
|
+
return self._get("/api/v1/platforms")
|
|
84
|
+
|
|
85
|
+
def get_publish_params_config(self, platform_id: str) -> dict:
|
|
86
|
+
"""Get publish parameter config for a specific platform."""
|
|
87
|
+
return self._get(f"/api/v1/platforms/{platform_id}/publish-params-config")
|
|
88
|
+
|
|
89
|
+
# ── Publish Tasks ─────────────────────────────────────
|
|
90
|
+
|
|
91
|
+
def create_task(self, task_data: dict) -> dict:
|
|
92
|
+
"""Create a new publish task."""
|
|
93
|
+
return self._post("/api/v1/publish", task_data)
|
|
94
|
+
|
|
95
|
+
def report_task_result(self, task_uuid: str, result: dict) -> dict:
|
|
96
|
+
"""Report the result of a CLI-executed task."""
|
|
97
|
+
return self._put(f"/api/v1/cli/tasks/{task_uuid}/report", result)
|
|
98
|
+
|
|
99
|
+
def register_device(self, device_id: str, device_name: str, os_type: str) -> dict:
|
|
100
|
+
"""Register CLI device with backend."""
|
|
101
|
+
return self._post("/api/v1/cli/device/register", {
|
|
102
|
+
"device_id": device_id,
|
|
103
|
+
"device_name": device_name,
|
|
104
|
+
"os_type": os_type,
|
|
105
|
+
})
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"""Authentication management for huimei-cli."""
|
|
2
|
+
|
|
3
|
+
import json
|
|
4
|
+
import base64
|
|
5
|
+
|
|
6
|
+
from huimei_cli.config import get_config, save_config, get_server_url, save_token
|
|
7
|
+
from huimei_cli.api_client import ApiClient, ApiError
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def do_login(username: str, password: str, server_url: str = None) -> bool:
|
|
11
|
+
"""Login to the huimei server and save token to config.
|
|
12
|
+
|
|
13
|
+
Args:
|
|
14
|
+
username: User's username.
|
|
15
|
+
password: User's password.
|
|
16
|
+
server_url: Optional server URL override.
|
|
17
|
+
|
|
18
|
+
Returns:
|
|
19
|
+
True if login succeeded, False otherwise.
|
|
20
|
+
"""
|
|
21
|
+
url = server_url or get_server_url()
|
|
22
|
+
client = ApiClient(server_url=url)
|
|
23
|
+
try:
|
|
24
|
+
data = client.login(username, password)
|
|
25
|
+
token = data.get("token") if isinstance(data, dict) else None
|
|
26
|
+
if not token:
|
|
27
|
+
return False
|
|
28
|
+
save_token(token)
|
|
29
|
+
# Also persist server_url if overridden
|
|
30
|
+
if server_url:
|
|
31
|
+
cfg = get_config()
|
|
32
|
+
cfg["server_url"] = server_url
|
|
33
|
+
save_config(cfg)
|
|
34
|
+
return True
|
|
35
|
+
except (ApiError, Exception):
|
|
36
|
+
return False
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
def is_logged_in() -> bool:
|
|
40
|
+
"""Check whether a valid token exists in config."""
|
|
41
|
+
cfg = get_config()
|
|
42
|
+
return bool(cfg.get("token"))
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def get_current_user() -> dict | None:
|
|
46
|
+
"""Decode the JWT token payload to get current user info.
|
|
47
|
+
|
|
48
|
+
Decodes without verification — only reads the payload claims.
|
|
49
|
+
|
|
50
|
+
Returns:
|
|
51
|
+
Dict of user claims from token, or None if not logged in.
|
|
52
|
+
"""
|
|
53
|
+
cfg = get_config()
|
|
54
|
+
token = cfg.get("token")
|
|
55
|
+
if not token:
|
|
56
|
+
return None
|
|
57
|
+
try:
|
|
58
|
+
payload_b64 = token.split(".")[1]
|
|
59
|
+
padding = 4 - len(payload_b64) % 4
|
|
60
|
+
if padding != 4:
|
|
61
|
+
payload_b64 += "=" * padding
|
|
62
|
+
payload_bytes = base64.urlsafe_b64decode(payload_b64)
|
|
63
|
+
return json.loads(payload_bytes)
|
|
64
|
+
except (IndexError, ValueError, json.JSONDecodeError):
|
|
65
|
+
return None
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def logout() -> None:
|
|
69
|
+
"""Clear authentication token from config."""
|
|
70
|
+
cfg = get_config()
|
|
71
|
+
cfg.pop("token", None)
|
|
72
|
+
save_config(cfg)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""CLI commands package."""
|