public mod log #21

This commit is contained in:
rimu 2024-07-07 16:03:35 +08:00
parent 3647e2796d
commit 557e73d6a2
5 changed files with 94 additions and 7 deletions

View file

@ -36,8 +36,9 @@ class SiteMiscForm(FlaskForm):
registration_mode = SelectField(_l('Registration mode'), choices=types, default=1, coerce=str, render_kw={'class': 'form-select'})
application_question = TextAreaField(_l('Question to ask people applying for an account'))
auto_decline_referrers = TextAreaField(_l('Block registrations from these referrers (one per line)'))
log_activitypub_json = BooleanField(_l('Log ActivityPub JSON for debugging'))
default_theme = SelectField(_l('Default theme'), coerce=str, render_kw={'class': 'form-select'})
log_activitypub_json = BooleanField(_l('Log ActivityPub JSON for debugging'))
public_modlog = BooleanField(_l('Show moderation actions publicly'))
submit = SubmitField(_l('Save'))

View file

@ -155,6 +155,7 @@ def admin_misc():
db.session.add(site)
db.session.commit()
cache.delete_memoized(blocked_referrers)
set_setting('public_modlog', form.public_modlog.data)
flash('Settings saved.')
elif request.method == 'GET':
form.enable_downvotes.data = site.enable_downvotes
@ -169,6 +170,7 @@ def admin_misc():
form.auto_decline_referrers.data = site.auto_decline_referrers
form.log_activitypub_json.data = site.log_activitypub_json
form.default_theme.data = site.default_theme if site.default_theme is not None else ''
form.public_modlog.data = get_setting('public_modlog', False)
return render_template('admin/misc.html', title=_('Misc settings'), form=form,
moderating_communities=moderating_communities(current_user.get_id()),
joined_communities=joined_communities(current_user.get_id()),

View file

@ -32,7 +32,7 @@ from app.utils import render_template, get_setting, gibberish, request_etag_matc
generate_image_from_video_url, blocked_users, microblog_content_to_title, menu_topics, languages_for_form, \
make_cache_key
from app.models import Community, CommunityMember, Post, Site, User, utcnow, Domain, Topic, File, Instance, \
InstanceRole, Notification, Language, community_language, PostReply
InstanceRole, Notification, Language, community_language, PostReply, ModLog
@bp.route('/', methods=['HEAD', 'GET', 'POST'])
@ -353,6 +353,28 @@ def list_subscribed_communities():
menu_topics=menu_topics(), site=g.site)
@bp.route('/modlog', methods=['GET'])
def modlog():
page = request.args.get('page', 1, type=int)
low_bandwidth = request.cookies.get('low_bandwidth', '0') == '1'
modlog_entries = ModLog.query.filter(ModLog.public == True).order_by(desc(ModLog.created_at))
# Pagination
modlog_entries = modlog_entries.paginate(page=page, per_page=100 if not low_bandwidth else 50, error_out=False)
next_url = url_for('main.modlog', page=modlog_entries.next_num) if modlog_entries.has_next else None
prev_url = url_for('main.modlog', page=modlog_entries.prev_num) if modlog_entries.has_prev and page != 1 else None
return render_template('modlog.html',
title=_('Moderation Log'), modlog_entries=modlog_entries,
next_url=next_url, prev_url=prev_url, low_bandwidth=low_bandwidth,
moderating_communities=moderating_communities(current_user.get_id()),
joined_communities=joined_communities(current_user.get_id()),
menu_topics=menu_topics(), site=g.site,
inoculation=inoculation[randint(0, len(inoculation) - 1)]
)
@bp.route('/donate')
def donate():
return render_template('donate.html')

59
app/templates/modlog.html Normal file
View file

@ -0,0 +1,59 @@
{% if theme() and file_exists('app/templates/themes/' + theme() + '/base.html') -%}
{% extends 'themes/' + theme() + '/base.html' -%}
{% else -%}
{% extends "base.html" -%}
{% endif -%} -%}
{% from 'bootstrap5/form.html' import render_form -%}
{% set active_child = 'list_communities' -%}
{% block app_content -%}
<h1>{{ _('Moderation log') }}</h1>
<div class="table-responsive-md mt-4">
{% if modlog_entries.items %}
<table class="table table-responsive">
<thead>
<tr>
<th>{{ _('When') }}</th>
<th>{{ _('Moderator') }}</th>
<th>{{ _('Action') }}</th>
</tr>
</thead>
<tbody>
{% for modlog_entry in modlog_entries.items %}
<tr>
<td>{{ moment(modlog_entry.created_at).fromNow() }}</td>
<td>{{ render_username(modlog_entry.author) }}</td>
<td>{{ modlog_entry.action_to_str() }}
{% if modlog_entry.link and modlog_entry.link_text -%}
<a href="/{{ modlog_entry.link }}">{{ modlog_entry.link_text}}</a>
{% elif modlog_entry.link_text -%}
{{ modlog_entry.link_text }}
{% endif -%}
{% if modlog_entry.reason -%}
<br>{{ _('Reason:') }} {{ modlog_entry.reason }}
{% endif -%}
{% if modlog_entry.community_id -%}
<a href="/c/{{ modlog_entry.community.link() }}">{{ _(' in %(community_name)s', community_name='' + modlog_entry.community.display_name()) }}</a>
{% endif -%}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% else -%}
<p>{{ _('There are no moderation actions to show.') }}</p>
{% endif -%}
</div>
<nav aria-label="Pagination" class="mt-4" role="navigation">
{% if prev_url -%}
<a href="{{ prev_url }}" class="btn btn-primary" rel='nofollow'>
<span aria-hidden="true">&larr;</span> {{ _('Previous page') }}
</a>
{% endif -%}
{% if next_url -%}
<a href="{{ next_url }}" class="btn btn-primary" rel='nofollow'>
{{ _('Next page') }} <span aria-hidden="true">&rarr;</span>
</a>
{% endif -%}
</nav>
{% endblock -%}

View file

@ -131,7 +131,9 @@ def head_request(uri, params=None, headers=None) -> requests.Response:
return response
# saves an arbitrary object into a persistent key-value store. cached.
# Saves an arbitrary object into a persistent key-value store. cached.
# Similar to g.site.* except g.site.* is populated on every single page load so g.site is best for settings that are
# accessed very often (e.g. every page load)
@cache.memoize(timeout=50)
def get_setting(name: str, default=None):
setting = Settings.query.filter_by(name=name).first()
@ -1152,7 +1154,7 @@ def actor_contains_blocked_words(actor):
return False
def add_to_modlog(action: str, community_id: int = None, reason: str = '', link: str = '', link_text: str = '', public: bool = False):
def add_to_modlog(action: str, community_id: int = None, reason: str = '', link: str = '', link_text: str = ''):
""" Adds a new entry to the Moderation Log """
if action not in ModLog.action_map.keys():
raise Exception('Invalid action: ' + action)
@ -1161,11 +1163,12 @@ def add_to_modlog(action: str, community_id: int = None, reason: str = '', link:
else:
action_type = 'mod'
db.session.add(ModLog(user_id=current_user.id, community_id=community_id, type=action_type, action=action,
reason=reason, link=link, link_text=link_text, public=public))
reason=reason, link=link, link_text=link_text, public=get_setting('public_modlog', False)))
db.session.commit()
def add_to_modlog_activitypub(action: str, actor: User, community_id: int = None, reason: str = '', link: str = '', link_text: str = '', public: bool = False):
def add_to_modlog_activitypub(action: str, actor: User, community_id: int = None, reason: str = '', link: str = '',
link_text: str = ''):
""" Adds a new entry to the Moderation Log - identical to above except has an 'actor' parameter """
if action not in ModLog.action_map.keys():
raise Exception('Invalid action: ' + action)
@ -1174,5 +1177,5 @@ def add_to_modlog_activitypub(action: str, actor: User, community_id: int = None
else:
action_type = 'mod'
db.session.add(ModLog(user_id=actor.id, community_id=community_id, type=action_type, action=action,
reason=reason, link=link, link_text=link_text, public=public))
reason=reason, link=link, link_text=link_text, public=get_setting('public_modlog', False)))
db.session.commit()