Files
email-organizer/app/routes/emails.py
2025-08-07 21:34:44 -07:00

202 lines
8.2 KiB
Python

from flask import Blueprint, render_template, request, jsonify, make_response
from flask_login import login_required, current_user
from app import db
from app.models import Folder
from app.imap_service import IMAPService
from app.processed_emails_service import ProcessedEmailsService
import logging
emails_bp = Blueprint('emails', __name__)
@emails_bp.route('/api/folders/<int:folder_id>/pending-emails', methods=['GET'])
@login_required
def get_pending_emails(folder_id):
"""Get pending emails for a folder with email metadata."""
try:
# Find the folder and ensure it belongs to the current user
folder = Folder.query.filter_by(id=folder_id, user_id=current_user.id).first()
if not folder:
return jsonify({'error': 'Folder not found'}), 404
# Get IMAP service to fetch email data
imap_service = IMAPService(current_user)
# Get all email UIDs in the folder
all_uids = imap_service.get_folder_email_uids(folder.name)
# Get processed emails service
processed_emails_service = ProcessedEmailsService(current_user)
# Get pending email UIDs
pending_uids = processed_emails_service.get_pending_emails(folder.name)
# Get email headers for pending emails
pending_emails = []
for uid in pending_uids:
headers = imap_service.get_email_headers(folder.name, uid)
if headers:
# Add UID to the response
email_data = {
'uid': uid,
'subject': headers.get('subject', 'No Subject'),
'date': headers.get('date', ''),
'from': headers.get('from', ''),
'to': headers.get('to', ''),
'message_id': headers.get('message_id', '')
}
pending_emails.append(email_data)
# Return the pending emails in a dialog format
response = make_response(render_template('partials/pending_emails_dialog.html',
folder=folder,
pending_emails=pending_emails))
response.headers['HX-Trigger'] = 'open-modal'
return response
except Exception as e:
logging.exception("Error getting pending emails: %s", e)
return jsonify({'error': 'An unexpected error occurred'}), 500
@emails_bp.route('/api/folders/<int:folder_id>/emails/<email_uid>/process', methods=['POST'])
@login_required
def mark_email_processed(folder_id, email_uid):
"""Mark a specific email as processed."""
try:
# Find the folder and ensure it belongs to the current user
folder = Folder.query.filter_by(id=folder_id, user_id=current_user.id).first()
if not folder:
return jsonify({'error': 'Folder not found'}), 404
# Get processed emails service
processed_emails_service = ProcessedEmailsService(current_user)
# Mark email as processed
success = processed_emails_service.mark_email_processed(folder.name, email_uid)
if success:
# Get updated counts
pending_count = processed_emails_service.get_pending_count(folder.name)
# Update the folder's count based on folder type
if folder.folder_type == 'tidy':
folder.pending_count = pending_count
elif folder.folder_type == 'destination':
# For destination folders, update emails_count
folder.emails_count = pending_count
db.session.commit()
# Return updated dialog body
response = make_response(render_template('partials/pending_emails_updated.html',
folder=folder,
uid=email_uid))
response.headers['HX-Trigger'] = 'close-modal'
return response
else:
return jsonify({'error': 'Failed to mark email as processed'}), 500
except Exception as e:
logging.exception("Error marking email as processed: %s", e)
return jsonify({'error': 'An unexpected error occurred'}), 500
@emails_bp.route('/api/folders/<int:folder_id>/sync-emails', methods=['POST'])
@login_required
def sync_folder_emails(folder_id):
"""Sync emails for a specific folder with processed email tracking."""
try:
# Find the folder and ensure it belongs to the current user
folder = Folder.query.filter_by(id=folder_id, user_id=current_user.id).first()
if not folder:
return jsonify({'error': 'Folder not found'}), 404
# Get IMAP service to fetch email UIDs
imap_service = IMAPService(current_user)
print(imap_service)
# Get all email UIDs in the folder
email_uids = imap_service.get_folder_email_uids(folder.name)
if not email_uids:
return jsonify({'error': 'No emails found in folder'}), 200
# Get processed emails service
processed_emails_service = ProcessedEmailsService(current_user)
# Sync emails with the processed emails service
new_emails_count = processed_emails_service.sync_folder_emails(folder.name, email_uids)
# Get updated counts
pending_count = processed_emails_service.get_pending_count(folder.name)
# Update the folder's counts based on folder type
if folder.folder_type == 'tidy':
folder.pending_count = pending_count
folder.total_count = len(email_uids)
elif folder.folder_type == 'destination':
# For destination folders, update emails_count
folder.emails_count = pending_count # Using pending_count as emails_count for destination folders
db.session.commit()
# Return success response with updated counts
return jsonify({
'success': True,
'message': f'Synced {new_emails_count} new emails',
'pending_count': pending_count,
'total_count': len(email_uids)
})
except Exception as e:
logging.exception("Error syncing folder emails: %s", e)
return jsonify({'error': 'An unexpected error occurred'}), 500
@emails_bp.route('/api/folders/<int:folder_id>/process-emails', methods=['POST'])
@login_required
def process_folder_emails(folder_id):
"""Process multiple emails in a folder (mark as processed)."""
try:
# Find the folder and ensure it belongs to the current user
folder = Folder.query.filter_by(id=folder_id, user_id=current_user.id).first()
if not folder:
return jsonify({'error': 'Folder not found'}), 404
# Get email UIDs from form data
email_uids = request.form.getlist('email_uids')
if not email_uids:
return jsonify({'error': 'No email UIDs provided'}), 400
# Get processed emails service
processed_emails_service = ProcessedEmailsService(current_user)
# Mark emails as processed
processed_count = processed_emails_service.mark_emails_processed(folder.name, email_uids)
if processed_count > 0:
# Get updated counts
pending_count = processed_emails_service.get_pending_count(folder.name)
# Update the folder's count based on folder type
if folder.folder_type == 'tidy':
folder.pending_count = pending_count
elif folder.folder_type == 'destination':
# For destination folders, update emails_count
folder.emails_count = pending_count
db.session.commit()
return jsonify({
'success': True,
'message': f'Processed {processed_count} emails',
'pending_count': pending_count
})
else:
return jsonify({'error': 'No emails were processed'}), 400
except Exception as e:
logging.exception("Error processing folder emails: %s", e)
return jsonify({'error': 'An unexpected error occurred'}), 500