File size: 12,917 Bytes
09281fe
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
"""
Document to Vector Database Integration Test
Demonstrates the complete workflow: document_processer.py -> vector_database.py
"""

import os
import sys
import tkinter as tk
from tkinter import filedialog
from pathlib import Path
import tempfile
import json
from datetime import datetime

def select_file():
    """Open file dialog to select any supported document file"""
    root = tk.Tk()
    root.withdraw()
    
    file_path = filedialog.askopenfilename(
        title="Select a document to process and store in vector database",
        filetypes=[
            ("All supported files", "*.pdf;*.txt;*.docx;*.html;*.htm;*.eml;*.msg;*.csv;*.json"),
            ("PDF files", "*.pdf"),
            ("Text files", "*.txt"),
            ("Word documents", "*.docx"),
            ("HTML files", "*.html;*.htm"),
            ("Email files", "*.eml;*.msg"),
            ("CSV files", "*.csv"),
            ("JSON files", "*.json"),
            ("All files", "*.*")
        ]
    )
    
    root.destroy()
    return file_path

def process_and_store_document(file_path, use_ocr=False):
    """Process a document and store it in the vector database"""
    try:
        print(f"πŸ”„ Step 1: Processing document with document_processer.py")
        print(f"πŸ“„ File: {file_path}")
        print(f"πŸ“ File size: {os.path.getsize(file_path) / 1024:.1f} KB")
        
        # Import and use document processor
        from document_processer import AdvancedDocumentProcessor
        
        # Initialize document processor
        doc_processor = AdvancedDocumentProcessor()
        
        # Process the document
        chunks = doc_processor.process_document(file_path, use_ocr=use_ocr)
        
        if not chunks:
            print("❌ No chunks extracted from document")
            return False, "No chunks extracted"
        
        print(f"βœ… Successfully processed {len(chunks)} chunks")
        
        # Display chunk information
        print(f"\nπŸ“‹ Chunk Analysis:")
        text_chunks = [c for c in chunks if c.section_type == 'main_text']
        table_chunks = [c for c in chunks if c.section_type == 'table']
        metadata_chunks = [c for c in chunks if c.section_type == 'metadata']
        
        print(f"   πŸ“ Text chunks: {len(text_chunks)}")
        print(f"   πŸ“Š Table chunks: {len(table_chunks)}")
        print(f"   🏷️  Metadata chunks: {len(metadata_chunks)}")
        
        # Show sample chunks
        for i, chunk in enumerate(chunks[:3]):
            print(f"\n   Chunk {i+1}:")
            print(f"     ID: {chunk.chunk_id}")
            print(f"     Type: {chunk.section_type}")
            print(f"     Content: {chunk.content[:100]}...")
        
        print(f"\nπŸ”„ Step 2: Storing in vector database")
        
        # Import and use vector database
        from vector_database import VectorDatabase
        
        # Initialize vector database
        vector_db = VectorDatabase(
            embedding_model="all-MiniLM-L6-v2",
            collection_name="processed_documents",
            persist_directory="./vector_db",
            use_gpu=True
        )
        
        # Add documents to vector database
        success = vector_db.add_documents(chunks)
        
        if not success:
            print("❌ Failed to store documents in vector database")
            return False, "Vector database storage failed"
        
        print(f"βœ… Successfully stored {len(chunks)} chunks in vector database")
        
        # Get database statistics
        stats = vector_db.get_document_statistics()
        print(f"\nπŸ“Š Vector Database Statistics:")
        print(f"   Total chunks: {stats.get('total_chunks', 0)}")
        print(f"   Unique sources: {stats.get('unique_sources', 0)}")
        print(f"   File types: {stats.get('file_types', [])}")
        
        return True, chunks
        
    except Exception as e:
        print(f"❌ Error in process_and_store_document: {e}")
        import traceback
        traceback.print_exc()
        return False, str(e)

def test_search_functionality(vector_db, original_file):
    """Test search functionality with the stored document"""
    print(f"\nπŸ” Step 3: Testing search functionality")
    
    # Get filename for search terms
    filename = Path(original_file).stem
    
    # Create some test queries
    test_queries = [
        filename,  # Search by filename
        "document",  # Generic search
        "text content",  # Content search
    ]
    
    for query in test_queries:
        print(f"\nπŸ” Searching for: '{query}'")
        
        # Semantic search
        semantic_results = vector_db.search_similar(query, n_results=3)
        print(f"   πŸ“ Semantic search results: {len(semantic_results)}")
        
        for i, result in enumerate(semantic_results[:2]):
            print(f"     Result {i+1}: Score {result.similarity_score:.3f}")
            print(f"       Source: {result.source_file}")
            print(f"       Content: {result.content[:80]}...")
        
        # Hybrid search
        hybrid_results = vector_db.hybrid_search(query, n_results=3)
        print(f"   πŸ”„ Hybrid search results: {len(hybrid_results)}")
        
        for i, result in enumerate(hybrid_results[:2]):
            print(f"     Result {i+1}: Score {result.similarity_score:.3f}")
            print(f"       Source: {result.source_file}")
            print(f"       Content: {result.content[:80]}...")

def create_sample_documents():
    """Create sample documents for testing"""
    test_dir = tempfile.mkdtemp()
    print(f"πŸ“ Created test directory: {test_dir}")
    
    # Create sample TXT file
    txt_content = """
    Sample Document for Testing
    
    This is a sample text document that will be processed and stored in the vector database.
    It contains multiple paragraphs with various topics including:
    
    1. Technology and AI
    2. Business processes
    3. Data analysis
    4. Machine learning applications
    
    The document processor should extract this content and create chunks.
    The vector database should then store these chunks with embeddings.
    """
    
    txt_path = os.path.join(test_dir, "sample_document.txt")
    with open(txt_path, 'w', encoding='utf-8') as f:
        f.write(txt_content)
    
    # Create sample JSON file
    json_data = {
        "title": "Sample JSON Document",
        "author": "Test User",
        "content": "This is a sample JSON document for testing the document processor and vector database integration.",
        "topics": ["document processing", "vector database", "AI", "machine learning"],
        "metadata": {
            "created": datetime.now().isoformat(),
            "version": "1.0",
            "tags": ["test", "sample", "integration"]
        }
    }
    
    json_path = os.path.join(test_dir, "sample_data.json")
    with open(json_path, 'w', encoding='utf-8') as f:
        json.dump(json_data, f, indent=2)
    
    return test_dir, {
        'txt': txt_path,
        'json': json_path
    }

def main():
    """Main function to test document to vector database workflow"""
    print("πŸš€ Document to Vector Database Integration Test")
    print("="*60)
    print("This test demonstrates the complete workflow:")
    print("1. Process document with document_processer.py")
    print("2. Store processed chunks in vector_database.py")
    print("3. Test search functionality")
    print()
    
    # Check if required modules are available
    try:
        from document_processer import AdvancedDocumentProcessor
        print("βœ… Document processor available")
    except ImportError as e:
        print(f"❌ Document processor not available: {e}")
        return
    
    try:
        from vector_database import VectorDatabase
        print("βœ… Vector database available")
    except ImportError as e:
        print(f"❌ Vector database not available: {e}")
        return
    
    print("\nChoose an option:")
    print("1. Select a file to process")
    print("2. Use sample documents")
    print("3. Process from command line")
    
    choice = input("Enter choice (1, 2, or 3): ").strip()
    
    if choice == "1":
        # Select file
        print("\nπŸ“ Please select a document to process...")
        file_path = select_file()
        
        if not file_path:
            print("❌ No file selected")
            return
        
        # Ask about OCR
        use_ocr = input("Use OCR for PDFs? (y/n): ").lower().strip() in ['y', 'yes']
        
        # Process and store
        success, result = process_and_store_document(file_path, use_ocr)
        
        if success:
            # Test search functionality
            vector_db = VectorDatabase()
            test_search_functionality(vector_db, file_path)
            
            print(f"\nπŸŽ‰ Complete workflow successful!")
            print(f"πŸ“„ Processed: {file_path}")
            print(f"πŸ“Š Stored in vector database")
            print(f"πŸ” Search functionality tested")
        
    elif choice == "2":
        # Use sample documents
        test_dir, sample_files = create_sample_documents()
        
        print(f"\nπŸ§ͺ Testing with sample documents...")
        
        for file_type, file_path in sample_files.items():
            print(f"\nπŸ“„ Processing {file_type.upper()} file...")
            success, result = process_and_store_document(file_path)
            
            if success:
                print(f"βœ… {file_type.upper()} file processed successfully")
            else:
                print(f"❌ {file_type.upper()} file failed: {result}")
        
        # Clean up
        import shutil
        shutil.rmtree(test_dir, ignore_errors=True)
        print(f"\n🧹 Cleaned up test directory")
        
    elif choice == "3":
        # Command line processing
        if len(sys.argv) < 2:
            print("❌ Usage: python test_document_to_vector.py <file_path> [--ocr]")
            return
        
        file_path = sys.argv[1]
        use_ocr = "--ocr" in sys.argv
        
        if not os.path.exists(file_path):
            print(f"❌ File not found: {file_path}")
            return
        
        print(f"πŸ”„ Processing file from command line: {file_path}")
        success, result = process_and_store_document(file_path, use_ocr)
        
        if success:
            print(f"πŸŽ‰ Successfully processed and stored: {file_path}")
        else:
            print(f"❌ Failed: {result}")
    
    else:
        print("❌ Invalid choice")

def batch_process_directory():
    """Process all supported files in a directory"""
    print("πŸ”„ Batch Processing Directory")
    print("="*40)
    
    # Select directory
    root = tk.Tk()
    root.withdraw()
    directory = filedialog.askdirectory(title="Select directory containing documents")
    root.destroy()
    
    if not directory:
        print("❌ No directory selected")
        return
    
    # Find supported files
    supported_extensions = {'.pdf', '.txt', '.docx', '.html', '.htm', '.eml', '.msg', '.csv', '.json'}
    files_to_process = []
    
    for ext in supported_extensions:
        files_to_process.extend(Path(directory).glob(f"*{ext}"))
    
    if not files_to_process:
        print("❌ No supported files found in directory")
        return
    
    print(f"πŸ“ Found {len(files_to_process)} files to process")
    
    # Initialize vector database
    vector_db = VectorDatabase()
    
    # Process each file
    results = {}
    for file_path in files_to_process:
        print(f"\nπŸ”„ Processing: {file_path.name}")
        
        success, result = process_and_store_document(str(file_path))
        
        if success:
            print(f"βœ… Success: {len(result)} chunks stored")
            results[file_path.name] = len(result)
        else:
            print(f"❌ Failed: {result}")
            results[file_path.name] = "ERROR"
    
    # Summary
    print(f"\nπŸ“Š BATCH PROCESSING SUMMARY")
    print(f"{'='*40}")
    successful = sum(1 for result in results.values() if isinstance(result, int))
    total = len(results)
    
    for filename, result in results.items():
        status = f"{result} chunks" if isinstance(result, int) else result
        print(f"{filename}: {status}")
    
    print(f"\nβœ… Successfully processed: {successful}/{total} files")
    
    # Test search with all documents
    print(f"\nπŸ” Testing search with all processed documents...")
    test_search_functionality(vector_db, "batch_processed")

if __name__ == "__main__":
    print("Choose workflow:")
    print("1. Single file processing")
    print("2. Batch directory processing")
    
    workflow_choice = input("Enter choice (1 or 2): ").strip()
    
    if workflow_choice == "1":
        main()
    elif workflow_choice == "2":
        batch_process_directory()
    else:
        print("❌ Invalid choice")