CoolFace
Apppublic

wangyiyi666/model-optimizer

sourceHugging Faceupdated 2mo agoView on Hugging Face
1likes
app_flask_old.py177 linesDownload Raw Back to root
1"""2模型优化服务 - Flask 前端3第一版:本地测试模式(先跑通完整通路)4 5后续部署到 HF Space 时可切换为 Gradio 版本6"""7from flask import Flask, request, render_template_string, send_file, jsonify8import os9import uuid10import shutil11from datetime import datetime12 13app = Flask(__name__)14 15# === 配置 ===16BASE_DIR = os.path.dirname(os.path.abspath(__file__))17INBOX = os.path.join(BASE_DIR, "..", "local", "tmp", "inbox")18OUTBOX = os.path.join(BASE_DIR, "..", "local", "tmp", "outbox")19os.makedirs(INBOX, exist_ok=True)20os.makedirs(OUTBOX, exist_ok=True)21 22SUPPORTED_FORMATS = [".glb", ".gltf", ".fbx", ".obj"]23 24def log(msg):25    timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")26    print(f"[{timestamp}] [WEB] {msg}")27 28 29HTML_TEMPLATE = """30<!DOCTYPE html>31<html>32<head>33    <title>3D 模型优化服务</title>34    <meta charset="utf-8">35    <style>36        body { font-family: -apple-system, sans-serif; max-width: 700px; margin: 50px auto; padding: 20px; background: #f5f5f5; }37        .card { background: white; border-radius: 12px; padding: 30px; margin: 20px 0; box-shadow: 0 2px 10px rgba(0,0,0,0.1); }38        h1 { text-align: center; color: #333; }39        .upload-area { border: 2px dashed #ccc; border-radius: 8px; padding: 40px; text-align: center; margin: 20px 0; }40        .upload-area:hover { border-color: #667eea; }41        input[type="file"] { margin: 10px 0; }42        button { background: #667eea; color: white; border: none; padding: 12px 30px; border-radius: 6px; cursor: pointer; font-size: 16px; }43        button:hover { background: #5a67d8; }44        .result { padding: 15px; border-radius: 8px; margin: 15px 0; }45        .success { background: #d4edda; color: #155724; }46        .waiting { background: #fff3cd; color: #856404; }47        .error { background: #f8d7da; color: #721c24; }48        input[type="text"] { padding: 10px; width: 200px; border: 1px solid #ddd; border-radius: 6px; font-size: 16px; }49        .info { color: #666; font-size: 14px; }50        a.download { display: inline-block; background: #28a745; color: white; padding: 10px 20px; border-radius: 6px; text-decoration: none; margin-top: 10px; }51    </style>52</head>53<body>54    <h1>🛠️ 3D 模型优化服务</h1>55    56    <div class="card">57        <h2>📤 上传模型</h2>58        <form action="/upload" method="post" enctype="multipart/form-data">59            <div class="upload-area">60                <p>选择 3D 模型文件</p>61                <input type="file" name="model" accept=".glb,.gltf,.fbx,.obj">62                <p class="info">支持格式: GLB, GLTF, FBX, OBJ</p>63            </div>64            <button type="submit">🚀 提交优化</button>65        </form>66        {% if upload_msg %}67        <div class="result {{ upload_class }}">{{ upload_msg }}</div>68        {% endif %}69    </div>70 71    <div class="card">72        <h2>🔍 查询结果</h2>73        <form action="/status" method="get">74            <input type="text" name="task_id" placeholder="输入任务ID" value="{{ query_id or '' }}">75            <button type="submit">查询</button>76        </form>77        {% if status_msg %}78        <div class="result {{ status_class }}">{{ status_msg }}</div>79        {% endif %}80        {% if download_ready %}81        <a class="download" href="/download/{{ download_id }}">⬇️ 下载优化结果</a>82        {% endif %}83    </div>84 85    <div class="info" style="text-align:center; margin-top: 30px;">86        输出格式: GLB | Worker 每30秒检查一次任务87    </div>88</body>89</html>90"""91 92 93@app.route("/")94def index():95    return render_template_string(HTML_TEMPLATE)96 97 98@app.route("/upload", methods=["POST"])99def upload():100    file = request.files.get("model")101    if not file or file.filename == "":102        return render_template_string(HTML_TEMPLATE, 103            upload_msg="请选择文件", upload_class="error")104 105    filename = file.filename106    ext = os.path.splitext(filename)[1].lower()107    log(f"收到上传: {filename}")108 109    if ext not in SUPPORTED_FORMATS:110        log(f"格式不支持: {ext}")111        return render_template_string(HTML_TEMPLATE,112            upload_msg=f"不支持的格式: {ext}", upload_class="error")113 114    # 生成任务ID并保存文件115    task_id = str(uuid.uuid4())[:8]116    target_path = os.path.join(INBOX, f"{task_id}{ext}")117    file.save(target_path)118    file_size = os.path.getsize(target_path)119 120    log(f"文件已保存: {task_id}{ext} ({file_size} bytes), 任务ID: {task_id}")121 122    return render_template_string(HTML_TEMPLATE,123        upload_msg=f"✅ 上传成功!任务ID: {task_id}  (请保存此ID用于查询结果)",124        upload_class="success")125 126 127@app.route("/status")128def status():129    task_id = request.args.get("task_id", "").strip()130    if not task_id:131        return render_template_string(HTML_TEMPLATE,132            status_msg="请输入任务ID", status_class="error", query_id=task_id)133 134    log(f"查询状态: {task_id}")135 136    # 检查 outbox137    result_file = os.path.join(OUTBOX, f"{task_id}_optimized.glb")138    if os.path.exists(result_file):139        size = os.path.getsize(result_file)140        log(f"任务 {task_id} 已完成 ({size} bytes)")141        return render_template_string(HTML_TEMPLATE,142            status_msg=f"✅ 优化完成!文件大小: {size} bytes",143            status_class="success", download_ready=True, 144            download_id=task_id, query_id=task_id)145 146    # 检查 inbox147    for f in os.listdir(INBOX):148        if f.startswith(task_id):149            log(f"任务 {task_id} 仍在队列中")150            return render_template_string(HTML_TEMPLATE,151                status_msg="⏳ 处理中,请稍后再查询...",152                status_class="waiting", query_id=task_id)153 154    log(f"任务 {task_id} 未找到")155    return render_template_string(HTML_TEMPLATE,156        status_msg="❌ 未找到该任务,请检查ID是否正确",157        status_class="error", query_id=task_id)158 159 160@app.route("/download/<task_id>")161def download(task_id):162    result_file = os.path.join(OUTBOX, f"{task_id}_optimized.glb")163    if os.path.exists(result_file):164        log(f"用户下载: {task_id}_optimized.glb")165        return send_file(result_file, as_attachment=True,166                        download_name=f"{task_id}_optimized.glb")167    return "文件不存在", 404168 169 170if __name__ == "__main__":171    log("=" * 40)172    log("Web 前端启动")173    log(f"  Inbox:  {INBOX}")174    log(f"  Outbox: {OUTBOX}")175    log("=" * 40)176    app.run(host="0.0.0.0", port=5000, debug=True)177