From b820306e2e66fa897a3ec7d0318f5a348397b5a1 Mon Sep 17 00:00:00 2001
From: Emmy D'Anello <emmy.danello@animath.fr>
Date: Sun, 28 Apr 2024 17:04:34 +0200
Subject: [PATCH] Automatically create appropriated channels when
 tournaments/pools/participations are updated

Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
---
 chat/apps.py                                  |   7 ++
 .../commands/create_chat_channels.py          |   1 -
 chat/signals.py                               | 100 ++++++++++++++++++
 tox.ini                                       |   4 +-
 4 files changed, 109 insertions(+), 3 deletions(-)
 create mode 100644 chat/signals.py

diff --git a/chat/apps.py b/chat/apps.py
index a17b8f5..ce683bf 100644
--- a/chat/apps.py
+++ b/chat/apps.py
@@ -2,8 +2,15 @@
 # SPDX-License-Identifier: GPL-3.0-or-later
 
 from django.apps import AppConfig
+from django.db.models.signals import post_save
 
 
 class ChatConfig(AppConfig):
     default_auto_field = "django.db.models.BigAutoField"
     name = "chat"
+
+    def ready(self):
+        from chat import signals
+        post_save.connect(signals.create_tournament_channels, "participation.Tournament")
+        post_save.connect(signals.create_pool_channels, "participation.Pool")
+        post_save.connect(signals.create_team_channel, "participation.Participation")
diff --git a/chat/management/commands/create_chat_channels.py b/chat/management/commands/create_chat_channels.py
index 0baf61c..666ee3f 100644
--- a/chat/management/commands/create_chat_channels.py
+++ b/chat/management/commands/create_chat_channels.py
@@ -3,7 +3,6 @@
 
 from django.core.management import BaseCommand
 from django.utils.translation import activate
-
 from participation.models import Team, Tournament
 from tfjm.permissions import PermissionType
 
diff --git a/chat/signals.py b/chat/signals.py
new file mode 100644
index 0000000..72056e3
--- /dev/null
+++ b/chat/signals.py
@@ -0,0 +1,100 @@
+# Copyright (C) 2024 by Animath
+# SPDX-License-Identifier: GPL-3.0-or-later
+
+from chat.models import Channel
+from participation.models import Participation, Pool, Tournament
+from tfjm.permissions import PermissionType
+
+
+def create_tournament_channels(instance: Tournament, **_kwargs):
+    tournament = instance
+
+    Channel.objects.update_or_create(
+        name=f"{tournament.name} - Annonces",
+        defaults=dict(
+            category=Channel.ChannelCategory.TOURNAMENT,
+            read_access=PermissionType.TOURNAMENT_MEMBER,
+            write_access=PermissionType.TOURNAMENT_ORGANIZER,
+            tournament=tournament,
+        ),
+    )
+
+    Channel.objects.update_or_create(
+        name=f"{tournament.name} - Général",
+        defaults=dict(
+            category=Channel.ChannelCategory.TOURNAMENT,
+            read_access=PermissionType.TOURNAMENT_MEMBER,
+            write_access=PermissionType.TOURNAMENT_MEMBER,
+            tournament=tournament,
+        ),
+    )
+
+    Channel.objects.update_or_create(
+        name=f"{tournament.name} - Détente",
+        defaults=dict(
+            category=Channel.ChannelCategory.TOURNAMENT,
+            read_access=PermissionType.TOURNAMENT_MEMBER,
+            write_access=PermissionType.TOURNAMENT_MEMBER,
+            tournament=tournament,
+        ),
+    )
+
+    Channel.objects.update_or_create(
+        name=f"{tournament.name} - Juré⋅es",
+        defaults=dict(
+            category=Channel.ChannelCategory.TOURNAMENT,
+            read_access=PermissionType.JURY_MEMBER,
+            write_access=PermissionType.JURY_MEMBER,
+            tournament=tournament,
+        ),
+    )
+
+    if tournament.remote:
+        Channel.objects.update_or_create(
+            name=f"{tournament.name} - Président⋅es de jury",
+            defaults=dict(
+                category=Channel.ChannelCategory.TOURNAMENT,
+                read_access=PermissionType.TOURNAMENT_JURY_PRESIDENT,
+                write_access=PermissionType.TOURNAMENT_JURY_PRESIDENT,
+                tournament=tournament,
+            ),
+        )
+
+
+def create_pool_channels(instance: Pool, **_kwargs):
+    pool = instance
+    tournament = pool.tournament
+
+    if tournament.remote:
+        Channel.objects.update_or_create(
+            name=f"{tournament.name} - Poule {pool.short_name}",
+            defaults=dict(
+                category=Channel.ChannelCategory.TOURNAMENT,
+                read_access=PermissionType.POOL_MEMBER,
+                write_access=PermissionType.POOL_MEMBER,
+                pool=pool,
+            ),
+        )
+
+        Channel.objects.update_or_create(
+            name=f"{tournament.name} - Poule {pool.short_name} - Jury",
+            defaults=dict(
+                category=Channel.ChannelCategory.TOURNAMENT,
+                read_access=PermissionType.JURY_MEMBER,
+                write_access=PermissionType.JURY_MEMBER,
+                pool=pool,
+            ),
+        )
+
+
+def create_team_channel(instance: Participation, **_kwargs):
+    if instance.valid:
+        Channel.objects.update_or_create(
+            name=f"Équipe {instance.team.trigram}",
+            defaults=dict(
+                category=Channel.ChannelCategory.TEAM,
+                read_access=PermissionType.TEAM_MEMBER,
+                write_access=PermissionType.TEAM_MEMBER,
+                team=instance.team,
+            ),
+        )
diff --git a/tox.ini b/tox.ini
index aa524c4..521eccb 100644
--- a/tox.ini
+++ b/tox.ini
@@ -13,7 +13,7 @@ deps = coverage
 
 commands =
     python manage.py compilemessages -i .tox -i venv
-    coverage run --source=api,draw,logs,participation,registration,tfjm ./manage.py test api/ draw/ logs/ participation/ registration/ tfjm/
+    coverage run --source=api,draw,logs,participation,registration,tfjm ./manage.py test api/ chat/ draw/ logs/ participation/ registration/ tfjm/
     coverage report -m
 
 [testenv:linters]
@@ -26,7 +26,7 @@ deps =
     pep8-naming
     pyflakes
 commands =
-    flake8 api/ draw/ logs/ participation/ registration/ tfjm/
+    flake8 api/ chat/ draw/ logs/ participation/ registration/ tfjm/
 
 [flake8]
 exclude =