diff --git a/修复文件/Dockerfile b/修复文件/Dockerfile new file mode 100644 index 0000000..d6d669f --- /dev/null +++ b/修复文件/Dockerfile @@ -0,0 +1,37 @@ +# 基础镜像选择 +FROM python:3.10-slim + +# 设置工作目录 +WORKDIR /app + +# 安装系统依赖 +RUN apt-get update && \ + apt-get install -y --no-install-recommends \ + build-essential \ + ffmpeg \ + && apt-get clean \ + && rm -rf /var/lib/apt/lists/* + +# 拷贝依赖文件并安装 +COPY requirements.txt . +RUN pip install --no-cache-dir -r requirements.txt + +# 拷贝应用文件 +COPY . . + +# 创建必要的目录 +RUN mkdir -p uploads output /mounted_summaries + +# 设置环境变量 +ENV PYTHONUNBUFFERED=1 +ENV GUNICORN_CMD_ARGS="--config=gunicorn_config.py" +ENV PORT=5000 + +# 添加执行权限 +RUN chmod +x /app/entrypoint.sh + +# 暴露端口 +EXPOSE 5000 + +# 使用entrypoint.sh作为启动命令 +ENTRYPOINT ["/app/entrypoint.sh"] \ No newline at end of file diff --git a/修复文件/docker_fix_all.sh b/修复文件/docker_fix_all.sh new file mode 100644 index 0000000..7d51367 --- /dev/null +++ b/修复文件/docker_fix_all.sh @@ -0,0 +1,38 @@ +#!/bin/bash +# 综合修复脚本,应用所有修复并重启服务 + +set -e +echo "开始执行综合修复..." + +# 备份当前app.py文件 +echo "备份原始app.py文件..." +cp /app/app.py /app/app.py.backup.original + +# 应用路由修复 +echo "应用路由修复..." +python3 /app/fix_routes.py + +# 应用进度显示修复 +echo "应用进度显示修复..." +python3 /app/fix_progress.py + +# 应用上传显示修复 +echo "应用上传文件后显示修复..." +python3 /app/fix_upload_display.py + +# 创建entrypoint.sh文件 +echo "创建entrypoint.sh启动脚本..." +cat > /app/entrypoint.sh << 'EOF' +#!/bin/bash +cd /app +gunicorn app:app -b 0.0.0.0:5000 +EOF + +# 添加执行权限 +chmod +x /app/entrypoint.sh + +echo "所有修复已应用完成!服务将重新启动..." + +# 重启服务 +cd /app +exec /app/entrypoint.sh \ No newline at end of file diff --git a/修复文件/entrypoint.sh b/修复文件/entrypoint.sh new file mode 100644 index 0000000..64a02c7 --- /dev/null +++ b/修复文件/entrypoint.sh @@ -0,0 +1,3 @@ +#!/bin/bash +cd /app +gunicorn app:app -b 0.0.0.0:5000 \ No newline at end of file diff --git a/修复文件/fix_progress.py b/修复文件/fix_progress.py new file mode 100644 index 0000000..914afda --- /dev/null +++ b/修复文件/fix_progress.py @@ -0,0 +1,162 @@ +#!/usr/bin/env python3 +# 修复任务列表,显示正确的处理进度 + +import os +import logging + +# 配置日志 +logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s') +logger = logging.getLogger(__name__) + +def fix_progress(): + try: + app_file = '/app/app.py' + backup_file = '/app/app.py.backup.progress' + + # 备份原始文件 + if os.path.exists(app_file): + with open(app_file, 'r', encoding='utf-8') as f: + original_content = f.read() + + with open(backup_file, 'w', encoding='utf-8') as f: + f.write(original_content) + + logger.info(f"已备份原始文件到 {backup_file}") + + # 新的 api_get_tasks 函数实现 + new_api_tasks_function = ''' +@app.route('/api/tasks') +def api_get_tasks(): + """获取所有任务列表""" + tasks = [] + try: + # 遍历输出目录中的所有作业 + for job_id in os.listdir(app.config['OUTPUT_FOLDER']): + job_dir = os.path.join(app.config['OUTPUT_FOLDER'], job_id) + if os.path.isdir(job_dir): + # 尝试读取结果文件 + results_file = os.path.join(job_dir, "results.json") + log_file = os.path.join(job_dir, "process.log") + + # 默认任务信息 + task = { + "id": job_id, + "status": "completed", + "progress": 100, + "result_path": f"/view_report/{job_id}", + "filename": f"视频_{job_id[:6]}", + "uploaded_at": "2024-05-01 12:00:00", + "size": 0, + "message": "处理完成" + } + + # 尝试从日志文件获取进度信息 + if os.path.exists(log_file): + try: + with open(log_file, 'r') as f: + last_line = "" + for line in f: + if "处理进度:" in line: + last_line = line + + if last_line: + import re + progress_match = re.search(r'处理进度: (\d+)%', last_line) + if progress_match: + progress = int(progress_match.group(1)) + task["progress"] = progress + + # 更新状态 + if progress < 100: + task["status"] = "processing" + task["message"] = f"正在处理中... {progress}%" + except Exception as e: + print(f"读取日志文件出错: {str(e)}") + + # 尝试从原始视频文件获取信息 + try: + # 检查是否有同名的视频文件 + for filename in os.listdir(app.config['UPLOAD_FOLDER']): + if job_id in filename: + task["filename"] = filename + video_path = os.path.join(app.config['UPLOAD_FOLDER'], filename) + task["size"] = os.path.getsize(video_path) + break + except Exception as e: + print(f"获取视频文件信息出错: {str(e)}") + + # 尝试从结果文件获取更多信息 + if os.path.exists(results_file): + try: + with open(results_file, 'r') as f: + import json + results = json.load(f) + # 填充任务信息 + if "video_info" in results and "filename" in results["video_info"]: + task["filename"] = results["video_info"]["filename"] + if "analysis" in results and "timestamp" in results["analysis"]: + task["uploaded_at"] = results["analysis"]["timestamp"] + except Exception as e: + print(f"解析结果文件出错: {str(e)}") + + # 检查摘要文件 + summary_path = os.path.join(job_dir, "summary.html") + if os.path.exists(summary_path): + # 使用view_report路由 + task["result_path"] = f"/view_report/{job_id}" + else: + # 查找其他HTML文件 + html_files = [f for f in os.listdir(job_dir) if f.endswith('.html')] + if html_files: + # 使用第一个HTML文件作为摘要 + task["result_path"] = f"/results/{job_id}/{html_files[0]}" + + tasks.append(task) + except Exception as e: + print(f"获取任务列表出错: {str(e)}") + + # 按上传时间排序,最新的在前面 + tasks.sort(key=lambda x: x.get("uploaded_at", ""), reverse=True) + + return jsonify({"tasks": tasks}) +''' + + # 查找 api_get_tasks 函数位置 + start_marker = "@app.route('/api/tasks'" + end_marker = "return jsonify({\"tasks\": tasks})" + + if start_marker in original_content and end_marker in original_content: + # 找到函数的开始位置 + start_pos = original_content.find(start_marker) + + # 找到函数的结束位置(包括右花括号) + end_pos = original_content.find(end_marker, start_pos) + # 找到右花括号 + end_pos = original_content.find("}", end_pos) + 1 + + # 将原始内容分成三部分 + before_function = original_content[:start_pos] + after_function = original_content[end_pos:] + + # 创建新的内容 + new_content = before_function + new_api_tasks_function + after_function + + # 写回文件 + with open(app_file, 'w', encoding='utf-8') as f: + f.write(new_content) + + logger.info("成功修复任务列表进度显示") + else: + logger.error("未找到 api_get_tasks 函数,无法修复") + return False + + return True + except Exception as e: + logger.error(f"修复进度时出错: {str(e)}") + return False + +if __name__ == "__main__": + if fix_progress(): + print("修复成功!") + else: + print("修复失败,请检查日志。") \ No newline at end of file diff --git a/修复文件/fix_routes.py b/修复文件/fix_routes.py new file mode 100644 index 0000000..dd79a46 --- /dev/null +++ b/修复文件/fix_routes.py @@ -0,0 +1,117 @@ +#!/usr/bin/env python3 +# 检查服务器路由并修复问题 + +import os +import json +from flask import Flask, send_from_directory, jsonify, send_file + +# 设置应用 +app = Flask(__name__) +app.config['OUTPUT_FOLDER'] = '/app/output' +app.config['UPLOAD_FOLDER'] = '/app/uploads' + +@app.route('/view_report/') +def view_report(task_id): + """提供报告预览页面""" + try: + task_output_dir = os.path.join(app.config['OUTPUT_FOLDER'], task_id) + html_path = os.path.join(task_output_dir, "summary.html") + + if os.path.exists(html_path): + print(f"提供报告预览: {html_path}") + return send_file(html_path) + else: + # 查找是否有备用报告文件 + backup_files = [f for f in os.listdir(task_output_dir) if f.endswith('.html')] + if backup_files: + alt_html_path = os.path.join(task_output_dir, backup_files[0]) + print(f"提供备用报告预览: {alt_html_path}") + return send_file(alt_html_path) + else: + return "找不到报告文件", 404 + except Exception as e: + print(f"提供报告预览时出错: {str(e)}") + return f"服务器错误: {str(e)}", 500 + +@app.route('/results//') +def get_result_file(job_id, filename): + """提供访问结果文件的路由""" + try: + file_path = os.path.join(app.config['OUTPUT_FOLDER'], job_id, filename) + if os.path.exists(file_path): + return send_file(file_path) + else: + return f"文件不存在: {file_path}", 404 + except Exception as e: + return f"访问文件出错: {str(e)}", 500 + +@app.route('/api/tasks') +def api_get_tasks(): + """获取所有任务列表""" + tasks = [] + try: + # 遍历输出目录中的所有作业 + for job_id in os.listdir(app.config['OUTPUT_FOLDER']): + job_dir = os.path.join(app.config['OUTPUT_FOLDER'], job_id) + if os.path.isdir(job_dir): + # 尝试读取结果文件 + results_file = os.path.join(job_dir, "results.json") + + # 默认任务信息 + task = { + "id": job_id, + "status": "completed", + "progress": 100, + "result_path": f"/view_report/{job_id}", + "filename": f"视频_{job_id[:6]}", + "uploaded_at": "2024-05-01 12:00:00", + "size": 0, + "message": "处理完成" + } + + # 尝试从原始视频文件获取信息 + try: + # 检查是否有同名的视频文件 + for filename in os.listdir(app.config['UPLOAD_FOLDER']): + if job_id in filename: + task["filename"] = filename + break + except Exception: + pass + + # 尝试从结果文件获取更多信息 + if os.path.exists(results_file): + try: + with open(results_file, 'r') as f: + results = json.load(f) + # 填充任务信息 + if "video_info" in results and "filename" in results["video_info"]: + task["filename"] = results["video_info"]["filename"] + if "analysis" in results and "timestamp" in results["analysis"]: + task["uploaded_at"] = results["analysis"]["timestamp"] + except Exception as e: + print(f"解析结果文件出错: {str(e)}") + + # 如果没有摘要文件,检查目录中是否有HTML文件 + summary_path = os.path.join(job_dir, "summary.html") + if not os.path.exists(summary_path): + html_files = [f for f in os.listdir(job_dir) if f.endswith('.html')] + if html_files: + # 使用第一个HTML文件作为摘要 + task["result_path"] = f"/results/{job_id}/{html_files[0]}" + + tasks.append(task) + except Exception as e: + print(f"获取任务列表出错: {str(e)}") + + return jsonify({"tasks": tasks}) + +# 打印路由表 +def print_routes(): + print("\n当前应用路由表:") + for rule in app.url_map.iter_rules(): + print(f"{rule.endpoint}: {rule.rule}") + +if __name__ == "__main__": + print_routes() + app.run(debug=True, host='0.0.0.0', port=5000) \ No newline at end of file