Skip to content

Commit

Permalink
Merge branch 'hotfix/2.7.5'
Browse files Browse the repository at this point in the history
  • Loading branch information
tienne-B committed Feb 12, 2023
2 parents 14500cf + 9d62cfa commit f0c1c05
Show file tree
Hide file tree
Showing 23 changed files with 96 additions and 71 deletions.
16 changes: 16 additions & 0 deletions .github/CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@
Change Log
==========

2.7.5
-----
*Release date: 13 February 2023*

- Fixed checkins not automatically updating through private URLs and API
- Prevented API error when creating ballot with incorrect speakers (BACKEND-AVN)
- Added ability to search results by team name, rather than by reference
- Fixed ballot resaving through Edit Database (BACKEND-AVR)
- Removed trailing commas after panels in room allocations. Thank you to Trần Trang Linh for the fix!
- Corrected missing checkin identifiers showing as "null". Thanks again to Trần Trang Linh!
- Removed Render installation instructions [until that service can be reliably used]
- Fixed conflicts not showing when dragging panels
- Fixed adjudicator record pages crashing if shared between tournaments
- Corrected a few typos


2.7.4
-----
*Release date: 11 December 2022*
Expand Down
4 changes: 2 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@

# General information about the project.
project = 'Tabbycat'
copyright = '2022, Philip Belesky, Chuan-Zheng Lee, Étienne Beaulé'
copyright = '2023, Philip Belesky, Chuan-Zheng Lee, Étienne Beaulé'
author = 'Philip Belesky, Chuan-Zheng Lee, Étienne Beaulé'

# The version info for the project you're documenting, acts as replacement for
Expand All @@ -60,7 +60,7 @@
# The short X.Y version.
version = '2.7'
# The full version, including alpha/beta/rc tags.
release = '2.7.4'
release = '2.7.5'

rst_epilog = """
.. |vrelease| replace:: v{release}
Expand Down
1 change: 0 additions & 1 deletion docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ formats too. If you're looking for a general overview of the software, check out
:maxdepth: 1
:caption: Installation

install/render
install/heroku
install/local
install/docker
Expand Down
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 2 additions & 2 deletions tabbycat/api/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -1123,8 +1123,8 @@ def save(self, **kwargs):
def validate(self, data):
# Make sure the score is the sum of the speech scores
score = data.get('score', None)
speeches = data.get('speeches', None)
if speeches is None:
speeches = data.get('speeches', [])
if len(speeches) == 0:
if score is not None:
raise serializers.ValidationError("Speeches are required to assign scores.")
elif score is not None and score != sum(speech['score'] for speech in speeches):
Expand Down
5 changes: 2 additions & 3 deletions tabbycat/api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -326,9 +326,8 @@ def broadcast_checkin(self, obj, check):
group_name = CheckInEventConsumer.group_prefix + "_" + self.tournament.slug
async_to_sync(get_channel_layer().group_send)(group_name, {
'type': 'send_json',
'data': {
'checkins': [checkin_dict],
},
'checkins': [checkin_dict],
'created': check,
})
return checkin

Expand Down
36 changes: 20 additions & 16 deletions tabbycat/checkins/templates/PeopleStatusMixin.vue
Original file line number Diff line number Diff line change
Expand Up @@ -30,26 +30,30 @@ export default {
},
methods: {
getToolTipForPerson: function (entity) {
if (!this.teamCodes && entity.type !== 'Team' && entity.institution === null && entity.identifier !== null) {
const subs = [entity.name, entity.type, entity.identifier[0]]
return this.tct('%s, a %s of no institutional affiliation with identifier of %s', subs)
}
if (!this.teamCodes && entity.type !== 'Team' && entity.institution === null) {
const subs = [entity.name, entity.type]
return this.tct('%s, a %s of no institutional affiliation with no assigned identifier', subs)
}
if (!this.teamCodes && entity.type !== 'Team' && entity.identifier !== null) {
const subs = [entity.name, entity.type, entity.institution.name, entity.identifier[0]]
return this.tct('%s, a %s from %s with identifier of %s', subs)
}
if (!this.teamCodes && entity.type !== 'Team') {
const subs = [entity.name, entity.type, entity.institution.name]
return this.tct('%s, a %s from %s with no assigned identifier', subs)
if (entity.institution === null) {
if (entity.identifier[0]) {
const subs = [entity.name, entity.type, entity.identifier[0]]
return this.tct('%s, a %s of no institutional affiliation with identifier of %s', subs)
} else {
const subs = [entity.name, entity.type]
return this.tct('%s, a %s of no institutional affiliation with no identifier', subs)
}
}
if (entity.identifier[0]) {
const subs = [entity.name, entity.type, entity.institution.name, entity.identifier[0]]
return this.tct('%s, a %s from %s with identifier of %s', subs)
} else {
const subs = [entity.name, entity.type, entity.institution.name]
return this.tct('%s, a %s from %s with no identifier', subs)
}
}
if (entity.speakers !== null && entity.type === 'Team') {
if (entity.speakers && entity.type === 'Team') {
const speakers = []
_.forEach(entity.speakers, (speaker) => {
if (speaker.status) {
if (!speaker.identifier[0]) {
speakers.push(this.tct('%s (Absent; no id)', [speaker.name]))
} else if (speaker.status) {
speakers.push(this.tct('%s (Present; id=%s)', [speaker.name, speaker.identifier[0]]))
} else {
speakers.push(this.tct('%s (Absent; id=%s)', [speaker.name, speaker.identifier[0]]))
Expand Down
30 changes: 15 additions & 15 deletions tabbycat/checkins/templates/VenuesStatusMixin.vue
Original file line number Diff line number Diff line change
Expand Up @@ -19,22 +19,22 @@ export default {
_.forEach(entity.categories, (c) => {
categories.push(c.name)
})
if (entity.categories.length > 0 && entity.identifier !== null) {
const substitutions = [entity.name, categories.join(', '), entity.identifier[0]]
return this.tct('%s (%s) with identifier of %s', substitutions)
}
if (entity.categories.length === 0 && entity.identifier !== null) {
const substitutions = [entity.name, entity.identifier[0]]
return this.tct('%s (no category) with identifier of %s', substitutions)
}
if (entity.categories.length > 0) {
const substitutions = [entity.name, categories.join(', ')]
return this.tct('%s (%s) with no assigned identifier', substitutions)
}
if (entity.categories.length === 0) {
return this.tct('%s (no category) with no assigned identifier', [entity.name])
if (entity.categories.length) {
if (entity.identifier[0]) {
const substitutions = [entity.name, categories.join(', '), entity.identifier[0]]
return this.tct('%s (%s) with identifier of %s', substitutions)
} else {
const substitutions = [entity.name, categories.join(', ')]
return this.tct('%s (%s) with no identifier', substitutions)
}
} else {
if (entity.identifier[0]) {
const substitutions = [entity.name, entity.identifier[0]]
return this.tct('%s (no category) with identifier of %s', substitutions)
} else {
return this.tct('%s (no category) with no identifier', [entity.name])
}
}
return entity.name
},
},
computed: {
Expand Down
2 changes: 1 addition & 1 deletion tabbycat/checkins/templates/checkin_printables.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
{% block page-alerts %}

{% blocktrans trimmed asvar p1 %}
Each of the barcodes below is also an image file that can be download individually. If you want to download them all at once try using a 'bulk downloader' extension/plugin for your browser, such as <a href="https://chrome.google.com/webstore/detail/svg-export/naeaaedieihlkmdajjefioajbbdbdjgp?hl=en-GB">this one (for Chrome)</a>. To download them as a list you can go to Check-Ins section of the Edit Database area and copy/paste from the relevant table.
Each of the barcodes below is also an image file that can be downloaded individually. If you want to download them all at once try using a 'bulk downloader' extension/plugin for your browser, such as <a href="https://chrome.google.com/webstore/detail/svg-export/naeaaedieihlkmdajjefioajbbdbdjgp?hl=en-GB">this one (for Chrome)</a>. To download them as a list you can go to Check-Ins section of the Edit Database area and copy/paste from the relevant table.
{% endblocktrans %}
{% include "components/explainer-card.html" with type="info" %}

Expand Down
8 changes: 4 additions & 4 deletions tabbycat/checkins/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ def post(self, request, *args, **kwargs):

existing_checkin = get_unexpired_checkins(t, 'checkin_window_people').filter(identifier=identifier)
action = request.POST.get('action')
created = action == 'checkin'
if action == 'revoke':
if existing_checkin.exists():
existing_checkin.delete()
Expand All @@ -281,7 +282,7 @@ def post(self, request, *args, **kwargs):
else:
messages.error(request, _("Whoops! Looks like your check-in was already revoked."))
return super().post(request, *args, **kwargs)
elif action == 'checkin':
elif created:
if existing_checkin.exists():
messages.error(request, _("Whoops! Looks like you're already checked in."))
return super().post(request, *args, **kwargs)
Expand All @@ -298,9 +299,8 @@ def post(self, request, *args, **kwargs):
async_to_sync(get_channel_layer().group_send)(
group_name, {
'type': 'send_json',
'data': {
'checkins': [checkin_dict],
},
'checkins': [checkin_dict],
'created': created,
},
)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
{% blocktrans trimmed asvar p2 %}
You can add up to 198 adjudicators at a time. If you have more than 198
adjudicators, split them into chunks. (Please don't try to add more than 198
in one go; the system will crash and you will lose data.)
in one go; the system will crash, and you will lose data.)
{% endblocktrans %}
{% include "components/explainer-card.html" with type="info" %}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
{% blocktrans trimmed asvar p2 %}
You can add up to 141 teams at a time. If you have more than 141 teams,
split them into chunks. (Please don't try to add more than 141 in one go;
the system will crash and you will lose data.)
the system will crash, and you will lose data.)
{% endblocktrans %}
{% include "components/explainer-card.html" with type="info" %}

Expand Down
8 changes: 4 additions & 4 deletions tabbycat/participants/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,11 +194,11 @@ def use_team_code_names(self):
return use_team_code_names(self.tournament, self.admin)

@staticmethod
def allocations_set(obj, admin):
def allocations_set(self, obj, admin, tournament):
model_related = {'Team': 'debateteam_set', 'Adjudicator': 'debateadjudicator_set'}[type(obj).__name__]
try:
qs = getattr(obj, model_related).filter(
debate__round__in=obj.tournament.current_rounds).select_related('debate__round')
debate__round__in=tournament.current_rounds).select_related('debate__round')
if admin:
qs = qs.prefetch_related(Prefetch('debate__round__roundmotion_set',
queryset=RoundMotion.objects.select_related('motion')))
Expand All @@ -214,7 +214,7 @@ def get_context_data(self, **kwargs):
kwargs['admin_page'] = self.admin
kwargs['draw_released'] = self.tournament.current_round.draw_status == Round.STATUS_RELEASED
kwargs['use_code_names'] = self.use_team_code_names()
kwargs[self.model_kwarg] = self.allocations_set(self.object, self.admin)
kwargs[self.model_kwarg] = self.allocations_set(self.object, self.admin, self.tournament)

return super().get_context_data(**kwargs)

Expand Down Expand Up @@ -423,7 +423,7 @@ def post(self, request, *args, **kwargs):
self.set_category_eligibility(participant, posted_info[str(participant_id)])
self.log_action()
except Exception:
message = "Error handling eligiblity updates"
message = "Error handling eligibility updates"
logger.exception(message)
return JsonResponse({'status': 'false', 'message': message}, status=500)

Expand Down
2 changes: 1 addition & 1 deletion tabbycat/printing/templates/randomised_url_sheets.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
{% block page-alerts %}
<div class="alert alert-info d-print-none">
{% blocktrans trimmed %}
This page is designed to be printed as double sided A4 sheets, with the
This page is designed to be printed as double-sided A4 sheets, with the
outside facing side showing the participant name and the inside facing side
showing the URL. Use CTRL-P to print; for best results use Chrome.
{% endblocktrans %}
Expand Down
4 changes: 2 additions & 2 deletions tabbycat/privateurls/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,9 +213,9 @@ def get_context_data(self, **kwargs):
kwargs['checkins_used'] = False

if hasattr(self.object, 'adjudicator'):
kwargs['debateadjudications'] = BaseRecordView.allocations_set(self.object.adjudicator, False)
kwargs['debateadjudications'] = BaseRecordView.allocations_set(self.object.adjudicator, False, self.tournament)
else:
kwargs['debateteams'] = BaseRecordView.allocations_set(self.object.speaker.team, False)
kwargs['debateteams'] = BaseRecordView.allocations_set(self.object.speaker.team, False, self.tournament)

kwargs['draw_released'] = t.current_round.draw_status == Round.STATUS_RELEASED
kwargs['feedback_pref'] = t.pref('participant_feedback') == 'private-urls'
Expand Down
12 changes: 6 additions & 6 deletions tabbycat/results/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class BallotSubmissionAdmin(TabbycatModelAdminFieldsMixin, ModelAdmin):
list_display = ('id', 'debate', 'version', 'get_round', 'timestamp',
'submitter_type', 'submitter', 'confirmer', 'confirmed')
list_editable = ('confirmed',)
search_fields = ('debate__debateteam__team__reference', 'debate__debateteam__team__institution__name')
search_fields = ('debate__debateteam__team__short_name', 'debate__debateteam__team__institution__name')
raw_id_fields = ('debate', 'motion')
list_filter = ('debate__round', 'debate__round__tournament', 'submitter', 'confirmer')
# This incurs a massive performance hit
Expand All @@ -33,7 +33,7 @@ def get_queryset(self, request):
Prefetch('debate__debateteam_set', queryset=DebateTeam.objects.select_related('team')))

def resave_ballots(self, request, queryset):
q = queryset.select_related('debate__round__tournament').order_by('tournament_id')
q = queryset.select_related('debate__round__tournament').order_by('debate__round__tournament_id')
count = q.count()
for tournament, bss in groupby(q, lambda bs: bs.debate.round.tournament):
populate_results(bss, tournament)
Expand All @@ -55,7 +55,7 @@ def resave_ballots(self, request, queryset):
class TeamScoreAdmin(TabbycatModelAdminFieldsMixin, ModelAdmin):
list_display = ('id', 'ballot_submission', 'get_round', 'get_team', 'points', 'win', 'score')
search_fields = ('debate_team__debate__round__seq', 'debate_team__debate__round__tournament__name',
'debate_team__team__reference', 'debate_team__team__institution__name')
'debate_team__team__short_name', 'debate_team__team__institution__name')
list_filter = ('debate_team__debate__round', )
raw_id_fields = ('ballot_submission', 'debate_team')

Expand All @@ -75,7 +75,7 @@ def get_queryset(self, request):
class TeamScoreByAdjAdmin(TabbycatModelAdminFieldsMixin, ModelAdmin):
list_display = ('id', 'ballot_submission', 'get_round', 'get_adj_name', 'get_team', 'win', 'margin', 'score')
search_fields = ('debate_team__debate__round__seq', 'debate_team__debate__round__tournament__name',
'debate_team__team__reference', 'debate_team__team__institution__name')
'debate_team__team__short_name', 'debate_team__team__institution__name')
list_filter = ('debate_team__debate__round', 'debate_adjudicator__adjudicator__name')
raw_id_fields = ('ballot_submission', 'debate_adjudicator', 'debate_team')

Expand All @@ -99,7 +99,7 @@ class SpeakerScoreAdmin(TabbycatModelAdminFieldsMixin, ModelAdmin):
list_display = ('id', 'ballot_submission', 'get_round', 'get_team', 'position',
'get_speaker_name', 'score', 'ghost')
search_fields = ('debate_team__debate__round__abbreviation',
'debate_team__team__reference', 'debate_team__team__institution__name',
'debate_team__team__short_name', 'debate_team__team__institution__name',
'speaker__name')
list_filter = ('score', 'debate_team__debate__round', 'ghost')
raw_id_fields = ('debate_team', 'ballot_submission')
Expand All @@ -122,7 +122,7 @@ class SpeakerScoreByAdjAdmin(TabbycatModelAdminFieldsMixin, ModelAdmin):
list_display = ('id', 'ballot_submission', 'get_round', 'get_adj_name', 'get_team',
'get_speaker_name', 'position', 'score')
search_fields = ('debate_team__debate__round__seq',
'debate_team__team__reference', 'debate_team__team__institution__name',
'debate_team__team__short_name', 'debate_team__team__institution__name',
'debate_adjudicator__adjudicator__name')

list_filter = ('debate_team__debate__round', 'debate_adjudicator__adjudicator__name',
Expand Down
4 changes: 2 additions & 2 deletions tabbycat/settings/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@
# Version
# ==============================================================================

TABBYCAT_VERSION = '2.7.4'
TABBYCAT_VERSION = '2.7.5'
TABBYCAT_CODENAME = 'Pixie-bob'
READTHEDOCS_VERSION = 'v2.7.4'
READTHEDOCS_VERSION = 'v2.7.5'

# ==============================================================================
# Internationalization and Localization
Expand Down
2 changes: 1 addition & 1 deletion tabbycat/templates/admin/style_guide.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ <h6 class="mt-5">Nav actions</h6>
{% include "components/item-action.html" with text="Nav Action Item" icon="feather" %}
</div>

<h6 class="mt-5">Calls to Action (promp for necessary actions)</h6>
<h6 class="mt-5">Calls to Action (prompt for necessary actions)</h6>

{% include "components/item-action.html" with url="#" alone=True text="Go to the draw area to allocate adjudicators." type="success" to_complete=True %}

Expand Down
2 changes: 1 addition & 1 deletion tabbycat/templates/ajax/WebSocketMixin.vue
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ export default {
},
dismissLostConnectionAlert: function () {
if (this.lostConnections > 1) { // Only show modal when a connection is re-opened not opened
const explanation = `This page lost its connection to the server but has succesfully reopened
const explanation = `This page lost its connection to the server but has successfully reopened
it. Changes made to data on this page will now be saved. However, you may
want to refresh the page to verify that earlier changes were saved.`
this.showErrorAlert(explanation, null, 'Connection Resumed', 'text-success', true, true)
Expand Down
13 changes: 10 additions & 3 deletions tabbycat/templates/allocations/DragAndDropDebate.vue
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,16 @@
</slot>
<slot name="adjudicators">
<div class="flex-16 align-self-center p-2 small">
<span v-for="adj in debateOrPanel.adjudicators.C">{{ adj.name }} Ⓒ, </span>
<span v-for="adj in debateOrPanel.adjudicators.P">{{ adj.name }}, </span>
<span v-for="adj in debateOrPanel.adjudicators.T">{{ adj.name }} Ⓣ,</span>
<!-- Note that the use of comments below is not extranous, it prevents extra whitespace before the commas -->
<span v-for="adj in debateOrPanel.adjudicators.C">{{ adj.name }} Ⓒ<!--
--><span v-if="debateOrPanel.adjudicators.P.length + debateOrPanel.adjudicators.T.length > 0">,</span>
</span>
<span v-for="(adj, index) in debateOrPanel.adjudicators.P"> {{ adj.name }}<!--
--><span v-if="index !== debateOrPanel.adjudicators.P.length - 1 || debateOrPanel.adjudicators.T.length > 0">,</span>
</span>
<span v-for="(adj, index) in debateOrPanel.adjudicators.T"> {{ adj.name }} Ⓣ<!--
--><span v-if="debateOrPanel.adjudicators.T.length > 1 && index !== debateOrPanel.adjudicators.T.length - 1">,</span>
</span>
</div>
</slot>
</div>
Expand Down
Loading

0 comments on commit f0c1c05

Please sign in to comment.