File size: 3,952 Bytes
f3997d4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
"""
Document text extraction utilities for various file formats.
"""
import os
from typing import Optional
import PyPDF2
import docx
from unstructured.partition.auto import partition


class DocumentExtractor:
    """Extract text content from various document formats."""
    
    @staticmethod
    def extract_text(file_path: str, file_type: str) -> str:
        """
        Extract text from a document file.
        
        Args:
            file_path: Path to the document file
            file_type: File extension (pdf, txt, docx)
            
        Returns:
            Extracted text content
            
        Raises:
            ValueError: If file type is not supported
            Exception: If extraction fails
        """
        if not os.path.exists(file_path):
            raise FileNotFoundError(f"File not found: {file_path}")
        
        file_type = file_type.lower()
        
        try:
            if file_type == 'txt':
                return DocumentExtractor._extract_txt(file_path)
            elif file_type == 'pdf':
                return DocumentExtractor._extract_pdf(file_path)
            elif file_type == 'docx':
                return DocumentExtractor._extract_docx(file_path)
            else:
                raise ValueError(f"Unsupported file type: {file_type}")
                
        except Exception as e:
            print(f"Error extracting text from {file_path}: {e}")
            raise
    
    @staticmethod
    def _extract_txt(file_path: str) -> str:
        """Extract text from TXT file."""
        with open(file_path, 'r', encoding='utf-8', errors='ignore') as f:
            return f.read()
    
    @staticmethod
    def _extract_pdf(file_path: str) -> str:
        """Extract text from PDF file using PyPDF2."""
        text_content = []
        
        try:
            with open(file_path, 'rb') as f:
                pdf_reader = PyPDF2.PdfReader(f)
                
                for page_num in range(len(pdf_reader.pages)):
                    page = pdf_reader.pages[page_num]
                    text = page.extract_text()
                    if text.strip():
                        text_content.append(text)
            
            return "\n\n".join(text_content)
            
        except Exception as e:
            print(f"PyPDF2 extraction failed, trying unstructured library: {e}")
            # Fallback to unstructured library
            return DocumentExtractor._extract_with_unstructured(file_path)
    
    @staticmethod
    def _extract_docx(file_path: str) -> str:
        """Extract text from DOCX file."""
        try:
            doc = docx.Document(file_path)
            text_content = []
            
            # Extract paragraphs
            for paragraph in doc.paragraphs:
                if paragraph.text.strip():
                    text_content.append(paragraph.text)
            
            # Extract tables
            for table in doc.tables:
                for row in table.rows:
                    row_text = " | ".join(cell.text.strip() for cell in row.cells)
                    if row_text.strip():
                        text_content.append(row_text)
            
            return "\n\n".join(text_content)
            
        except Exception as e:
            print(f"python-docx extraction failed: {e}")
            raise
    
    @staticmethod
    def _extract_with_unstructured(file_path: str) -> str:
        """
        Extract text using unstructured library (fallback method).
        This handles complex PDFs with tables and images better.
        """
        try:
            elements = partition(filename=file_path)
            text_content = [str(element) for element in elements]
            return "\n\n".join(text_content)
        except Exception as e:
            print(f"Unstructured extraction failed: {e}")
            raise


# Global extractor instance
document_extractor = DocumentExtractor()