init
This commit is contained in:
126
run.py
Normal file
126
run.py
Normal file
@@ -0,0 +1,126 @@
|
||||
"""
|
||||
故事提取工具 - 入口脚本
|
||||
支持开发模式和 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()
|
||||
Reference in New Issue
Block a user