from flask import Blueprint, render_template, redirect, url_for, flash, request, abort from flask_login import current_user, login_required from app import db from models import User, Category, Topic, Post, Tag, Report, Role from forms import CreateCategoryForm, EditCategoryForm, EditUserForm, CreateTagForm import logging # Set up logger logger = logging.getLogger(__name__) # Create blueprint admin_bp = Blueprint('admin', __name__, url_prefix='/admin') # Admin access middleware @admin_bp.before_request def check_admin(): # Vérifie si l'utilisateur est authentifié, sinon redirige vers la page de connexion if not current_user.is_authenticated: flash('Vous devez être connecté pour accéder à cette page.', 'warning') return redirect(url_for('auth.login')) # Vérifie si l'utilisateur est modérateur ou admin, sinon affiche une erreur if not current_user.is_moderator(): abort(403) # Forbidden # Routes @admin_bp.route('/') def dashboard(): # Count stats for dashboard user_count = User.query.count() topic_count = Topic.query.count() post_count = Post.query.count() report_count = Report.query.filter_by(is_resolved=False).count() # Prepare stats dictionary for template stats = { 'users': user_count, 'topics': topic_count, 'posts': post_count, 'unresolved_reports': report_count } # Get recent activities recent_activities = [] # Add recent reports recent_reports = Report.query.filter_by(is_resolved=False)\ .order_by(Report.created_at.desc())\ .limit(5)\ .all() for report in recent_reports: activity = { 'icon': 'flag', 'description': f'Nouveau signalement par {report.reporter.username}', 'timestamp': report.created_at } recent_activities.append(activity) # Add recent topics recent_topics = Topic.query.order_by(Topic.created_at.desc()).limit(5).all() for topic in recent_topics: activity = { 'icon': 'message-square', 'description': f'Nouveau sujet créé par {topic.author.username}', 'timestamp': topic.created_at } recent_activities.append(activity) # Sort activities by timestamp recent_activities.sort(key=lambda x: x['timestamp'], reverse=True) recent_activities = recent_activities[:10] # Limit to 10 activities return render_template('admin/dashboard.html', stats=stats, recent_activities=recent_activities) # Category management @admin_bp.route('/categories') def manage_categories(): if not current_user.is_admin(): abort(403) # Only admins can manage categories categories = Category.query.order_by(Category.order).all() return render_template('admin/manage_categories.html', categories=categories) @admin_bp.route('/categories/create', methods=['GET', 'POST']) def create_category(): if not current_user.is_admin(): abort(403) form = CreateCategoryForm() if form.validate_on_submit(): category = Category( name=form.name.data, description=form.description.data, order=int(form.order.data) ) db.session.add(category) db.session.commit() flash('Category created successfully!', 'success') return redirect(url_for('admin.manage_categories')) return render_template('admin/create_category.html', form=form) @admin_bp.route('/categories//edit', methods=['GET', 'POST']) def edit_category(id): if not current_user.is_admin(): abort(403) category = Category.query.get_or_404(id) form = EditCategoryForm() if form.validate_on_submit(): category.name = form.name.data category.description = form.description.data category.order = int(form.order.data) db.session.commit() flash('Category updated successfully!', 'success') return redirect(url_for('admin.manage_categories')) # Pre-fill form if request.method == 'GET': form.name.data = category.name form.description.data = category.description form.order.data = str(category.order) return render_template('admin/edit_category.html', form=form, category=category) @admin_bp.route('/categories//delete', methods=['POST']) def delete_category(id): if not current_user.is_admin(): abort(403) category = Category.query.get_or_404(id) # Check if category has topics if category.topics.count() > 0: flash('Cannot delete category that contains topics.', 'danger') return redirect(url_for('admin.manage_categories')) db.session.delete(category) db.session.commit() flash('Category deleted successfully!', 'success') return redirect(url_for('admin.manage_categories')) # User management @admin_bp.route('/users') def manage_users(): if not current_user.is_admin(): abort(403) page = request.args.get('page', 1, type=int) per_page = 20 users = User.query.order_by(User.username)\ .paginate(page=page, per_page=per_page, error_out=False) return render_template('admin/manage_users.html', users=users) @admin_bp.route('/users//edit', methods=['GET', 'POST']) def edit_user(id): if not current_user.is_admin(): abort(403) user = User.query.get_or_404(id) form = EditUserForm() if form.validate_on_submit(): user.role = form.role.data user.is_active = form.is_active.data user.is_banned = form.is_banned.data user.ban_reason = form.ban_reason.data if form.is_banned.data else None db.session.commit() flash('User updated successfully!', 'success') return redirect(url_for('admin.manage_users')) # Pre-fill form if request.method == 'GET': form.role.data = user.role form.is_active.data = user.is_active form.is_banned.data = user.is_banned form.ban_reason.data = user.ban_reason return render_template('admin/edit_user.html', form=form, user=user) # Report management @admin_bp.route('/reports') def manage_reports(): page = request.args.get('page', 1, type=int) per_page = 20 show_resolved = request.args.get('show_resolved', False, type=bool) if show_resolved: reports = Report.query.order_by(Report.created_at.desc()) else: reports = Report.query.filter_by(is_resolved=False).order_by(Report.created_at.desc()) reports = reports.paginate(page=page, per_page=per_page, error_out=False) return render_template('admin/manage_reports.html', reports=reports, show_resolved=show_resolved) @admin_bp.route('/reports//resolve', methods=['POST']) def resolve_report(id): report = Report.query.get_or_404(id) report.is_resolved = True report.resolved_by_id = current_user.id report.resolved_at = db.func.now() db.session.commit() flash('Report marked as resolved.', 'success') return redirect(url_for('admin.manage_reports')) @admin_bp.route('/reports//delete_content', methods=['POST']) def delete_reported_content(id): report = Report.query.get_or_404(id) # Delete the reported content if report.post_id: post = Post.query.get(report.post_id) if post: db.session.delete(post) elif report.topic_id and not report.post_id: topic = Topic.query.get(report.topic_id) if topic: db.session.delete(topic) # Mark report as resolved report.is_resolved = True report.resolved_by_id = current_user.id report.resolved_at = db.func.now() db.session.commit() flash('Reported content has been deleted and report resolved.', 'success') return redirect(url_for('admin.manage_reports')) # Tag management @admin_bp.route('/tags') def manage_tags(): if not current_user.is_admin(): abort(403) page = request.args.get('page', 1, type=int) per_page = 30 tags = Tag.query.order_by(Tag.name)\ .paginate(page=page, per_page=per_page, error_out=False) return render_template('admin/manage_tags.html', tags=tags) @admin_bp.route('/tags/create', methods=['GET', 'POST']) def create_tag(): if not current_user.is_admin(): abort(403) form = CreateTagForm() if form.validate_on_submit(): tag = Tag(name=form.name.data.lower()) db.session.add(tag) db.session.commit() flash('Tag created successfully!', 'success') return redirect(url_for('admin.manage_tags')) return render_template('admin/create_tag.html', form=form) @admin_bp.route('/tags//delete', methods=['POST']) def delete_tag(id): if not current_user.is_admin(): abort(403) tag = Tag.query.get_or_404(id) # Remove tag from topics for topic in tag.topics: topic.tags.remove(tag) # Delete the tag db.session.delete(tag) db.session.commit() flash('Tag deleted successfully!', 'success') return redirect(url_for('admin.manage_tags'))