Files
Story-extractor/run.py
2026-04-24 16:02:16 +08:00

127 lines
3.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
故事提取工具 - 入口脚本
支持开发模式和 PyInstaller 打包模式
"""
import os
import sys
import shutil
import socket
import webbrowser
import threading
import time
def get_base_dir() -> str:
"""获取基础目录"""
if getattr(sys, 'frozen', False):
return os.path.dirname(sys.executable)
else:
return os.path.dirname(os.path.abspath(__file__))
def cleanup_data(base_dir: str):
"""启动时清理数据库缓存和临时文件"""
print("正在清理上次运行的数据...")
# 实际数据目录(开发模式下在 backend/ 下,打包后在 exe 同级目录下)
if getattr(sys, 'frozen', False):
data_dir = base_dir
else:
data_dir = os.path.join(base_dir, "backend")
# 清理数据库
db_dir = os.path.join(data_dir, "data")
if os.path.exists(db_dir):
for f in os.listdir(db_dir):
if f.endswith((".db", ".db-wal", ".db-shm", ".db-journal")):
try:
os.remove(os.path.join(db_dir, f))
except Exception:
pass
# 清理上传的文件
uploads_dir = os.path.join(data_dir, "uploads")
if os.path.exists(uploads_dir):
for subdir in ["transcripts", "persons", "photos"]:
sub = os.path.join(uploads_dir, subdir)
if os.path.exists(sub):
shutil.rmtree(sub, ignore_errors=True)
# 清理导出文件
exports_dir = os.path.join(data_dir, "exports")
if os.path.exists(exports_dir):
shutil.rmtree(exports_dir, ignore_errors=True)
# 重新创建目录结构
for d in [db_dir, uploads_dir, exports_dir]:
os.makedirs(d, exist_ok=True)
for sub in ["transcripts", "persons", "photos"]:
os.makedirs(os.path.join(uploads_dir, sub), exist_ok=True)
print("清理完成!")
def find_free_port(start_port: int = 8000) -> int:
"""找到一个可用端口"""
for port in range(start_port, start_port + 100):
try:
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
s.bind(("127.0.0.1", port))
return port
except OSError:
continue
return start_port
def open_browser(port: int):
"""延迟打开浏览器"""
time.sleep(2)
url = f"http://localhost:{port}"
print(f"\n正在打开浏览器: {url}")
webbrowser.open(url)
def main():
base_dir = get_base_dir()
# 1. 清理数据
cleanup_data(base_dir)
# 2. 找可用端口
port = find_free_port(8000)
if port != 8000:
print(f"端口 8000 被占用,使用端口 {port}")
# 3. 启动服务
print(f"\n{'='*50}")
print(f" 故事提取工具")
print(f" 访问地址: http://localhost:{port}")
print(f" 按 Ctrl+C 停止服务")
print(f"{'='*50}\n")
# 延迟打开浏览器(不阻塞主线程)
threading.Thread(target=open_browser, args=(port,), daemon=True).start()
# 启动 uvicorn
os.environ["APP_PORT"] = str(port)
if getattr(sys, 'frozen', False):
# 打包模式:直接 import 并运行
import uvicorn
# 把 backend 目录加到 path让 app 包能被找到
backend_dir = os.path.join(base_dir, "backend")
if backend_dir not in sys.path:
sys.path.insert(0, backend_dir)
uvicorn.run("app.main:app", host="0.0.0.0", port=port, log_level="info")
else:
# 开发模式
import uvicorn
backend_dir = os.path.join(base_dir, "backend")
if backend_dir not in sys.path:
sys.path.insert(0, backend_dir)
uvicorn.run("app.main:app", host="0.0.0.0", port=port, log_level="info")
if __name__ == "__main__":
main()