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 from django.http import HttpResponse from django.http import HttpResponseRedirect from django.db.models import Case, When, Value, IntegerField, Count, F 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 . 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 } # 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.change_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.change_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('/ban?user=%d'%(submission.user.pk)) 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.change_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.change_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('

Error

You cannot vote for your own submission.

', status=400) # 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: if not vote.positive == pos_bool: vote.positive = pos_bool vote.save() else: vote.delete() else: new_vote = SubmissionVote( user=user, submission=submission, positive=pos_bool ) new_vote.save() return HttpResponseRedirect('/show/%s/episode/%d/%d'%(abbr, submission.episode.season.number, submission.episode.episode))