mirror of
https://gitlab.com/animath/si/plateforme.git
synced 2025-08-02 01:14:52 +02:00
Add french comments on chat application
Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
@@ -13,6 +13,11 @@ from tfjm.permissions import PermissionType
|
||||
|
||||
|
||||
class Channel(models.Model):
|
||||
"""
|
||||
Ce modèle représente un canal de chat, défini par son nom, sa catégorie, les permissions de lecture et d'écriture
|
||||
requises pour accéder au canal, et éventuellement un tournoi, une poule ou une équipe associée.
|
||||
"""
|
||||
|
||||
class ChannelCategory(models.TextChoices):
|
||||
GENERAL = 'general', _("General channels")
|
||||
TOURNAMENT = 'tournament', _("Tournament channels")
|
||||
@@ -22,6 +27,7 @@ class Channel(models.Model):
|
||||
name = models.CharField(
|
||||
max_length=255,
|
||||
verbose_name=_("name"),
|
||||
help_text=_("Visible name of the channel."),
|
||||
)
|
||||
|
||||
category = models.CharField(
|
||||
@@ -29,18 +35,22 @@ class Channel(models.Model):
|
||||
verbose_name=_("category"),
|
||||
choices=ChannelCategory,
|
||||
default=ChannelCategory.GENERAL,
|
||||
help_text=_("Category of the channel, between general channels, tournament-specific channels, team channels "
|
||||
"or private channels. Will be used to sort channels in the channel list."),
|
||||
)
|
||||
|
||||
read_access = models.CharField(
|
||||
max_length=16,
|
||||
verbose_name=_("read permission"),
|
||||
choices=PermissionType,
|
||||
help_text=_("Permission type that is required to read the messages of the channels."),
|
||||
)
|
||||
|
||||
write_access = models.CharField(
|
||||
max_length=16,
|
||||
verbose_name=_("write permission"),
|
||||
choices=PermissionType,
|
||||
help_text=_("Permission type that is required to write a message to a channel."),
|
||||
)
|
||||
|
||||
tournament = models.ForeignKey(
|
||||
@@ -92,10 +102,20 @@ class Channel(models.Model):
|
||||
)
|
||||
|
||||
def get_visible_name(self, user: User) -> str:
|
||||
"""
|
||||
Renvoie le nom du channel tel qu'il est visible pour l'utilisateur⋅rice donné.
|
||||
Dans le cas d'un canal classique, renvoie directement le nom.
|
||||
Dans le cas d'un canal privé, renvoie la liste des personnes membres du canal,
|
||||
à l'exception de la personne connectée, afin de ne pas afficher son propre nom.
|
||||
Dans le cas d'un chat avec uniquement soi-même, on affiche que notre propre nom.
|
||||
"""
|
||||
if self.private:
|
||||
# Le canal est privé, on renvoie la liste des personnes membres du canal
|
||||
# à l'exception de soi-même (sauf si on est la seule personne dans le canal)
|
||||
users = [f"{u.first_name} {u.last_name}" for u in self.invited.all() if u != user] \
|
||||
or [f"{user.first_name} {user.last_name}"]
|
||||
return ", ".join(users)
|
||||
# Le canal est public, on renvoie directement le nom
|
||||
return self.name
|
||||
|
||||
def __str__(self):
|
||||
@@ -103,39 +123,77 @@ class Channel(models.Model):
|
||||
|
||||
@staticmethod
|
||||
async def get_accessible_channels(user: User, permission_type: str = 'read') -> QuerySet["Channel"]:
|
||||
"""
|
||||
Renvoie les canaux auxquels l'utilisateur⋅rice donné a accès, en lecture ou en écriture.
|
||||
|
||||
Types de permissions :
|
||||
ANONYMOUS : Tout le monde, y compris les utilisateur⋅rices non connecté⋅es
|
||||
AUTHENTICATED : Toustes les utilisateur⋅rices connecté⋅es
|
||||
VOLUNTEER : Toustes les bénévoles
|
||||
TOURNAMENT_MEMBER : Toustes les membres d'un tournoi donné (orgas, juré⋅es, participant⋅es)
|
||||
TOURNAMENT_ORGANIZER : Les organisateur⋅rices d'un tournoi donné
|
||||
TOURNAMENT_JURY_PRESIDENT : Les organisateur⋅rices et les président⋅es de jury d'un tournoi donné
|
||||
JURY_MEMBER : Les membres du jury d'une poule donnée, ou les organisateur⋅rices du tournoi
|
||||
POOL_MEMBER : Les membres du jury et les participant⋅es d'une poule donnée, ou les organisateur⋅rices du tournoi
|
||||
TEAM_MEMBER : Les membres d'une équipe donnée
|
||||
PRIVATE : Les utilisateur⋅rices explicitement invité⋅es
|
||||
ADMIN : Les utilisateur⋅rices administrateur⋅rices (qui ont accès à tout)
|
||||
|
||||
Les canaux privés sont utilisés pour les messages privés, et ne sont pas affichés aux admins.
|
||||
|
||||
:param user: L'utilisateur⋅rice dont on veut récupérer la liste des canaux.
|
||||
:param permission_type: Le type de permission concerné (read ou write).
|
||||
:return: Le Queryset des canaux autorisés.
|
||||
"""
|
||||
permission_type = 'write_access' if 'write' in permission_type.lower() else 'read_access'
|
||||
|
||||
qs = Channel.objects.none()
|
||||
if user.is_anonymous:
|
||||
# Les utilisateur⋅rices non connecté⋅es ont accès aux canaux publics pour toustes
|
||||
return Channel.objects.filter(**{permission_type: PermissionType.ANONYMOUS})
|
||||
|
||||
# Les utilisateur⋅rices connecté⋅es ont accès aux canaux publics pour les personnes connectées
|
||||
qs |= Channel.objects.filter(**{permission_type: PermissionType.AUTHENTICATED})
|
||||
registration = await Registration.objects.prefetch_related('user').aget(user_id=user.id)
|
||||
|
||||
if registration.is_admin:
|
||||
# Les administrateur⋅rices ont accès à tous les canaux, sauf les canaux privés sont iels ne sont pas membres
|
||||
return Channel.objects.prefetch_related('invited').exclude(~Q(invited=user) & Q(private=True)).all()
|
||||
|
||||
if registration.is_volunteer:
|
||||
registration = await VolunteerRegistration.objects \
|
||||
.prefetch_related('jury_in__tournament', 'organized_tournaments').aget(user_id=user.id)
|
||||
|
||||
# Les bénévoles ont accès aux canaux pour bénévoles
|
||||
qs |= Channel.objects.filter(**{permission_type: PermissionType.VOLUNTEER})
|
||||
|
||||
# Iels ont accès aux tournois dont iels sont organisateur⋅rices ou juré⋅es
|
||||
# pour la permission TOURNAMENT_MEMBER
|
||||
qs |= Channel.objects.filter(Q(tournament__in=registration.interesting_tournaments),
|
||||
**{permission_type: PermissionType.TOURNAMENT_MEMBER})
|
||||
|
||||
# Iels ont accès aux canaux pour les organisateur⋅rices des tournois dont iels sont organisateur⋅rices
|
||||
# pour la permission TOURNAMENT_ORGANIZER
|
||||
qs |= Channel.objects.filter(Q(tournament__in=registration.organized_tournaments.all()),
|
||||
**{permission_type: PermissionType.TOURNAMENT_ORGANIZER})
|
||||
|
||||
# Iels ont accès aux canaux pour les organisateur⋅rices et président⋅es de jury des tournois dont iels sont
|
||||
# organisateur⋅rices ou juré⋅es pour la permission TOURNAMENT_JURY_PRESIDENT
|
||||
qs |= Channel.objects.filter(Q(tournament__pools__in=registration.pools_presided.all())
|
||||
| Q(tournament__in=registration.organized_tournaments.all()),
|
||||
**{permission_type: PermissionType.TOURNAMENT_JURY_PRESIDENT})
|
||||
|
||||
# Iels ont accès aux canaux pour les juré⋅es des poules dont iels sont juré⋅es
|
||||
# ou les organisateur⋅rices des tournois dont iels sont organisateur⋅rices
|
||||
# pour la permission JURY_MEMBER
|
||||
qs |= Channel.objects.filter(Q(pool__in=registration.jury_in.all())
|
||||
| Q(pool__tournament__in=registration.organized_tournaments.all())
|
||||
| Q(pool__tournament__pools__in=registration.pools_presided.all()),
|
||||
**{permission_type: PermissionType.JURY_MEMBER})
|
||||
|
||||
# Iels ont accès aux canaux pour les juré⋅es et participant⋅es des poules dont iels sont juré⋅es
|
||||
# ou les organisateur⋅rices des tournois dont iels sont organisateur⋅rices
|
||||
# pour la permission POOL_MEMBER
|
||||
qs |= Channel.objects.filter(Q(pool__in=registration.jury_in.all())
|
||||
| Q(pool__tournament__in=registration.organized_tournaments.all())
|
||||
| Q(pool__tournament__pools__in=registration.pools_presided.all()),
|
||||
@@ -151,15 +209,20 @@ class Channel(models.Model):
|
||||
if team.participation.final:
|
||||
tournaments.append(await Tournament.objects.aget(final=True))
|
||||
|
||||
# Les participant⋅es ont accès aux canaux généraux pour le tournoi dont iels sont membres
|
||||
# Cela comprend la finale s'iels sont finalistes
|
||||
qs |= Channel.objects.filter(Q(tournament__in=tournaments),
|
||||
**{permission_type: PermissionType.TOURNAMENT_MEMBER})
|
||||
|
||||
# Iels ont accès aux canaux généraux pour les poules dont iels sont participant⋅es
|
||||
qs |= Channel.objects.filter(Q(pool__in=team.participation.pools.all()),
|
||||
**{permission_type: PermissionType.POOL_MEMBER})
|
||||
|
||||
# Iels ont accès aux canaux propres à leur équipe
|
||||
qs |= Channel.objects.filter(Q(team=team),
|
||||
**{permission_type: PermissionType.TEAM_MEMBER})
|
||||
|
||||
# Les utilisateur⋅rices ont de plus accès aux messages privés qui leur sont adressés
|
||||
qs |= Channel.objects.filter(invited=user).prefetch_related('invited')
|
||||
|
||||
return qs
|
||||
@@ -171,6 +234,12 @@ class Channel(models.Model):
|
||||
|
||||
|
||||
class Message(models.Model):
|
||||
"""
|
||||
Ce modèle représente un message de chat.
|
||||
Un message appartient à un canal, et est défini par son contenu, son auteur⋅rice, sa date de création et sa date
|
||||
de dernière modification.
|
||||
De plus, on garde en mémoire les utilisateur⋅rices qui ont lu le message.
|
||||
"""
|
||||
channel = models.ForeignKey(
|
||||
Channel,
|
||||
on_delete=models.CASCADE,
|
||||
@@ -208,55 +277,74 @@ class Message(models.Model):
|
||||
help_text=_("Users who have read the message."),
|
||||
)
|
||||
|
||||
def get_author_name(self):
|
||||
def get_author_name(self) -> str:
|
||||
"""
|
||||
Renvoie le nom de l'auteur⋅rice du message, en fonction de son rôle dans l'organisation
|
||||
dans le cadre d'un⋅e bénévole, ou de son équipe dans le cadre d'un⋅e participant⋅e.
|
||||
"""
|
||||
registration = self.author.registration
|
||||
|
||||
author_name = f"{self.author.first_name} {self.author.last_name}"
|
||||
if registration.is_volunteer:
|
||||
if registration.is_admin:
|
||||
# Les administrateur⋅rices ont le suffixe (CNO)
|
||||
author_name += " (CNO)"
|
||||
|
||||
if self.channel.pool:
|
||||
if registration == self.channel.pool.jury_president:
|
||||
# Læ président⋅e de jury de la poule a le suffixe (P. jury)
|
||||
author_name += " (P. jury)"
|
||||
elif registration in self.channel.pool.juries.all():
|
||||
# Les juré⋅es de la poule ont le suffixe (Juré⋅e)
|
||||
author_name += " (Juré⋅e)"
|
||||
elif registration in self.channel.pool.tournament.organizers.all():
|
||||
# Les organisateur⋅rices du tournoi ont le suffixe (CRO)
|
||||
author_name += " (CRO)"
|
||||
else:
|
||||
# Les éventuel⋅les autres bénévoles ont le suffixe (Bénévole)
|
||||
author_name += " (Bénévole)"
|
||||
elif self.channel.tournament:
|
||||
if registration in self.channel.tournament.organizers.all():
|
||||
# Les organisateur⋅rices du tournoi ont le suffixe (CRO)
|
||||
author_name += " (CRO)"
|
||||
elif any([registration.id == pool.jury_president
|
||||
for pool in self.channel.tournament.pools.all()]):
|
||||
# Les président⋅es de jury des poules ont le suffixe (P. jury)
|
||||
# mentionnant l'ensemble des poules qu'iels président
|
||||
pools = ", ".join([pool.short_name
|
||||
for pool in self.channel.tournament.pools.all()
|
||||
if pool.jury_president == registration])
|
||||
author_name += f" (P. jury {pools})"
|
||||
elif any([pool.juries.contains(registration)
|
||||
for pool in self.channel.tournament.pools.all()]):
|
||||
# Les juré⋅es des poules ont le suffixe (Juré⋅e)
|
||||
# mentionnant l'ensemble des poules auxquelles iels participent
|
||||
pools = ", ".join([pool.short_name
|
||||
for pool in self.channel.tournament.pools.all()
|
||||
if pool.juries.acontains(registration)])
|
||||
author_name += f" (Juré⋅e {pools})"
|
||||
else:
|
||||
# Les éventuel⋅les autres bénévoles ont le suffixe (Bénévole)
|
||||
author_name += " (Bénévole)"
|
||||
else:
|
||||
if registration.organized_tournaments.exists():
|
||||
# Les organisateur⋅rices de tournois ont le suffixe (CRO) mentionnant les tournois organisés
|
||||
tournaments = ", ".join([tournament.name
|
||||
for tournament in registration.organized_tournaments.all()])
|
||||
author_name += f" (CRO {tournaments})"
|
||||
if Pool.objects.filter(jury_president=registration).exists():
|
||||
# Les président⋅es de jury ont le suffixe (P. jury) mentionnant les tournois présidés
|
||||
tournaments = Tournament.objects.filter(pools__jury_president=registration).distinct()
|
||||
tournaments = ", ".join([tournament.name for tournament in tournaments])
|
||||
author_name += f" (P. jury {tournaments})"
|
||||
elif registration.jury_in.exists():
|
||||
# Les juré⋅es ont le suffixe (Juré⋅e) mentionnant les tournois auxquels iels participent
|
||||
tournaments = Tournament.objects.filter(pools__juries=registration).distinct()
|
||||
tournaments = ", ".join([tournament.name for tournament in tournaments])
|
||||
author_name += f" (Juré⋅e {tournaments})"
|
||||
else:
|
||||
if registration.team_id:
|
||||
# Le trigramme de l'équipe de læ participant⋅e est ajouté en suffixe
|
||||
team = Team.objects.get(id=registration.team_id)
|
||||
author_name += f" ({team.trigram})"
|
||||
else:
|
||||
@@ -264,7 +352,11 @@ class Message(models.Model):
|
||||
|
||||
return author_name
|
||||
|
||||
async def aget_author_name(self):
|
||||
async def aget_author_name(self) -> str:
|
||||
"""
|
||||
Fonction asynchrone pour récupérer le nom de l'auteur⋅rice du message.
|
||||
Voir `get_author_name` pour plus de détails.
|
||||
"""
|
||||
return await sync_to_async(self.get_author_name)()
|
||||
|
||||
class Meta:
|
||||
|
Reference in New Issue
Block a user