|
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 |
|
|
|
|
|
logger = logging.getLogger(__name__) |
|
|
|
|
|
admin_bp = Blueprint('admin', __name__, url_prefix='/admin') |
|
|
|
|
|
@admin_bp.before_request |
|
def check_admin(): |
|
|
|
if not current_user.is_authenticated: |
|
flash('Vous devez être connecté pour accéder à cette page.', 'warning') |
|
return redirect(url_for('auth.login')) |
|
|
|
|
|
if not current_user.is_moderator(): |
|
abort(403) |
|
|
|
|
|
@admin_bp.route('/') |
|
def 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() |
|
|
|
|
|
stats = { |
|
'users': user_count, |
|
'topics': topic_count, |
|
'posts': post_count, |
|
'unresolved_reports': report_count |
|
} |
|
|
|
|
|
recent_activities = [] |
|
|
|
|
|
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) |
|
|
|
|
|
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) |
|
|
|
|
|
recent_activities.sort(key=lambda x: x['timestamp'], reverse=True) |
|
recent_activities = recent_activities[:10] |
|
|
|
return render_template('admin/dashboard.html', |
|
stats=stats, |
|
recent_activities=recent_activities) |
|
|
|
|
|
@admin_bp.route('/categories') |
|
def manage_categories(): |
|
if not current_user.is_admin(): |
|
abort(403) |
|
|
|
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/<int:id>/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')) |
|
|
|
|
|
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/<int:id>/delete', methods=['POST']) |
|
def delete_category(id): |
|
if not current_user.is_admin(): |
|
abort(403) |
|
|
|
category = Category.query.get_or_404(id) |
|
|
|
|
|
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')) |
|
|
|
|
|
@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/<int:id>/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')) |
|
|
|
|
|
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) |
|
|
|
|
|
@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/<int:id>/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/<int:id>/delete_content', methods=['POST']) |
|
def delete_reported_content(id): |
|
report = Report.query.get_or_404(id) |
|
|
|
|
|
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) |
|
|
|
|
|
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')) |
|
|
|
|
|
@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/<int:id>/delete', methods=['POST']) |
|
def delete_tag(id): |
|
if not current_user.is_admin(): |
|
abort(403) |
|
|
|
tag = Tag.query.get_or_404(id) |
|
|
|
|
|
for topic in tag.topics: |
|
topic.tags.remove(tag) |
|
|
|
|
|
db.session.delete(tag) |
|
db.session.commit() |
|
|
|
flash('Tag deleted successfully!', 'success') |
|
return redirect(url_for('admin.manage_tags')) |
|
|