from django.template import RequestContext
from django.shortcuts import render, get_list_or_404, get_object_or_404
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, 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, Ban
from . import forms
import datetime
# Create your views here.
# Index page of a show
class IndexView(TemplateView):
template_name = "show.html"
def get_context_data(self, abbr, **kwargs):
ctx = super().get_context_data()
# Get show by abbr, add episode count to the show and return only the first object
show = get_object_or_404(Show, abbr=abbr)
# Get all seasons of the show and annotate episode counts onto them
seasons = show.seasons.all()
# Add fields to context
ctx['show'] = show
ctx['seasons'] = seasons
return ctx
# Episodes page of a show
class EpisodeView(TemplateView):
template_name = "episode.html"
def get_context_data(self, abbr, season, episode, **kwargs):
ctx = super().get_context_data()
# Get show by abbr
show = get_object_or_404(Show, abbr=abbr)
episode = get_object_or_404(Episode, show=show,season__number=season,episode=episode)
# I acknowledge that this is a mess. A functional mess. But a mess nonetheless. Hey, that rhymed!
submissions = episode.submissions.annotate(
positives=Count(
Case(
When(
votes__positive=True,
then=Value(1)
)
)
),
negatives=Count('votes') - F('positives'),
score=F('positives') - F('negatives')
).order_by('-score')
# Add fields to context
ctx['show'] = show
ctx['episode'] = episode
ctx['submissions'] = submissions
return ctx
# Submission form GET and POST
@login_required
def SubmissionForm(req, abbr, season, episode):
show = get_object_or_404(Show, abbr=abbr)
episode = get_object_or_404(Episode, show=show,season__number=season,episode=episode)
user = req.user
form = forms.SubmissionForm()
# Request context
ctx = {
'form': form,
'show': show,
'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)
ctx['form'] = form
if form.is_valid():
form_data = form.cleaned_data
# Check if the URL has already been submitted
if Submission.objects.filter(episode=episode,url=form_data['url']).count() > 0:
ctx['error'] = 'This URL has already been submitted!'
return render(req, "submit.html", ctx)
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!'
return render(req, "submit.html", ctx)
new_submission = form.save(commit=False)
new_submission.user = user
new_submission.episode = episode
new_submission.save()
return HttpResponseRedirect('/show/%s/episode/%d/%d'%(abbr, episode.season.number, episode.episode))
else:
ctx['error'] = 'Invalid fields!'
return render(req, "submit.html", ctx)
# Edit a submission - for moderators
@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)
episode = submission.episode
user = req.user
form = forms.SubmissionForm(instance=submission)
# Request context
ctx = {
'form': form,
'show': show,
'episode': episode
}
# Handle POST
if req.method == 'POST':
if 'delete' in req.POST:
submission.delete()
return HttpResponseRedirect('/show/%s/episode/%d/%d'%(abbr, episode.season.number, episode.episode))
if 'delete_ban' in req.POST:
submission.delete()
return HttpResponseRedirect('/show/%s/create_ban?user=%s'%(abbr,submission.user.username))
form = forms.SubmissionForm(req.POST, instance=submission)
ctx['form'] = form
if form.is_valid():
form_data = form.cleaned_data
form.save()
return HttpResponseRedirect('/show/%s/episode/%d/%d'%(abbr, episode.season.number, episode.episode))
else:
ctx['error'] = 'Invalid fields!'
return render(req, "submit_mod.html", ctx)
# Season form GET and POST
@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
form = forms.SeasonForm()
# Request context
ctx = {
'form': form,
'show': show
}
# Handle POST
if req.method == 'POST':
form = forms.SeasonForm(req.POST)
ctx['form'] = form
if form.is_valid():
form_data = form.cleaned_data
# Check if the URL has already been submitted
if Season.objects.filter(show=show,number=form_data['number']).count() > 0:
ctx['error'] = 'This season has already been submitted!'
return render(req, "season_add.html", ctx)
new_season = form.save(commit=False)
new_season.show = show
new_season.save()
return HttpResponseRedirect('/show/%s'%(abbr))
else:
ctx['error'] = 'Invalid fields!'
return render(req, "season_add.html", ctx)
# Episode form GET and POST
@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)
user = req.user
form = forms.EpisodeForm()
# Request context
ctx = {
'form': form,
'season': season,
'show': show
}
# Handle POST
if req.method == 'POST':
form = forms.EpisodeForm(req.POST)
ctx['form'] = form
if form.is_valid():
form_data = form.cleaned_data
# Check if the URL has already been submitted
if Episode.objects.filter(show=show,episode=form_data['episode'],season=season).count() > 0:
ctx['error'] = 'This episode has already been submitted!'
return render(req, "episode_add.html", ctx)
new_episode = form.save(commit=False)
new_episode.show = show
new_episode.season = season
new_episode.save()
return HttpResponseRedirect('/show/%s'%(abbr))
else:
ctx['error'] = 'Invalid fields!'
return render(req, "episode_add.html", ctx)
# Vote request
# /show/{{abbr}}/vote/{{submission id}}/{{positive == 1}}
class SubmissionVoteSubmit(LoginRequiredMixin, View):
def post (self, req, abbr, subid, positive):
# Convert positive parameter into a boolean
pos_bool = int(positive) == 1
user = req.user
# Get the submission from the database
submission = get_object_or_404(Submission, id=subid)
# Prevent voting for own submission
if submission.user == user:
return HttpResponse('
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.