def save(self, *args, **kwargs): """Additional field input""" # provides a slug is one is missed, updates if title changes slug = self.slug slugified = slugify(self.title) if slug != slugified: self.slug = slugified #we don't use init for this as it's derived here prior_has_been_public = self.has_been_public if self.access > 0: self.has_been_public = True # Add wordcount self.wordcount = html_wordcount(self.content) super(Story, self).save() # check if story has not been public before if self.access > 0 and not prior_has_been_public: notice = Notice.objects.filter(story=self).first() if not notice: notice = Notice.objects.create( category=Notice.Category.STORY_ANNOUNCE) notice.post_story(self) #If it has, only announce if privacy is increasing or title has changed elif (self._initial_title != self.title or self._initial_access != self.access): notice.post_story(self)
def verify_wordcount_for_old_stories(self, error_message): """repeated code to verify old stories meet criteria""" self.contest.save() self.form = EnterContestOldStoryForm( data={"story": self.story}, story_wordcount=html_wordcount(self.story.content), contest_max_wordcount=self.contest.max_wordcount, contest_expiry_date=self.contest.expiry_date, ) self.assertFalse(self.form.is_valid()) self.assertTrue(error_message in self.form.non_field_errors())
def validate_newstory_wordcount(self, error_message): """repeated functionality that tests wordcount of new function""" self.contest.save() self.form = EnterContestNewStoryForm( data={}, story_wordcount=html_wordcount(self.story.content), contest_max_wordcount=self.contest.max_wordcount, contest_expiry_date=self.contest.expiry_date, ) self.assertFalse(self.form.is_valid()) self.assertTrue(error_message in self.form.non_field_errors())
def clean(self): # check if wordcount is excessive cleaned_data = super().clean() if cleaned_data.get("final"): words_to_count = strip_tags(cleaned_data.get("content")) crit_wordcount = html_wordcount(words_to_count) self.wordcount = crit_wordcount if self.wordcount < CRIT_MIN_WORDCOUNT: raise forms.ValidationError("Entrants deserve at least " + str(CRIT_MIN_WORDCOUNT) + " words for their efforts!") if cleaned_data.get("score") == 0: raise forms.ValidationError( "You can't submit a final judgement without a score.") return self.cleaned_data # never forget this! ;o)
def setUp(self): """set up""" self.story = Story( title="Story1", content="This is a <b>story</b>", access=Story.PRIVATE ) self.story.save() self.contest = Contest( max_wordcount=10, expiry_date=timezone.now() + timezone.timedelta(7), start_date=timezone.now(), title="Contest1", content="This is a <b>contest</b>", ) self.contest.save() self.form = EnterContestOldStoryForm( data={"story": self.story}, story_wordcount=html_wordcount(self.story.content), contest_max_wordcount=self.contest.max_wordcount, contest_expiry_date=self.contest.expiry_date, )
def enter_contest_new_story( request, contest_slug, ): """User enters new story Args: request (request): HTTP page request contest_id (int): id of contest record. Returns: [type]: [description] """ contest_context = get_object_or_404(Contest, slug=contest_slug) entry = get_object_or_404(Entry, author=request.user, contest=contest_context.pk) if entry.content: messages.error(request, "You have already entered this contest.") if contest_context.is_judge_volunteer(request.user): messages.error( request, "You have volunteered to be a judge in this competition") return redirect("view contest details", contest_slug=contest_context.slug) if contest_context.is_judge(request.user): messages.error(request, "You are already a judge for this competition") return redirect("view contest details", contest_slug=contest_context.slug) if not contest_context.content: messages.error( request, "There's no prompt for this contest yet. Go back from whence ye came", ) return redirect("view contest details", contest_slug=contest_context.slug) story_form = ContestStoryForm(request.POST or None) if request.method == "POST": if contest_context.status > Contest.WRITING: messages.error( request, "This contest is not currently open for new entries.") # return with fields filled so work isn't lost return render( request, "promptarena/enter-contest-new-story.html", { "contest_context": contest_context, #'entry_form': entry_form, "story_form": story_form, }, ) if story_form.is_valid(): story_wordcount = html_wordcount(story_form.instance.content) entry_form = EnterContestNewStoryForm( request.POST, instance=entry, contest_max_wordcount=contest_context.max_wordcount, story_wordcount=story_wordcount, contest_expiry_date=contest_context.expiry_date, ) if entry_form.is_valid(): # add user to story story_form_uncommitted = story_form.save(commit=False) story_form_uncommitted.author = request.user # add contest and snapshot of story (title and content) to entry entry_form_uncommitted = entry_form.save(commit=False) entry_form_uncommitted.story = story_form_uncommitted entry_form_uncommitted.title = story_form_uncommitted.title entry_form_uncommitted.content = story_form_uncommitted.content entry_form_uncommitted.contest = contest_context if contest_context.hellrules == Contest.MANDATORY_HELLRULE: entry_form_uncommitted.request_hellrule = True story_form_uncommitted.save() entry_form_uncommitted.save() # Create crits for non-internally judged stories # (internally judged stories create crits on closure to ignore fails) # If a judge is created later, crits are created upon judge assignment if contest_context.mode == Contest.JUDGE_TABLE: contest_judges = ContestJudges.objects.filter( contest=contest_context, category__gte=ContestJudges.ACCEPTED) for c_j in contest_judges: Crit.objects.create(entry=entry, reviewer=c_j.judge) messages.success( request, "Your entry was submitted successfully! Hopefully it doesn't suck.", ) return redirect("view contests") # return with fields filled so work isn't lost return render( request, "promptarena/enter-contest-new-story.html", { "contest_context": contest_context, "story_form": story_form, "entry_context": entry, }, ) return render( request, "promptarena/enter-contest-new-story.html", { "contest_context": contest_context, "story_form": story_form, "entry_context": entry, }, )
def judgemode(request, crit_slug=""): """Judge the supplicants mercilessly This vierw does double duty - as a list of crits and as a page to write crits Args: request ([type]): [description] crit_slug (str, optional): ID of crit record. Defaults to empty string. Returns: Page: takes user to appropriate page and context """ crit = {} #Check crit slug is legit if crit_slug: try: crit = Crit.objects.select_related("entry").get( slug=crit_slug, reviewer=request.user) except Crit.DoesNotExist: messages.error( request, "You are seeing crits where there are none. Don't crit drunk (too often)", ) return redirect("judgemode") if crit: crit_form = EnterCritForm(request.POST or None, instance=crit) else: crit_form = EnterCritForm(request.POST or None) if request.method == "POST" and crit_form.is_valid(): # check that this rating has not been used before in a RUMBLE used_scores = (Crit.objects.filter( entry__contest=crit.entry.contest, reviewer=crit.reviewer, score=crit.score, ).exclude(pk=crit.pk, ).exclude(score=Crit.UNSCORED)) if used_scores and crit.entry.contest.mode == Contest.RUMBLE: messages.error( request, "You have already used that rank in this contest. Each rank given to an entry must be different.", ) else: # assign wordcount to instance and add some info to the crit crit_wordcount = html_wordcount(crit_form.instance.content) crit_form_uncommitted = crit_form.save(commit=False) crit_form_uncommitted.wordcount = crit_wordcount crit_form_uncommitted.reviewer = request.user crit_form_uncommitted.save() #check the critter is finished with the crit if crit_form_uncommitted.final: messages.success( request, "You have successfully critted a contest entry") else: messages.success(request, "You have saved your critique for later") return redirect("judgemode") #get list of crits for user, where the contest is not already closed crit_list = (Crit.objects.filter(reviewer=request.user, ).exclude( entry__contest__status=Contest.CLOSED).select_related( "entry", "entry__story", "entry__contest").order_by("entry__contest", "-score")) unfinished_crit_list = (Crit.objects.filter( reviewer=request.user, entry__contest__status=Contest.CLOSED, final=False).select_related("entry", "entry__story", "entry__contest").order_by( "entry__contest", "-score")) #get lists of judges for non-closed contests judge_context = (ContestJudges.objects.filter( judge=request.user, contest__mode=Contest.JUDGE_TABLE).exclude( contest__status=Contest.CLOSED).select_related("contest")) context = { "crit_list": crit_list, "judge_context": judge_context, "unfinished_crit_list": unfinished_crit_list, } #if we are looking at an actual drit if crit: context["form"] = crit_form context["crit_context"] = crit return render(request, "promptarena/judgemode.html", context)