mirror of
https://codeberg.org/rimu/pyfedi
synced 2025-01-23 19:36:56 -08:00
domain block and ban
This commit is contained in:
parent
d4ea6aba0e
commit
888cce94fc
4 changed files with 160 additions and 14 deletions
|
@ -3,14 +3,16 @@ from flask_login import login_user, logout_user, current_user, login_required
|
|||
from flask_babel import _
|
||||
|
||||
from app import db, constants
|
||||
from app.models import Post, Domain, Community
|
||||
from app.models import Post, Domain, Community, DomainBlock
|
||||
from app.domain import bp
|
||||
from app.utils import get_setting, render_template
|
||||
from app.utils import get_setting, render_template, permission_required
|
||||
from sqlalchemy import desc
|
||||
|
||||
|
||||
@bp.route('/d/<domain_id>', methods=['GET'])
|
||||
def show_domain(domain_id):
|
||||
page = request.args.get('page', 1, type=int)
|
||||
|
||||
if '.' in domain_id:
|
||||
domain = Domain.query.filter_by(name=domain_id, banned=False).first()
|
||||
else:
|
||||
|
@ -23,16 +25,81 @@ def show_domain(domain_id):
|
|||
filter(Post.from_bot == False, Post.domain_id == domain.id, Community.banned == False).\
|
||||
order_by(desc(Post.last_active)).all()
|
||||
else:
|
||||
posts = Post.query.join(Community).filter(Post.domain_id == domain.id, Community.banned == False).order_by(desc(Post.last_active)).all()
|
||||
# todo: pagination
|
||||
posts = Post.query.join(Community).filter(Post.domain_id == domain.id, Community.banned == False).order_by(desc(Post.last_active))
|
||||
# pagination
|
||||
posts = posts.paginate(page=page, per_page=100, error_out=False)
|
||||
next_url = url_for('main.index', page=posts.next_num) if posts.has_next else None
|
||||
prev_url = url_for('main.index', page=posts.prev_num) if posts.has_prev and page != 1 else None
|
||||
return render_template('domain/domain.html', domain=domain, title=domain.name, posts=posts,
|
||||
POST_TYPE_IMAGE=constants.POST_TYPE_IMAGE, POST_TYPE_LINK=constants.POST_TYPE_LINK)
|
||||
POST_TYPE_IMAGE=constants.POST_TYPE_IMAGE, POST_TYPE_LINK=constants.POST_TYPE_LINK,
|
||||
next_url=next_url, prev_url=prev_url)
|
||||
else:
|
||||
abort(404)
|
||||
|
||||
|
||||
@bp.route('/domains', methods=['GET'])
|
||||
def domains():
|
||||
domains = Domain.query.filter_by(banned=False).order_by(Domain.name).all()
|
||||
page = request.args.get('page', 1, type=int)
|
||||
search = request.args.get('search', '')
|
||||
|
||||
return render_template('domain/domains.html', title='All known domains', domains=domains)
|
||||
domains = Domain.query.filter_by(banned=False)
|
||||
if search != '':
|
||||
domains = domains.filter(Domain.name.ilike(f'%{search}%'))
|
||||
domains = domains.order_by(Domain.name)
|
||||
domains = domains.paginate(page=page, per_page=100, error_out=False)
|
||||
|
||||
next_url = url_for('main.index', page=domains.next_num) if domains.has_next else None
|
||||
prev_url = url_for('main.index', page=domains.prev_num) if domains.has_prev and page != 1 else None
|
||||
|
||||
return render_template('domain/domains.html', title='All known domains', domains=domains,
|
||||
next_url=next_url, prev_url=prev_url, search=search)
|
||||
|
||||
|
||||
@bp.route('/d/<int:domain_id>/block')
|
||||
@login_required
|
||||
def domain_block(domain_id):
|
||||
domain = Domain.query.get_or_404(domain_id)
|
||||
block = DomainBlock.query.filter_by(user_id=current_user.id, domain_id=domain_id).first()
|
||||
if not block:
|
||||
block = DomainBlock(user_id=current_user.id, domain_id=domain_id)
|
||||
db.session.add(block)
|
||||
db.session.commit()
|
||||
flash(_('%(name)s blocked.', name=domain.name))
|
||||
return redirect(url_for('domain.show_domain', domain_id=domain.id))
|
||||
|
||||
|
||||
@bp.route('/d/<int:domain_id>/unblock')
|
||||
@login_required
|
||||
def domain_unblock(domain_id):
|
||||
domain = Domain.query.get_or_404(domain_id)
|
||||
block = DomainBlock.query.filter_by(user_id=current_user.id, domain_id=domain_id).first()
|
||||
if not block:
|
||||
db.session.delete(block)
|
||||
db.session.commit()
|
||||
flash(_('%(name)s un-blocked.', name=domain.name))
|
||||
return redirect(url_for('domain.show_domain', domain_id=domain.id))
|
||||
|
||||
|
||||
@bp.route('/d/<int:domain_id>/ban')
|
||||
@login_required
|
||||
@permission_required('manage users')
|
||||
def domain_ban(domain_id):
|
||||
domain = Domain.query.get_or_404(domain_id)
|
||||
if domain:
|
||||
domain.banned = True
|
||||
db.session.commit()
|
||||
domain.purge_content()
|
||||
flash(_('%(name)s banned for all users and all content deleted.', name=domain.name))
|
||||
return redirect(url_for('domain.domains'))
|
||||
|
||||
|
||||
@bp.route('/d/<int:domain_id>/unban')
|
||||
@login_required
|
||||
@permission_required('manage users')
|
||||
def domain_unban(domain_id):
|
||||
domain = Domain.query.get_or_404(domain_id)
|
||||
if domain:
|
||||
domain.banned = True
|
||||
db.session.commit()
|
||||
flash(_('%(name)s un-banned for all users.', name=domain.name))
|
||||
return redirect(url_for('domain.show_domain', domain_id=domain.id))
|
||||
|
|
|
@ -796,6 +796,21 @@ class Domain(db.Model):
|
|||
notify_mods = db.Column(db.Boolean, default=False, index=True)
|
||||
notify_admins = db.Column(db.Boolean, default=False, index=True)
|
||||
|
||||
def blocked_by(self, user):
|
||||
block = DomainBlock.query.filter_by(domain_id=self.id, user_id=user.id).first()
|
||||
return block is not None
|
||||
|
||||
def purge_content(self):
|
||||
files = File.query.join(Post).filter(Post.domain_id == self.id).all()
|
||||
for file in files:
|
||||
file.delete_from_disk()
|
||||
posts = Post.query.filter_by(domain_id=self.id).all()
|
||||
for post in posts:
|
||||
post.delete_dependencies()
|
||||
post.flush_cache()
|
||||
db.session.delete(post)
|
||||
db.session.commit()
|
||||
|
||||
|
||||
class DomainBlock(db.Model):
|
||||
user_id = db.Column(db.Integer, db.ForeignKey('user.id'), primary_key=True)
|
||||
|
|
|
@ -19,10 +19,64 @@
|
|||
<p>{{ _('No posts in this domain yet.') }}</p>
|
||||
{% endfor %}
|
||||
</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">←</span> {{ _('Previous page') }}
|
||||
</a>
|
||||
{% endif %}
|
||||
{% if next_url %}
|
||||
<a href="{{ next_url }}" class="btn btn-primary" rel='nofollow'>
|
||||
{{ _('Next page') }} <span aria-hidden="true">→</span>
|
||||
</a>
|
||||
{% endif %}
|
||||
</nav>
|
||||
</div>
|
||||
|
||||
<aside class="col-12 col-md-4 side_pane" role="complementary">
|
||||
{% if current_user.is_authenticated %}
|
||||
<div class="card mt-3">
|
||||
<div class="card-header">
|
||||
<h2>{{ _('Domain management') }}</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
{% if domain.blocked_by(current_user) %}
|
||||
<div class="col-4">
|
||||
<a class="w-100 btn btn-primary" href="/d/{{ domain.id }}/unblock">{{ _('Unblock') }}</a>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="col-4">
|
||||
<a class="w-100 btn btn-primary" href="/d/{{ domain.id }}/block">{{ _('Block') }}</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% if user_access('ban users', current_user.id) or user_access('manage users', current_user.id) %}
|
||||
<div class="card mt-3">
|
||||
<div class="card-header">
|
||||
<h2>{{ _('Domain management') }}</h2>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="row">
|
||||
{% if domain.banned %}
|
||||
<div class="col-8">
|
||||
<a class="w-100 btn btn-primary confirm_first" href="/d/{{ domain.id }}/unban">{{ _('Unban') }}</a>
|
||||
</div>
|
||||
{% else %}
|
||||
<div class="col-8">
|
||||
<a class="w-100 btn btn-primary confirm_first" href="/d/{{ domain.id }}/ban">{{ _('Ban instance-wide') }}</a>
|
||||
</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
{% include "_inoculation_links.html" %}
|
||||
</aside>
|
||||
</div>
|
||||
<div class="row">
|
||||
|
|
|
@ -10,16 +10,26 @@
|
|||
<li class="breadcrumb-item active">Domains</li>
|
||||
</ol>
|
||||
</nav>
|
||||
{% if search == '' %}
|
||||
<h1 class="mt-2">{{ _('All known domains') }}</h1>
|
||||
<div class="post_list">
|
||||
<ul>
|
||||
{% else %}
|
||||
<h1 class="mt-2">{{ _('Domains containing %(search)s', search=search) }}</h1>
|
||||
{% endif %}
|
||||
<form method="get"><input type="search" name="search" value="{{ search }}" placeholder="{{ _('Search') }}" autofocus></form>
|
||||
<table class="table table-striped">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ _('Domain') }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for domain in domains %}
|
||||
<li>
|
||||
<a href="{{ url_for('domain.show_domain', domain_id=domain.id) }}">{{ domain.name }}</a>
|
||||
</li>
|
||||
<tr>
|
||||
<th><a href="{{ url_for('domain.show_domain', domain_id=domain.id) }}">{{ domain.name }}</a></th>
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<aside class="col-12 col-md-4 side_pane" role="complementary">
|
||||
|
|
Loading…
Reference in a new issue