From 64e2d8d2649dc0e1a6e6ff58d9fac85bf94a4016 Mon Sep 17 00:00:00 2001 From: Yohann D'ANELLO Date: Mon, 18 Jan 2021 02:07:31 +0100 Subject: [PATCH] Manage Matrix channels --- .../commands/fix_matrix_channels.py | 306 ++++++++++++++++-- apps/participation/models.py | 2 +- 2 files changed, 280 insertions(+), 28 deletions(-) diff --git a/apps/participation/management/commands/fix_matrix_channels.py b/apps/participation/management/commands/fix_matrix_channels.py index 7fbd742..3346ca6 100644 --- a/apps/participation/management/commands/fix_matrix_channels.py +++ b/apps/participation/management/commands/fix_matrix_channels.py @@ -5,21 +5,22 @@ import os from asgiref.sync import async_to_sync from django.core.management import BaseCommand -from registration.models import AdminRegistration, Registration +from participation.models import Team, Tournament +from registration.models import AdminRegistration, Registration, VolunteerRegistration from tfjm.matrix import Matrix, RoomPreset, RoomVisibility class Command(BaseCommand): - def handle(self, *args, **options): + def handle(self, *args, **options): # noqa: C901 Matrix.set_display_name("Bot du TFJM²") if not os.getenv("SYNAPSE_PASSWORD"): avatar_uri = "plop" else: # pragma: no cover if not os.path.isfile(".matrix_avatar"): - stat_file = os.stat("tfjm/static/logo.svg") - with open("tfjm/static/logo.svg", "rb") as f: - resp = Matrix.upload(f, filename="logo.svg", content_type="image/svg", + stat_file = os.stat("tfjm/static/logo.png") + with open("tfjm/static/logo.png", "rb") as f: + resp = Matrix.upload(f, filename="logo.png", content_type="image/png", filesize=stat_file.st_size)[0][0] avatar_uri = resp.content_uri with open(".matrix_avatar", "w") as f: @@ -29,6 +30,67 @@ class Command(BaseCommand): with open(".matrix_avatar", "r") as f: avatar_uri = f.read().rstrip(" \t\r\n") + # Create basic channels + if not async_to_sync(Matrix.resolve_room_alias)("#aide-jurys-orgas:tfjm.org"): + Matrix.create_room( + visibility=RoomVisibility.public, + alias="aide-jurys-orgas", + name="Aide jurys & orgas", + topic="Pour discuter de propblèmes d'organisation", + federate=False, + preset=RoomPreset.private_chat, + ) + + if not async_to_sync(Matrix.resolve_room_alias)("#annonces:tfjm.org"): + Matrix.create_room( + visibility=RoomVisibility.public, + alias="annonces", + name="Annonces", + topic="Informations importantes du TFJM²", + federate=False, + preset=RoomPreset.public_chat, + ) + + if not async_to_sync(Matrix.resolve_room_alias)("#bienvenue:tfjm.org"): + Matrix.create_room( + visibility=RoomVisibility.public, + alias="bienvenue", + name="Bienvenue", + topic="Bienvenue au TFJM² 2021 !", + federate=False, + preset=RoomPreset.public_chat, + ) + + if not async_to_sync(Matrix.resolve_room_alias)("#bot:tfjm.org"): + Matrix.create_room( + visibility=RoomVisibility.public, + alias="bot", + name="#bot", + topic="Vive les r0b0ts", + federate=False, + preset=RoomPreset.public_chat, + ) + + if not async_to_sync(Matrix.resolve_room_alias)("#cno:tfjm.org"): + Matrix.create_room( + visibility=RoomVisibility.public, + alias="cno", + name="#cno", + topic="Channel des dieux", + federate=False, + preset=RoomPreset.private_chat, + ) + + if not async_to_sync(Matrix.resolve_room_alias)("#dev-bot:tfjm.org"): + Matrix.create_room( + visibility=RoomVisibility.public, + alias="dev-bot", + name="Bot - développement", + topic="Vive le bot", + federate=False, + preset=RoomPreset.private_chat, + ) + if not async_to_sync(Matrix.resolve_room_alias)("#faq:tfjm.org"): Matrix.create_room( visibility=RoomVisibility.public, @@ -39,12 +101,12 @@ class Command(BaseCommand): preset=RoomPreset.public_chat, ) - if not async_to_sync(Matrix.resolve_room_alias)("#annonces:tfjm.org"): + if not async_to_sync(Matrix.resolve_room_alias)("#flood:tfjm.org"): Matrix.create_room( visibility=RoomVisibility.public, - alias="annonces", - name="Annonces", - topic="Informations importantes du TFJM²", + alias="flood", + name="#flood", + topic="Discutez de tout et de rien !", federate=False, preset=RoomPreset.public_chat, ) @@ -59,34 +121,224 @@ class Command(BaseCommand): preset=RoomPreset.public_chat, ) - if not async_to_sync(Matrix.resolve_room_alias)("#flood:tfjm.org"): - Matrix.create_room( - visibility=RoomVisibility.public, - alias="flood", - name="Flood", - topic="Discutez de tout et de rien !", - federate=False, - preset=RoomPreset.public_chat, - ) - + # Setup avaters + Matrix.set_room_avatar("#aide-jury-orgas:tfjm.org", avatar_uri) Matrix.set_room_avatar("#annonces:tfjm.org", avatar_uri) + Matrix.set_room_avatar("#bienvenue:tfjm.org", avatar_uri) + Matrix.set_room_avatar("#bot:tfjm.org", avatar_uri) + Matrix.set_room_avatar("#cno:tfjm.org", avatar_uri) Matrix.set_room_avatar("#faq:tfjm.org", avatar_uri) - Matrix.set_room_avatar("#je-cherche-une-equipe:tfjm.org", avatar_uri) Matrix.set_room_avatar("#flood:tfjm.org", avatar_uri) + Matrix.set_room_avatar("#je-cherche-une-equipe:tfjm.org", avatar_uri) + # Read-only channels Matrix.set_room_power_level_event("#annonces:tfjm.org", "events_default", 50) + Matrix.set_room_power_level_event("#bienvenue:tfjm.org", "events_default", 50) + # Invite everyone to public channels for r in Registration.objects.all(): Matrix.invite("#annonces:tfjm.org", f"@{r.matrix_username}:tfjm.org") + Matrix.invite("#bienvenue:tfjm.org", f"@{r.matrix_username}:tfjm.org") + Matrix.invite("#bot:tfjm.org", f"@{r.matrix_username}:tfjm.org") Matrix.invite("#faq:tfjm.org", f"@{r.matrix_username}:tfjm.org") + Matrix.invite("#flood:tfjm.org", f"@{r.matrix_username}:tfjm.org") Matrix.invite("#je-cherche-une-equipe:tfjm.org", f"@{r.matrix_username}:tfjm.org") - Matrix.invite("#flood:tfjm.org", f"@{r.matrix_username}:tfjm.org") + # Volunteers have access to the help channel + for volunteer in VolunteerRegistration.objects.all(): + Matrix.invite("#aide-jury-orgas:tfjm.org", f"@{volunteer.matrix_username}:tfjm.org") + + # Admins are admins for admin in AdminRegistration.objects.all(): - Matrix.set_room_power_level("#annonces:tfjm.org", - f"@{admin.matrix_username}:tfjm.org", 95) - Matrix.set_room_power_level("#faq:tfjm.org", - f"@{admin.matrix_username}:tfjm.org", 95) - Matrix.set_room_power_level("#flood:tfjm.org", - f"@{admin.matrix_username}:tfjm.org", 95) + Matrix.invite("#cno:tfjm.org", f"@{admin.matrix_username}:tfjm.org") + Matrix.invite("#dev-bot:tfjm.org", f"@{admin.matrix_username}:tfjm.org") + + Matrix.set_room_power_level("#aide-jury-orgas:tfjm.org", f"@{admin.matrix_username}:tfjm.org", 95) + Matrix.set_room_power_level("#annonces:tfjm.org", f"@{admin.matrix_username}:tfjm.org", 95) + Matrix.set_room_power_level("#bot:tfjm.org", f"@{admin.matrix_username}:tfjm.org", 95) + Matrix.set_room_power_level("#cno:tfjm.org", f"@{admin.matrix_username}:tfjm.org", 95) + Matrix.set_room_power_level("#dev-bot:tfjm.org", f"@{admin.matrix_username}:tfjm.org", 95) + Matrix.set_room_power_level("#faq:tfjm.org", f"@{admin.matrix_username}:tfjm.org", 95) + Matrix.set_room_power_level("#flood:tfjm.org", f"@{admin.matrix_username}:tfjm.org", 95) + Matrix.set_room_power_level("#je-cherche-une-equipe:tfjm.org", f"@{admin.matrix_username}:tfjm.org", 95) + + # Create tournament-specific channels + for tournament in Tournament.objects.all(): + name = tournament.name + slug = name.lower().replace(" ", "-") + + if not async_to_sync(Matrix.resolve_room_alias)(f"#annonces-{slug}:tfjm.org"): + Matrix.create_room( + visibility=RoomVisibility.public, + alias=f"annonces-{slug}", + name=f"{name} - Annonces", + topic=f"Annonces du tournoi de {name}", + federate=False, + preset=RoomPreset.private_chat, + ) + + if not async_to_sync(Matrix.resolve_room_alias)(f"#general-{slug}:tfjm.org"): + Matrix.create_room( + visibility=RoomVisibility.public, + alias=f"general-{slug}", + name=f"{name} - Général", + topic=f"Accueil du tournoi de {name}", + federate=False, + preset=RoomPreset.private_chat, + ) + + if not async_to_sync(Matrix.resolve_room_alias)(f"#flood-{slug}:tfjm.org"): + Matrix.create_room( + visibility=RoomVisibility.public, + alias=f"flood-{slug}", + name=f"{name} - Flood", + topic=f"Discussion libre du tournoi de {name}", + federate=False, + preset=RoomPreset.private_chat, + ) + + if not async_to_sync(Matrix.resolve_room_alias)(f"#jury-{slug}:tfjm.org"): + Matrix.create_room( + visibility=RoomVisibility.public, + alias=f"jury-{slug}", + name=f"{name} - Jury", + topic=f"Discussion entre les orgas et jurys du tournoi de {name}", + federate=False, + preset=RoomPreset.private_chat, + ) + + if not async_to_sync(Matrix.resolve_room_alias)(f"#orga-{slug}:tfjm.org"): + Matrix.create_room( + visibility=RoomVisibility.public, + alias=f"orga-{slug}", + name=f"{name} - Organisateurs", + topic=f"Discussion entre les orgas du tournoi de {name}", + federate=False, + preset=RoomPreset.private_chat, + ) + + # Setup avatars + Matrix.set_room_avatar(f"#annonces-{slug}:tfjm.org", avatar_uri) + Matrix.set_room_avatar(f"#flood-{slug}:tfjm.org", avatar_uri) + Matrix.set_room_avatar(f"#general-{slug}:tfjm.org", avatar_uri) + Matrix.set_room_avatar(f"#jury-{slug}:tfjm.org", avatar_uri) + Matrix.set_room_avatar(f"#orga-{slug}:tfjm.org", avatar_uri) + + # Invite admins and give permissions + for admin in AdminRegistration.objects.all(): + Matrix.invite(f"#annonces-{slug}:tfjm.org", f"@{admin.matrix_username}:tfjm.org") + Matrix.invite(f"#flood-{slug}:tfjm.org", f"@{admin.matrix_username}:tfjm.org") + Matrix.invite(f"#general-{slug}:tfjm.org", f"@{admin.matrix_username}:tfjm.org") + Matrix.invite(f"#jury-{slug}:tfjm.org", f"@{admin.matrix_username}:tfjm.org") + Matrix.invite(f"#orga-{slug}:tfjm.org", f"@{admin.matrix_username}:tfjm.org") + + Matrix.set_room_power_level(f"#annonces-{slug}:tfjm.org", f"@{admin.matrix_username}:tfjm.org", 95) + Matrix.set_room_power_level(f"#flood-{slug}:tfjm.org", f"@{admin.matrix_username}:tfjm.org", 95) + Matrix.set_room_power_level(f"#general-{slug}:tfjm.org", f"@{admin.matrix_username}:tfjm.org", 95) + Matrix.set_room_power_level(f"#jury-{slug}:tfjm.org", f"@{admin.matrix_username}:tfjm.org", 95) + Matrix.set_room_power_level(f"#orga-{slug}:tfjm.org", f"@{admin.matrix_username}:tfjm.org", 95) + + # Invite organizers and give permissions + for orga in tournament.organizers.all(): + Matrix.invite(f"#annonces-{slug}:tfjm.org", f"@{orga.matrix_username}:tfjm.org") + Matrix.invite(f"#flood-{slug}:tfjm.org", f"@{orga.matrix_username}:tfjm.org") + Matrix.invite(f"#general-{slug}:tfjm.org", f"@{orga.matrix_username}:tfjm.org") + Matrix.invite(f"#jury-{slug}:tfjm.org", f"@{orga.matrix_username}:tfjm.org") + Matrix.invite(f"#orga-{slug}:tfjm.org", f"@{orga.matrix_username}:tfjm.org") + + Matrix.set_room_power_level(f"#annonces-{slug}:tfjm.org", f"@{orga.matrix_username}:tfjm.org", 50) + Matrix.set_room_power_level(f"#flood-{slug}:tfjm.org", f"@{orga.matrix_username}:tfjm.org", 50) + Matrix.set_room_power_level(f"#general-{slug}:tfjm.org", f"@{orga.matrix_username}:tfjm.org", 50) + Matrix.set_room_power_level(f"#jury-{slug}:tfjm.org", f"@{orga.matrix_username}:tfjm.org", 50) + Matrix.set_room_power_level(f"#orga-{slug}:tfjm.org", f"@{orga.matrix_username}:tfjm.org", 50) + + # Invite participants + for participation in tournament.participations.filter(valid=True).all(): + for participant in participation.team.participants.all(): + Matrix.invite(f"#annonces-{slug}:tfjm.org", f"@{participant.matrix_username}:tfjm.org") + Matrix.invite(f"#flood-{slug}:tfjm.org", f"@{participant.matrix_username}:tfjm.org") + Matrix.invite(f"#general-{slug}:tfjm.org", f"@{participant.matrix_username}:tfjm.org") + + # Create pool-specific channels + for pool in tournament.pools.all(): + if not async_to_sync(Matrix.resolve_room_alias)(f"#poule-{pool.id}:tfjm.org"): + Matrix.create_room( + visibility=RoomVisibility.public, + alias=f"poule-{pool.id}", + name=f"{name} - Jour {pool.round} - Poule " + f"{', '.join(participation.team.trigram for participation in pool.participations.all())}", + topic=f"Discussion avec les équipes - {pool}", + federate=False, + preset=RoomPreset.private_chat, + ) + if not async_to_sync(Matrix.resolve_room_alias)(f"#poule-{slug}-{pool.id}-jurys:tfjm.org"): + Matrix.create_room( + visibility=RoomVisibility.public, + alias=f"poule-{slug}-{pool.id}-jurys", + name=f"{name} - Jour {pool.round} - Jurys poule " + f"{', '.join(participation.team.trigram for participation in pool.participations.all())}", + topic=f"Discussion avec les jurys - {pool}", + federate=False, + preset=RoomPreset.private_chat, + ) + + Matrix.set_room_avatar(f"#poule-{slug}-{pool.id}:tfjm.org", avatar_uri) + Matrix.set_room_avatar(f"#poule-{slug}-{pool.id}-jurys:tfjm.org", avatar_uri) + + # Invite admins and give permissions + for admin in AdminRegistration.objects.all(): + Matrix.invite(f"#poule-{slug}-{pool.id}:tfjm.org", f"@{admin.matrix_username}:tfjm.org") + Matrix.invite(f"#poule-{slug}-{pool.id}-jurys:tfjm.org", f"@{admin.matrix_username}:tfjm.org") + + Matrix.set_room_power_level(f"#poule-{slug}-{pool.id}:tfjm.org", + f"@{admin.matrix_username}:tfjm.org", 95) + Matrix.set_room_power_level(f"#poule-{slug}-{pool.id}-jury:tfjm.org", + f"@{admin.matrix_username}:tfjm.org", 95) + + # Invite organizers and give permissions + for orga in VolunteerRegistration.objects.all(): + Matrix.invite(f"#poule-{slug}-{pool.id}:tfjm.org", f"@{orga.matrix_username}:tfjm.org") + Matrix.invite(f"#poule-{slug}-{pool.id}-jurys:tfjm.org", f"@{orga.matrix_username}:tfjm.org") + + Matrix.set_room_power_level(f"#poule-{slug}-{pool.id}:tfjm.org", + f"@{orga.matrix_username}:tfjm.org", 50) + Matrix.set_room_power_level(f"#poule-{slug}-{pool.id}-jury:tfjm.org", + f"@{orga.matrix_username}:tfjm.org", 50) + + # Invite the jury, give good permissions + for jury in pool.juries.all(): + Matrix.invite(f"#annonces-{slug}:tfjm.org", f"@{jury.matrix_username}:tfjm.org") + Matrix.invite(f"#general-{slug}:tfjm.org", f"@{jury.matrix_username}:tfjm.org") + Matrix.invite(f"#flood-{slug}:tfjm.org", f"@{jury.matrix_username}:tfjm.org") + Matrix.invite(f"#jury-{slug}:tfjm.org", f"@{jury.matrix_username}:tfjm.org") + Matrix.invite(f"#orga-{slug}:tfjm.org", f"@{jury.matrix_username}:tfjm.org") + Matrix.invite(f"#poule-{slug}-{pool.id}:tfjm.org", f"@{jury.matrix_username}:tfjm.org") + Matrix.invite(f"#poule-{slug}-{pool.id}-jurys:tfjm.org", f"@{jury.matrix_username}:tfjm.org") + + Matrix.set_room_power_level(f"#jury-{slug}:tfjm.org", f"@{jury.matrix_username}:tfjm.org", 50) + Matrix.set_room_power_level(f"#poule-{slug}-{pool.id}:tfjm.org", + f"@{jury.matrix_username}:tfjm.org", 50) + Matrix.set_room_power_level(f"#poule-{slug}-{pool.id}-jury:tfjm.org", + f"@{jury.matrix_username}:tfjm.org", 50) + + # Invite participants to the right pool + for participation in pool.participations.all(): + for participant in participation.team.participants.all(): + Matrix.invite(f"#poule-{slug}-{pool.id}:tfjm.org", f"@{participant.matrix_username}:tfjm.org") + + # Create private channels for teams + for team in Team.objects.all(): + if not async_to_sync(Matrix.resolve_room_alias)(f"#equipe-{team.trigram.lower()}:tfjm.org"): + Matrix.create_room( + visibility=RoomVisibility.public, + alias=f"equipe-{team.trigram.lower()}", + name=f"Équipe {team.trigram}", + topic=f"Discussion interne de l'équipe {team.name}", + federate=False, + preset=RoomPreset.private_chat, + ) + for participant in team.participants.all(): + Matrix.invite(f"#equipe-{team.trigram.lower}:tfjm.org", f"@{participant.matrix_username}:tfjm.org") + Matrix.set_room_power_level(f"#equipe-{team.trigram.lower}:tfjm.org", + f"@{participant.matrix_username}:tfjm.org", 50) diff --git a/apps/participation/models.py b/apps/participation/models.py index d506aee..2db89f7 100644 --- a/apps/participation/models.py +++ b/apps/participation/models.py @@ -210,7 +210,7 @@ class Tournament(models.Model): """ :return: The mailing list to contact the team members. """ - return f"organisateurs-{self.name.lower().replace(' ', '-')}@{os.getenv('SYMPA_HOST', 'localhost')}" + return f"jurys-{self.name.lower().replace(' ', '-')}@{os.getenv('SYMPA_HOST', 'localhost')}" def create_mailing_lists(self): """