9b6295c7 by 柴进

nanobanana初版

0 parents
1 <!-- OPENSPEC:START -->
2 # OpenSpec Instructions
3
4 These instructions are for AI assistants working in this project.
5
6 Always open `@/openspec/AGENTS.md` when the request:
7 - Mentions planning or proposals (words like proposal, spec, change, plan)
8 - Introduces new capabilities, breaking changes, architecture shifts, or big performance/security work
9 - Sounds ambiguous and you need the authoritative spec before coding
10
11 Use `@/openspec/AGENTS.md` to learn:
12 - How to create and apply change proposals
13 - Spec format and conventions
14 - Project structure and guidelines
15
16 Keep this managed block so 'openspec update' can refresh the instructions.
17
18 <!-- OPENSPEC:END -->
...\ No newline at end of file ...\ No newline at end of file
1 <!-- OPENSPEC:START -->
2 # OpenSpec Instructions
3
4 These instructions are for AI assistants working in this project.
5
6 Always open `@/openspec/AGENTS.md` when the request:
7 - Mentions planning or proposals (words like proposal, spec, change, plan)
8 - Introduces new capabilities, breaking changes, architecture shifts, or big performance/security work
9 - Sounds ambiguous and you need the authoritative spec before coding
10
11 Use `@/openspec/AGENTS.md` to learn:
12 - How to create and apply change proposals
13 - Spec format and conventions
14 - Project structure and guidelines
15
16 Keep this managed block so 'openspec update' can refresh the instructions.
17
18 <!-- OPENSPEC:END -->
...\ No newline at end of file ...\ No newline at end of file
1 # Gemini Image Generator
2
3 简洁的跨平台桌面应用,使用 Google Gemini API 生成图片。
4
5 ## 功能特性
6
7 - **用户认证**: 基于 MySQL 的登录系统,确保只有授权用户可访问
8 - 输入文本 Prompt 生成图片
9 - 支持上传多张参考图片
10 - 多种图片比例选择(1:1, 16:9, 4:3 等)
11 - 多种分辨率选择(1K, 2K, 4K)
12 - 支持两种模型:gemini-2.5-flash-image 和 gemini-3-pro-image-preview
13 - 实时预览生成的图片
14 - 一键下载生成的图片
15 - 跨平台支持(Windows 和 macOS)
16
17 ## 系统要求
18
19 - Python 3.8 或更高版本
20 - 有效的 Google AI API 密钥
21 - MySQL 数据库访问权限(用于用户认证)
22
23 ## 快速开始
24
25 ### 开发模式运行
26
27 1. 安装依赖:
28 ```bash
29 pip install -r requirements.txt
30 ```
31
32 2. 配置数据库和 API 密钥:
33 - 编辑 `config.json` 文件,配置以下字段:
34 ```json
35 {
36 "api_key": "你的Google AI API密钥",
37 "db_config": {
38 "host": "你的MySQL主机地址",
39 "port": 3306,
40 "user": "数据库用户名",
41 "password": "数据库密码",
42 "database": "数据库名",
43 "table": "nano_banana_users"
44 },
45 "last_user": ""
46 }
47 ```
48
49 3. 创建数据库表:
50 ```sql
51 CREATE TABLE `nano_banana_users` (
52 `user_name` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
53 `passwd` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL,
54 `status` varchar(255) COLLATE utf8mb4_unicode_ci DEFAULT NULL
55 ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
56 ```
57
58 4. 添加初始用户:
59 ```bash
60 python user_util.py add admin your_password
61 ```
62
63 5. 运行应用:
64 ```bash
65 python image_generator.py
66 ```
67
68 首次运行会显示登录界面,使用创建的账户登录。
69
70 ### 打包为可执行文件
71
72 #### Windows
73
74 双击运行 `build_windows.bat` 或在命令行执行:
75 ```cmd
76 build_windows.bat
77 ```
78
79 生成的可执行文件位于 `dist\GeminiImageGenerator.exe`
80
81 #### macOS
82
83 在终端执行:
84 ```bash
85 chmod +x build_mac.sh
86 ./build_mac.sh
87 ```
88
89 生成的应用程序位于 `dist/GeminiImageGenerator.app`
90
91 ## 配置文件位置
92
93 应用会根据运行模式自动选择配置文件位置:
94
95 **开发模式**(直接运行 Python):
96 - 配置文件:`./config.json`(当前目录)
97
98 **打包后的应用**:
99 - **macOS**: `~/Library/Application Support/ZB100ImageGenerator/config.json`
100 - **Windows**: `%APPDATA%\ZB100ImageGenerator\config.json`
101 - **Linux**: `~/.config/zb100imagegenerator/config.json`
102
103 首次运行打包应用时,会自动从打包的模板复制 API 密钥到用户目录。
104
105 ## 用户管理
106
107 应用内置用户管理工具 `user_util.py`(仅管理员使用,不随客户端分发)。
108
109 ### 用户管理命令
110
111 ```bash
112 # 添加新用户
113 python user_util.py add <username> <password>
114
115 # 列出所有用户
116 python user_util.py list
117
118 # 禁用用户
119 python user_util.py disable <username>
120
121 # 启用用户
122 python user_util.py enable <username>
123
124 # 重置密码
125 python user_util.py reset <username> <new_password>
126 ```
127
128 ### 示例
129
130 ```bash
131 # 添加管理员账户
132 python user_util.py add admin MySecurePass123
133
134 # 查看所有用户
135 python user_util.py list
136
137 # 禁用某个用户
138 python user_util.py disable testuser
139
140 # 重置用户密码
141 python user_util.py reset admin NewPassword456
142 ```
143
144 ### 安全说明
145
146 - 密码使用 SHA256 哈希存储,数据库和本地均不保存明文
147 - 所有数据库操作使用参数化查询,防止 SQL 注入
148 - user_util.py 工具仅供管理员使用,不应分发给普通用户
149 - 应用会记住上次登录的用户名(可选),但不会保存密码
150
151 ## 使用说明
152
153 1. **登录应用**
154 - 应用启动时显示登录界面
155 - 输入用户名和密码
156 - 可勾选"记住用户名"选项,下次自动填充用户名
157 - 登录成功后进入主界面
158
159 2. **配置 API 密钥**
160 - 编辑配置文件中的 `api_key` 字段
161 - 或通过应用界面的收藏提示词功能自动保存
162
163 3. **上传参考图片(可选)**
164 - 点击 "添加图片" 按钮选择一张或多张参考图片
165 - 这些图片将作为生成图片的参考
166 - 可以单独删除每张图片
167
168 3. **输入 Prompt**
169 - 在提示词文本框中输入你想生成的图片描述
170 - 可以使用 "收藏" 功能保存常用提示词
171 - 从下拉菜单快速选择已保存的提示词
172
173 4. **选择生成参数**
174 - **宽高比**: 选择图片的宽高比(1:1, 16:9 等)
175 - **图片尺寸**: 选择图片的分辨率(1K/2K/4K)
176 - **AI 模型**: 选择使用的模型
177
178 5. **生成图片**
179 - 点击 "生成图片" 按钮
180 - 等待生成完成,生成的图片会显示在预览区域
181 - 双击预览图可用系统默认查看器打开
182
183 6. **下载图片**
184 - 点击 "下载图片" 按钮
185 - 选择保存位置和文件格式(PNG/JPEG)
186
187 ## 项目结构
188
189 ```
190 Nano_Banana_App/
191 ├── image_generator.py # 主程序文件(含登录界面和数据库认证)
192 ├── user_util.py # 用户管理工具(管理员专用)
193 ├── requirements.txt # Python 依赖
194 ├── config.json # 配置文件(API密钥+数据库配置)
195 ├── build_windows.bat # Windows 打包脚本
196 ├── build_mac.sh # macOS 打包脚本
197 └── README.md # 本文件
198 ```
199
200 ## 技术栈
201
202 - **GUI 框架**: Tkinter(Python 内置)
203 - **图片处理**: Pillow
204 - **API 客户端**: google-genai
205 - **数据库**: PyMySQL
206 - **打包工具**: PyInstaller
207
208 ## 获取 API 密钥
209
210 访问 [Google AI Studio](https://makersuite.google.com/app/apikey) 获取免费的 API 密钥。
211
212 ## 注意事项
213
214 - API 密钥会保存在 `config.json` 文件中,请妥善保管
215 - 使用 API 可能会产生费用,请查看 Google AI 的定价信息
216 - 生成高分辨率图片(4K)需要更多时间和 API 配额
217
218 ## 故障排查
219
220 ### 登录相关问题
221
222 **无法登录 / 数据库连接失败**
223 - 检查 `config.json` 中的 `db_config` 配置是否正确
224 - 确认数据库服务器可访问(检查防火墙/网络)
225 - 验证数据库用户名和密码是否正确
226 - 确认表 `nano_banana_users` 已创建
227
228 **"未找到数据库配置" 错误**
229 - 确保 `config.json` 包含 `db_config` 字段
230 - 参考快速开始章节的配置示例
231
232 **"用户名或密码错误" 提示**
233 - 使用 `python user_util.py list` 查看用户列表
234 - 确认用户状态为 'active'
235 - 使用 `user_util.py` 重置密码或创建新用户
236
237 **密码不匹配**
238 - 确保数据库中存储的是 SHA256 哈希值,而非明文密码
239 - 使用 `user_util.py add` 添加用户,会自动计算哈希
240
241 ### 配置文件只读错误(macOS/Windows 打包应用)
242 **问题**: 提示 "read-only file system: config.json"
243
244 **原因**: 打包后的应用资源目录是只读的,无法在应用包内写入文件
245
246 **解决方案**:
247 - ✅ 已修复:应用现在会自动将配置保存到用户目录
248 - macOS: `~/Library/Application Support/ZB100ImageGenerator/config.json`
249 - Windows: `%APPDATA%\ZB100ImageGenerator\config.json`
250 - 首次运行会自动创建配置文件夹和文件
251
252 ### 生成失败
253 - 检查 API 密钥是否正确
254 - 检查网络连接是否正常
255 - 查看错误信息,确认是否超出配额
256
257 ### 找不到 API 密钥
258 - 开发模式:检查项目目录下的 `config.json` 文件
259 - 打包应用:检查用户目录下的配置文件(见上方配置文件位置)
260 - 手动创建配置文件并添加完整配置(参考快速开始章节)
261
262 ### 打包失败
263 - 确保安装了所有依赖:`pip install -r requirements.txt`
264 - 检查 Python 版本是否符合要求(3.8+)
265 - Windows: 确保有 `zb100_kehuan.ico` 图标文件(或修改打包脚本移除 `--icon` 参数)
266 - 注意: `user_util.py` 不应打包进客户端版本(仅管理员使用)
267
268 ## 技术设计原则
269
270 本项目遵循 Linus Torvalds 的设计哲学:
271
272 - **简洁至上**: 使用 Tkinter 内置 GUI,避免重型框架
273 - **零特殊情况**: 统一的错误处理和数据流
274 - **实用主义**: 直接解决问题,不过度设计
275 - **清晰数据结构**: 简单的配置管理和图片数据流
276
277 ## 许可证
278
279 MIT License
1 # -*- mode: python ; coding: utf-8 -*-
2
3
4 a = Analysis(
5 ['image_generator.py'],
6 pathex=[],
7 binaries=[],
8 datas=[('config.json', '.')],
9 hiddenimports=[],
10 hookspath=[],
11 hooksconfig={},
12 runtime_hooks=[],
13 excludes=[],
14 noarchive=False,
15 optimize=0,
16 )
17 pyz = PYZ(a.pure)
18
19 exe = EXE(
20 pyz,
21 a.scripts,
22 a.binaries,
23 a.datas,
24 [],
25 name='ZB100ImageGenerator',
26 debug=False,
27 bootloader_ignore_signals=False,
28 strip=False,
29 upx=True,
30 upx_exclude=[],
31 runtime_tmpdir=None,
32 console=False,
33 disable_windowed_traceback=False,
34 argv_emulation=False,
35 target_arch=None,
36 codesign_identity=None,
37 entitlements_file=None,
38 icon=['zb100_kehuan.ico'],
39 )
1 #!/bin/bash
2 # macOS Build Script for Gemini Image Generator
3
4 echo "================================"
5 echo "Building Gemini Image Generator"
6 echo "================================"
7
8 # Check if virtual environment exists
9 if [ ! -d "venv" ]; then
10 echo "Creating virtual environment..."
11 python3 -m venv venv
12 fi
13
14 # Activate virtual environment
15 echo "Activating virtual environment..."
16 source venv/bin/activate
17
18 # Install dependencies
19 echo "Installing dependencies..."
20 pip install --upgrade pip
21 pip install -r requirements.txt
22
23 # Clean previous builds
24 echo "Cleaning previous builds..."
25 rm -rf build dist *.spec
26
27 # Build executable
28 echo "Building executable..."
29 pyinstaller --name="ZB100ImageGenerator" \
30 --onefile \
31 --windowed \
32 --add-data "config.json:." \
33 image_generator_qt.py
34
35 # Check if build was successful
36 if [ -f "dist/ZB100ImageGenerator.app/Contents/MacOS/ZB100ImageGenerator" ] || [ -f "dist/ZB100ImageGenerator" ]; then
37 echo "================================"
38 echo "Build successful!"
39 echo "Application: dist/ZB100ImageGenerator.app (or dist/ZB100ImageGenerator)"
40 echo "================================"
41 else
42 echo "================================"
43 echo "Build failed!"
44 echo "================================"
45 fi
1 @echo off
2 REM Windows Build Script for Gemini Image Generator
3
4 echo ================================
5 echo Building Gemini Image Generator
6 echo ================================
7
8 REM Check if virtual environment exists
9 if not exist "venv" (
10 echo Creating virtual environment...
11 python -m venv venv
12 )
13
14 REM Activate virtual environment
15 echo Activating virtual environment...
16 call venv\Scripts\activate.bat
17
18 REM Install dependencies
19 echo Installing dependencies...
20 pip install --upgrade pip
21 pip install -r requirements.txt
22
23 REM Clean previous builds
24 echo Cleaning previous builds...
25 if exist "build" rd /s /q build
26 if exist "dist" rd /s /q dist
27 if exist "*.spec" del /q *.spec
28
29 REM Build executable
30 echo Building executable...
31 pyinstaller --name="ZB100ImageGenerator" ^
32 --onefile ^
33 --windowed ^
34 --icon=zb100_kehuan.ico ^
35 --add-data "config.json;." ^
36 image_generator_qt.py
37
38 REM Check if build was successful
39 if exist "dist\ZB100ImageGenerator.exe" (
40 echo ================================
41 echo Build successful!
42 echo Executable: dist\ZB100ImageGenerator.exe
43 echo ================================
44 ) else (
45 echo ================================
46 echo Build failed!
47 echo ================================
48 )
49
50 pause
1 @echo off
2 REM 导出 Windows 环境的精确依赖版本
3
4 echo 正在导出依赖版本...
5
6 pip freeze | findstr /C:"google-genai" /C:"Pillow" /C:"PyQt5" /C:"pyinstaller" > requirements-lock.txt
7
8 echo.
9 echo 已导出到 requirements-lock.txt
10 echo 请将此文件复制到 Mac 上使用
11 echo.
12
13 type requirements-lock.txt
14
15 pause
1 # Qt GUI 版本依赖
2 # 核心依赖
3 google-genai>=1.0.0,<2.0.0
4 Pillow>=10.0.0,<11.0.0
5 PyQt5>=5.15.0,<6.0.0
6
7 # 数据库依赖
8 pymysql>=1.0.0,<2.0.0
9
10 # 打包工具
11 pyinstaller>=6.0.0,<7.0.0
1 #!/bin/bash
2 # Mac 环境设置脚本
3
4 echo "================================"
5 echo "Mac 环境设置 - Qt 版本"
6 echo "================================"
7
8 # 检查 Python 版本
9 python_version=$(python3 --version 2>&1)
10 echo "Python 版本: $python_version"
11
12 # 创建虚拟环境
13 if [ ! -d "venv" ]; then
14 echo "创建虚拟环境..."
15 python3 -m venv venv
16 fi
17
18 # 激活虚拟环境
19 echo "激活虚拟环境..."
20 source venv/bin/activate
21
22 # 升级 pip
23 echo "升级 pip..."
24 pip install --upgrade pip
25
26 # 卸载可能冲突的旧版本
27 echo "清理旧版本..."
28 pip uninstall -y google-genai Pillow PyQt5 pyinstaller 2>/dev/null
29
30 # 安装依赖
31 echo "================================"
32 echo "安装依赖..."
33 echo "================================"
34
35 # 如果有锁定版本文件,优先使用
36 if [ -f "requirements-lock.txt" ]; then
37 echo "使用锁定版本 (requirements-lock.txt)..."
38 pip install -r requirements-lock.txt
39 else
40 echo "使用范围版本 (requirements.txt)..."
41 pip install -r requirements.txt
42 fi
43
44 # 验证安装
45 echo "================================"
46 echo "验证安装..."
47 echo "================================"
48
49 pip list | grep -E "google-genai|Pillow|PyQt5|pyinstaller"
50
51 echo "================================"
52 echo "设置完成!"
53 echo "================================"
54 echo ""
55 echo "运行应用: python3 image_generator_qt.py"
56 echo ""
1 #!/usr/bin/env python3
2 # -*- coding: utf-8 -*-
3 """
4 用户管理工具 - 管理员专用
5
6 用法:
7 python user_util.py add <username> <password> # 添加用户
8 python user_util.py list # 列出用户
9 python user_util.py disable <username> # 禁用用户
10 python user_util.py enable <username> # 启用用户
11 python user_util.py reset <username> <password> # 重置密码
12
13 安全提示:
14 - 此工具仅供管理员使用,请勿分发给用户
15 - 避免在命令行直接输入密码(可被 shell 历史记录)
16 - 建议使用环境变量或交互式输入密码
17 """
18
19 import hashlib
20 import pymysql
21 import json
22 import sys
23 import os
24 from pathlib import Path
25
26 # Windows 控制台编码修复
27 if sys.platform == 'win32':
28 import codecs
29 sys.stdout = codecs.getwriter('utf-8')(sys.stdout.buffer, 'strict')
30 sys.stderr = codecs.getwriter('utf-8')(sys.stderr.buffer, 'strict')
31
32
33 def hash_password(password: str) -> str:
34 """使用 SHA256 哈希密码"""
35 return hashlib.sha256(password.encode('utf-8')).hexdigest()
36
37
38 class UserManager:
39 """用户管理类"""
40 def __init__(self, db_config):
41 self.config = db_config
42
43 def add_user(self, username, password):
44 """添加新用户"""
45 hashed = hash_password(password)
46 conn = None
47 try:
48 conn = pymysql.connect(
49 host=self.config['host'],
50 port=self.config.get('port', 3306),
51 user=self.config['user'],
52 password=self.config['password'],
53 database=self.config['database'],
54 connect_timeout=5
55 )
56
57 with conn.cursor() as cursor:
58 sql = f"INSERT INTO {self.config['table']} (user_name, passwd, status) VALUES (%s, %s, %s)"
59 cursor.execute(sql, (username, hashed, 'active'))
60 conn.commit()
61 print(f"✓ 用户 '{username}' 添加成功")
62 print(f" 密码哈希: {hashed[:16]}...")
63
64 except pymysql.IntegrityError:
65 print(f"✗ 用户 '{username}' 已存在")
66 except pymysql.OperationalError as e:
67 print(f"✗ 数据库连接失败: {e}")
68 except Exception as e:
69 print(f"✗ 添加用户失败: {e}")
70 finally:
71 if conn:
72 conn.close()
73
74 def list_users(self):
75 """列出所有用户"""
76 conn = None
77 try:
78 conn = pymysql.connect(
79 host=self.config['host'],
80 port=self.config.get('port', 3306),
81 user=self.config['user'],
82 password=self.config['password'],
83 database=self.config['database'],
84 connect_timeout=5
85 )
86
87 with conn.cursor() as cursor:
88 sql = f"SELECT user_name, passwd, status FROM {self.config['table']}"
89 cursor.execute(sql)
90 results = cursor.fetchall()
91
92 if not results:
93 print("没有找到任何用户")
94 return
95
96 # 打印表格
97 print("\n用户列表:")
98 print(" ┌────────────────────────┬──────────┬──────────────────┐")
99 print(" │ 用户名 │ 状态 │ 密码哈希(前8位) │")
100 print(" ├────────────────────────┼──────────┼──────────────────┤")
101
102 for row in results:
103 username = row[0] or ""
104 passwd_hash = row[1] or ""
105 status = row[2] or "NULL"
106
107 # 填充空格使对齐
108 username_display = username[:20].ljust(20)
109 status_display = status[:8].ljust(8)
110 hash_display = passwd_hash[:16] if passwd_hash else "N/A".ljust(16)
111
112 print(f" │ {username_display} │ {status_display} │ {hash_display} │")
113
114 print(" └────────────────────────┴──────────┴──────────────────┘")
115 print(f"\n总计: {len(results)} 个用户\n")
116
117 except pymysql.OperationalError as e:
118 print(f"✗ 数据库连接失败: {e}")
119 except Exception as e:
120 print(f"✗ 查询用户失败: {e}")
121 finally:
122 if conn:
123 conn.close()
124
125 def disable_user(self, username):
126 """禁用用户"""
127 self._update_user_status(username, 'disabled', "已禁用")
128
129 def enable_user(self, username):
130 """启用用户"""
131 self._update_user_status(username, 'active', "已启用")
132
133 def _update_user_status(self, username, status, action_name):
134 """更新用户状态"""
135 conn = None
136 try:
137 conn = pymysql.connect(
138 host=self.config['host'],
139 port=self.config.get('port', 3306),
140 user=self.config['user'],
141 password=self.config['password'],
142 database=self.config['database'],
143 connect_timeout=5
144 )
145
146 with conn.cursor() as cursor:
147 sql = f"UPDATE {self.config['table']} SET status=%s WHERE user_name=%s"
148 affected = cursor.execute(sql, (status, username))
149
150 if affected > 0:
151 conn.commit()
152 print(f"✓ 用户 '{username}' {action_name}")
153 else:
154 print(f"✗ 用户 '{username}' 不存在")
155
156 except pymysql.OperationalError as e:
157 print(f"✗ 数据库连接失败: {e}")
158 except Exception as e:
159 print(f"✗ 更新用户状态失败: {e}")
160 finally:
161 if conn:
162 conn.close()
163
164 def reset_password(self, username, new_password):
165 """重置用户密码"""
166 hashed = hash_password(new_password)
167 conn = None
168 try:
169 conn = pymysql.connect(
170 host=self.config['host'],
171 port=self.config.get('port', 3306),
172 user=self.config['user'],
173 password=self.config['password'],
174 database=self.config['database'],
175 connect_timeout=5
176 )
177
178 with conn.cursor() as cursor:
179 sql = f"UPDATE {self.config['table']} SET passwd=%s WHERE user_name=%s"
180 affected = cursor.execute(sql, (hashed, username))
181
182 if affected > 0:
183 conn.commit()
184 print(f"✓ 用户 '{username}' 密码已重置")
185 print(f" 新密码哈希: {hashed[:16]}...")
186 else:
187 print(f"✗ 用户 '{username}' 不存在")
188
189 except pymysql.OperationalError as e:
190 print(f"✗ 数据库连接失败: {e}")
191 except Exception as e:
192 print(f"✗ 重置密码失败: {e}")
193 finally:
194 if conn:
195 conn.close()
196
197
198 def load_db_config():
199 """从 config.json 加载数据库配置"""
200 config_path = Path('config.json')
201
202 if not config_path.exists():
203 print(f"✗ 配置文件不存在: {config_path}")
204 print(f" 请确保在项目目录下运行此工具")
205 return None
206
207 try:
208 with open(config_path, 'r', encoding='utf-8') as f:
209 config = json.load(f)
210 db_config = config.get('db_config')
211
212 if not db_config:
213 print("✗ 配置文件中未找到 db_config 字段")
214 return None
215
216 required_fields = ['host', 'user', 'password', 'database', 'table']
217 missing = [f for f in required_fields if f not in db_config]
218
219 if missing:
220 print(f"✗ db_config 缺少必需字段: {', '.join(missing)}")
221 return None
222
223 return db_config
224
225 except json.JSONDecodeError:
226 print(f"✗ 配置文件格式错误: {config_path}")
227 return None
228 except Exception as e:
229 print(f"✗ 加载配置失败: {e}")
230 return None
231
232
233 def print_help():
234 """打印帮助信息"""
235 print(__doc__)
236
237
238 def main():
239 """主函数"""
240 if len(sys.argv) < 2:
241 print_help()
242 sys.exit(1)
243
244 command = sys.argv[1].lower()
245
246 # 加载数据库配置
247 db_config = load_db_config()
248 if not db_config:
249 sys.exit(1)
250
251 manager = UserManager(db_config)
252
253 # 处理命令
254 if command == 'add':
255 if len(sys.argv) != 4:
256 print("用法: python user_util.py add <username> <password>")
257 sys.exit(1)
258 username = sys.argv[2]
259 password = sys.argv[3]
260 manager.add_user(username, password)
261
262 elif command == 'list':
263 manager.list_users()
264
265 elif command == 'disable':
266 if len(sys.argv) != 3:
267 print("用法: python user_util.py disable <username>")
268 sys.exit(1)
269 username = sys.argv[2]
270 manager.disable_user(username)
271
272 elif command == 'enable':
273 if len(sys.argv) != 3:
274 print("用法: python user_util.py enable <username>")
275 sys.exit(1)
276 username = sys.argv[2]
277 manager.enable_user(username)
278
279 elif command == 'reset':
280 if len(sys.argv) != 4:
281 print("用法: python user_util.py reset <username> <password>")
282 sys.exit(1)
283 username = sys.argv[2]
284 new_password = sys.argv[3]
285 manager.reset_password(username, new_password)
286
287 else:
288 print(f"✗ 未知命令: {command}")
289 print_help()
290 sys.exit(1)
291
292
293 if __name__ == '__main__':
294 main()
No preview for this file type