diff --git a/backend/routes/utilities.py b/backend/routes/utilities.py index e394d3d..e443d7b 100644 --- a/backend/routes/utilities.py +++ b/backend/routes/utilities.py @@ -120,6 +120,63 @@ def move_guid_files(): return redirect(url_for("main.index")) +@utils_bp.route("/move_gpu_files", methods=["POST"]) +@login_required +def move_gpu_files(): + """ + data/idrac_info → data/gpu_serial 로 GPU 시리얼 텍스트 파일 이동 + """ + src = Path(Config.IDRAC_INFO_FOLDER) # 예: data/idrac_info + dst = Path(Config.GPU_FOLDER) # 예: data/gpu_serial + dst.mkdir(parents=True, exist_ok=True) + + moved = 0 + errors = [] + + try: + for file in src.iterdir(): + if not file.is_file(): + continue + + # GPU 관련 텍스트 파일만 이동 (GUID 등 제외) + if not file.name.lower().endswith(".txt"): + continue + + try: + # 파일 존재 확인 + if not file.exists(): + errors.append(f"{file.name}: 파일이 존재하지 않음") + continue + + # 대상 파일이 이미 존재하면 스킵 + target = dst / file.name + if target.exists(): + logging.warning(f"⚠️ 이미 존재하여 건너뜀: {file.name}") + continue + + # 파일 이동 + shutil.move(str(file), str(target)) + moved += 1 + + except Exception as e: + error_msg = f"{file.name}: {str(e)}" + errors.append(error_msg) + logging.error(f"❌ GPU 파일 이동 실패: {error_msg}") + + # 결과 메시지 + if moved > 0: + flash(f"GPU 시리얼 파일이 성공적으로 이동되었습니다. ({moved}개)", "success") + logging.info(f"✅ GPU 파일 이동 완료 ({moved}개)") + + if errors: + logging.warning(f"⚠️ 일부 파일 이동 실패: {errors}") + flash(f"일부 GPU 파일 이동 실패: {len(errors)}개", "warning") + + except Exception as e: + logging.error(f"❌ GPU 이동 오류: {e}") + flash(f"오류 발생: {e}", "danger") + + return redirect(url_for("main.index")) @utils_bp.route("/update_server_list", methods=["POST"]) @login_required @@ -182,6 +239,56 @@ def update_guid_list(): return redirect(url_for("main.index")) +@utils_bp.route("/update_gpu_list", methods=["POST"]) +@login_required +def update_gpu_list(): + """ + GPU 시리얼용 리스트(gpu_serial_list.txt)를 갱신하고 Excel을 생성합니다. + - form name="gpu_list_content" 로 내용 전달 (S/T 목록 라인별) + - txt_to_excel.py --preset gpu --list-file + """ + content = request.form.get("server_list_content") + if not content: + flash("내용을 입력하세요.", "warning") + return redirect(url_for("main.index")) + + server_list_dir = Path(Config.SERVER_LIST_FOLDER) + list_path = server_list_dir / "gpu_list.txt" + # txt_to_excel.py는 server_list 폴더에 둔다고 가정 (위치 다르면 경로만 수정) + script_path = server_list_dir / "GPUTOExecl.py" + + try: + # 1) gpu_serial_list.txt 저장 + list_path.write_text(content, encoding="utf-8") + + # 2) 엑셀 생성 실행 (GPU 프리셋) + cmd = [ + sys.executable, + str(script_path), + "--preset", "gpu", + "--list-file", str(list_path), + ] + result = subprocess.run( + cmd, + capture_output=True, + text=True, + check=True, + cwd=str(server_list_dir), # data/server_list 기준 실행 + timeout=300, + ) + logging.info(f"[GPU] 리스트 스크립트 실행 STDOUT:\n{result.stdout}") + if result.stderr: + logging.warning(f"[GPU] 리스트 스크립트 STDERR:\n{result.stderr}") + + flash("GPU 리스트가 업데이트되었습니다.", "success") + except subprocess.CalledProcessError as e: + logging.error(f"[GPU] 스크립트 오류: {e.stderr}") + flash(f"스크립트 실행 실패: {e.stderr}", "danger") + except Exception as e: + logging.error(f"[GPU] 처리 오류: {e}") + flash(f"GPU 리스트 처리 중 오류 발생: {e}", "danger") + + return redirect(url_for("main.index")) @utils_bp.route("/download_excel") @login_required @@ -192,4 +299,4 @@ def download_excel(): return redirect(url_for("main.index")) logging.info(f"엑셀 파일 다운로드: {path}") - return send_file(str(path), as_attachment=True, download_name="mac_info.xlsx") \ No newline at end of file + return send_file(str(path), as_attachment=True, download_name="mac_info.xlsx") diff --git a/backend/templates/index.html b/backend/templates/index.html index 1e01cb2..8c63d58 100644 --- a/backend/templates/index.html +++ b/backend/templates/index.html @@ -6,7 +6,7 @@ {# 플래시 메시지 #} {% with messages = get_flashed_messages(with_categories=true) %} {% if messages %} -
+
{% for cat, msg in messages %}