Spaces:
Sleeping
Sleeping
Upload 8 files
Browse files- .env.example +12 -0
- .gitignore +1 -1
- main.py +17 -0
- requirements.txt +5 -1
.env.example
CHANGED
|
@@ -13,6 +13,18 @@ ADMIN_KEY=your-admin-secret-key
|
|
| 13 |
# 服务端口(可选,默认 7860)
|
| 14 |
# PORT=7860
|
| 15 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 16 |
# ============================================
|
| 17 |
# 其他配置请在管理面板的"系统设置"中配置
|
| 18 |
# 包括:API密钥、代理、图片生成、重试策略等
|
|
|
|
| 13 |
# 服务端口(可选,默认 7860)
|
| 14 |
# PORT=7860
|
| 15 |
|
| 16 |
+
# ============================================
|
| 17 |
+
# 数据库配置(可选,用于无持久化存储的环境如 HF Spaces)
|
| 18 |
+
# ============================================
|
| 19 |
+
# 支持 PostgreSQL 数据库存储(账户/设置/统计)
|
| 20 |
+
# 未设置时使用本地文件存储(原有行为)
|
| 21 |
+
#
|
| 22 |
+
# 示例(Neon PostgreSQL):
|
| 23 |
+
# DATABASE_URL=postgresql://user:password@ep-xxx.aws.neon.tech/dbname?sslmode=require
|
| 24 |
+
#
|
| 25 |
+
# 注意:使用数据库存储需要安装 asyncpg:pip install asyncpg
|
| 26 |
+
# DATABASE_URL=
|
| 27 |
+
|
| 28 |
# ============================================
|
| 29 |
# 其他配置请在管理面板的"系统设置"中配置
|
| 30 |
# 包括:API密钥、代理、图片生成、重试策略等
|
.gitignore
CHANGED
|
@@ -24,7 +24,7 @@ wheels/
|
|
| 24 |
venv/
|
| 25 |
env/
|
| 26 |
ENV/
|
| 27 |
-
|
| 28 |
# IDE
|
| 29 |
.vscode/
|
| 30 |
.idea/
|
|
|
|
| 24 |
venv/
|
| 25 |
env/
|
| 26 |
ENV/
|
| 27 |
+
.venv
|
| 28 |
# IDE
|
| 29 |
.vscode/
|
| 30 |
.idea/
|
main.py
CHANGED
|
@@ -72,6 +72,9 @@ from core import uptime as uptime_tracker
|
|
| 72 |
# 导入配置管理和模板系统
|
| 73 |
from core.config import config_manager, config
|
| 74 |
|
|
|
|
|
|
|
|
|
|
| 75 |
# ---------- 日志配置 ----------
|
| 76 |
|
| 77 |
# 内存日志缓冲区 (保留最近 3000 条日志,重启后清空)
|
|
@@ -83,6 +86,13 @@ stats_lock = asyncio.Lock() # 改为异步锁
|
|
| 83 |
|
| 84 |
async def load_stats():
|
| 85 |
"""加载统计数据(异步)。"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
try:
|
| 87 |
if os.path.exists(STATS_FILE):
|
| 88 |
async with aiofiles.open(STATS_FILE, 'r', encoding='utf-8') as f:
|
|
@@ -104,6 +114,13 @@ async def load_stats():
|
|
| 104 |
|
| 105 |
async def save_stats(stats):
|
| 106 |
"""保存统计数据(异步,避免阻塞事件循环)"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 107 |
try:
|
| 108 |
async with aiofiles.open(STATS_FILE, 'w', encoding='utf-8') as f:
|
| 109 |
await f.write(json.dumps(stats, ensure_ascii=False, indent=2))
|
|
|
|
| 72 |
# 导入配置管理和模板系统
|
| 73 |
from core.config import config_manager, config
|
| 74 |
|
| 75 |
+
# 数据库存储支持
|
| 76 |
+
from core import storage
|
| 77 |
+
|
| 78 |
# ---------- 日志配置 ----------
|
| 79 |
|
| 80 |
# 内存日志缓冲区 (保留最近 3000 条日志,重启后清空)
|
|
|
|
| 86 |
|
| 87 |
async def load_stats():
|
| 88 |
"""加载统计数据(异步)。"""
|
| 89 |
+
if storage.is_database_enabled():
|
| 90 |
+
try:
|
| 91 |
+
data = await asyncio.to_thread(storage.load_stats_sync)
|
| 92 |
+
if isinstance(data, dict):
|
| 93 |
+
return data
|
| 94 |
+
except Exception as e:
|
| 95 |
+
logger.error(f"[STATS] 数据库加载失败: {str(e)[:50]}")
|
| 96 |
try:
|
| 97 |
if os.path.exists(STATS_FILE):
|
| 98 |
async with aiofiles.open(STATS_FILE, 'r', encoding='utf-8') as f:
|
|
|
|
| 114 |
|
| 115 |
async def save_stats(stats):
|
| 116 |
"""保存统计数据(异步,避免阻塞事件循环)"""
|
| 117 |
+
if storage.is_database_enabled():
|
| 118 |
+
try:
|
| 119 |
+
saved = await asyncio.to_thread(storage.save_stats_sync, stats)
|
| 120 |
+
if saved:
|
| 121 |
+
return
|
| 122 |
+
except Exception as e:
|
| 123 |
+
logger.error(f"[STATS] 数据库保存失败: {str(e)[:50]}")
|
| 124 |
try:
|
| 125 |
async with aiofiles.open(STATS_FILE, 'w', encoding='utf-8') as f:
|
| 126 |
await f.write(json.dumps(stats, ensure_ascii=False, indent=2))
|
requirements.txt
CHANGED
|
@@ -7,4 +7,8 @@ python-dotenv==1.0.1
|
|
| 7 |
itsdangerous==2.1.2
|
| 8 |
python-multipart==0.0.6
|
| 9 |
pyyaml>=6.0
|
| 10 |
-
jinja2>=3.1.0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
itsdangerous==2.1.2
|
| 8 |
python-multipart==0.0.6
|
| 9 |
pyyaml>=6.0
|
| 10 |
+
jinja2>=3.1.0
|
| 11 |
+
|
| 12 |
+
# 可选:PostgreSQL 数据库支持(用于 HF Spaces 等无持久化存储的环境)
|
| 13 |
+
# 如需使用,请取消下行注释并设置 DATABASE_URL 环境变量
|
| 14 |
+
# asyncpg>=0.29.0
|