Spaces:
Sleeping
Sleeping
| from flask import Blueprint, send_from_directory, current_app, request, jsonify | |
| from flask_login import login_required, current_user | |
| from utils import get_db_connection | |
| import os | |
| import base64 | |
| from datetime import datetime | |
| image_bp = Blueprint('image_bp', __name__) | |
| def serve_processed_image(filename): | |
| current_app.logger.info(f"Serving processed image: {filename}") | |
| return send_from_directory(current_app.config['PROCESSED_FOLDER'], filename) | |
| def serve_tmp_image(filename): | |
| current_app.logger.info(f"Serving temporary image: {filename}") | |
| return send_from_directory(current_app.config['TEMP_FOLDER'], filename) | |
| # Proxy routes for /neetprep/processed and /neetprep/tmp | |
| def serve_neetprep_processed_image(filename): | |
| current_app.logger.info(f"Serving /neetprep/processed image: {filename}") | |
| return send_from_directory(current_app.config['PROCESSED_FOLDER'], filename) | |
| def serve_neetprep_tmp_image(filename): | |
| current_app.logger.info(f"Serving /neetprep/tmp image: {filename}") | |
| return send_from_directory(current_app.config['TEMP_FOLDER'], filename) | |
| def save_note_image(): | |
| try: | |
| if 'image' not in request.files: | |
| return jsonify({'error': 'No image file provided'}), 400 | |
| file = request.files['image'] | |
| image_id = request.form.get('image_id') | |
| session_id = request.form.get('session_id') | |
| if not image_id or not session_id: | |
| return jsonify({'error': 'Missing image_id or session_id'}), 400 | |
| # Validate ownership | |
| conn = get_db_connection() | |
| img = conn.execute("SELECT i.id, s.user_id FROM images i JOIN sessions s ON i.session_id = s.id WHERE i.id = ?", (image_id,)).fetchone() | |
| if not img or img['user_id'] != current_user.id: | |
| conn.close() | |
| return jsonify({'error': 'Unauthorized or image not found'}), 403 | |
| # Save the file | |
| filename = f"note_{session_id}_{image_id}_{int(datetime.now().timestamp())}.png" | |
| save_path = os.path.join(current_app.config['PROCESSED_FOLDER'], filename) | |
| file.save(save_path) | |
| # Update DB | |
| conn.execute("UPDATE images SET note_filename = ? WHERE id = ?", (filename, image_id)) | |
| conn.commit() | |
| conn.close() | |
| return jsonify({'success': True, 'filename': filename}) | |
| except Exception as e: | |
| current_app.logger.error(f"Error saving note: {e}") | |
| return jsonify({'error': str(e)}), 500 | |
| def toggle_note_in_pdf(): | |
| """Toggle whether a note should be included in the generated PDF.""" | |
| try: | |
| data = request.json | |
| image_id = data.get('image_id') | |
| include = data.get('include', True) | |
| if not image_id: | |
| return jsonify({'error': 'Missing image_id'}), 400 | |
| conn = get_db_connection() | |
| img = conn.execute(""" | |
| SELECT i.id, s.user_id FROM images i | |
| JOIN sessions s ON i.session_id = s.id WHERE i.id = ? | |
| """, (image_id,)).fetchone() | |
| if not img or img['user_id'] != current_user.id: | |
| conn.close() | |
| return jsonify({'error': 'Unauthorized'}), 403 | |
| conn.execute("UPDATE images SET include_note_in_pdf = ? WHERE id = ?", | |
| (1 if include else 0, image_id)) | |
| conn.commit() | |
| conn.close() | |
| return jsonify({'success': True, 'include': include}) | |
| except Exception as e: | |
| current_app.logger.error(f"Error toggling note in PDF: {e}") | |
| return jsonify({'error': str(e)}), 500 | |
| def delete_note(): | |
| """Delete a note image for a question.""" | |
| try: | |
| data = request.json | |
| image_id = data.get('image_id') | |
| if not image_id: | |
| return jsonify({'error': 'Missing image_id'}), 400 | |
| conn = get_db_connection() | |
| img = conn.execute(""" | |
| SELECT i.id, i.note_filename, s.user_id FROM images i | |
| JOIN sessions s ON i.session_id = s.id WHERE i.id = ? | |
| """, (image_id,)).fetchone() | |
| if not img or img['user_id'] != current_user.id: | |
| conn.close() | |
| return jsonify({'error': 'Unauthorized'}), 403 | |
| # Delete the file if it exists | |
| if img['note_filename']: | |
| note_path = os.path.join(current_app.config['PROCESSED_FOLDER'], img['note_filename']) | |
| if os.path.exists(note_path): | |
| os.remove(note_path) | |
| conn.execute("UPDATE images SET note_filename = NULL, note_json = NULL WHERE id = ?", (image_id,)) | |
| conn.commit() | |
| conn.close() | |
| return jsonify({'success': True}) | |
| except Exception as e: | |
| current_app.logger.error(f"Error deleting note: {e}") | |
| return jsonify({'error': str(e)}), 500 | |
| def save_note_json(): | |
| """Save revision notes as JSON and rasterized PNG for PDF/quiz display.""" | |
| try: | |
| data = request.json | |
| image_id = data.get('image_id') | |
| session_id = data.get('session_id') | |
| json_data = data.get('json_data') | |
| image_data = data.get('image_data') | |
| if not image_id or not session_id or not json_data: | |
| return jsonify({'error': 'Missing required fields'}), 400 | |
| # Validate ownership | |
| conn = get_db_connection() | |
| img = conn.execute(""" | |
| SELECT i.id, s.user_id FROM images i | |
| JOIN sessions s ON i.session_id = s.id WHERE i.id = ? | |
| """, (image_id,)).fetchone() | |
| if not img or img['user_id'] != current_user.id: | |
| conn.close() | |
| return jsonify({'error': 'Unauthorized'}), 403 | |
| # Save JSON to database | |
| conn.execute("UPDATE images SET note_json = ? WHERE id = ?", (json_data, image_id)) | |
| # Save rasterized PNG if provided (needed for PDF generation and quiz display) | |
| if image_data and image_data.startswith('data:image/'): | |
| # Strip the data URL prefix (e.g. "data:image/png;base64,") | |
| header, encoded = image_data.split(',', 1) | |
| img_bytes = base64.b64decode(encoded) | |
| filename = f"note_{session_id}_{image_id}_{int(datetime.now().timestamp())}.png" | |
| save_path = os.path.join(current_app.config['PROCESSED_FOLDER'], filename) | |
| with open(save_path, 'wb') as f: | |
| f.write(img_bytes) | |
| conn.execute("UPDATE images SET note_filename = ? WHERE id = ?", (filename, image_id)) | |
| conn.commit() | |
| conn.close() | |
| return jsonify({'success': True}) | |
| except Exception as e: | |
| current_app.logger.error(f"Error saving note JSON: {e}") | |
| return jsonify({'error': str(e)}), 500 | |
| def get_note_json(image_id): | |
| """Get revision notes as JSON.""" | |
| try: | |
| conn = get_db_connection() | |
| img = conn.execute(""" | |
| SELECT i.note_json, s.user_id FROM images i | |
| JOIN sessions s ON i.session_id = s.id WHERE i.id = ? | |
| """, (image_id,)).fetchone() | |
| if not img or img['user_id'] != current_user.id: | |
| conn.close() | |
| return jsonify({'error': 'Unauthorized'}), 403 | |
| conn.close() | |
| if img['note_json']: | |
| return jsonify({'success': True, 'json_data': img['note_json']}) | |
| else: | |
| return jsonify({'success': False, 'error': 'No note found'}), 404 | |
| except Exception as e: | |
| current_app.logger.error(f"Error getting note JSON: {e}") | |
| return jsonify({'error': str(e)}), 500 |