email log

This commit is contained in:
2025-06-02 09:30:42 +02:00
parent 38e24a690a
commit 5a9b6be79d
4 changed files with 406 additions and 2 deletions

View File

@@ -1,6 +1,6 @@
from flask import render_template, Blueprint, redirect, url_for, request, flash, Response, jsonify, session
from flask_login import current_user, login_required
from models import User, db, Room, RoomFile, RoomMemberPermission, SiteSettings, Event, Conversation, Message, MessageAttachment, Notif, EmailTemplate
from models import User, db, Room, RoomFile, RoomMemberPermission, SiteSettings, Event, Conversation, Message, MessageAttachment, Notif, EmailTemplate, Mail
from routes.auth import require_password_change
import os
from werkzeug.utils import secure_filename
@@ -11,6 +11,8 @@ import sys
import time
from forms import CompanySettingsForm
from utils import log_event, create_notification, get_unread_count
from io import StringIO
import csv
# Set up logging to show in console
logging.basicConfig(
@@ -1119,4 +1121,166 @@ def init_routes(main_bp):
})
except Exception as e:
db.session.rollback()
return jsonify({'error': str(e)}), 500
return jsonify({'error': str(e)}), 500
@main_bp.route('/settings/mails')
@login_required
def mails():
if not current_user.is_admin:
flash('Only administrators can access mail logs.', 'error')
return redirect(url_for('main.dashboard'))
# Get filter parameters
status = request.args.get('status')
date_range = request.args.get('date_range', '7d')
user_id = request.args.get('user_id')
page = request.args.get('page', 1, type=int)
per_page = 10
# Calculate date range
end_date = datetime.utcnow()
if date_range == '24h':
start_date = end_date - timedelta(days=1)
elif date_range == '7d':
start_date = end_date - timedelta(days=7)
elif date_range == '30d':
start_date = end_date - timedelta(days=30)
else:
start_date = None
# Build query
query = Mail.query
if status:
query = query.filter_by(status=status)
if start_date:
query = query.filter(Mail.created_at >= start_date)
if user_id:
query = query.filter(Mail.recipient == User.query.get(user_id).email)
# Get total count for pagination
total_mails = query.count()
total_pages = (total_mails + per_page - 1) // per_page
# Get paginated mails
mails = query.order_by(Mail.created_at.desc()).paginate(page=page, per_page=per_page)
# Get all users for filter dropdown
users = User.query.order_by(User.username).all()
# Check if this is an AJAX request
if request.headers.get('X-Requested-With') == 'XMLHttpRequest':
return render_template('settings/tabs/mails.html',
mails=mails.items,
total_pages=total_pages,
current_page=page,
status=status,
date_range=date_range,
user_id=user_id,
users=users,
csrf_token=session.get('csrf_token'))
# For full page requests, render the full settings page
site_settings = SiteSettings.get_settings()
return render_template('settings/settings.html',
primary_color=site_settings.primary_color,
secondary_color=site_settings.secondary_color,
active_tab='mails',
site_settings=site_settings,
mails=mails.items,
total_pages=total_pages,
current_page=page,
users=users,
csrf_token=session.get('csrf_token'))
@main_bp.route('/settings/mails/<int:mail_id>')
@login_required
def get_mail_details(mail_id):
if not current_user.is_admin:
return jsonify({'error': 'Unauthorized'}), 403
mail = Mail.query.get_or_404(mail_id)
return jsonify({
'id': mail.id,
'recipient': mail.recipient,
'subject': mail.subject,
'body': mail.body,
'status': mail.status,
'created_at': mail.created_at.isoformat(),
'sent_at': mail.sent_at.isoformat() if mail.sent_at else None,
'template': {
'id': mail.template.id,
'name': mail.template.name
} if mail.template else None
})
@main_bp.route('/settings/mails/download')
@login_required
def download_mails():
if not current_user.is_admin:
flash('Only administrators can download mail logs.', 'error')
return redirect(url_for('main.dashboard'))
# Get filter parameters
status = request.args.get('status')
date_range = request.args.get('date_range', '7d')
user_id = request.args.get('user_id')
# Calculate date range
end_date = datetime.utcnow()
if date_range == '24h':
start_date = end_date - timedelta(days=1)
elif date_range == '7d':
start_date = end_date - timedelta(days=7)
elif date_range == '30d':
start_date = end_date - timedelta(days=30)
else:
start_date = None
# Build query
query = Mail.query
if status:
query = query.filter_by(status=status)
if start_date:
query = query.filter(Mail.created_at >= start_date)
if user_id:
query = query.filter(Mail.recipient == User.query.get(user_id).email)
# Get all mails
mails = query.order_by(Mail.created_at.desc()).all()
# Create CSV
output = StringIO()
writer = csv.writer(output)
# Write header
writer.writerow([
'Created At',
'Recipient',
'Subject',
'Status',
'Template',
'Sent At'
])
# Write data
for mail in mails:
writer.writerow([
mail.created_at.strftime('%Y-%m-%d %H:%M:%S'),
mail.recipient,
mail.subject,
mail.status,
mail.template.name if mail.template else '-',
mail.sent_at.strftime('%Y-%m-%d %H:%M:%S') if mail.sent_at else '-'
])
output.seek(0)
return Response(
output,
mimetype='text/csv',
headers={
'Content-Disposition': f'attachment; filename=mail_log_{datetime.utcnow().strftime("%Y%m%d_%H%M%S")}.csv'
}
)