mirror of
https://codeberg.org/rimu/pyfedi
synced 2025-01-23 19:36:56 -08:00
when adding moderators do a fuzzy search and present a list of people to add. fixes #248
This commit is contained in:
parent
8f5af6f14d
commit
6d555c4c54
9 changed files with 126 additions and 77 deletions
|
@ -65,7 +65,7 @@ class EditCommunityForm(FlaskForm):
|
||||||
|
|
||||||
class AddModeratorForm(FlaskForm):
|
class AddModeratorForm(FlaskForm):
|
||||||
user_name = StringField(_l('User name'), validators=[DataRequired()])
|
user_name = StringField(_l('User name'), validators=[DataRequired()])
|
||||||
submit = SubmitField(_l('Add'))
|
submit = SubmitField(_l('Find'))
|
||||||
|
|
||||||
|
|
||||||
class EscalateReportForm(FlaskForm):
|
class EscalateReportForm(FlaskForm):
|
||||||
|
|
|
@ -18,7 +18,7 @@ from app.community.forms import SearchRemoteCommunity, CreateDiscussionForm, Cre
|
||||||
EscalateReportForm, ResolveReportForm, CreateVideoForm, CreatePollForm, RetrieveRemotePost
|
EscalateReportForm, ResolveReportForm, CreateVideoForm, CreatePollForm, RetrieveRemotePost
|
||||||
from app.community.util import search_for_community, actor_to_community, \
|
from app.community.util import search_for_community, actor_to_community, \
|
||||||
save_post, save_icon_file, save_banner_file, send_to_remote_instance, \
|
save_post, save_icon_file, save_banner_file, send_to_remote_instance, \
|
||||||
delete_post_from_community, delete_post_reply_from_community, community_in_list
|
delete_post_from_community, delete_post_reply_from_community, community_in_list, find_local_users
|
||||||
from app.constants import SUBSCRIPTION_MEMBER, SUBSCRIPTION_OWNER, POST_TYPE_LINK, POST_TYPE_ARTICLE, POST_TYPE_IMAGE, \
|
from app.constants import SUBSCRIPTION_MEMBER, SUBSCRIPTION_OWNER, POST_TYPE_LINK, POST_TYPE_ARTICLE, POST_TYPE_IMAGE, \
|
||||||
SUBSCRIPTION_PENDING, SUBSCRIPTION_MODERATOR, REPORT_STATE_NEW, REPORT_STATE_ESCALATED, REPORT_STATE_RESOLVED, \
|
SUBSCRIPTION_PENDING, SUBSCRIPTION_MODERATOR, REPORT_STATE_NEW, REPORT_STATE_ESCALATED, REPORT_STATE_RESOLVED, \
|
||||||
REPORT_STATE_DISCARDED, POST_TYPE_VIDEO, NOTIF_COMMUNITY, POST_TYPE_POLL, MICROBLOG_APPS
|
REPORT_STATE_DISCARDED, POST_TYPE_VIDEO, NOTIF_COMMUNITY, POST_TYPE_POLL, MICROBLOG_APPS
|
||||||
|
@ -988,18 +988,16 @@ def community_mod_list(community_id: int):
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@bp.route('/community/<int:community_id>/moderators/add', methods=['GET', 'POST'])
|
@bp.route('/community/<int:community_id>/moderators/add/<int:user_id>', methods=['GET', 'POST'])
|
||||||
@login_required
|
@login_required
|
||||||
def community_add_moderator(community_id: int):
|
def community_add_moderator(community_id: int, user_id: int):
|
||||||
if current_user.banned:
|
if current_user.banned:
|
||||||
return show_ban_message()
|
return show_ban_message()
|
||||||
community = Community.query.get_or_404(community_id)
|
community = Community.query.get_or_404(community_id)
|
||||||
if community.is_owner() or current_user.is_admin():
|
new_moderator = User.query.get_or_404(user_id)
|
||||||
form = AddModeratorForm()
|
if community.is_owner() or current_user.is_admin() and not new_moderator.banned:
|
||||||
if form.validate_on_submit():
|
existing_member = CommunityMember.query.filter(CommunityMember.user_id == new_moderator.id,
|
||||||
new_moderator = search_for_user(form.user_name.data)
|
CommunityMember.community_id == community_id).first()
|
||||||
if new_moderator:
|
|
||||||
existing_member = CommunityMember.query.filter(CommunityMember.user_id == new_moderator.id, CommunityMember.community_id == community_id).first()
|
|
||||||
if existing_member:
|
if existing_member:
|
||||||
existing_member.is_moderator = True
|
existing_member.is_moderator = True
|
||||||
else:
|
else:
|
||||||
|
@ -1038,11 +1036,23 @@ def community_add_moderator(community_id: int):
|
||||||
cache.delete_memoized(joined_communities, new_moderator.id)
|
cache.delete_memoized(joined_communities, new_moderator.id)
|
||||||
cache.delete_memoized(community_moderators, community_id)
|
cache.delete_memoized(community_moderators, community_id)
|
||||||
return redirect(url_for('community.community_mod_list', community_id=community.id))
|
return redirect(url_for('community.community_mod_list', community_id=community.id))
|
||||||
else:
|
|
||||||
flash(_('Account not found'), 'warning')
|
|
||||||
|
|
||||||
return render_template('community/community_add_moderator.html', title=_('Add moderator to %(community)s', community=community.display_name()),
|
|
||||||
community=community, form=form,
|
@bp.route('/community/<int:community_id>/moderators/find', methods=['GET', 'POST'])
|
||||||
|
@login_required
|
||||||
|
def community_find_moderator(community_id: int):
|
||||||
|
if current_user.banned:
|
||||||
|
return show_ban_message()
|
||||||
|
community = Community.query.get_or_404(community_id)
|
||||||
|
if community.is_owner() or current_user.is_admin():
|
||||||
|
form = AddModeratorForm()
|
||||||
|
potential_moderators = None
|
||||||
|
if form.validate_on_submit():
|
||||||
|
potential_moderators = find_local_users(form.user_name.data)
|
||||||
|
|
||||||
|
return render_template('community/community_find_moderator.html', title=_('Add moderator to %(community)s',
|
||||||
|
community=community.display_name()),
|
||||||
|
community=community, form=form, potential_moderators=potential_moderators,
|
||||||
moderating_communities=moderating_communities(current_user.get_id()),
|
moderating_communities=moderating_communities(current_user.get_id()),
|
||||||
joined_communities=joined_communities(current_user.get_id()),
|
joined_communities=joined_communities(current_user.get_id()),
|
||||||
menu_topics=menu_topics(), site=g.site
|
menu_topics=menu_topics(), site=g.site
|
||||||
|
|
|
@ -727,3 +727,8 @@ def community_in_list(community_id, community_list):
|
||||||
if community_id == tup[0]:
|
if community_id == tup[0]:
|
||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
def find_local_users(search: str) -> List[User]:
|
||||||
|
return User.query.filter(User.banned == False, User.deleted == False, User.ap_id == None, User.user_name.ilike(f"%{search}%")).\
|
||||||
|
order_by(desc(User.reputation)).all()
|
||||||
|
|
|
@ -1,19 +0,0 @@
|
||||||
{% if theme() and file_exists('app/templates/themes/' + theme() + '/base.html') %}
|
|
||||||
{% extends 'themes/' + theme() + '/base.html' %}
|
|
||||||
{% else %}
|
|
||||||
{% extends "base.html" %}
|
|
||||||
{% endif %} %}
|
|
||||||
{% from 'bootstrap/form.html' import render_form %}
|
|
||||||
|
|
||||||
{% block app_content %}
|
|
||||||
<div class="row">
|
|
||||||
<div class="col col-login mx-auto">
|
|
||||||
<div class="card mt-5">
|
|
||||||
<div class="card-body p-6">
|
|
||||||
<div class="card-title">{{ _('Add moderator to %(community)s', community=community.display_name()) }}</div>
|
|
||||||
{{ render_form(form) }}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
{% endblock %}
|
|
51
app/templates/community/community_find_moderator.html
Normal file
51
app/templates/community/community_find_moderator.html
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
{% if theme() and file_exists('app/templates/themes/' + theme() + '/base.html') %}
|
||||||
|
{% extends 'themes/' + theme() + '/base.html' %}
|
||||||
|
{% else %}
|
||||||
|
{% extends "base.html" %}
|
||||||
|
{% endif %} %}
|
||||||
|
{% from 'bootstrap/form.html' import render_form %}
|
||||||
|
|
||||||
|
{% block app_content %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col col-login mx-auto">
|
||||||
|
<div class="card mt-5">
|
||||||
|
<div class="card-body p-6">
|
||||||
|
<div class="card-title">{{ _('Add moderator to %(community)s', community=community.display_name()) }}</div>
|
||||||
|
{{ render_form(form) }}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% if potential_moderators != None %}
|
||||||
|
<div class="row">
|
||||||
|
<div class="col mx-auto">
|
||||||
|
<div class="card mt-5">
|
||||||
|
<div class="card-body p-6">
|
||||||
|
{% if potential_moderators -%}
|
||||||
|
<div class="card-title">{{ _('Found some people:') }}</div>
|
||||||
|
<table class="table table-striped">
|
||||||
|
{% for user in potential_moderators -%}
|
||||||
|
<tr>
|
||||||
|
<td class="align-middle">{{ render_username(user) }}</td>
|
||||||
|
<td class="text-right">
|
||||||
|
{% if community_membership(user, community) != SUBSCRIPTION_MODERATOR %}
|
||||||
|
<a class="btn btn-primary" href="{{ url_for('community.community_add_moderator', community_id=community.id, user_id=user.id) }}">{{ _('Add') }}</a>
|
||||||
|
{% else %}
|
||||||
|
{{ _('Already a moderator') }}
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
{% endfor -%}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
{% else -%}
|
||||||
|
<div class="card-title">{{ _('No people found') }}</div>
|
||||||
|
<p>{{ _('Only local accounts can be added as moderators.') }}</p>
|
||||||
|
{% endif -%}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
{% endblock %}
|
|
@ -23,7 +23,7 @@
|
||||||
</div>
|
</div>
|
||||||
<p>{{ _('See and change who moderates this community') }}</p>
|
<p>{{ _('See and change who moderates this community') }}</p>
|
||||||
<div class="col-12 text-right">
|
<div class="col-12 text-right">
|
||||||
<a class="btn btn-primary" href="{{ url_for('community.community_add_moderator', community_id=community.id) }}">{{ _('Add moderator') }}</a>
|
<a class="btn btn-primary" href="{{ url_for('community.community_find_moderator', community_id=community.id) }}">{{ _('Add moderator') }}</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<table class="table table-responsive">
|
<table class="table table-responsive">
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
<h1 class="mt-2">{{ _('Reports') }}</h1>
|
<h1 class="mt-2">{{ _('Reports') }}</h1>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-md-2 text-right">
|
<div class="col-12 col-md-2 text-right">
|
||||||
<!-- <a class="btn btn-primary" href="{{ url_for('community.community_add_moderator', community_id=community.id) }}">{{ _('Add moderator') }}</a> -->
|
<!-- <a class="btn btn-primary" href="{{ url_for('community.community_find_moderator', community_id=community.id) }}">{{ _('Add moderator') }}</a> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p>{{ _('See and handle all reports made about %(community)s', community=community.display_name()) }}.</p>
|
<p>{{ _('See and handle all reports made about %(community)s', community=community.display_name()) }}.</p>
|
||||||
|
|
|
@ -21,7 +21,7 @@
|
||||||
<h1 class="mt-2">{{ _('Subscribers') }}</h1>
|
<h1 class="mt-2">{{ _('Subscribers') }}</h1>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-md-2 text-right">
|
<div class="col-12 col-md-2 text-right">
|
||||||
<!-- <a class="btn btn-primary" href="{{ url_for('community.community_add_moderator', community_id=community.id) }}">{{ _('Add moderator') }}</a> -->
|
<!-- <a class="btn btn-primary" href="{{ url_for('community.community_find_moderator', community_id=community.id) }}">{{ _('Add moderator') }}</a> -->
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p>{{ _('See who is subscribed to %(community)s', community=community.display_name()) }}</p>
|
<p>{{ _('See who is subscribed to %(community)s', community=community.display_name()) }}</p>
|
||||||
|
|
|
@ -8,7 +8,8 @@ from flask_login import current_user
|
||||||
from app import create_app, db, cli
|
from app import create_app, db, cli
|
||||||
import os, click
|
import os, click
|
||||||
from flask import session, g, json, request, current_app
|
from flask import session, g, json, request, current_app
|
||||||
from app.constants import POST_TYPE_LINK, POST_TYPE_IMAGE, POST_TYPE_ARTICLE, POST_TYPE_VIDEO, POST_TYPE_POLL
|
from app.constants import POST_TYPE_LINK, POST_TYPE_IMAGE, POST_TYPE_ARTICLE, POST_TYPE_VIDEO, POST_TYPE_POLL, \
|
||||||
|
SUBSCRIPTION_MODERATOR
|
||||||
from app.models import Site
|
from app.models import Site
|
||||||
from app.utils import getmtime, gibberish, shorten_string, shorten_url, digits, user_access, community_membership, \
|
from app.utils import getmtime, gibberish, shorten_string, shorten_url, digits, user_access, community_membership, \
|
||||||
can_create_post, can_upvote, can_downvote, shorten_number, ap_datetime, current_theme, community_link_to_href, \
|
can_create_post, can_upvote, can_downvote, shorten_number, ap_datetime, current_theme, community_link_to_href, \
|
||||||
|
@ -24,7 +25,8 @@ def app_context_processor():
|
||||||
return os.path.getmtime('app/static/' + filename)
|
return os.path.getmtime('app/static/' + filename)
|
||||||
return dict(getmtime=getmtime, instance_domain=current_app.config['SERVER_NAME'],
|
return dict(getmtime=getmtime, instance_domain=current_app.config['SERVER_NAME'],
|
||||||
POST_TYPE_LINK=POST_TYPE_LINK, POST_TYPE_IMAGE=POST_TYPE_IMAGE,
|
POST_TYPE_LINK=POST_TYPE_LINK, POST_TYPE_IMAGE=POST_TYPE_IMAGE,
|
||||||
POST_TYPE_ARTICLE=POST_TYPE_ARTICLE, POST_TYPE_VIDEO=POST_TYPE_VIDEO, POST_TYPE_POLL=POST_TYPE_POLL)
|
POST_TYPE_ARTICLE=POST_TYPE_ARTICLE, POST_TYPE_VIDEO=POST_TYPE_VIDEO, POST_TYPE_POLL=POST_TYPE_POLL,
|
||||||
|
SUBSCRIPTION_MODERATOR=SUBSCRIPTION_MODERATOR)
|
||||||
|
|
||||||
|
|
||||||
@app.shell_context_processor
|
@app.shell_context_processor
|
||||||
|
|
Loading…
Reference in a new issue