commit
c31fb93218
@ -68,7 +68,14 @@ class Show(TimestampedModel):
|
|||||||
upload_to = name_banner,
|
upload_to = name_banner,
|
||||||
help_text="A banner used for the show's page.",
|
help_text="A banner used for the show's page.",
|
||||||
verbose_name="Banner"
|
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):
|
def __str__(self):
|
||||||
return '%s [%s]'%(self.name,self.abbr)
|
return '%s [%s]'%(self.name,self.abbr)
|
||||||
|
|
||||||
|
@ -26,7 +26,7 @@ label {
|
|||||||
width: 200px;
|
width: 200px;
|
||||||
display: block;
|
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;
|
padding: 5px;
|
||||||
font-size: 120%;
|
font-size: 120%;
|
||||||
width: 280px;
|
width: 280px;
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
<span class="logo">Episodes<span class="period">.</span>Community</span>
|
<span class="logo">Episodes<span class="period">.</span>Community</span>
|
||||||
<div class="userdata">
|
<div class="userdata">
|
||||||
{% if user.is_authenticated %}
|
{% if user.is_authenticated %}
|
||||||
|
{% if user.is_staff %}<a class="mod" href="/admin"><i class="fa fa-fw fa-shield"></a></i>{% endif %}
|
||||||
{{ user.display_name }}
|
{{ user.display_name }}
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="/login">Log in</a>
|
<a href="/login">Log in</a>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
from django import forms
|
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 SubmissionForm(forms.ModelForm):
|
||||||
class Meta():
|
class Meta():
|
||||||
@ -19,3 +19,8 @@ class EpisodeForm(forms.ModelForm):
|
|||||||
class Meta():
|
class Meta():
|
||||||
model = Episode
|
model = Episode
|
||||||
fields = ('episode','name','summary','airdate',)
|
fields = ('episode','name','summary','airdate',)
|
||||||
|
|
||||||
|
class BanForm(forms.ModelForm):
|
||||||
|
class Meta():
|
||||||
|
model = Ban
|
||||||
|
fields = ('reason','expiration','permanent',)
|
||||||
|
35
Show/templates/create_ban.html
Normal file
35
Show/templates/create_ban.html
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
{% extends "base.html" %}
|
||||||
|
{% block title %}
|
||||||
|
Ban an user from {{show.name}} - Episodes.Community
|
||||||
|
{% endblock %}
|
||||||
|
{% block content %}
|
||||||
|
<section class="show-details">
|
||||||
|
<div class="banner" style="background-image: url(/media/uploaded_resources/{{show.banner}});"></div>
|
||||||
|
<div class="banner-cover">
|
||||||
|
<div class="artwork">
|
||||||
|
<img src="/media/uploaded_resources/{{show.artwork}}">
|
||||||
|
</div>
|
||||||
|
<div class="details">
|
||||||
|
<h1>{{show.name}}</h1>
|
||||||
|
<p class="description">
|
||||||
|
{{show.description}}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
<section class="submissions">
|
||||||
|
<a href="/show/{{show.abbr}}" class="button"><i class="fa fa-fw fa-home"></i> Show Index</a>
|
||||||
|
<h1>Ban an User</h1>
|
||||||
|
{% if error %}
|
||||||
|
<div class="message error">{{error}}</div>
|
||||||
|
{% endif %}
|
||||||
|
<form action="" method="post">
|
||||||
|
{% csrf_token %}
|
||||||
|
<p>Banning user <b>{{ target.display_name }}</b></p>
|
||||||
|
{{ form }}
|
||||||
|
<input type="submit" value="Ban" />
|
||||||
|
<input type="submit" name="delete" value="Ban and Delete all submissions" />
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</section>
|
||||||
|
{% endblock %}
|
@ -42,7 +42,7 @@
|
|||||||
<section class="submissions">
|
<section class="submissions">
|
||||||
<a href="/show/{{show.abbr}}" class="button"><i class="fa fa-fw fa-home"></i> Show Index</a>
|
<a href="/show/{{show.abbr}}" class="button"><i class="fa fa-fw fa-home"></i> Show Index</a>
|
||||||
{% if user.is_authenticated %}
|
{% if user.is_authenticated %}
|
||||||
{% if "change_show" in show_perms %}
|
{% if "can_moderate_show" in show_perms %}
|
||||||
<a href="/show/{{show.abbr}}/episode/{{episode.season.number}}/{{episode.episode}}/submit" class="button modbutton"><i class="fa fa-fw fa-plus"></i> Add New Link</a>
|
<a href="/show/{{show.abbr}}/episode/{{episode.season.number}}/{{episode.episode}}/submit" class="button modbutton"><i class="fa fa-fw fa-plus"></i> Add New Link</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="/show/{{show.abbr}}/episode/{{episode.season.number}}/{{episode.episode}}/submit" class="button"><i class="fa fa-fw fa-plus"></i> Submit New Link</a>
|
<a href="/show/{{show.abbr}}/episode/{{episode.season.number}}/{{episode.episode}}/submit" class="button"><i class="fa fa-fw fa-plus"></i> Submit New Link</a>
|
||||||
@ -70,8 +70,15 @@
|
|||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div class="data">
|
<div class="data">
|
||||||
<span class="timestamp">Submitted {{sbm.timestamp}} by {{sbm.user.display_name}}</span><span class="divider">·</span>
|
{% get_obj_perms sbm.user for show as "publisher_perms" %}
|
||||||
{% if "change_show" in show_perms %}
|
<span class="timestamp">Submitted {{sbm.timestamp}} by
|
||||||
|
{% if sbm.user.is_staff or "can_moderate_show" in publisher_perms %}
|
||||||
|
<span class="mod"><i class="fa fa-fw fa-shield"></i></span>
|
||||||
|
{% endif %}
|
||||||
|
<span class="display_name">{{sbm.user.display_name}}</span>
|
||||||
|
</span>
|
||||||
|
<span class="divider">·</span>
|
||||||
|
{% if "can_moderate_show" in show_perms %}
|
||||||
<a href="/show/{{show.abbr}}/submission/{{sbm.id}}/moderate" class="button modbutton"><i class="fa fa-fw fa-shield"></i> Change</a>
|
<a href="/show/{{show.abbr}}/submission/{{sbm.id}}/moderate" class="button modbutton"><i class="fa fa-fw fa-shield"></i> Change</a>
|
||||||
{% else %}
|
{% else %}
|
||||||
<a href="/report?url={{ request.get_full_path|urlencode }}&submission={{ sbm.id }}" class="report">Report Invalid or Spam</a>
|
<a href="/report?url={{ request.get_full_path|urlencode }}&submission={{ sbm.id }}" class="report">Report Invalid or Spam</a>
|
||||||
|
@ -38,13 +38,13 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section class="seasons">
|
<section class="seasons">
|
||||||
{% if "change_show" in show_perms %}
|
{% if "can_moderate_show" in show_perms %}
|
||||||
<a href="/show/{{show.abbr}}/season/new" class="button modbutton"><i class="fa fa-fw fa-plus"></i> Add a Season</a>
|
<a href="/show/{{show.abbr}}/season/new" class="button modbutton"><i class="fa fa-fw fa-plus"></i> Add a Season</a>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<h1>Watch Now</h1>
|
<h1>Watch Now</h1>
|
||||||
{% for season in seasons %}
|
{% for season in seasons %}
|
||||||
<div class="season" data-season="{{season.number}}">
|
<div class="season" data-season="{{season.number}}">
|
||||||
{% if "change_show" in show_perms %}
|
{% if "can_moderate_show" in show_perms %}
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<a href="/show/{{show.abbr}}/season/{{season.number}}/append" class="action"><i class="fa fa-fw fa-plus"></i></a>
|
<a href="/show/{{show.abbr}}/season/{{season.number}}/append" class="action"><i class="fa fa-fw fa-plus"></i></a>
|
||||||
</div>
|
</div>
|
||||||
|
@ -27,6 +27,8 @@
|
|||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
<section class="submissions">
|
<section class="submissions">
|
||||||
|
{% load guardian_tags %}
|
||||||
|
{% get_obj_perms request.user for show as "show_perms" %}
|
||||||
<a href="/show/{{show.abbr}}" class="button"><i class="fa fa-fw fa-home"></i> Show Index</a>
|
<a href="/show/{{show.abbr}}" class="button"><i class="fa fa-fw fa-home"></i> Show Index</a>
|
||||||
<a href="/show/{{show.abbr}}/episode/{{episode.season.number}}/{{episode.episode}}-{{episode.name|slugify}}" class="button">Back to Episode</a>
|
<a href="/show/{{show.abbr}}/episode/{{episode.season.number}}/{{episode.episode}}-{{episode.name|slugify}}" class="button">Back to Episode</a>
|
||||||
<h1>Submission</h1>
|
<h1>Submission</h1>
|
||||||
@ -38,7 +40,9 @@
|
|||||||
{{ form }}
|
{{ form }}
|
||||||
<input type="submit" value="Edit" />
|
<input type="submit" value="Edit" />
|
||||||
<input type="submit" name="delete" value="Delete" />
|
<input type="submit" name="delete" value="Delete" />
|
||||||
|
{% if "can_create_show_ban" in show_perms %}
|
||||||
<input type="submit" name="delete_ban" value="Delete and Ban User" />
|
<input type="submit" name="delete_ban" value="Delete and Ban User" />
|
||||||
|
{% endif %}
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
@ -20,6 +20,7 @@ from . import views
|
|||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
url(r'^$', views.IndexView.as_view()),
|
url(r'^$', views.IndexView.as_view()),
|
||||||
|
url(r'^create_ban$', views.BanFromShowForm),
|
||||||
url(r'^season/new$', views.SeasonSubmitForm),
|
url(r'^season/new$', views.SeasonSubmitForm),
|
||||||
url(r'^season/(?P<season>\d{1,4})/append$', views.EpisodeSubmitForm),
|
url(r'^season/(?P<season>\d{1,4})/append$', views.EpisodeSubmitForm),
|
||||||
url(r'^submission/(?P<submission>\d{1,4})/moderate$', views.SubmissionModForm),
|
url(r'^submission/(?P<submission>\d{1,4})/moderate$', views.SubmissionModForm),
|
||||||
|
@ -4,15 +4,13 @@ from django.views import View
|
|||||||
from django.views.generic.base import TemplateView
|
from django.views.generic.base import TemplateView
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.http import Http404
|
from django.http import Http404, HttpResponseForbidden, HttpResponse, HttpResponseRedirect
|
||||||
from django.http import HttpResponse
|
from django.db.models import Case, When, Value, IntegerField, Count, F, Q
|
||||||
from django.http import HttpResponseRedirect
|
|
||||||
from django.db.models import Case, When, Value, IntegerField, Count, F
|
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
|
|
||||||
from guardian.decorators import permission_required_or_403
|
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
|
from . import forms
|
||||||
|
|
||||||
@ -87,6 +85,12 @@ def SubmissionForm(req, abbr, season, episode):
|
|||||||
'episode': 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.<br>Reason: %s'%(bans.first().reason))
|
||||||
|
|
||||||
# Handle POST
|
# Handle POST
|
||||||
if req.method == 'POST':
|
if req.method == 'POST':
|
||||||
form = forms.SubmissionForm(req.POST)
|
form = forms.SubmissionForm(req.POST)
|
||||||
@ -100,7 +104,7 @@ def SubmissionForm(req, abbr, season, episode):
|
|||||||
ctx['error'] = 'This URL has already been submitted!'
|
ctx['error'] = 'This URL has already been submitted!'
|
||||||
return render(req, "submit.html", ctx)
|
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
|
# 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:
|
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!'
|
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)
|
return render(req, "submit.html", ctx)
|
||||||
|
|
||||||
# Edit a submission - for moderators
|
# 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):
|
def SubmissionModForm(req, abbr, submission):
|
||||||
show = get_object_or_404(Show, abbr=abbr)
|
show = get_object_or_404(Show, abbr=abbr)
|
||||||
submission = get_object_or_404(Submission, pk=submission)
|
submission = get_object_or_404(Submission, pk=submission)
|
||||||
@ -136,14 +140,13 @@ def SubmissionModForm(req, abbr, submission):
|
|||||||
|
|
||||||
# Handle POST
|
# Handle POST
|
||||||
if req.method == 'POST':
|
if req.method == 'POST':
|
||||||
|
|
||||||
if 'delete' in req.POST:
|
if 'delete' in req.POST:
|
||||||
submission.delete()
|
submission.delete()
|
||||||
return HttpResponseRedirect('/show/%s/episode/%d/%d'%(abbr, episode.season.number, episode.episode))
|
return HttpResponseRedirect('/show/%s/episode/%d/%d'%(abbr, episode.season.number, episode.episode))
|
||||||
|
|
||||||
if 'delete_ban' in req.POST:
|
if 'delete_ban' in req.POST:
|
||||||
submission.delete()
|
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)
|
form = forms.SubmissionForm(req.POST, instance=submission)
|
||||||
ctx['form'] = form
|
ctx['form'] = form
|
||||||
@ -159,7 +162,7 @@ def SubmissionModForm(req, abbr, submission):
|
|||||||
return render(req, "submit_mod.html", ctx)
|
return render(req, "submit_mod.html", ctx)
|
||||||
|
|
||||||
# Season form GET and POST
|
# 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):
|
def SeasonSubmitForm(req, abbr):
|
||||||
show = get_object_or_404(Show, abbr=abbr)
|
show = get_object_or_404(Show, abbr=abbr)
|
||||||
user = req.user
|
user = req.user
|
||||||
@ -196,7 +199,7 @@ def SeasonSubmitForm(req, abbr):
|
|||||||
return render(req, "season_add.html", ctx)
|
return render(req, "season_add.html", ctx)
|
||||||
|
|
||||||
# Episode form GET and POST
|
# 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):
|
def EpisodeSubmitForm(req, abbr, season):
|
||||||
show = get_object_or_404(Show, abbr=abbr)
|
show = get_object_or_404(Show, abbr=abbr)
|
||||||
season = get_object_or_404(Season, show=show,number=season)
|
season = get_object_or_404(Season, show=show,number=season)
|
||||||
@ -251,6 +254,14 @@ class SubmissionVoteSubmit(LoginRequiredMixin, View):
|
|||||||
if submission.user == user:
|
if submission.user == user:
|
||||||
return HttpResponse('<h1>Error</h1><p>You cannot vote for your own submission.</p>', status=400)
|
return HttpResponse('<h1>Error</h1><p>You cannot vote for your own submission.</p>', 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.<br>Reason: %s'%(bans.first().reason))
|
||||||
|
|
||||||
# Allow changing a vote from positive to negative or vice-versa. Delete vote if its a re-vote
|
# 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()
|
vote = submission.votes.filter(user=user,submission__id=submission.id).first()
|
||||||
if vote:
|
if vote:
|
||||||
@ -269,3 +280,60 @@ class SubmissionVoteSubmit(LoginRequiredMixin, View):
|
|||||||
|
|
||||||
return HttpResponseRedirect('/show/%s/episode/%d/%d'%(abbr, submission.episode.season.number, submission.episode.episode))
|
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)
|
||||||
|
|
||||||
|
# Delete all of the user's submissions for this show
|
||||||
|
if 'delete' in req.POST:
|
||||||
|
Submission.objects.filter(episode__show=show,user=banTarget).delete()
|
||||||
|
|
||||||
|
return HttpResponseRedirect('/show/%s'%(abbr))
|
||||||
|
else:
|
||||||
|
ctx['error'] = 'Invalid fields!'
|
||||||
|
|
||||||
|
return render(req, "create_ban.html", ctx)
|
||||||
|
Reference in New Issue
Block a user