+ {% include "registration/includes/login.html" %}
+
+
+
+
+
diff --git a/chat/tests.py b/chat/tests.py
new file mode 100644
index 0000000..80ea069
--- /dev/null
+++ b/chat/tests.py
@@ -0,0 +1,2 @@
+# Copyright (C) 2024 by Animath
+# SPDX-License-Identifier: GPL-3.0-or-later
diff --git a/chat/urls.py b/chat/urls.py
new file mode 100644
index 0000000..9adf06e
--- /dev/null
+++ b/chat/urls.py
@@ -0,0 +1,18 @@
+# Copyright (C) 2024 by Animath
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from django.contrib.auth.views import LoginView, LogoutView
+from django.urls import path
+from django.utils.translation import gettext_lazy as _
+from tfjm.views import LoginRequiredTemplateView
+
+app_name = 'chat'
+
+urlpatterns = [
+ path('', LoginRequiredTemplateView.as_view(template_name="chat/chat.html",
+ extra_context={'title': _("Chat")}), name='chat'),
+ path('fullscreen/', LoginRequiredTemplateView.as_view(template_name="chat/fullscreen.html", login_url='chat:login'),
+ name='fullscreen'),
+ path('login/', LoginView.as_view(template_name="chat/login.html"), name='login'),
+ path('logout/', LogoutView.as_view(next_page='chat:fullscreen'), name='logout'),
+]
diff --git a/draw/consumers.py b/draw/consumers.py
index d64c888..7719b8d 100644
--- a/draw/consumers.py
+++ b/draw/consumers.py
@@ -9,6 +9,7 @@ from random import randint, shuffle
from asgiref.sync import sync_to_async
from channels.generic.websocket import AsyncJsonWebsocketConsumer
from django.conf import settings
+from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.utils import translation
from django.utils.translation import gettext_lazy as _
@@ -44,6 +45,8 @@ class DrawConsumer(AsyncJsonWebsocketConsumer):
We accept only if this is a user of a team of the associated tournament, or a volunteer
of the tournament.
"""
+ if '_fake_user_id' in self.scope['session']:
+ self.scope['user'] = await User.objects.aget(pk=self.scope['session']['_fake_user_id'])
# Fetch the registration of the current user
user = self.scope['user']
diff --git a/draw/migrations/0003_alter_teamdraw_options.py b/draw/migrations/0003_alter_teamdraw_options.py
new file mode 100644
index 0000000..8725ba9
--- /dev/null
+++ b/draw/migrations/0003_alter_teamdraw_options.py
@@ -0,0 +1,28 @@
+# Generated by Django 5.0.3 on 2024-04-22 22:11
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ("draw", "0002_alter_teamdraw_purposed"),
+ ]
+
+ operations = [
+ migrations.AlterModelOptions(
+ name="teamdraw",
+ options={
+ "ordering": (
+ "round__draw__tournament__name",
+ "round__number",
+ "pool__letter",
+ "passage_index",
+ "choice_dice",
+ "passage_dice",
+ ),
+ "verbose_name": "team draw",
+ "verbose_name_plural": "team draws",
+ },
+ ),
+ ]
diff --git a/draw/routing.py b/draw/routing.py
deleted file mode 100644
index 8ce6085..0000000
--- a/draw/routing.py
+++ /dev/null
@@ -1,10 +0,0 @@
-# Copyright (C) 2023 by Animath
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-from django.urls import path
-
-from . import consumers
-
-websocket_urlpatterns = [
- path("ws/draw/", consumers.DrawConsumer.as_asgi()),
-]
diff --git a/draw/tests.py b/draw/tests.py
index 9f3ec6a..bbb209a 100644
--- a/draw/tests.py
+++ b/draw/tests.py
@@ -14,8 +14,8 @@ from django.contrib.sites.models import Site
from django.test import TestCase
from django.urls import reverse
from participation.models import Team, Tournament
+from tfjm import routing as websocket_routing
-from . import routing
from .models import Draw, Pool, Round, TeamDraw
@@ -55,7 +55,7 @@ class TestDraw(TestCase):
# Connect to Websocket
headers = [(b'cookie', self.async_client.cookies.output(header='', sep='; ').encode())]
- communicator = WebsocketCommunicator(AuthMiddlewareStack(URLRouter(routing.websocket_urlpatterns)),
+ communicator = WebsocketCommunicator(AuthMiddlewareStack(URLRouter(websocket_routing.websocket_urlpatterns)),
"/ws/draw/", headers)
connected, subprotocol = await communicator.connect()
self.assertTrue(connected)
diff --git a/locale/fr/LC_MESSAGES/django.po b/locale/fr/LC_MESSAGES/django.po
index 5043b78..831fcea 100644
--- a/locale/fr/LC_MESSAGES/django.po
+++ b/locale/fr/LC_MESSAGES/django.po
@@ -7,7 +7,7 @@ msgid ""
msgstr ""
"Project-Id-Version: TFJM\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2024-04-22 23:36+0200\n"
+"POT-Creation-Date: 2024-04-28 23:37+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: Emmy D'Anello \n"
"Language-Team: LANGUAGE \n"
@@ -21,14 +21,41 @@ msgstr ""
msgid "API"
msgstr "API"
-#: draw/admin.py:39 draw/admin.py:57 draw/admin.py:75
-#: participation/admin.py:109 participation/models.py:253
-#: participation/tables.py:88
-msgid "teams"
-msgstr "équipes"
+#: chat/models.py:17 chat/templates/chat/content.html:18
+msgid "General channels"
+msgstr "Canaux généraux"
-#: draw/admin.py:53 draw/admin.py:71 draw/admin.py:88 draw/models.py:26
-#: participation/admin.py:79 participation/admin.py:140
+#: chat/models.py:18 chat/templates/chat/content.html:22
+msgid "Tournament channels"
+msgstr "Canaux de tournois"
+
+#: chat/models.py:19 chat/templates/chat/content.html:26
+msgid "Team channels"
+msgstr "Canaux d'équipes"
+
+#: chat/models.py:20 chat/templates/chat/content.html:30
+msgid "Private channels"
+msgstr "Messages privés"
+
+#: chat/models.py:24 participation/models.py:35 participation/models.py:263
+#: participation/tables.py:18 participation/tables.py:34
+msgid "name"
+msgstr "nom"
+
+#: chat/models.py:29
+msgid "category"
+msgstr "catégorie"
+
+#: chat/models.py:36
+msgid "read permission"
+msgstr "permission de lecture"
+
+#: chat/models.py:42
+msgid "write permission"
+msgstr "permission d'écriture"
+
+#: chat/models.py:52 draw/admin.py:53 draw/admin.py:71 draw/admin.py:88
+#: draw/models.py:26 participation/admin.py:79 participation/admin.py:140
#: participation/admin.py:171 participation/models.py:693
#: participation/models.py:717 participation/models.py:935
#: registration/models.py:756
@@ -36,6 +63,174 @@ msgstr "équipes"
msgid "tournament"
msgstr "tournoi"
+#: chat/models.py:54
+msgid ""
+"For a permission that concerns a tournament, indicates what is the concerned "
+"tournament."
+msgstr ""
+"Pour une permission qui concerne un tournoi, indique quel est le tournoi "
+"concerné."
+
+#: chat/models.py:63 draw/models.py:429 draw/models.py:456
+#: participation/admin.py:136 participation/admin.py:155
+#: participation/models.py:1434 participation/models.py:1443
+#: participation/tables.py:84
+msgid "pool"
+msgstr "poule"
+
+#: chat/models.py:65
+msgid ""
+"For a permission that concerns a pool, indicates what is the concerned pool."
+msgstr ""
+"Pour une permission qui concerne une poule, indique quelle est la poule "
+"concernée."
+
+#: chat/models.py:74 draw/templates/draw/tournament_content.html:277
+#: participation/admin.py:167 participation/models.py:252
+#: participation/models.py:708
+#: participation/templates/participation/tournament_harmonize.html:15
+#: registration/models.py:157 registration/models.py:747
+#: registration/tables.py:39
+#: registration/templates/registration/payment_form.html:52
+msgid "team"
+msgstr "équipe"
+
+#: chat/models.py:76
+msgid ""
+"For a permission that concerns a team, indicates what is the concerned team."
+msgstr ""
+"Pour une permission qui concerne une équipe, indique quelle est l'équipe "
+"concernée."
+
+#: chat/models.py:80
+msgid "private"
+msgstr "privé"
+
+#: chat/models.py:82
+msgid ""
+"If checked, only users who have been explicitly added to the channel will be "
+"able to access it."
+msgstr ""
+"Si sélectionné, seul⋅es les utilisateur⋅rices qui ont été explicitement "
+"ajouté⋅es au canal pourront y accéder."
+
+#: chat/models.py:87
+msgid "invited users"
+msgstr "Utilisateur⋅rices invité"
+
+#: chat/models.py:90
+msgid ""
+"Extra users who have been invited to the channel, in addition to the "
+"permitted group of the channel."
+msgstr ""
+"Utilisateur⋅rices supplémentaires qui ont été invité⋅es au canal, en plus du "
+"groupe autorisé du canal."
+
+#: chat/models.py:102
+#, python-brace-format
+msgid "Channel {name}"
+msgstr "Canal {name}"
+
+#: chat/models.py:168 chat/models.py:177
+msgid "channel"
+msgstr "canal"
+
+#: chat/models.py:169
+msgid "channels"
+msgstr "canaux"
+
+#: chat/models.py:183
+msgid "author"
+msgstr "auteur⋅rice"
+
+#: chat/models.py:190
+msgid "created at"
+msgstr "créé le"
+
+#: chat/models.py:195
+msgid "updated at"
+msgstr "modifié le"
+
+#: chat/models.py:200
+msgid "content"
+msgstr "contenu"
+
+#: chat/models.py:205
+msgid "users read"
+msgstr "utilisateur⋅rices ayant lu"
+
+#: chat/models.py:208
+msgid "Users who have read the message."
+msgstr "Utilisateur⋅rices qui ont lu le message."
+
+#: chat/models.py:271
+msgid "message"
+msgstr "message"
+
+#: chat/models.py:272
+msgid "messages"
+msgstr "messages"
+
+#: chat/templates/chat/content.html:4
+msgid "JavaScript must be enabled on your browser to access chat."
+msgstr "JavaScript doit être activé sur votre navigateur pour accéder au chat."
+
+#: chat/templates/chat/content.html:8
+msgid "Chat channels"
+msgstr "Canaux de chat"
+
+#: chat/templates/chat/content.html:14
+msgid "Sort by unread messages"
+msgstr "Trier par messages non lus"
+
+#: chat/templates/chat/content.html:38
+msgid ""
+"You can install a shortcut to the chat on your home screen using the "
+"download button on the header."
+msgstr ""
+"Vous pouvez installer un raccourci vers le chat sur votre écran d'accueil en "
+"utilisant le bouton de téléchargement dans l'en-tête."
+
+#: chat/templates/chat/content.html:56
+msgid "Toggle fullscreen mode"
+msgstr "Inverse le mode plein écran"
+
+#: chat/templates/chat/content.html:60 tfjm/templates/navbar.html:117
+msgid "Log out"
+msgstr "Déconnexion"
+
+#: chat/templates/chat/content.html:64
+msgid "Install app on home screen"
+msgstr "Installer l'application sur l'écran d'accueil"
+
+#: chat/templates/chat/content.html:76
+msgid "Fetch previous messages…"
+msgstr "Récupérer les messages précédents…"
+
+#: chat/templates/chat/content.html:87
+msgid "Send message…"
+msgstr "Envoyer un message…"
+
+#: chat/templates/chat/login.html:10 chat/templates/chat/login.html:30
+#: registration/templates/registration/password_reset_complete.html:10
+#: tfjm/templates/base.html:84 tfjm/templates/base.html:85
+#: tfjm/templates/navbar.html:98
+#: tfjm/templates/registration/includes/login.html:22
+#: tfjm/templates/registration/login.html:7
+#: tfjm/templates/registration/login.html:8
+msgid "Log in"
+msgstr "Connexion"
+
+#: chat/urls.py:13 tfjm/templates/navbar.html:66
+msgid "Chat"
+msgstr "Chat"
+
+#: draw/admin.py:39 draw/admin.py:57 draw/admin.py:75
+#: participation/admin.py:109 participation/models.py:253
+#: participation/tables.py:88
+msgid "teams"
+msgstr "équipes"
+
#: draw/admin.py:92 draw/models.py:234 draw/models.py:448
#: participation/models.py:939
msgid "round"
@@ -45,68 +240,68 @@ msgstr "tour"
msgid "Draw"
msgstr "Tirage au sort"
-#: draw/consumers.py:30
+#: draw/consumers.py:31
msgid "You are not an organizer."
msgstr "Vous n'êtes pas un⋅e organisateur⋅rice."
-#: draw/consumers.py:162
+#: draw/consumers.py:165
msgid "The draw is already started."
msgstr "Le tirage a déjà commencé."
-#: draw/consumers.py:168
+#: draw/consumers.py:171
msgid "Invalid format"
msgstr "Format invalide"
-#: draw/consumers.py:173
+#: draw/consumers.py:176
#, python-brace-format
msgid "The sum must be equal to the number of teams: expected {len}, got {sum}"
msgstr ""
"La somme doit être égale au nombre d'équipes : attendu {len}, obtenu {sum}"
-#: draw/consumers.py:178
+#: draw/consumers.py:181
msgid "There can be at most one pool with 5 teams."
msgstr "Il ne peut y avoir au plus qu'une seule poule de 5 équipes."
-#: draw/consumers.py:218
+#: draw/consumers.py:221
msgid "Draw started!"
msgstr "Le tirage a commencé !"
-#: draw/consumers.py:240
+#: draw/consumers.py:243
#, python-brace-format
msgid "The draw for the tournament {tournament} will start."
msgstr "Le tirage au sort du tournoi {tournament} va commencer."
-#: draw/consumers.py:251 draw/consumers.py:277 draw/consumers.py:687
-#: draw/consumers.py:904 draw/consumers.py:993 draw/consumers.py:1015
-#: draw/consumers.py:1106 draw/templates/draw/tournament_content.html:5
+#: draw/consumers.py:254 draw/consumers.py:280 draw/consumers.py:690
+#: draw/consumers.py:907 draw/consumers.py:996 draw/consumers.py:1018
+#: draw/consumers.py:1109 draw/templates/draw/tournament_content.html:5
msgid "The draw has not started yet."
msgstr "Le tirage au sort n'a pas encore commencé."
-#: draw/consumers.py:264
+#: draw/consumers.py:267
#, python-brace-format
msgid "The draw for the tournament {tournament} is aborted."
msgstr "Le tirage au sort du tournoi {tournament} est annulé."
-#: draw/consumers.py:304 draw/consumers.py:325 draw/consumers.py:621
-#: draw/consumers.py:692 draw/consumers.py:909
+#: draw/consumers.py:307 draw/consumers.py:328 draw/consumers.py:624
+#: draw/consumers.py:695 draw/consumers.py:912
msgid "This is not the time for this."
msgstr "Ce n'est pas le moment pour cela."
-#: draw/consumers.py:317 draw/consumers.py:320
+#: draw/consumers.py:320 draw/consumers.py:323
msgid "You've already launched the dice."
msgstr "Vous avez déjà lancé le dé."
-#: draw/consumers.py:323
+#: draw/consumers.py:326
msgid "It is not your turn."
msgstr "Ce n'est pas votre tour."
-#: draw/consumers.py:410
+#: draw/consumers.py:413
#, python-brace-format
msgid "Dices from teams {teams} are identical. Please relaunch your dices."
msgstr ""
"Les dés des équipes {teams} sont identiques. Merci de relancer vos dés."
-#: draw/consumers.py:1018
+#: draw/consumers.py:1021
msgid "This is only available for the final tournament."
msgstr "Cela n'est possible que pour la finale."
@@ -213,12 +408,6 @@ msgstr "L'instance complète de la poule."
msgid "Pool {letter}{number}"
msgstr "Poule {letter}{number}"
-#: draw/models.py:429 draw/models.py:456 participation/admin.py:136
-#: participation/admin.py:155 participation/models.py:1434
-#: participation/models.py:1443 participation/tables.py:84
-msgid "pool"
-msgstr "poule"
-
#: draw/models.py:430 participation/models.py:1435
msgid "pools"
msgstr "poules"
@@ -352,15 +541,6 @@ msgstr "Tirer un problème pour"
msgid "Pb."
msgstr "Pb."
-#: draw/templates/draw/tournament_content.html:277 participation/admin.py:167
-#: participation/models.py:252 participation/models.py:708
-#: participation/templates/participation/tournament_harmonize.html:15
-#: registration/models.py:157 registration/models.py:747
-#: registration/tables.py:39
-#: registration/templates/registration/payment_form.html:52
-msgid "team"
-msgstr "équipe"
-
#: draw/templates/draw/tournament_content.html:287
#: draw/templates/draw/tournament_content.html:288
#: draw/templates/draw/tournament_content.html:289
@@ -589,11 +769,6 @@ msgstr "Ce⋅tte défenseur⋅se ne travaille pas sur ce problème."
msgid "The PDF file must not have more than 2 pages."
msgstr "Le fichier PDF ne doit pas avoir plus de 2 pages."
-#: participation/models.py:35 participation/models.py:263
-#: participation/tables.py:18 participation/tables.py:34
-msgid "name"
-msgstr "nom"
-
#: participation/models.py:41 participation/tables.py:39
msgid "trigram"
msgstr "trigramme"
@@ -1219,16 +1394,6 @@ msgstr "Pas d'équipe définie"
msgid "Update"
msgstr "Modifier"
-#: participation/templates/participation/chat.html:7
-msgid ""
-"The chat feature is now out of usage. If you feel that having a chat feature "
-"between participants is important, for example to build a team, please "
-"contact us."
-msgstr ""
-"La fonctionnalité de chat est désormais hors-service. Si vous pensez "
-"qu'avoir un chat entre les participant⋅es est important, par exemple pour "
-"former une équipe, merci de nous contacter."
-
#: participation/templates/participation/create_team.html:11
#: participation/templates/participation/tournament_form.html:14
#: tfjm/templates/base.html:80
@@ -2899,14 +3064,6 @@ msgstr "Changer mon mot de passe"
msgid "Your password has been set. You may go ahead and log in now."
msgstr "Votre mot de passe a été changé. Vous pouvez désormais vous connecter."
-#: registration/templates/registration/password_reset_complete.html:10
-#: tfjm/templates/base.html:84 tfjm/templates/base.html:85
-#: tfjm/templates/navbar.html:98 tfjm/templates/registration/login.html:7
-#: tfjm/templates/registration/login.html:8
-#: tfjm/templates/registration/login.html:30
-msgid "Log in"
-msgstr "Connexion"
-
#: registration/templates/registration/password_reset_confirm.html:9
msgid ""
"Please enter your new password twice so we can verify you typed it in "
@@ -3484,11 +3641,55 @@ msgstr "Autorisation parentale de {student}.{ext}"
msgid "Payment receipt of {registrations}.{ext}"
msgstr "Justificatif de paiement de {registrations}.{ext}"
-#: tfjm/settings.py:167
+#: tfjm/permissions.py:9
+msgid "Everyone, including anonymous users"
+msgstr "Tout le monde, incluant les utilisateur⋅rices anonymes"
+
+#: tfjm/permissions.py:10
+msgid "Authenticated users"
+msgstr "Utilisateur⋅rices connecté⋅es"
+
+#: tfjm/permissions.py:11
+msgid "All volunteers"
+msgstr "Toustes les bénévoles"
+
+#: tfjm/permissions.py:12
+msgid "All members of a given tournament"
+msgstr "Toustes les membres d'un tournoi donné"
+
+#: tfjm/permissions.py:13
+msgid "Tournament organizers only"
+msgstr "Organisateur⋅rices du tournoi seulement"
+
+#: tfjm/permissions.py:14
+msgid "Tournament organizers and jury presidents of the tournament"
+msgstr "Organisateur⋅rices du tournoi et président⋅es de jury du tournoi"
+
+#: tfjm/permissions.py:15
+msgid "Jury members of the pool"
+msgstr "Membres du jury de la poule"
+
+#: tfjm/permissions.py:16
+msgid "Jury members and participants of the pool"
+msgstr "Membre du jury et participant⋅es de la poule"
+
+#: tfjm/permissions.py:17
+msgid "Members of the team and organizers of concerned tournaments"
+msgstr "Membres de l'équipe et organisateur⋅rices des tournois concernés"
+
+#: tfjm/permissions.py:18
+msgid "Private, reserved to explicit authorized users"
+msgstr "Privé, réservé aux utilisateur⋅rices explicitement autorisé⋅es"
+
+#: tfjm/permissions.py:19
+msgid "Admin users"
+msgstr "Administrateur⋅rices"
+
+#: tfjm/settings.py:169
msgid "English"
msgstr "Anglais"
-#: tfjm/settings.py:168
+#: tfjm/settings.py:170
msgid "French"
msgstr "Français"
@@ -3577,10 +3778,6 @@ msgstr "Mon équipe"
msgid "My participation"
msgstr "Ma participation"
-#: tfjm/templates/navbar.html:67
-msgid "Chat"
-msgstr "Chat"
-
#: tfjm/templates/navbar.html:72
msgid "Administration"
msgstr "Administration"
@@ -3601,19 +3798,7 @@ msgstr "S'inscrire"
msgid "My account"
msgstr "Mon compte"
-#: tfjm/templates/navbar.html:115
-msgid "Log out"
-msgstr "Déconnexion"
-
-#: tfjm/templates/registration/logged_out.html:8
-msgid "Thanks for spending some quality time with the Web site today."
-msgstr "Merci d'avoir utilisé la plateforme du TFJM²."
-
-#: tfjm/templates/registration/logged_out.html:9
-msgid "Log in again"
-msgstr "Se reconnecter"
-
-#: tfjm/templates/registration/login.html:13
+#: tfjm/templates/registration/includes/login.html:5
#, python-format
msgid ""
"You are authenticated as %(user)s, but are not authorized to access this "
@@ -3622,14 +3807,22 @@ msgstr ""
"Vous êtes connecté⋅e en tant que %(user)s, mais n'êtes pas autorisé⋅e à "
"accéder à cette page. Voulez-vous vous reconnecter avec un autre compte ?"
-#: tfjm/templates/registration/login.html:25
+#: tfjm/templates/registration/includes/login.html:17
msgid "Your username is your e-mail address."
msgstr "Votre identifiant est votre adresse e-mail."
-#: tfjm/templates/registration/login.html:28
+#: tfjm/templates/registration/includes/login.html:20
msgid "Forgotten your password?"
msgstr "Mot de passe oublié ?"
+#: tfjm/templates/registration/logged_out.html:8
+msgid "Thanks for spending some quality time with the Web site today."
+msgstr "Merci d'avoir utilisé la plateforme du TFJM²."
+
+#: tfjm/templates/registration/logged_out.html:9
+msgid "Log in again"
+msgstr "Se reconnecter"
+
#: tfjm/templates/search/search.html:6 tfjm/templates/search/search.html:10
msgid "Search"
msgstr "Chercher"
@@ -3645,8 +3838,3 @@ msgstr "Aucun résultat."
#: tfjm/templates/sidebar.html:10 tfjm/templates/sidebar.html:21
msgid "Informations"
msgstr "Informations"
-
-#~ msgid "Can't determine the pool size. Are you sure your file is correct?"
-#~ msgstr ""
-#~ "Impossible de déterminer la taille de la poule. Êtes-vous sûr⋅e que le "
-#~ "fichier est correct ?"
diff --git a/participation/templates/participation/chat.html b/participation/templates/participation/chat.html
deleted file mode 100644
index bf47704..0000000
--- a/participation/templates/participation/chat.html
+++ /dev/null
@@ -1,13 +0,0 @@
-{% extends "base.html" %}
-
-{% load i18n %}
-
-{% block content %}
-
- {% blocktrans trimmed %}
- The chat feature is now out of usage. If you feel that having a chat
- feature between participants is important, for example to build a
- team, please contact us.
- {% endblocktrans %}
-
-{% endblock %}
diff --git a/participation/urls.py b/participation/urls.py
index 4125a4c..2c97587 100644
--- a/participation/urls.py
+++ b/participation/urls.py
@@ -2,7 +2,6 @@
# SPDX-License-Identifier: GPL-3.0-or-later
from django.urls import path
-from django.views.generic import TemplateView
from .views import CreateTeamView, FinalNotationSheetTemplateView, GSheetNotificationsView, JoinTeamView, \
MyParticipationDetailView, MyTeamDetailView, NotationSheetsArchiveView, NoteUpdateView, ParticipationDetailView, \
@@ -74,5 +73,4 @@ urlpatterns = [
path("pools/passages//update/", PassageUpdateView.as_view(), name="passage_update"),
path("pools/passages//solution/", SynthesisUploadView.as_view(), name="upload_synthesis"),
path("pools/passages/notes//", NoteUpdateView.as_view(), name="update_notes"),
- path("chat/", TemplateView.as_view(template_name="participation/chat.html"), name="chat")
]
diff --git a/tfjm/asgi.py b/tfjm/asgi.py
index 3bec7e0..417d54e 100644
--- a/tfjm/asgi.py
+++ b/tfjm/asgi.py
@@ -22,13 +22,13 @@ os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'tfjm.settings')
django_asgi_app = get_asgi_application()
# useful since the import must be done after the application initialization
-import draw.routing # noqa: E402, I202
+import tfjm.routing # noqa: E402, I202
application = ProtocolTypeRouter(
{
"http": django_asgi_app,
"websocket": AllowedHostsOriginValidator(
- AuthMiddlewareStack(URLRouter(draw.routing.websocket_urlpatterns))
+ AuthMiddlewareStack(URLRouter(tfjm.routing.websocket_urlpatterns))
),
}
)
diff --git a/tfjm/permissions.py b/tfjm/permissions.py
new file mode 100644
index 0000000..f29d5c6
--- /dev/null
+++ b/tfjm/permissions.py
@@ -0,0 +1,19 @@
+# Copyright (C) 2024 by Animath
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from django.db import models
+from django.utils.translation import gettext_lazy as _
+
+
+class PermissionType(models.TextChoices):
+ ANONYMOUS = 'anonymous', _("Everyone, including anonymous users")
+ AUTHENTICATED = 'authenticated', _("Authenticated users")
+ VOLUNTEER = 'volunteer', _("All volunteers")
+ TOURNAMENT_MEMBER = 'tournament', _("All members of a given tournament")
+ TOURNAMENT_ORGANIZER = 'organizer', _("Tournament organizers only")
+ TOURNAMENT_JURY_PRESIDENT = 'jury_president', _("Tournament organizers and jury presidents of the tournament")
+ JURY_MEMBER = 'jury', _("Jury members of the pool")
+ POOL_MEMBER = 'pool', _("Jury members and participants of the pool")
+ TEAM_MEMBER = 'team', _("Members of the team and organizers of concerned tournaments")
+ PRIVATE = 'private', _("Private, reserved to explicit authorized users")
+ ADMIN = 'admin', _("Admin users")
diff --git a/tfjm/routing.py b/tfjm/routing.py
new file mode 100644
index 0000000..08c54d8
--- /dev/null
+++ b/tfjm/routing.py
@@ -0,0 +1,11 @@
+# Copyright (C) 2024 by Animath
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+import chat.consumers
+from django.urls import path
+import draw.consumers
+
+websocket_urlpatterns = [
+ path("ws/chat/", chat.consumers.ChatConsumer.as_asgi()),
+ path("ws/draw/", draw.consumers.DrawConsumer.as_asgi()),
+]
diff --git a/tfjm/settings.py b/tfjm/settings.py
index c1b98bb..4c6a0e0 100644
--- a/tfjm/settings.py
+++ b/tfjm/settings.py
@@ -68,6 +68,7 @@ INSTALLED_APPS = [
'rest_framework.authtoken',
'api',
+ 'chat',
'draw',
'registration',
'participation',
@@ -101,6 +102,7 @@ MIDDLEWARE = [
ROOT_URLCONF = 'tfjm.urls'
LOGIN_REDIRECT_URL = "index"
+LOGOUT_REDIRECT_URL = "login"
TEMPLATES = [
{
diff --git a/tfjm/settings_prod.py b/tfjm/settings_prod.py
index d7f48b8..2024aeb 100644
--- a/tfjm/settings_prod.py
+++ b/tfjm/settings_prod.py
@@ -27,7 +27,7 @@ SESSION_COOKIE_SECURE = False
CSRF_COOKIE_SECURE = False
CSRF_COOKIE_HTTPONLY = False
X_FRAME_OPTIONS = 'DENY'
-SESSION_COOKIE_AGE = 60 * 60 * 3
+SESSION_COOKIE_AGE = 60 * 60 * 24 * 7 * 2 # 2 weeks
CHANNEL_LAYERS = {
"default": {
diff --git a/tfjm/static/tfjm-192.png b/tfjm/static/tfjm-192.png
new file mode 100644
index 0000000..a212e44
Binary files /dev/null and b/tfjm/static/tfjm-192.png differ
diff --git a/tfjm/static/tfjm-512.png b/tfjm/static/tfjm-512.png
new file mode 100644
index 0000000..5be044a
Binary files /dev/null and b/tfjm/static/tfjm-512.png differ
diff --git a/tfjm/static/tfjm-square.svg b/tfjm/static/tfjm-square.svg
new file mode 100644
index 0000000..7e76588
--- /dev/null
+++ b/tfjm/static/tfjm-square.svg
@@ -0,0 +1,91 @@
+
+
diff --git a/tfjm/templates/base.html b/tfjm/templates/base.html
index f272bd7..da1cff5 100644
--- a/tfjm/templates/base.html
+++ b/tfjm/templates/base.html
@@ -40,18 +40,18 @@
{% include "navbar.html" %}
-
diff --git a/tfjm/templates/registration/includes/login.html b/tfjm/templates/registration/includes/login.html
new file mode 100644
index 0000000..1ae3348
--- /dev/null
+++ b/tfjm/templates/registration/includes/login.html
@@ -0,0 +1,23 @@
+{% load i18n crispy_forms_filters %}
+
+{% if user.is_authenticated %}
+
+ {% blocktrans trimmed %}
+ You are authenticated as {{ user }}, but are not authorized to
+ access this page. Would you like to login to a different account?
+ {% endblocktrans %}
+
+{% endif %}
+
\ No newline at end of file
diff --git a/tfjm/templates/registration/login.html b/tfjm/templates/registration/login.html
index f033a0b..2695aa0 100644
--- a/tfjm/templates/registration/login.html
+++ b/tfjm/templates/registration/login.html
@@ -2,31 +2,11 @@
{% comment %}
SPDX-License-Identifier: GPL-2.0-or-later
{% endcomment %}
-{% load i18n crispy_forms_filters %}
+{% load i18n %}
{% block title %}{% trans "Log in" %}{% endblock %}
{% block content-title %}
- {% blocktrans trimmed %}
- You are authenticated as {{ user }}, but are not authorized to
- access this page. Would you like to login to a different account?
- {% endblocktrans %}
-