def serialize(self, tournament=None): if not tournament: tournament = self.debate.round.tournament # Shown in the results page on a per-ballot; always measured in tab TZ created_short = timezone.localtime(self.timestamp).strftime("%H:%M") # These are used by the status graph created = timezone.localtime(self.timestamp).isoformat() confirmed = None if self.confirm_timestamp and self.confirmed: confirmed = timezone.localtime(self.confirm_timestamp).isoformat() return { 'ballot_id': self.id, 'debate_id': self.debate.id, 'submitter': self.submitter.username if self.submitter else self.ip_address, 'admin_link': reverse_tournament('results-ballotset-edit', tournament, kwargs={'pk': self.id}), 'assistant_link': reverse_tournament('results-assistant-ballotset-edit', tournament, kwargs={'pk': self.id}), 'short_time': created_short, 'created_timestamp': created, 'confirmed_timestamp': confirmed, 'version': self.version, 'confirmed': self.confirmed, 'discarded': self.discarded, }
def get_context_data(self, **kwargs): tournament = self.get_tournament() teams_data = [] for team in Team.objects.filter(tournament=tournament): feedbacks = AdjudicatorFeedback.objects.filter(source_team__team=team).select_related( 'source_team__team').count() teams_data.append({ 'name': team.short_name, 'institution': team.institution.name, 'feedbacks': "%s Feedbacks" % feedbacks, 'rowLink': reverse_tournament('adjfeedback-view-from-team', tournament, kwargs={'pk': team.pk}), }) adjs_data = [] for adj in Adjudicator.objects.filter(tournament=tournament): feedbacks = AdjudicatorFeedback.objects.filter(source_adjudicator__adjudicator=adj).select_related( 'source_adjudicator__adjudicator').count(), adjs_data.append({ 'name': adj.name, 'institution': adj.institution.name, 'feedbacks': "%s Feedbacks" % feedbacks, 'rowLink': reverse_tournament('adjfeedback-view-from-adjudicator', tournament, kwargs={'pk': adj.pk}), }) kwargs['teams'] = teams_data kwargs['adjs'] = adjs_data return super().get_context_data(**kwargs)
def get_tables(self): tournament = self.tournament teams = tournament.team_set.all().annotate(feedback_count=Count('debateteam__adjudicatorfeedback')).prefetch_related('speaker_set') team_table = TabbycatTableBuilder( view=self, title=_('From Teams'), sort_key='team') team_table.add_team_columns(teams) team_feedback_data = [] for team in teams: count = team.feedback_count team_feedback_data.append({ 'text': ngettext("%(count)d feedback", "%(count)d feedbacks", count) % {'count': count}, 'link': reverse_tournament('adjfeedback-view-from-team', tournament, kwargs={'pk': team.id}), }) team_table.add_column({'key': 'feedbacks', 'title': _("Feedbacks")}, team_feedback_data) adjs = tournament.adjudicator_set.all().annotate(feedback_count=Count('debateadjudicator__adjudicatorfeedback')) adj_table = TabbycatTableBuilder( view=self, title=_('From Adjudicators'), sort_key='name') adj_table.add_adjudicator_columns(adjs) adj_feedback_data = [] for adj in adjs: count = adj.feedback_count adj_feedback_data.append({ 'text': ngettext("%(count)d feedback", "%(count)d feedbacks", count) % {'count': count}, 'link': reverse_tournament('adjfeedback-view-from-adjudicator', tournament, kwargs={'pk': adj.id}), }) adj_table.add_column({'key': 'feedbacks', 'title': _("Feedbacks")}, adj_feedback_data) return [team_table, adj_table]
def get_success_url(self): # Redirect to non-cached page: their original private URL if isinstance(self.object, Adjudicator): return reverse_tournament('adjfeedback-public-add-from-adjudicator-randomised', self.tournament, kwargs={'url_key': self.object.url_key}) elif isinstance(self.object, Speaker): return reverse_tournament('adjfeedback-public-add-from-team-randomised', self.tournament, kwargs={'url_key': self.object.url_key}) else: raise ValueError("Private feedback source is not of a valid type")
def get_success_url(self): # Redirect to non-cached page: the public feedback form if isinstance(self.object, Adjudicator): return reverse_tournament('adjfeedback-public-add-from-adjudicator-pk', self.tournament, kwargs={'source_id': self.object.id}) elif isinstance(self.object, Team): return reverse_tournament('adjfeedback-public-add-from-team-pk', self.tournament, kwargs={'source_id': self.object.id}) else: raise ValueError("Public feedback source is not of a valid type")
def _result_cell_two(self, ts, compress=False, show_score=False, show_ballots=False): if not hasattr(ts, 'debate_team') or not hasattr(ts.debate_team.opponent, 'team'): return {'text': self.BLANK_TEXT} opp = ts.debate_team.opponent.team opp_vshort = '<i class="emoji">' + opp.emoji + '</i>' if opp.emoji else "…" cell = { 'text': _(" vs %(opposition)s") % {'opposition': opp_vshort if compress else self._team_short_name(opp)}, 'popover': {'content': [], 'title': ''}, 'class': "no-wrap", } cell = self._result_cell_class_two(ts.win, cell) if ts.win is True: cell['popover']['title'] = _("Won against %(team)s") % {'team': self._team_long_name(opp)} elif ts.win is False: cell['popover']['title'] = _("Lost to %(team)s") % {'team': self._team_long_name(opp)} else: # None cell['popover']['title'] = _("No result for debate against %(team)s") % {'team': self._team_long_name(opp)} if show_score and ts.score is not None: score = ts.score if self.tournament.integer_scores(ts.debate_team.debate.round.stage) and score.is_integer(): score = int(ts.score) cell['subtext'] = metricformat(score) cell['popover']['content'].append( {'text': _("Total speaker score: <strong>%s</strong>") % metricformat(score)}) if show_ballots: if self.admin: cell['popover']['content'].append({ 'text': _("View/edit debate ballot"), 'link': reverse_tournament('results-ballotset-edit', self.tournament, kwargs={'pk': ts.ballot_submission_id}) }) elif self.tournament.pref('ballots_released'): cell['popover']['content'].append({ 'text': _("View debate ballot"), 'link': reverse_tournament('results-public-scoresheet-view', self.tournament, kwargs={'pk': ts.debate_team.debate_id}) }) if self._show_speakers_in_draw: cell['popover']['content'].append({ 'text': ", ".join([s.name for s in opp.speakers]) }) if self._show_record_links: cell['popover']['content'].append( self._team_record_link(opp)) return cell
def _team_record_link(self, team): if self.admin: return { 'text': _("View %(team)s's Record") % {'team': self._team_short_name(team)}, 'link': reverse_tournament('participants-team-record', self.tournament, kwargs={'pk': team.pk}) } elif self.tournament.pref('public_record'): return { 'text': _("View %(team)s's Record") % {'team': self._team_short_name(team)}, 'link': reverse_tournament('participants-public-team-record', self.tournament, kwargs={'pk': team.pk}) } else: return {'text': '', 'link': False}
def _team_record_link(self, team): if self.admin: return { 'text': "View %s's Team Record" % team.short_name, 'link': reverse_tournament('participants-team-record', self.tournament, kwargs={'pk': team.pk}) } elif self.tournament.pref('public_record'): return { 'text': "View %s's Team Record" % team.short_name, 'link': reverse_tournament('participants-public-team-record', self.tournament, kwargs={'pk': team.pk}) } else: return {'text': False, 'link': False}
def _adjudicator_record_link(self, adj): adj_short_name = adj.name.split(" ")[0] if self.admin: return { 'text': "View %s's Adjudication Record" % adj_short_name, 'link': reverse_tournament('participants-adjudicator-record', self.tournament, kwargs={'pk': adj.pk}) } elif self.tournament.pref('public_record'): return { 'text': "View %s's Adjudication Record" % adj_short_name, 'link': reverse_tournament('participants-public-adjudicator-record', self.tournament, kwargs={'pk': adj.pk}) } else: return {'text': False, 'link': False}
def get_table(self): if not self.is_draw_released(): return None debateadjs = DebateAdjudicator.objects.filter( debate__round=self.tournament.current_round, ).select_related( 'adjudicator', 'debate__venue', ).prefetch_related( 'debate__venue__venuecategory_set', ).order_by('adjudicator__name') table = TabbycatTableBuilder(view=self, sort_key='adj') data = [{ 'text': _("Add result from %(adjudicator)s") % {'adjudicator': da.adjudicator.name}, 'link': reverse_tournament('results-public-ballotset-new-pk', self.tournament, kwargs={'adj_id': da.adjudicator.id}), } for da in debateadjs] header = {'key': 'adj', 'title': _("Adjudicator")} table.add_column(header, data) debates = [da.debate for da in debateadjs] table.add_debate_venue_columns(debates) return table
def get_context_data(self, **kwargs): speaker_categories = self.tournament.speakercategory_set.all() json_categories = [bc.serialize for bc in speaker_categories] kwargs["speaker_categories"] = json.dumps(json_categories) kwargs["speaker_categories_length"] = speaker_categories.count() kwargs["save"] = reverse_tournament('participants-speaker-update-eligibility', self.tournament) return super().get_context_data(**kwargs)
def _adjudicator_record_link(self, adj, suffix=""): adj_short_name = adj.name.split(" ")[0] if self.admin: return { 'text': _("View %(a)s's %(d)s Record") % {'a': adj_short_name, 'd': suffix}, 'link': reverse_tournament('participants-adjudicator-record', self.tournament, kwargs={'pk': adj.pk}) } elif self.tournament.pref('public_record'): return { 'text': _("View %(a)s's %(d)s Record") % {'a': adj_short_name, 'd': suffix}, 'link': reverse_tournament('participants-public-adjudicator-record', self.tournament, kwargs={'pk': adj.pk}) } else: return {'text': '', 'link': False}
def dispatch(self, request, *args, **kwargs): tournament = self.tournament if tournament.current_round_id is None: full_path = self.request.get_full_path() if hasattr(self.request, 'user') and self.request.user.is_superuser: logger.warning("Current round wasn't set, redirecting to set-current-round page") set_current_round_url = reverse_tournament('tournament-set-current-round', self.tournament) redirect_url = add_query_parameter(set_current_round_url, 'next', full_path) return HttpResponseRedirect(redirect_url) else: logger.warning("Current round wasn't set, redirecting to site index") messages.warning(request, _("There's a problem with the data for the tournament " "%(tournament_name)s. Please contact a tab director and ask them to set its " "current round.") % {'tournament_name': tournament.name}) home_url = reverse('tabbycat-index') redirect_url = add_query_parameter(home_url, 'redirect', 'false') return HttpResponseRedirect(redirect_url) try: return super().dispatch(request, *args, **kwargs) except (MultipleDebateTeamsError, NoDebateTeamFoundError) as e: if hasattr(self.request, 'user') and self.request.user.is_superuser: logger.warning("Debate team side assignment error, redirecting to tournament-fix-debate-teams") messages.warning(request, _("You've been redirected to this page because of a problem with " "how teams are assigned to sides in a debate.")) return redirect_tournament('tournament-fix-debate-teams', tournament) else: logger.warning("Debate team side assignment error, redirecting to tournament-public-index") messages.warning(request, _("There's a problem with how teams are assigned to sides " "in a debate. The tab director will need to resolve this issue.")) return redirect_tournament('tournament-public-index', tournament)
def add_debate_ballot_link_column(self, debates): ballot_links_header = {'key': "Ballot", 'icon': 'glyphicon-search'} if self.admin: ballot_links_data = [{ 'text': "View/Edit Ballot", 'link': reverse_tournament('results-ballotset-edit', self.tournament, kwargs={'pk': debate.confirmed_ballot.id}) } if debate.confirmed_ballot else "" for debate in debates] self.add_column(ballot_links_header, ballot_links_data) elif self.tournament.pref('ballots_released'): ballot_links_header = {'key': "Ballot", 'icon': 'glyphicon-search'} ballot_links_data = [{ 'text': "View Ballot", 'link': reverse_tournament('results-public-scoresheet-view', self.tournament, kwargs={'pk': debate.id}) } if debate else "" for debate in debates] self.add_column(ballot_links_header, ballot_links_data)
def get_redirect_to(self, use_default=True): redirect_to = self.request.POST.get( self.redirect_field_name, self.request.GET.get(self.redirect_field_name, '') ) if not redirect_to and use_default: return reverse_tournament('tournament-admin-home', tournament=self.object) else: return redirect_to
def get_redirect_url(self, *args, **kwargs): # Override if self.tournament_redirect_pattern_name is specified, # otherwise just pass down the chain if self.tournament_redirect_pattern_name: try: return reverse_tournament(self.tournament_redirect_pattern_name, self.get_tournament(), args=args, kwargs=kwargs) except NoReverseMatch: pass return super().get_redirect_url(*args, **kwargs)
def get_standings_error_message(self, e): if self.request.user.is_superuser: instructions = self.admin_standings_error_instructions else: instructions = self.public_standings_error_instructions message = self.standings_error_message % {'message': str(e)} standings_options_url = reverse_tournament('options-tournament-section', self.tournament, kwargs={'section': 'standings'}) instructions %= {'standings_options_url': standings_options_url} return mark_safe(message + instructions)
def add_feedback_link_columns(self, adjudicators): link_head = { 'key': 'VF', 'icon': 'glyphicon-question-sign' } link_cell = [{ 'text': 'View<br>Feedback', 'class': 'view-feedback', 'link': reverse_tournament('adjfeedback-view-on-adjudicator', self.tournament, kwargs={'pk': adj.pk}) } for adj in adjudicators] self.add_column(link_head, link_cell)
def _record_link(progress): if isinstance(progress, FeedbackProgressForTeam): url_name = 'participants-team-record' if self.admin else 'participants-public-team-record' pk = progress.team.pk elif isinstance(progress, FeedbackProgressForAdjudicator): url_name = 'participants-adjudicator-record' if self.admin else 'participants-public-adjudicator-record' pk = progress.adjudicator.pk else: logger.error("Unrecognised progress type: %s", progress.__class__.__name__) return '' return reverse_tournament(url_name, self.tournament, kwargs={'pk': pk})
def get_ballot_text(self, debate): ballotsets_info = " " # These are prefetched, so sort using Python rather than generating an SQL query ballotsubmissions = sorted(debate.ballotsubmission_set.all(), key=lambda x: x.version) for ballotset in ballotsubmissions: if not self.admin and ballotset.discarded: continue link = reverse_tournament('results-ballotset-edit', self.tournament, kwargs={'pk': ballotset.id}) ballotsets_info += "<a href=" + link + ">" if ballotset.confirmed: edit_status = "Re-edit v" + str(ballotset.version) elif self.admin: edit_status = "Edit v" + str(ballotset.version) else: edit_status = "Review v" + str(ballotset.version) if ballotset.discarded: ballotsets_info += "<strike class='text-muted'>" + edit_status + "</strike></a><small> discarded; " else: ballotsets_info += edit_status + "</a><small>" if ballotset.submitter_type == ballotset.SUBMITTER_TABROOM: ballotsets_info += " <em>entered by " + ballotset.submitter.username + "</em>" elif ballotset.submitter_type == ballotset.SUBMITTER_PUBLIC: ballotsets_info += " <em>a public submission by " + ballotset.ip_address + "</em>" ballotsets_info += "</small><br />" if all(x.discarded for x in ballotsubmissions): link = reverse_tournament('results-ballotset-new', self.tournament, kwargs={'debate_id': debate.id}) ballotsets_info += "<a href=" + link + ">Enter Ballot</a>" return ballotsets_info
def add_feedback_link_columns(self, adjudicators): link_head = { 'key': 'view-feedback', 'icon': 'eye' } link_cell = [{ 'text': 'View %s<br>feedbacks' % (len(adj.feedback_data) - 1), # -1 to account for test score 'class': 'view-feedback', 'sort': adj.debates, 'link': reverse_tournament('adjfeedback-view-on-adjudicator', self.tournament, kwargs={'pk': adj.pk}) } for adj in adjudicators] self.add_column(link_head, link_cell)
def get_redirect_url(self, *args, **kwargs): # Override if self.tournament_redirect_pattern_name is specified, # otherwise just pass down the chain if self.tournament_redirect_pattern_name: try: return reverse_tournament(self.tournament_redirect_pattern_name, self.tournament, args=args, kwargs=kwargs) except NoReverseMatch: logger.warning("No Reverse Match for given tournament_slug_url_kwarg") pass return super().get_redirect_url(*args, **kwargs)
def get_table(self): tournament = self.get_tournament() table = TabbycatTableBuilder(view=self, sort_key="Name") table.add_adjudicator_columns(tournament.adjudicator_set.all()) feedback_data = [] for adj in tournament.adjudicator_set.all(): count = adj.adjudicatorfeedback_set.count() feedback_data.append({ 'text': "{:d} Feedbacks".format(count), 'link': reverse_tournament('adjfeedback-view-on-adjudicator', tournament, kwargs={'pk': adj.id}), }) table.add_column("Feedbacks", feedback_data) return table
def get_table(self): tournament = self.tournament table = TabbycatTableBuilder(view=self, sort_key="name") table.add_adjudicator_columns(tournament.adjudicator_set.all()) feedback_data = [] for adj in tournament.adjudicator_set.all().annotate(feedback_count=Count('adjudicatorfeedback')): count = adj.feedback_count feedback_data.append({ 'text': ngettext("%(count)d feedback", "%(count)d feedbacks", count) % {'count': count}, 'link': reverse_tournament('adjfeedback-view-on-adjudicator', tournament, kwargs={'pk': adj.id}), }) table.add_column({'key': 'feedbacks', 'title': _("Feedbacks")}, feedback_data) return table
def get_tables(self): tournament = self.get_tournament() teams = tournament.team_set.all() team_table = TabbycatTableBuilder( view=self, title='From Teams', sort_key='Name') team_table.add_team_columns(teams) team_feedback_data = [] for team in teams: count = AdjudicatorFeedback.objects.filter( source_team__team=team).select_related( 'source_team__team').count() team_feedback_data.append({ 'text': "{:d} Feedbacks".format(count), 'link': reverse_tournament('adjfeedback-view-from-team', tournament, kwargs={'pk': team.id}), }) team_table.add_column("Feedbacks", team_feedback_data) adjs = tournament.adjudicator_set.all() adj_table = TabbycatTableBuilder( view=self, title='From Adjudicators', sort_key='Feedbacks') adj_table.add_adjudicator_columns(adjs) adj_feedback_data = [] for adj in adjs: count = AdjudicatorFeedback.objects.filter( source_adjudicator__adjudicator=adj).select_related( 'source_adjudicator__adjudicator').count() adj_feedback_data.append({ 'text': "{:d} Feedbacks".format(count), 'link': reverse_tournament('adjfeedback-view-from-adjudicator', tournament, kwargs={'pk': adj.id}), }) adj_table.add_column("Feedbacks", adj_feedback_data) return [team_table, adj_table]
def add_debate_ballot_link_column(self, debates): ballot_links_header = {'key': "ballot", 'icon': 'search'} if self.admin: ballot_links_data = [{ 'text': _("View/Edit Ballot"), 'link': reverse_tournament('results-ballotset-edit', self.tournament, kwargs={'pk': debate.confirmed_ballot.id}) } if debate.confirmed_ballot else "" for debate in debates] self.add_column(ballot_links_header, ballot_links_data) elif self.tournament.pref('ballots_released'): ballot_links_header = {'key': "ballot", 'icon': 'search'} ballot_links_data = [] for debate in debates: if not debate.confirmed_ballot: ballot_links_data.append("") elif self.tournament.pref('teams_in_debate') == 'bp' and debate.round.is_break_round: ballot_links_data.append("") else: ballot_links_data.append({ 'text': _("View Ballot"), 'link': reverse_tournament('results-public-scoresheet-view', self.tournament, kwargs={'pk': debate.id}) }) self.add_column(ballot_links_header, ballot_links_data)
def post(self, request, *args, **kwargs): if self.round.draw_status != Round.STATUS_NONE: messages.error(request, _("Could not create draw for %(round)s, there was already a draw!") % {'round': self.round.name}) return super().post(request, *args, **kwargs) try: manager = DrawManager(self.round) manager.create() except DrawUserError as e: messages.error(request, mark_safe(_( "<p>The draw could not be created, for the following reason: " "<em>%(message)s</em></p>\n" "<p>Please fix this issue before attempting to create the draw.</p>" ) % {'message': str(e)})) logger.warning("User error creating draw: " + str(e), exc_info=True) return HttpResponseRedirect(reverse_round('availability-index', self.round)) except DrawFatalError as e: messages.error(request, mark_safe(_( "The draw could not be created, because the following error occurred: " "<em>%(message)s</em></p>\n" "<p>If this issue persists and you're not sure how to resolve it, please " "contact the developers.</p>" ) % {'message': str(e)})) logger.exception("Fatal error creating draw: " + str(e)) return HttpResponseRedirect(reverse_round('availability-index', self.round)) except StandingsError as e: message = _( "<p>The team standings could not be generated, because the following error occurred: " "<em>%(message)s</em></p>\n" "<p>Because generating the draw uses the current team standings, this " "prevents the draw from being generated.</p>" ) % {'message': str(e)} standings_options_url = reverse_tournament('options-tournament-section', self.tournament, kwargs={'section': 'standings'}) instructions = BaseStandingsView.admin_standings_error_instructions % {'standings_options_url': standings_options_url} messages.error(request, mark_safe(message + instructions)) logger.exception("Error generating standings for draw: " + str(e)) return HttpResponseRedirect(reverse_round('availability-index', self.round)) relevant_adj_venue_constraints = VenueConstraint.objects.filter( adjudicator__in=self.tournament.relevant_adjudicators) if not relevant_adj_venue_constraints.exists(): allocate_venues(self.round) else: messages.warning(request, _("Venues were not auto-allocated because there are one or more adjudicator venue constraints. " "You should run venue allocations after allocating adjudicators.")) self.log_action() return super().post(request, *args, **kwargs)
def get_ballot_cells(self, debate, tournament, view_role, user): # These are prefetched, so sort using Python rather than generating an SQL query ballotsubmissions = sorted(debate.ballotsubmission_set.all(), key=lambda x: x.version) if view_role == 'admin': link = 'results-ballotset-new' else: link = 'results-assistant-ballotset-new' return { 'component': 'ballots-cell', 'ballots': [b.serialize(tournament) for b in ballotsubmissions], 'current_user': user.username, 'acting_role': view_role, 'new_ballot': reverse_tournament(link, self.tournament, kwargs={'debate_id': debate.id}) }
def add_breaking_checkbox(self, adjudicators, key="Breaking"): breaking_header = { 'key': 'breaking', 'icon': 'award', 'tooltip': 'Whether the adj is marked as breaking (click to mark)', } breaking_data = [{ 'component': 'check-cell', 'checked': adj.breaking , 'sort': adj.breaking, 'type': 'breaking', 'saveURL': reverse_tournament('adjfeedback-set-adj-breaking-status', self.tournament), 'id': adj.pk, } for adj in adjudicators] self.add_column(breaking_header, breaking_data)
def _result_cell(self, ts, compress=False, show_score=False, show_ballots=False): if not hasattr(ts, 'debate_team') or not hasattr(ts.debate_team.opponent, 'team'): return {'text': '-'} opp = ts.debate_team.opponent.team opp_vshort = '<i class="emoji">' + opp.emoji + '</i>' if opp.emoji else "…" cell = { 'text': " vs " + (opp_vshort if compress else opp.short_name), 'popover': {'content': [{'text': ''}], 'title': ''} } if ts.win is True: cell['icon'] = "glyphicon-arrow-up text-success" cell['sort'] = 1 cell['popover']['title'] = "Won against " + opp.long_name elif ts.win is False: cell['icon'] = "glyphicon-arrow-down text-danger" cell['sort'] = 2 cell['popover']['title'] = "Lost to " + opp.long_name else: # None cell['icon'] = "" cell['sort'] = 3 cell['popover']['title'] = "No result for debate against " + opp.long_name if show_score: cell['subtext'] = metricformat(ts.score) cell['popover']['content'].append( {'text': 'Received <strong>%s</strong> team points' % metricformat(ts.score)}) if show_ballots: cell['popover']['content'].append( {'text': 'View Debate Ballot', 'link': reverse_tournament('results-public-scoresheet-view', self.tournament, kwargs={'pk': ts.debate_team.debate.id})}) if self._show_speakers_in_draw: cell['popover']['content'].append({'text': "Speakers in <strong>" + opp.short_name + "</strong>: " + ", ".join([s.name for s in opp.speakers])}) if self._show_record_links: cell['popover']['content'].append( self._team_record_link(opp)) return cell
def _build_url(adjudicator): path = reverse_tournament(url_name, tournament, kwargs={'url_key': adjudicator.url_key}) return self.request.build_absolute_uri(path)
def get_redirect_url(self, *args, **kwargs): return reverse_tournament('privateurls-person-index', self.tournament, kwargs={'url_key': kwargs['url_key']})
def get_redirect_url(self, *args, **kwargs): # Returns to the referring page (by way of hidden input with the path) fallback = reverse_tournament('adjfeedback-overview', self.tournament) return self.request.POST.get('next', fallback)
def get_redirect_url(self, *args, **kwargs): return reverse_tournament('admin-checkin-identifiers', self.tournament)
def get_extra(self): extra = super().get_extra() extra['url'] = self.request.build_absolute_uri(reverse_tournament('privateurls-person-index', self.tournament, kwargs={'url_key': '0'}))[:-2] return extra
def build_url(person): if person.url_key is None: return {'text': _("no URL"), 'class': 'text-warning'} path = reverse_tournament('privateurls-person-index', self.tournament, kwargs={'url_key': person.url_key}) return {'text': request.build_absolute_uri(path), 'class': 'small'}
def get_success_url(self): return reverse_tournament('post-results-public-ballotset-new', self.tournament)
def get_success_url(self): return reverse_tournament('privateurls-list', self.tournament)
def get_success_url(self): return reverse_tournament('adjfeedback-add-index', self.get_tournament())
def get_success_url(self): return reverse_tournament('options-tournament-index', self.get_tournament())
def get_success_url(self, *args, **kwargs): return reverse_tournament(self.success_url, self.tournament)
def get_success_url(self): return reverse_tournament('participants-list', self.tournament)
def get_success_url(self, *args, **kwargs): return reverse_tournament('importer-simple-index', self.get_tournament())
def get_success_url(self): return reverse_tournament('tournament-admin-home', self.importer.tournament)
def get_success_url(self): return reverse_tournament('results-assistant-round-list', self.tournament)
def populate_objects(self, prefill=True): super().populate_objects() use_code_names = use_team_code_names_data_entry(self.tournament, True) bses = BallotSubmission.objects.filter( debate=self.debate, participant_submitter__isnull=False, discarded=False, single_adj=True, ).distinct('participant_submitter').select_related( 'participant_submitter').order_by('participant_submitter', '-version') populate_results(bses, self.tournament) self.merged_ballots = bses # Handle result conflicts self.result = DebateResult(self.ballotsub, tournament=self.tournament) try: self.result.populate_from_merge(*[b.result for b in bses]) except ResultError as e: msg, t, adj, bs, side, speaker = e.args args = { 'ballot_url': reverse_tournament(self.edit_ballot_url, self.tournament, kwargs={'pk': bs.id}), 'adjudicator': adj.name, 'speaker': speaker.name, 'team': team_name_for_data_entry(self.debate.get_team(side), use_code_names), } if t == 'speaker': msg = _( "The speaking order in the ballots is inconsistent, so could not be merged." ) elif t == 'ghost': msg = _( "Duplicate speeches are marked inconsistently, so could not be merged." ) msg += _( " This error was caught in <a href='%(ballot_url)s'>%(adjudicator)s's ballot</a> for %(speaker)s (%(team)s)." ) messages.error(self.request, msg % args) return HttpResponseRedirect( reverse_round(self.ballot_list_url, self.debate.round)) # Handle motion conflicts bs_motions = BallotSubmission.objects.filter( id__in=[b.id for b in bses], motion__isnull=False, ).prefetch_related('debateteammotionpreference_set__debate_team') if self.tournament.pref('enable_motions'): try: merge_motions(self.ballotsub, bs_motions) except ValidationError as e: messages.error(self.request, e) return HttpResponseRedirect( reverse_round(self.ballot_list_url, self.debate.round)) # Vetos try: self.vetos = merge_motion_vetos(self.ballotsub, bs_motions) except ValidationError as e: messages.error(self.request, e) return HttpResponseRedirect( reverse_round(self.ballot_list_url, self.debate.round))
def _result_cell_two(self, ts, compress=False, show_score=False, show_ballots=False): if not hasattr(ts, 'debate_team') or not hasattr( ts.debate_team.opponent, 'team'): return {'text': self.BLANK_TEXT} opp = ts.debate_team.opponent.team opp_vshort = '<i class="emoji">' + opp.emoji + '</i>' if opp.emoji else "…" cell = { 'text': _(" vs %(opposition)s") % { 'opposition': opp_vshort if compress else self._team_short_name(opp) }, 'popover': { 'content': [], 'title': '' } } cell = self._result_cell_class_two(ts.win, cell) if ts.win is True: cell['popover']['title'] = _("Won against %(team)s") % { 'team': self._team_long_name(opp) } elif ts.win is False: cell['popover']['title'] = _("Lost to %(team)s") % { 'team': self._team_long_name(opp) } else: # None cell['popover']['title'] = _( "No result for debate against %(team)s") % { 'team': self._team_long_name(opp) } if show_score and ts.score is not None: score = ts.score if self.tournament.integer_scores( ts.debate_team.debate.round.stage) and score.is_integer(): score = int(ts.score) cell['subtext'] = metricformat(score) cell['popover']['content'].append({ 'text': _("Total speaker score: <strong>%s</strong>") % metricformat(score) }) if show_ballots: if self.admin: cell['popover']['content'].append({ 'text': _("View/edit debate ballot"), 'link': reverse_tournament('results-ballotset-edit', self.tournament, kwargs={'pk': ts.ballot_submission_id}) }) elif self.tournament.pref('ballots_released'): cell['popover']['content'].append({ 'text': _("View debate ballot"), 'link': reverse_tournament('results-public-scoresheet-view', self.tournament, kwargs={'pk': ts.debate_team.debate_id}) }) if self._show_speakers_in_draw: cell['popover']['content'].append({ 'text': _("Speakers in <strong>%(opp)s</strong>: %(speakers)s") % { 'opp': self._team_short_name(opp), 'speakers': ", ".join([s.name for s in opp.speakers]) } }) if self._show_record_links: cell['popover']['content'].append(self._team_record_link(opp)) return cell
def get_success_url(self): return reverse_tournament('privateurls-person-index', self.tournament, kwargs={'url_key': self.kwargs['url_key']})
def get_extra_info(self): info = super().get_extra_info() info['backUrl'] = reverse_tournament('panel-adjudicators-index', self.tournament) # Override info['backLabel'] = _("Return to Panels Overview") return info
def get_extra(self): extra = super().get_extra() extra['url'] = self.request.build_absolute_uri( reverse_tournament('standings-public-teams-current', self.tournament)) return extra
def get_success_url(self): return reverse_tournament('breakqual-teams', self.tournament, kwargs={'category': self.object.slug})
def get_success_url(self): t = Tournament.objects.order_by('id').last() return reverse_tournament('tournament-configure', tournament=t)
def get_success_url(self): return reverse_tournament('adjfeedback-overview', self.tournament)
def get_success_url(self): t = self.tournament return reverse_tournament('tournament-admin-home', tournament=t)
def get_from_team_link(self, team): return reverse_tournament('adjfeedback-public-add-from-team-pk', self.tournament, kwargs={'source_id': team.id})
def get_success_url(self): return reverse_tournament('notifications-email', self.tournament)
def _result_cell_bp(self, ts, compress=False, show_score=False, show_ballots=False): if not hasattr(ts, 'debate_team'): return {'text': self.BLANK_TEXT} other_teams = { dt.side: self._team_short_name(dt.team) for dt in ts.debate_team.debate.debateteam_set.all() } other_team_strs = [_("Teams in debate:")] for side in self.tournament.sides: if ts.debate_team.debate.sides_confirmed: line = _("%(team)s (%(side)s)") % { 'team': other_teams.get(side, "??"), 'side': get_side_name(self.tournament, side, 'abbr') } else: line = other_teams.get(side, "??") if side == ts.debate_team.side: line = "<strong>" + line + "</strong>" other_team_strs.append(line) cell = { 'popover': { 'content': [{ 'text': "<br />".join(other_team_strs) }], 'title': "", 'class': "no-wrap", } } if ts.debate_team.debate.round.is_break_round: cell = self._result_cell_class_four_elim(ts.win, cell) if ts.win is True: cell['text'] = _("advancing") cell['popover']['title'] = _("Advancing") elif ts.win is False: cell['text'] = _("eliminated") cell['popover']['title'] = _("Eliminated") else: cell['text'] = "–" cell['popover']['title'] = _("No result for debate") else: cell = self._result_cell_class_four(ts.points, cell) places = {0: _("4th"), 1: _("3rd"), 2: _("2nd"), 3: _("1st")} if ts.points is not None: place = places.get(ts.points, "??") cell['text'] = place cell['popover']['title'] = _("Placed %(place)s") % { 'place': place } else: cell['text'] = "–" cell['popover']['title'] = _("No result for debate") if show_score and ts.score is not None: score = ts.score if self.tournament.integer_scores( ts.debate_team.debate.round.stage) and score.is_integer(): score = int(ts.score) cell['subtext'] = metricformat(score) cell['popover']['content'].append({ 'text': _("Total speaker score: <strong>%s</strong>") % metricformat(score) }) if show_ballots: if self.admin: cell['popover']['content'].append({ 'text': _("View/edit debate ballot"), 'link': reverse_tournament('results-ballotset-edit', self.tournament, kwargs={'pk': ts.ballot_submission_id}) }) elif self.tournament.pref('ballots_released'): cell['popover']['content'].append({ 'text': _("View debate ballot"), 'link': reverse_tournament('results-public-scoresheet-view', self.tournament, kwargs={'pk': ts.debate_team.debate_id}) }) return cell
def build_link(person): if person.url_key is None: return '' path = reverse_tournament('privateurls-person-index', self.tournament, kwargs={'url_key': person.url_key}) return {'text': "🔗", 'link': request.build_absolute_uri(path)}
def _build_url(speaker): path = reverse_tournament( 'adjfeedback-public-add-from-team-randomised', tournament, kwargs={'url_key': speaker.team.url_key}) return self.request.build_absolute_uri(path)
def post(self, request, *args, **kwargs): tournament = self.get_tournament() speakers = Speaker.objects.filter(team__tournament=tournament, team__url_key__isnull=False, email__isnull=False) adjudicators = tournament.adjudicator_set.filter(url_key__isnull=False, email__isnull=False) if self.url_type is 'feedback': for speaker in speakers: if speaker.email is None: continue team_path = reverse_tournament( 'adjfeedback-public-add-from-team-randomised', tournament, kwargs={'url_key': speaker.team.url_key}) team_link = self.request.build_absolute_uri(team_path) message = ( '' 'Hi %s, \n\n' 'At %s we are using an online feedback system. As part of %s ' 'your team\'s feedback can be submitted at the following URL. ' 'This URL is unique to you — do not share it as anyone with ' 'this link can submit feedback on your team\s ' ' behalf. It will not change so we suggest bookmarking it. ' 'The URL is: \n\n %s' % (speaker.name, tournament.short_name, speaker.team.short_name, team_link)) try: send_mail("Your Feedback URL for %s" % tournament.short_name, message, settings.DEFAULT_FROM_EMAIL, [speaker.email], fail_silently=False) logger.info("Sent email with key to %s (%s)" % (speaker.email, speaker.name)) except: logger.info("Failed to send email to %s speaker.email") for adjudicator in adjudicators: if adjudicator.email is None: continue if self.url_type is 'feedback': adj_path = reverse_tournament( 'adjfeedback-public-add-from-adjudicator-randomised', tournament, kwargs={'url_key': adjudicator.url_key}) elif self.url_type is 'ballot': adj_path = reverse_tournament( 'results-public-ballotset-new-randomised', tournament, kwargs={'url_key': adjudicator.url_key}) adj_link = self.request.build_absolute_uri(adj_path) message = ( '' 'Hi %s, \n\n' 'At %s we are using an online %s system. Your %s ' 'can be submitted at the following URL. This URL is unique to ' 'you — do not share it as anyone with this link can submit ' '%ss on your behalf. It will not change so we suggest ' 'bookmarking it. The URL is: \n\n %s' % (adjudicator.name, tournament.short_name, self.url_type, self.url_type, self.url_type, adj_link)) try: send_mail("Your Feedback URL for %s" % tournament.short_name, message, settings.DEFAULT_FROM_EMAIL, [adjudicator.email], fail_silently=False) logger.info("Sent email with key to %s (%s)" % (adjudicator.email, adjudicator.name)) except: logger.info("Failed to send email %s" % adjudicator.email) messages.success(self.request, "Emails were sent for all teams and adjudicators.") return super().post(request, *args, **kwargs)