realsanjay commited on
Commit
6f2eed6
·
verified ·
1 Parent(s): 858e9ba

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +178 -1
app.py CHANGED
@@ -235,7 +235,184 @@ class EnhancedDocProcessor:
235
  results.append({"status": "error", "error": str(e), "file": file_path})
236
  return results
237
 
238
- # [Previous HTML_TEMPLATE remains the same]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239
 
240
  app = Flask(__name__)
241
  processor = EnhancedDocProcessor()
 
235
  results.append({"status": "error", "error": str(e), "file": file_path})
236
  return results
237
 
238
+ # HTML template with embedded JavaScript
239
+ HTML_TEMPLATE = """
240
+ <!DOCTYPE html>
241
+ <html lang="en">
242
+ <head>
243
+ <meta charset="UTF-8">
244
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
245
+ <title>Document Processor</title>
246
+ <script src="https://cdn.tailwindcss.com"></script>
247
+ <style>
248
+ /* Additional custom styles can go here */
249
+ .processing {
250
+ animation: pulse 2s infinite;
251
+ }
252
+ @keyframes pulse {
253
+ 0% { opacity: 1; }
254
+ 50% { opacity: 0.5; }
255
+ 100% { opacity: 1; }
256
+ }
257
+ </style>
258
+ </head>
259
+ <body class="bg-gray-50">
260
+ <div class="container mx-auto p-6 max-w-4xl">
261
+ <div class="mb-8">
262
+ <h1 class="text-3xl font-bold mb-2">Smart Document Processor</h1>
263
+ <p class="text-gray-600">Upload and analyze PDF documents with AI</p>
264
+ </div>
265
+
266
+ <!-- Upload Section -->
267
+ <div class="mb-8">
268
+ <div id="dropZone" class="border-2 border-dashed border-gray-300 rounded-lg p-8 text-center hover:border-blue-500 transition-colors">
269
+ <input type="file" multiple accept=".pdf" id="fileInput" class="hidden">
270
+ <div class="cursor-pointer">
271
+ <svg class="w-12 h-12 text-gray-400 mx-auto mb-4" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
272
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12"/>
273
+ </svg>
274
+ <span class="text-lg mb-2 block">Drop PDFs here or click to upload</span>
275
+ <span class="text-sm text-gray-500">Supports multiple files</span>
276
+ </div>
277
+ </div>
278
+ </div>
279
+
280
+ <!-- File List -->
281
+ <div id="fileList" class="mb-8 hidden">
282
+ <h2 class="text-xl font-semibold mb-4">Selected Files</h2>
283
+ <div id="fileListContent" class="space-y-2"></div>
284
+ <button id="processButton" class="mt-4 bg-blue-600 text-white px-6 py-2 rounded-lg hover:bg-blue-700 disabled:opacity-50">
285
+ Process Documents
286
+ </button>
287
+ </div>
288
+
289
+ <!-- Results Section -->
290
+ <div id="results" class="space-y-4"></div>
291
+
292
+ <!-- Error Alert -->
293
+ <div id="error" class="hidden mt-4 bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded"></div>
294
+ </div>
295
+
296
+ <script>
297
+ let files = [];
298
+ const dropZone = document.getElementById('dropZone');
299
+ const fileInput = document.getElementById('fileInput');
300
+ const fileList = document.getElementById('fileList');
301
+ const fileListContent = document.getElementById('fileListContent');
302
+ const processButton = document.getElementById('processButton');
303
+ const resultsDiv = document.getElementById('results');
304
+ const errorDiv = document.getElementById('error');
305
+
306
+ // Drag and drop handlers
307
+ dropZone.addEventListener('dragover', (e) => {
308
+ e.preventDefault();
309
+ dropZone.classList.add('border-blue-500');
310
+ });
311
+
312
+ dropZone.addEventListener('dragleave', () => {
313
+ dropZone.classList.remove('border-blue-500');
314
+ });
315
+
316
+ dropZone.addEventListener('drop', (e) => {
317
+ e.preventDefault();
318
+ dropZone.classList.remove('border-blue-500');
319
+ handleFiles(e.dataTransfer.files);
320
+ });
321
+
322
+ dropZone.addEventListener('click', () => {
323
+ fileInput.click();
324
+ });
325
+
326
+ fileInput.addEventListener('change', (e) => {
327
+ handleFiles(e.target.files);
328
+ });
329
+
330
+ function handleFiles(uploadedFiles) {
331
+ files = Array.from(uploadedFiles).filter(file => file.name.toLowerCase().endsWith('.pdf'));
332
+ updateFileList();
333
+ }
334
+
335
+ function updateFileList() {
336
+ if (files.length > 0) {
337
+ fileList.classList.remove('hidden');
338
+ fileListContent.innerHTML = files.map((file, index) => `
339
+ <div class="flex items-center p-3 bg-gray-50 rounded">
340
+ <svg class="w-5 h-5 text-gray-500 mr-3" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke="currentColor">
341
+ <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/>
342
+ </svg>
343
+ <span>${file.name}</span>
344
+ </div>
345
+ `).join('');
346
+ } else {
347
+ fileList.classList.add('hidden');
348
+ }
349
+ }
350
+
351
+
352
+ processButton.addEventListener('click', async () => {
353
+ if (files.length === 0) return;
354
+
355
+ processButton.disabled = true;
356
+ processButton.innerHTML = `
357
+ <svg class="animate-spin -ml-1 mr-3 h-5 w-5 text-white inline" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
358
+ <circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>
359
+ <path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
360
+ </svg>
361
+ Processing...
362
+ `;
363
+
364
+ const formData = new FormData();
365
+ files.forEach(file => {
366
+ formData.append('files[]', file);
367
+ });
368
+
369
+ try {
370
+ const response = await fetch('/batch_process', {
371
+ method: 'POST',
372
+ body: formData
373
+ });
374
+
375
+ const data = await response.json();
376
+ displayResults(data);
377
+ errorDiv.classList.add('hidden');
378
+ } catch (error) {
379
+ errorDiv.textContent = 'Failed to process documents. Please try again.';
380
+ errorDiv.classList.remove('hidden');
381
+ } finally {
382
+ processButton.disabled = false;
383
+ processButton.textContent = 'Process Documents';
384
+ }
385
+ });
386
+
387
+ function displayResults(results) {
388
+ resultsDiv.innerHTML = results.map(result => `
389
+ <div class="border rounded-lg p-4 bg-white shadow-sm">
390
+ <h3 class="font-medium mb-2">${result.result.filename}</h3>
391
+ <div class="grid grid-cols-2 gap-4">
392
+ <div>
393
+ <span class="text-gray-600">Type:</span>
394
+ <span class="ml-2">${result.result.doc_type}</span>
395
+ </div>
396
+ <div>
397
+ <span class="text-gray-600">Date:</span>
398
+ <span class="ml-2">${result.result.date || 'N/A'}</span>
399
+ </div>
400
+ <div>
401
+ <span class="text-gray-600">Amount:</span>
402
+ <span class="ml-2">${result.result.amount ? '$' + result.result.amount.toFixed(2) : 'N/A'}</span>
403
+ </div>
404
+ <div>
405
+ <span class="text-gray-600">Person:</span>
406
+ <span class="ml-2">${result.result.person_name}</span>
407
+ </div>
408
+ </div>
409
+ </div>
410
+ `).join('');
411
+ }
412
+ </script>
413
+ </body>
414
+ </html>
415
+ """
416
 
417
  app = Flask(__name__)
418
  processor = EnhancedDocProcessor()