# app.py (프로젝트별 디렉터리 지원 버전) import streamlit as st import json import os import base64 from pathlib import Path # --- 설정 --- DOCS_DIR = Path("/data/documents") JSON_DIR = Path("/data/jsons") # --- 헬퍼 함수 --- def scan_project_directories(docs_base_dir, json_base_dir): """ 두 베이스 디렉터리를 스캔하여, 공통된 서브디렉터리(프로젝트)를 찾고 그 안의 파일 쌍을 매핑한 딕셔너리를 반환합니다. """ projects_data = {} if not docs_base_dir.is_dir(): return projects_data # 문서 디렉터리 기준으로 서브디렉터리(프로젝트)를 찾음 for project_path in docs_base_dir.iterdir(): if project_path.is_dir(): project_name = project_path.name json_project_path = json_base_dir / project_name # JSON 디렉터리에도 해당 프로젝트 폴더가 있는지 확인 if json_project_path.is_dir(): # 프로젝트 내에서 파일 쌍 매칭 doc_files = {f.stem: f for f in project_path.iterdir() if f.is_file()} json_files = {f.stem: f for f in json_project_path.iterdir() if f.is_file() and f.suffix == '.json'} matching_pairs = {} for base_name, doc_path in doc_files.items(): if base_name in json_files: matching_pairs[base_name] = { "doc_path": doc_path, "json_path": json_files[base_name] } if matching_pairs: projects_data[project_name] = matching_pairs return projects_data def display_pdf(file_path): """PDF 파일을 웹 페이지에 임베드하여 표시합니다.""" with open(file_path, "rb") as f: base64_pdf = base64.b64encode(f.read()).decode('utf-8') pdf_display = f'' st.markdown(pdf_display, unsafe_allow_html=True) # --- 메인 UI 로직 --- def main(): st.set_page_config(layout="wide", page_title="결과 비교 도구") st.title("🗂️ 프로젝트별 결과 비교 도구") st.markdown("---") if not DOCS_DIR.is_dir() or not JSON_DIR.is_dir(): st.error(f"오류: 데이터 루트 디렉터리(`{DOCS_DIR}` 또는 `{JSON_DIR}`)를 찾을 수 없습니다.") return try: projects_data = scan_project_directories(DOCS_DIR, JSON_DIR) except Exception as e: st.error(f"프로젝트 목록을 읽는 중 오류가 발생했습니다: {e}") return if not projects_data: st.warning("비교할 프로젝트가 없습니다. 각 데이터 디렉터리 안에 동일한 이름의 하위 폴더가 있는지 확인하세요.") return # --- 1. 프로젝트 선택 --- st.sidebar.header("파일 선택") project_names = sorted(list(projects_data.keys())) selected_project = st.sidebar.selectbox( "1. 프로젝트를 선택하세요.", project_names ) if selected_project: files_in_project = projects_data[selected_project] # --- 2. 파일 선택 --- sorted_basenames = sorted(list(files_in_project.keys())) display_options = [f"{i}. {name}" for i, name in enumerate(sorted_basenames, 1)] selected_option = st.sidebar.selectbox( f"2. '{selected_project}' 프로젝트의 파일을 선택하세요.", display_options ) if selected_option: original_basename = selected_option.split('. ', 1)[1] st.header(f"🔎 비교 결과: `{selected_project} / {original_basename}`") selected_pair = files_in_project[original_basename] doc_path = selected_pair["doc_path"] json_path = selected_pair["json_path"] # --- 결과 표시 (이전과 동일) --- col1, col2 = st.columns(2) with col1: st.subheader("원본 문서") try: if doc_path.suffix.lower() == ".pdf": display_pdf(doc_path) elif doc_path.suffix.lower() in ['.png', '.jpg', '.jpeg']: st.image(str(doc_path), caption=f"원본 이미지: {doc_path.name}", use_container_width=True) else: st.warning(f"지원하지 않는 문서 형식입니다: {doc_path.name}") except Exception as e: st.error(f"문서 파일을 표시하는 중 오류가 발생했습니다: {e}") with col2: st.subheader("추출된 데이터 (JSON)") try: with open(json_path, 'r', encoding='utf-8') as f: data = json.load(f) if isinstance(data, list) and len(data) > 0: result_item = data[0] else: result_item = data if 'fields' in result_item: del result_item['fields'] st.json(result_item) except Exception as e: st.error(f"JSON 파일을 읽거나 처리하는 중 오류가 발생했습니다: {e}") if __name__ == "__main__": main()