Spaces:
Sleeping
Sleeping
| """ | |
| PDF 처리 모듈 | |
| - PDF 텍스트 추출 | |
| - 텍스트 청킹 | |
| - 임베딩 생성 및 저장 | |
| """ | |
| import fitz # PyMuPDF | |
| from typing import List, Dict | |
| from rag import get_embedding | |
| from database import save_document | |
| def extract_text_from_pdf(pdf_path: str) -> str: | |
| """PDF에서 텍스트 추출""" | |
| try: | |
| doc = fitz.open(pdf_path) | |
| text = "" | |
| for page in doc: | |
| text += page.get_text() | |
| doc.close() | |
| return text.strip() | |
| except Exception as e: | |
| raise Exception(f"PDF 텍스트 추출 실패: {str(e)}") | |
| def chunk_text(text: str, chunk_size: int = 500, overlap: int = 50) -> List[str]: | |
| """텍스트를 청크로 분할""" | |
| if not text: | |
| return [] | |
| chunks = [] | |
| start = 0 | |
| text_length = len(text) | |
| while start < text_length: | |
| end = start + chunk_size | |
| # 문장 끝에서 자르기 시도 | |
| if end < text_length: | |
| # 마침표, 물음표, 느낌표 찾기 | |
| for punct in ['. ', '? ', '! ', '\n\n', '\n']: | |
| last_punct = text.rfind(punct, start, end) | |
| if last_punct != -1: | |
| end = last_punct + 1 | |
| break | |
| chunk = text[start:end].strip() | |
| if chunk: | |
| chunks.append(chunk) | |
| start = end - overlap if end < text_length else text_length | |
| return chunks | |
| def process_pdf( | |
| pdf_path: str, | |
| title: str, | |
| category: str = "일반", | |
| chunk_size: int = 500 | |
| ) -> Dict: | |
| """ | |
| PDF 처리 파이프라인 | |
| 1. 텍스트 추출 | |
| 2. 청킹 | |
| 3. 임베딩 생성 | |
| 4. DB 저장 | |
| """ | |
| result = { | |
| "success": False, | |
| "message": "", | |
| "chunks_count": 0 | |
| } | |
| try: | |
| # 1. 텍스트 추출 | |
| text = extract_text_from_pdf(pdf_path) | |
| if not text: | |
| result["message"] = "PDF에서 텍스트를 추출할 수 없습니다." | |
| return result | |
| # 2. 청킹 | |
| chunks = chunk_text(text, chunk_size=chunk_size) | |
| if not chunks: | |
| result["message"] = "텍스트 분할에 실패했습니다." | |
| return result | |
| # 3. 각 청크 임베딩 및 저장 | |
| saved_count = 0 | |
| for i, chunk in enumerate(chunks): | |
| chunk_title = f"{title} (Part {i+1})" | |
| embedding = get_embedding(chunk) | |
| if save_document(chunk_title, chunk, embedding, category): | |
| saved_count += 1 | |
| result["success"] = True | |
| result["chunks_count"] = saved_count | |
| result["message"] = f"✅ {saved_count}개 청크가 성공적으로 저장되었습니다." | |
| except Exception as e: | |
| result["message"] = f"❌ 처리 중 오류 발생: {str(e)}" | |
| return result | |