""" Route to view full email message content if stored. """ from flask import render_template, abort, flash, redirect, Response, send_file, request, url_for from email_server.models import Session, EmailLog, EmailAttachment from email_server.tool_box import get_logger from .routes import email_bp import os logger = get_logger() @email_bp.route('/msg/content/') def view_message_content(log_id): """View the full message content for an email log if stored.""" session = Session() try: # Get log with attachments log = session.query(EmailLog).filter_by(id=log_id).first() if not log: abort(404) # Get attachments for this log attachments = session.query(EmailAttachment).filter_by(email_log_id=log_id).all() log.attachments = attachments return render_template('view_message_content.html', log=log) finally: session.close() @email_bp.route('/msg/attachment//download') def download_attachment(attachment_id): session = Session() try: attachment = session.query(EmailAttachment).get(attachment_id) if not attachment or not os.path.isfile(attachment.file_path): flash('Attachment not found.', 'danger') return redirect(url_for('email.logs', type='emails')) # Get the normalized content type and handle special cases content_type = attachment.content_type.lower() if attachment.content_type else 'application/octet-stream' extension = os.path.splitext(attachment.filename.lower())[1][1:] if '.' in attachment.filename else '' # Force download if requested as_attachment = request.args.get('download', '').lower() == 'true' # Map of extensions to content types for common files content_type_map = { 'txt': 'text/plain', 'csv': 'text/csv', 'pdf': 'application/pdf', 'jpg': 'image/jpeg', 'jpeg': 'image/jpeg', 'png': 'image/png', 'gif': 'image/gif', 'svg': 'image/svg+xml', 'html': 'text/html', 'htm': 'text/html', 'json': 'application/json', 'xml': 'text/xml', 'md': 'text/markdown', } # Update content type based on file extension if needed if content_type == 'application/octet-stream' and extension in content_type_map: content_type = content_type_map[extension] # Special handling for CSV files if content_type == 'text/csv' and not as_attachment: try: with open(attachment.file_path, 'r') as f: csv_content = f.read() # Create a simple HTML table view for CSV html_content = '' # Convert CSV to HTML table for i, line in enumerate(csv_content.split('\n')): if not line.strip(): continue html_content += '' if i == 0: # Header row html_content += ''.join(f'' for cell in line.split(',')) else: html_content += ''.join(f'' for cell in line.split(',')) html_content += '' html_content += '
{cell}{cell}
' return Response(html_content, mimetype='text/html') except Exception as e: logger.warning(f"Failed to create CSV preview: {e}") # Fall back to normal file handling # Determine if the file should be viewed in browser if as_attachment: # Force download return send_file( attachment.file_path, as_attachment=True, download_name=attachment.filename ) else: # Try to display in browser return send_file( attachment.file_path, mimetype=content_type ) finally: session.close() @email_bp.route('/msg/attachment//delete', methods=['POST', 'GET']) def delete_attachment(attachment_id): session = Session() try: attachment = session.query(EmailAttachment).get(attachment_id) if not attachment: flash('Attachment not found.', 'danger') return redirect(url_for('email.logs', type='emails')) # Remove file from disk if os.path.isfile(attachment.file_path): os.remove(attachment.file_path) # Remove from DB session.delete(attachment) session.commit() flash('Attachment deleted.', 'success') return redirect(url_for('email.logs', type='emails')) finally: session.close()