adapt /admin and /reports to new interface

This commit is contained in:
Yusur 2025-10-23 04:26:30 +02:00
parent 6b11bf4537
commit a4144c67a9
9 changed files with 68 additions and 10 deletions

View file

@ -163,6 +163,8 @@ async def error_handler_for(status: int, message: str, template: str):
case WantsContentType.JSON:
return jsonify({'error': f'{message}', 'status': status}), status
case WantsContentType.HTML:
if request.path.startswith('/admin'):
return await render_template('admin/' + template, message=f'{message}'), status
return await render_template(template, message=f'{message}'), status
case WantsContentType.PLAIN:
return f'{message} (HTTP {status})', status, {'content-type': 'text/plain; charset=UTF-8'}

View file

@ -0,0 +1,10 @@
{% extends "admin/admin_base.html" %}
{% block content %}
<div class="centered">
<h2>Bad Request</h2>
<p><a href="/">Back to homepage.</a></p>
</div>
{% endblock %}

View file

@ -0,0 +1,12 @@
{% extends "admin/admin_base.html" %}
{% from "macros/title.html" import title_tag with context %}
{% block content %}
<div class="centered">
<h2>Access Denied</h2>
<p><a href="/">Back to homepage.</a></p>
</div>
{% endblock %}

View file

@ -0,0 +1,12 @@
{% extends "admin/admin_base.html" %}
{% from "macros/title.html" import title_tag with context %}
{% block content %}
<div class="centered">
<h2>Not Found</h2>
<p><a href="/admin/">Back</a></p>
</div>
{% endblock %}

View file

@ -0,0 +1,11 @@
{% extends "admin/admin_base.html" %}
{% block content %}
<div class="centered">
<h2>Internal Server Error</h2>
<p>It's on us. <a href="javascript:history.go(0)">Refresh the page</a>.</p>
</div>
{% endblock %}

View file

@ -5,7 +5,7 @@
{{ title_tag("Admin") }}
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="/static/css/style.css">
<link rel="stylesheet" type="text/css" href="/admin/style.css">
{% for private_style in private_styles %}
<link rel="stylesheet" href="{{ private_style }}" />
{% endfor %}

View file

@ -1,6 +1,6 @@
{% macro embed_post(p) %}
<div id="post-{{ p.id | to_b32l }}" class="post-frame" data-endpoint="{{ p.id | to_b32l }}">
<h3 class="message-title"><a href="{{ p.url() }}">{{ p.title }}</a></h3>
<h3 class="message-title"><a href="/={{ p.id | to_b32l }}">{{ p.title }}</a></h3>
<div class="message-meta">Posted by <a href="{{ p.author.url() }}">@{{ p.author.username }}</a>
{% if p.parent_post %}
as a comment on <a href="{{ p.parent_post.url() }}">post “{{ p.parent_post.title }}”</a>

View file

@ -2,9 +2,10 @@
import datetime
from functools import wraps
import os
from typing import Callable
import warnings
from quart import Blueprint, abort, redirect, render_template, request, url_for
from quart import Blueprint, abort, redirect, render_template, request, send_from_directory, url_for
from quart_auth import current_user
from markupsafe import Markup
from sqlalchemy import insert, select, update
@ -23,11 +24,11 @@ current_user: UserLoader
def admin_required(func: Callable):
@wraps(func)
def wrapper(*a, **ka):
async def wrapper(*a, **ka):
user: User = current_user.user
if not user or not user.is_administrator:
abort(403)
return func(*a, **ka)
return await func(*a, **ka)
return wrapper
@ -155,10 +156,14 @@ def escalate_report(target, source: PostReport):
async def homepage():
return await render_template('admin/admin_home.html')
@bp.route('/admin/style.css')
async def style_css():
return await send_from_directory(os.path.dirname(os.path.dirname(__file__)) + '/static/css', 'style.css')
@bp.route('/admin/reports/')
@admin_required
async def reports():
report_list = db.paginate(select(PostReport).order_by(PostReport.id.desc()))
report_list = await db.paginate(select(PostReport).order_by(PostReport.id.desc()))
return await render_template('admin/admin_reports.html',
report_list=report_list, report_reasons=REPORT_REASON_STRINGS)
@ -169,10 +174,13 @@ async def report_detail(id: int):
report = (await session.execute(select(PostReport).where(PostReport.id == id))).scalar()
if report is None:
abort(404)
target = await report.target()
if target is None:
abort(404)
if request.method == 'POST':
form = await get_request_form()
action = REPORT_ACTIONS[form['do']]
await action(report.target(), report)
await action(target, report)
return redirect(url_for('admin.reports'))
return await render_template('admin/admin_report_detail.html', report=report,
report_reasons=REPORT_REASON_STRINGS)
@ -188,7 +196,7 @@ async def strikes():
@bp.route('/admin/users/')
@admin_required
async def users():
user_list = db.paginate(select(User).order_by(User.joined_at.desc()))
user_list = await db.paginate(select(User).order_by(User.joined_at.desc()))
return await render_template('admin/admin_users.html',
user_list=user_list, account_status_string=colorized_account_status_string)
@ -219,5 +227,7 @@ async def user_detail(id: int):
else:
abort(400)
strikes = (await session.execute(select(UserStrike).where(UserStrike.user_id == id).order_by(UserStrike.id.desc()))).scalars()
return render_template('admin/admin_user_detail.html', u=u,
return await render_template('admin/admin_user_detail.html', u=u,
report_reasons=REPORT_REASON_STRINGS, account_status_string=colorized_account_status_string, strikes=strikes)

View file

@ -5,6 +5,7 @@ from __future__ import annotations
from quart import Blueprint, render_template, request
from quart_auth import current_user, login_required
from sqlalchemy import insert, select
from suou import Snowflake
from freak import UserLoader
from ..models import REPORT_TARGET_COMMENT, REPORT_TARGET_POST, ReportReason, User, post_report_reasons, Comment, Post, PostReport, REPORT_REASONS, db
@ -35,7 +36,7 @@ async def report_post(id: int):
reason_code = REPORT_REASONS[reason]
))
session.commit()
return await render_template('reports/report_done.html', back_to_url=p.url())
return await render_template('reports/report_done.html', back_to_url='/=' + Snowflake(p.id).to_b32l())
return await render_template('reports/report_post.html', id = id,
report_reasons = post_report_reasons, description_text=description_text)