From cfd71a15d64bd4eb99b127ffb72095c092639aa8 Mon Sep 17 00:00:00 2001 From: pjmalandrino Date: Mon, 26 May 2025 15:59:48 +0200 Subject: [PATCH] Add visu on first part --- app.py | 56 +++++++++++++++++++++++++++++++++++++++++++++++ index.html | 6 +++++ static/app.js | 36 +++++++++++++++++++++++++++++- static/styles.css | 25 +++++++++++++++++++++ 4 files changed, 122 insertions(+), 1 deletion(-) diff --git a/app.py b/app.py index a6c0f46..a4f6cec 100644 --- a/app.py +++ b/app.py @@ -274,6 +274,62 @@ def results(filename): logger.error(f"Error serving file {filename}: {str(e)}") return jsonify({'error': f"Error serving file: {filename}"}), 500 +@app.route('/pdf-preview//') +def pdf_preview(pdf_file, page_num): + """Generate and serve a preview image of a PDF page""" + try: + import pdf2image + from PIL import Image + import io + + # Check if PDF exists + if not os.path.exists(pdf_file): + return jsonify({'error': f'PDF file not found: {pdf_file}'}), 404 + + # Convert PDF page to image + logger.info(f"Generating preview for {pdf_file} page {page_num}") + + # Use moderate DPI for preview (lower than analyzer's 200) + preview_dpi = 150 + + try: + pdf_images = pdf2image.convert_from_path( + pdf_file, + dpi=preview_dpi, + first_page=page_num, + last_page=page_num + ) + + if not pdf_images: + return jsonify({'error': f'Could not extract page {page_num} from PDF'}), 400 + + # Get the first (and only) page + pil_image = pdf_images[0] + + # Resize if too large (max width 1200px for web preview) + max_width = 1200 + if pil_image.width > max_width: + ratio = max_width / pil_image.width + new_height = int(pil_image.height * ratio) + pil_image = pil_image.resize((max_width, new_height), Image.LANCZOS) + + # Convert to bytes + img_io = io.BytesIO() + pil_image.save(img_io, 'PNG', optimize=True) + img_io.seek(0) + + return send_file(img_io, mimetype='image/png', + as_attachment=False, + download_name=f'{pdf_file}_page_{page_num}_preview.png') + + except Exception as e: + logger.error(f"Error converting PDF to image: {str(e)}") + return jsonify({'error': f'Error converting PDF to image: {str(e)}'}), 500 + + except Exception as e: + logger.error(f"Error generating PDF preview: {str(e)}") + return jsonify({'error': str(e)}), 500 + @app.route('/check-environment') def check_environment(): """Endpoint to check the environment and available scripts""" diff --git a/index.html b/index.html index 6b237e0..b6921ca 100644 --- a/index.html +++ b/index.html @@ -68,6 +68,12 @@ + + +
Analysis Process:
    diff --git a/static/app.js b/static/app.js index f8ee25a..b922a6a 100644 --- a/static/app.js +++ b/static/app.js @@ -8,6 +8,33 @@ const generatedOutputs = { extractor: false }; +// Load and display PDF preview +function loadPDFPreview() { + const pdfFile = document.getElementById('pdf_file').value; + const pageNum = document.getElementById('page_num').value; + + if (!pdfFile) { + document.getElementById('pdf-preview-container').classList.add('hidden'); + return; + } + + // Update page number display + document.getElementById('preview-page-num').textContent = pageNum; + + // Load the preview image + const previewImg = document.getElementById('pdf-preview-image'); + previewImg.src = `/pdf-preview/${encodeURIComponent(pdfFile)}/${pageNum}`; + + // Show the preview container + document.getElementById('pdf-preview-container').classList.remove('hidden'); + + // Handle loading errors + previewImg.onerror = function() { + this.alt = 'Failed to load PDF preview'; + console.error('Failed to load PDF preview'); + }; +} + // Tab switching functionality function switchTab(tabName) { // Hide all tab contents @@ -25,7 +52,10 @@ function switchTab(tabName) { event.target.classList.add('active'); // Show previously generated content when switching tabs - if (tabName === 'visualizer' && generatedOutputs.visualizer) { + if (tabName === 'analyzer') { + // Load PDF preview if a PDF is selected + loadPDFPreview(); + } else if (tabName === 'visualizer' && generatedOutputs.visualizer) { document.getElementById('result-image').src = generatedOutputs.visualizer + '?t=' + new Date().getTime(); document.getElementById('image-container').classList.remove('hidden'); } else if (tabName === 'extractor' && generatedOutputs.extractor) { @@ -186,6 +216,10 @@ window.addEventListener('DOMContentLoaded', function() { pdfStatus.innerHTML = 'Error: ' + error.message + ''; }); + // Add event listeners for PDF selection and page number changes + document.getElementById('pdf_file').addEventListener('change', loadPDFPreview); + document.getElementById('page_num').addEventListener('change', loadPDFPreview); + // Run an environment check on startup checkEnvironment(); diff --git a/static/styles.css b/static/styles.css index 506c0bb..f7c1aeb 100644 --- a/static/styles.css +++ b/static/styles.css @@ -424,6 +424,31 @@ button:disabled { box-shadow: var(--shadow-md); } +/* PDF Preview container */ +#pdf-preview-container { + margin-top: var(--spacing-lg); + text-align: center; + padding: var(--spacing-lg); + background: var(--surface-light); + border-radius: var(--radius-md); + border: 1px solid var(--border-light); +} + +#pdf-preview-container h4 { + color: var(--primary-dark); + margin: 0 0 var(--spacing-md) 0; + font-size: 1rem; + font-weight: 500; +} + +#pdf-preview-image { + max-width: 100%; + max-height: 600px; + border-radius: var(--radius-sm); + box-shadow: var(--shadow-md); + object-fit: contain; +} + /* Extracted Images Gallery */ #extracted-images-container { margin-top: var(--spacing-lg);