mirror of
https://codeberg.org/rimu/pyfedi
synced 2025-01-23 11:26: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):
|
||||
user_name = StringField(_l('User name'), validators=[DataRequired()])
|
||||
submit = SubmitField(_l('Add'))
|
||||
submit = SubmitField(_l('Find'))
|
||||
|
||||
|
||||
class EscalateReportForm(FlaskForm):
|
||||
|
|
|
@ -18,7 +18,7 @@ from app.community.forms import SearchRemoteCommunity, CreateDiscussionForm, Cre
|
|||
EscalateReportForm, ResolveReportForm, CreateVideoForm, CreatePollForm, RetrieveRemotePost
|
||||
from app.community.util import search_for_community, actor_to_community, \
|
||||
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, \
|
||||
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
|
||||
|
@ -988,65 +988,75 @@ 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
|
||||
def community_add_moderator(community_id: int):
|
||||
def community_add_moderator(community_id: int, user_id: int):
|
||||
if current_user.banned:
|
||||
return show_ban_message()
|
||||
community = Community.query.get_or_404(community_id)
|
||||
new_moderator = User.query.get_or_404(user_id)
|
||||
if community.is_owner() or current_user.is_admin() and not new_moderator.banned:
|
||||
existing_member = CommunityMember.query.filter(CommunityMember.user_id == new_moderator.id,
|
||||
CommunityMember.community_id == community_id).first()
|
||||
if existing_member:
|
||||
existing_member.is_moderator = True
|
||||
else:
|
||||
new_member = CommunityMember(community_id=community_id, user_id=new_moderator.id, is_moderator=True)
|
||||
db.session.add(new_member)
|
||||
db.session.commit()
|
||||
flash(_('Moderator added'))
|
||||
|
||||
# Notify new mod
|
||||
if new_moderator.is_local():
|
||||
notify = Notification(title=_('You are now a moderator of %(name)s', name=community.display_name()),
|
||||
url='/c/' + community.name, user_id=new_moderator.id,
|
||||
author_id=current_user.id)
|
||||
new_moderator.unread_notifications += 1
|
||||
db.session.add(notify)
|
||||
db.session.commit()
|
||||
else:
|
||||
# for remote users, send a chat message to let them know
|
||||
existing_conversation = Conversation.find_existing_conversation(recipient=new_moderator,
|
||||
sender=current_user)
|
||||
if not existing_conversation:
|
||||
existing_conversation = Conversation(user_id=current_user.id)
|
||||
existing_conversation.members.append(new_moderator)
|
||||
existing_conversation.members.append(current_user)
|
||||
db.session.add(existing_conversation)
|
||||
db.session.commit()
|
||||
server = current_app.config['SERVER_NAME']
|
||||
send_message(f"Hi there. I've added you as a moderator to the community !{community.name}@{server}.",
|
||||
existing_conversation.id)
|
||||
|
||||
add_to_modlog('add_mod', community_id=community_id, link_text=new_moderator.display_name(),
|
||||
link=new_moderator.link())
|
||||
|
||||
# Flush cache
|
||||
cache.delete_memoized(moderating_communities, new_moderator.id)
|
||||
cache.delete_memoized(joined_communities, new_moderator.id)
|
||||
cache.delete_memoized(community_moderators, community_id)
|
||||
return redirect(url_for('community.community_mod_list', community_id=community.id))
|
||||
|
||||
|
||||
@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():
|
||||
new_moderator = search_for_user(form.user_name.data)
|
||||
if new_moderator:
|
||||
existing_member = CommunityMember.query.filter(CommunityMember.user_id == new_moderator.id, CommunityMember.community_id == community_id).first()
|
||||
if existing_member:
|
||||
existing_member.is_moderator = True
|
||||
else:
|
||||
new_member = CommunityMember(community_id=community_id, user_id=new_moderator.id, is_moderator=True)
|
||||
db.session.add(new_member)
|
||||
db.session.commit()
|
||||
flash(_('Moderator added'))
|
||||
potential_moderators = find_local_users(form.user_name.data)
|
||||
|
||||
# Notify new mod
|
||||
if new_moderator.is_local():
|
||||
notify = Notification(title=_('You are now a moderator of %(name)s', name=community.display_name()),
|
||||
url='/c/' + community.name, user_id=new_moderator.id,
|
||||
author_id=current_user.id)
|
||||
new_moderator.unread_notifications += 1
|
||||
db.session.add(notify)
|
||||
db.session.commit()
|
||||
else:
|
||||
# for remote users, send a chat message to let them know
|
||||
existing_conversation = Conversation.find_existing_conversation(recipient=new_moderator,
|
||||
sender=current_user)
|
||||
if not existing_conversation:
|
||||
existing_conversation = Conversation(user_id=current_user.id)
|
||||
existing_conversation.members.append(new_moderator)
|
||||
existing_conversation.members.append(current_user)
|
||||
db.session.add(existing_conversation)
|
||||
db.session.commit()
|
||||
server = current_app.config['SERVER_NAME']
|
||||
send_message(f"Hi there. I've added you as a moderator to the community !{community.name}@{server}.",
|
||||
existing_conversation.id)
|
||||
|
||||
add_to_modlog('add_mod', community_id=community_id, link_text=new_moderator.display_name(),
|
||||
link=new_moderator.link())
|
||||
|
||||
# Flush cache
|
||||
cache.delete_memoized(moderating_communities, new_moderator.id)
|
||||
cache.delete_memoized(joined_communities, new_moderator.id)
|
||||
cache.delete_memoized(community_moderators, 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,
|
||||
moderating_communities=moderating_communities(current_user.get_id()),
|
||||
joined_communities=joined_communities(current_user.get_id()),
|
||||
menu_topics=menu_topics(), site=g.site
|
||||
)
|
||||
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()),
|
||||
joined_communities=joined_communities(current_user.get_id()),
|
||||
menu_topics=menu_topics(), site=g.site
|
||||
)
|
||||
|
||||
|
||||
@bp.route('/community/<int:community_id>/moderators/remove/<int:user_id>', methods=['GET', 'POST'])
|
||||
|
|
|
@ -727,3 +727,8 @@ def community_in_list(community_id, community_list):
|
|||
if community_id == tup[0]:
|
||||
return True
|
||||
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>
|
||||
<p>{{ _('See and change who moderates this community') }}</p>
|
||||
<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>
|
||||
<table class="table table-responsive">
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<h1 class="mt-2">{{ _('Reports') }}</h1>
|
||||
</div>
|
||||
<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>
|
||||
<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>
|
||||
</div>
|
||||
<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>
|
||||
<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
|
||||
import os, click
|
||||
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.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, \
|
||||
|
@ -24,7 +25,8 @@ def app_context_processor():
|
|||
return os.path.getmtime('app/static/' + filename)
|
||||
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_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
|
||||
|
|
Loading…
Reference in a new issue