From 4c2e0d0f916c0d24318db67b030055edbce06737 Mon Sep 17 00:00:00 2001 From: Evert Date: Wed, 27 Dec 2017 17:01:39 +0200 Subject: [PATCH] Bans - Implement show bans --- LandingPage/models.py | 9 +++- LandingPage/static/css/style.css | 2 +- Show/forms.py | 7 ++- Show/templates/create_ban.html | 34 +++++++++++++ Show/templates/episode.html | 4 +- Show/templates/show.html | 4 +- Show/templates/submit_mod.html | 4 ++ Show/urls.py | 1 + Show/views.py | 85 ++++++++++++++++++++++++++++---- 9 files changed, 133 insertions(+), 17 deletions(-) create mode 100644 Show/templates/create_ban.html diff --git a/LandingPage/models.py b/LandingPage/models.py index 9295e45..53bbc91 100644 --- a/LandingPage/models.py +++ b/LandingPage/models.py @@ -68,7 +68,14 @@ class Show(TimestampedModel): upload_to = name_banner, help_text="A banner used for the show's page.", verbose_name="Banner" - ) + ) + + class Meta: + permissions = ( + ('can_create_show_ban', 'Can ban an user from submitting to this show'), + ('can_moderate_show', 'Can add episodes, seasons and unrestricted submissions'), + ) + def __str__(self): return '%s [%s]'%(self.name,self.abbr) diff --git a/LandingPage/static/css/style.css b/LandingPage/static/css/style.css index 9000d5e..076f37b 100644 --- a/LandingPage/static/css/style.css +++ b/LandingPage/static/css/style.css @@ -26,7 +26,7 @@ label { width: 200px; display: block; } -input[type=text], input:not([type=submit]) { +input[type=text], input[type=email], input[type=password], input[type=number], input[type=url] { padding: 5px; font-size: 120%; width: 280px; diff --git a/Show/forms.py b/Show/forms.py index 663c3a4..1f358bb 100644 --- a/Show/forms.py +++ b/Show/forms.py @@ -1,5 +1,5 @@ from django import forms -from LandingPage.models import Submission, Season, Episode +from LandingPage.models import Submission, Season, Episode, Ban, User class SubmissionForm(forms.ModelForm): class Meta(): @@ -19,3 +19,8 @@ class EpisodeForm(forms.ModelForm): class Meta(): model = Episode fields = ('episode','name','summary','airdate',) + +class BanForm(forms.ModelForm): + class Meta(): + model = Ban + fields = ('reason','expiration','permanent',) diff --git a/Show/templates/create_ban.html b/Show/templates/create_ban.html new file mode 100644 index 0000000..2a390d6 --- /dev/null +++ b/Show/templates/create_ban.html @@ -0,0 +1,34 @@ +{% extends "base.html" %} +{% block title %} + Ban an user from {{show.name}} - Episodes.Community +{% endblock %} +{% block content %} +
+ + +
+
+  Show Index +

Ban an User

+ {% if error %} +
{{error}}
+ {% endif %} +
+ {% csrf_token %} +

Banning user {{ target.display_name }}

+ {{ form }} + +
+ +
+{% endblock %} diff --git a/Show/templates/episode.html b/Show/templates/episode.html index 16d6ba7..3bc5b27 100644 --- a/Show/templates/episode.html +++ b/Show/templates/episode.html @@ -42,7 +42,7 @@
 Show Index {% if user.is_authenticated %} - {% if "change_show" in show_perms %} + {% if "can_moderate_show" in show_perms %}  Add New Link {% else %}  Submit New Link @@ -71,7 +71,7 @@
Submitted {{sbm.timestamp}} by {{sbm.user.display_name}}· - {% if "change_show" in show_perms %} + {% if "can_moderate_show" in show_perms %}  Change {% else %} Report Invalid or Spam diff --git a/Show/templates/show.html b/Show/templates/show.html index a25be66..e5b3dfb 100644 --- a/Show/templates/show.html +++ b/Show/templates/show.html @@ -38,13 +38,13 @@
- {% if "change_show" in show_perms %} + {% if "can_moderate_show" in show_perms %}  Add a Season {% endif %}

Watch Now

{% for season in seasons %}
- {% if "change_show" in show_perms %} + {% if "can_moderate_show" in show_perms %}
diff --git a/Show/templates/submit_mod.html b/Show/templates/submit_mod.html index 1d2636d..5d83de9 100644 --- a/Show/templates/submit_mod.html +++ b/Show/templates/submit_mod.html @@ -27,6 +27,8 @@
+ {% load guardian_tags %} + {% get_obj_perms request.user for show as "show_perms" %}  Show Index Back to Episode

Submission

@@ -38,7 +40,9 @@ {{ form }} + {% if "can_create_show_ban" in show_perms %} + {% endif %}
diff --git a/Show/urls.py b/Show/urls.py index 9eaecc5..8bcdbee 100644 --- a/Show/urls.py +++ b/Show/urls.py @@ -20,6 +20,7 @@ from . import views urlpatterns = [ url(r'^$', views.IndexView.as_view()), + url(r'^create_ban$', views.BanFromShowForm), url(r'^season/new$', views.SeasonSubmitForm), url(r'^season/(?P\d{1,4})/append$', views.EpisodeSubmitForm), url(r'^submission/(?P\d{1,4})/moderate$', views.SubmissionModForm), diff --git a/Show/views.py b/Show/views.py index eff4d8c..8c8a55d 100644 --- a/Show/views.py +++ b/Show/views.py @@ -4,15 +4,13 @@ from django.views import View from django.views.generic.base import TemplateView from django.contrib.auth.decorators import login_required from django.conf import settings -from django.http import Http404 -from django.http import HttpResponse -from django.http import HttpResponseRedirect -from django.db.models import Case, When, Value, IntegerField, Count, F +from django.http import Http404, HttpResponseForbidden, HttpResponse, HttpResponseRedirect +from django.db.models import Case, When, Value, IntegerField, Count, F, Q from django.contrib.auth.mixins import LoginRequiredMixin from guardian.decorators import permission_required_or_403 -from LandingPage.models import User, Show, Season, Episode, Submission, SubmissionVote +from LandingPage.models import User, Show, Season, Episode, Submission, SubmissionVote, Ban from . import forms @@ -87,6 +85,12 @@ def SubmissionForm(req, abbr, season, episode): 'episode': episode } + # Get bans for this user regarding this show + bans = Ban.objects.filter(Q(scope=show) | Q(site_wide=True), Q(expiration__gte=datetime.datetime.now()) | Q(permanent=True), user=user) + + if bans.count() > 0: + return HttpResponseForbidden('You are banned from submitting links to this show.
Reason: %s'%(bans.first().reason)) + # Handle POST if req.method == 'POST': form = forms.SubmissionForm(req.POST) @@ -100,7 +104,7 @@ def SubmissionForm(req, abbr, season, episode): ctx['error'] = 'This URL has already been submitted!' return render(req, "submit.html", ctx) - if not user.has_perm('LandingPage.change_show'): + if not user.has_perm('LandingPage.can_moderate_show', show): # Check if there has been a submission by this user for this episode within the last 24 hours if Submission.objects.filter(user=user,episode=episode,timestamp__gte=datetime.datetime.now() - datetime.timedelta(hours=24)).count() > 0: ctx['error'] = 'You can only submit one link for an episode in 24 hours!' @@ -118,7 +122,7 @@ def SubmissionForm(req, abbr, season, episode): return render(req, "submit.html", ctx) # Edit a submission - for moderators -@permission_required_or_403('LandingPage.change_show', (Show, 'abbr', 'abbr'), accept_global_perms=True) +@permission_required_or_403('LandingPage.can_moderate_show', (Show, 'abbr', 'abbr'), accept_global_perms=True) def SubmissionModForm(req, abbr, submission): show = get_object_or_404(Show, abbr=abbr) submission = get_object_or_404(Submission, pk=submission) @@ -143,7 +147,7 @@ def SubmissionModForm(req, abbr, submission): if 'delete_ban' in req.POST: submission.delete() - return HttpResponseRedirect('/ban?user=%d'%(submission.user.pk)) + return HttpResponseRedirect('/show/%s/create_ban?user=%s'%(abbr,submission.user.username)) form = forms.SubmissionForm(req.POST, instance=submission) ctx['form'] = form @@ -159,7 +163,7 @@ def SubmissionModForm(req, abbr, submission): return render(req, "submit_mod.html", ctx) # Season form GET and POST -@permission_required_or_403('LandingPage.change_show', (Show, 'abbr', 'abbr'), accept_global_perms=True) +@permission_required_or_403('LandingPage.can_moderate_show', (Show, 'abbr', 'abbr'), accept_global_perms=True) def SeasonSubmitForm(req, abbr): show = get_object_or_404(Show, abbr=abbr) user = req.user @@ -196,7 +200,7 @@ def SeasonSubmitForm(req, abbr): return render(req, "season_add.html", ctx) # Episode form GET and POST -@permission_required_or_403('LandingPage.change_show', (Show, 'abbr', 'abbr'), accept_global_perms=True) +@permission_required_or_403('LandingPage.can_moderate_show', (Show, 'abbr', 'abbr'), accept_global_perms=True) def EpisodeSubmitForm(req, abbr, season): show = get_object_or_404(Show, abbr=abbr) season = get_object_or_404(Season, show=show,number=season) @@ -251,6 +255,14 @@ class SubmissionVoteSubmit(LoginRequiredMixin, View): if submission.user == user: return HttpResponse('

Error

You cannot vote for your own submission.

', status=400) + show = submission.episode.show + + # Get bans for this user regarding this show + bans = Ban.objects.filter(Q(scope=show) | Q(site_wide=True), Q(expiration__gte=datetime.datetime.now()) | Q(permanent=True), user=user) + + if bans.count() > 0: + return HttpResponseForbidden('You are banned from voting on this show.
Reason: %s'%(bans.first().reason)) + # Allow changing a vote from positive to negative or vice-versa. Delete vote if its a re-vote vote = submission.votes.filter(user=user,submission__id=submission.id).first() if vote: @@ -269,3 +281,56 @@ class SubmissionVoteSubmit(LoginRequiredMixin, View): return HttpResponseRedirect('/show/%s/episode/%d/%d'%(abbr, submission.episode.season.number, submission.episode.episode)) +# Episode form GET and POST +@permission_required_or_403('LandingPage.can_create_show_ban', (Show, 'abbr', 'abbr'), accept_global_perms=True) +def BanFromShowForm(req, abbr): + show = get_object_or_404(Show, abbr=abbr) + user = req.user + + banTarget = get_object_or_404(User, username=req.GET.get('user', None)) + + if banTarget == user: + return HttpResponseForbidden('You cannot ban yourself!') + + if banTarget.is_staff: + return HttpResponseForbidden('You cannot ban a staff member!') + + if banTarget.has_perm('LandingPage.can_moderate_show', show): + return HttpResponseForbidden('You cannot ban another moderator!') + + form = forms.BanForm() + + # Request context + ctx = { + 'form': form, + 'show': show, + 'target': banTarget + } + + # Handle POST + if req.method == 'POST': + form = forms.BanForm(req.POST) + ctx['form'] = form + + if form.is_valid(): + form_data = form.cleaned_data + + # Save + new_ban = form.save(commit=False) + + if form_data['permanent']: + new_ban.expiration = datetime.datetime.now() + + new_ban.site_wide = False + new_ban.user = banTarget + new_ban.admin = user + new_ban.save() + + # Add show to scope + new_ban.scope.add(show) + + return HttpResponseRedirect('/show/%s'%(abbr)) + else: + ctx['error'] = 'Invalid fields!' + + return render(req, "create_ban.html", ctx)