mirror of
				https://gitlab.com/animath/si/plateforme.git
				synced 2025-11-04 03:02:14 +01:00 
			
		
		
		
	Add script to create channels per tournament, pools and teams. Put channels in categories
Signed-off-by: Emmy D'Anello <emmy.danello@animath.fr>
This commit is contained in:
		@@ -8,8 +8,8 @@ from .models import Channel, Message
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
@admin.register(Channel)
 | 
					@admin.register(Channel)
 | 
				
			||||||
class ChannelAdmin(admin.ModelAdmin):
 | 
					class ChannelAdmin(admin.ModelAdmin):
 | 
				
			||||||
    list_display = ('name', 'read_access', 'write_access', 'tournament', 'pool', 'team', 'private',)
 | 
					    list_display = ('name', 'category', 'read_access', 'write_access', 'tournament', 'private',)
 | 
				
			||||||
    list_filter = ('read_access', 'write_access', 'tournament', 'private',)
 | 
					    list_filter = ('category', 'read_access', 'write_access', 'tournament', 'private',)
 | 
				
			||||||
    search_fields = ('name', 'tournament__name', 'team__name', 'team__trigram',)
 | 
					    search_fields = ('name', 'tournament__name', 'team__name', 'team__trigram',)
 | 
				
			||||||
    autocomplete_fields = ('tournament', 'pool', 'team', 'invited', )
 | 
					    autocomplete_fields = ('tournament', 'pool', 'team', 'invited', )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,7 +3,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
from channels.generic.websocket import AsyncJsonWebsocketConsumer
 | 
					from channels.generic.websocket import AsyncJsonWebsocketConsumer
 | 
				
			||||||
from django.contrib.auth.models import User
 | 
					from django.contrib.auth.models import User
 | 
				
			||||||
from participation.models import Team, Pool, Tournament
 | 
					 | 
				
			||||||
from registration.models import Registration
 | 
					from registration.models import Registration
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from .models import Channel, Message
 | 
					from .models import Channel, Message
 | 
				
			||||||
@@ -78,6 +77,7 @@ class ChatConsumer(AsyncJsonWebsocketConsumer):
 | 
				
			|||||||
                {
 | 
					                {
 | 
				
			||||||
                    'id': channel.id,
 | 
					                    'id': channel.id,
 | 
				
			||||||
                    'name': channel.name,
 | 
					                    'name': channel.name,
 | 
				
			||||||
 | 
					                    'category': channel.category,
 | 
				
			||||||
                    'read_access': True,
 | 
					                    'read_access': True,
 | 
				
			||||||
                    'write_access': await write_channels.acontains(channel),
 | 
					                    'write_access': await write_channels.acontains(channel),
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										0
									
								
								chat/management/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								chat/management/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										0
									
								
								chat/management/commands/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								chat/management/commands/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										144
									
								
								chat/management/commands/create_chat_channels.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								chat/management/commands/create_chat_channels.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,144 @@
 | 
				
			|||||||
 | 
					# Copyright (C) 2024 by Animath
 | 
				
			||||||
 | 
					# SPDX-License-Identifier: GPL-3.0-or-later
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.core.management import BaseCommand
 | 
				
			||||||
 | 
					from django.utils.translation import activate
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from participation.models import Team, Tournament
 | 
				
			||||||
 | 
					from tfjm.permissions import PermissionType
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from ...models import Channel
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Command(BaseCommand):
 | 
				
			||||||
 | 
					    def handle(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        activate('fr')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Channel.objects.update_or_create(
 | 
				
			||||||
 | 
					            name="Annonces",
 | 
				
			||||||
 | 
					            defaults=dict(
 | 
				
			||||||
 | 
					                category=Channel.ChannelCategory.GENERAL,
 | 
				
			||||||
 | 
					                read_access=PermissionType.AUTHENTICATED,
 | 
				
			||||||
 | 
					                write_access=PermissionType.ADMIN,
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Channel.objects.update_or_create(
 | 
				
			||||||
 | 
					            name="Aide jurys et orgas",
 | 
				
			||||||
 | 
					            defaults=dict(
 | 
				
			||||||
 | 
					                category=Channel.ChannelCategory.GENERAL,
 | 
				
			||||||
 | 
					                read_access=PermissionType.VOLUNTEER,
 | 
				
			||||||
 | 
					                write_access=PermissionType.VOLUNTEER,
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Channel.objects.update_or_create(
 | 
				
			||||||
 | 
					            name="Général",
 | 
				
			||||||
 | 
					            defaults=dict(
 | 
				
			||||||
 | 
					                category=Channel.ChannelCategory.GENERAL,
 | 
				
			||||||
 | 
					                read_access=PermissionType.AUTHENTICATED,
 | 
				
			||||||
 | 
					                write_access=PermissionType.AUTHENTICATED,
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Channel.objects.update_or_create(
 | 
				
			||||||
 | 
					            name="Je cherche une équipe",
 | 
				
			||||||
 | 
					            defaults=dict(
 | 
				
			||||||
 | 
					                category=Channel.ChannelCategory.GENERAL,
 | 
				
			||||||
 | 
					                read_access=PermissionType.AUTHENTICATED,
 | 
				
			||||||
 | 
					                write_access=PermissionType.AUTHENTICATED,
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        Channel.objects.update_or_create(
 | 
				
			||||||
 | 
					            name="Détente",
 | 
				
			||||||
 | 
					            defaults=dict(
 | 
				
			||||||
 | 
					                category=Channel.ChannelCategory.GENERAL,
 | 
				
			||||||
 | 
					                read_access=PermissionType.AUTHENTICATED,
 | 
				
			||||||
 | 
					                write_access=PermissionType.AUTHENTICATED,
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for tournament in Tournament.objects.all():
 | 
				
			||||||
 | 
					            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,
 | 
				
			||||||
 | 
					                    ),
 | 
				
			||||||
 | 
					                )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                for pool in tournament.pools.all():
 | 
				
			||||||
 | 
					                    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,
 | 
				
			||||||
 | 
					                        ),
 | 
				
			||||||
 | 
					                    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for team in Team.objects.filter(participation__valid=True).all():
 | 
				
			||||||
 | 
					            Channel.objects.update_or_create(
 | 
				
			||||||
 | 
					                name=f"Équipe {team.trigram}",
 | 
				
			||||||
 | 
					                defaults=dict(
 | 
				
			||||||
 | 
					                    category=Channel.ChannelCategory.TEAM,
 | 
				
			||||||
 | 
					                    read_access=PermissionType.TEAM_MEMBER,
 | 
				
			||||||
 | 
					                    write_access=PermissionType.TEAM_MEMBER,
 | 
				
			||||||
 | 
					                    team=team,
 | 
				
			||||||
 | 
					                ),
 | 
				
			||||||
 | 
					            )
 | 
				
			||||||
@@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					# Generated by Django 5.0.3 on 2024-04-28 11:08
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.db import migrations, models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ("chat", "0001_initial"),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.AlterModelOptions(
 | 
				
			||||||
 | 
					            name="channel",
 | 
				
			||||||
 | 
					            options={
 | 
				
			||||||
 | 
					                "ordering": ("category", "name"),
 | 
				
			||||||
 | 
					                "verbose_name": "channel",
 | 
				
			||||||
 | 
					                "verbose_name_plural": "channels",
 | 
				
			||||||
 | 
					            },
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AddField(
 | 
				
			||||||
 | 
					            model_name="channel",
 | 
				
			||||||
 | 
					            name="category",
 | 
				
			||||||
 | 
					            field=models.CharField(
 | 
				
			||||||
 | 
					                choices=[
 | 
				
			||||||
 | 
					                    ("general", "General channels"),
 | 
				
			||||||
 | 
					                    ("tournament", "Tournament channels"),
 | 
				
			||||||
 | 
					                    ("team", "Team channels"),
 | 
				
			||||||
 | 
					                    ("private", "Private channels"),
 | 
				
			||||||
 | 
					                ],
 | 
				
			||||||
 | 
					                default="general",
 | 
				
			||||||
 | 
					                max_length=255,
 | 
				
			||||||
 | 
					                verbose_name="category",
 | 
				
			||||||
 | 
					            ),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
@@ -13,11 +13,24 @@ from tfjm.permissions import PermissionType
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Channel(models.Model):
 | 
					class Channel(models.Model):
 | 
				
			||||||
 | 
					    class ChannelCategory(models.TextChoices):
 | 
				
			||||||
 | 
					        GENERAL = 'general', _("General channels")
 | 
				
			||||||
 | 
					        TOURNAMENT = 'tournament', _("Tournament channels")
 | 
				
			||||||
 | 
					        TEAM = 'team', _("Team channels")
 | 
				
			||||||
 | 
					        PRIVATE = 'private', _("Private channels")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    name = models.CharField(
 | 
					    name = models.CharField(
 | 
				
			||||||
        max_length=255,
 | 
					        max_length=255,
 | 
				
			||||||
        verbose_name=_("name"),
 | 
					        verbose_name=_("name"),
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    category = models.CharField(
 | 
				
			||||||
 | 
					        max_length=255,
 | 
				
			||||||
 | 
					        verbose_name=_("category"),
 | 
				
			||||||
 | 
					        choices=ChannelCategory,
 | 
				
			||||||
 | 
					        default=ChannelCategory.GENERAL,
 | 
				
			||||||
 | 
					    )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    read_access = models.CharField(
 | 
					    read_access = models.CharField(
 | 
				
			||||||
        max_length=16,
 | 
					        max_length=16,
 | 
				
			||||||
        verbose_name=_("read permission"),
 | 
					        verbose_name=_("read permission"),
 | 
				
			||||||
@@ -90,7 +103,7 @@ class Channel(models.Model):
 | 
				
			|||||||
            return Channel.objects.filter(**{permission_type: PermissionType.ANONYMOUS})
 | 
					            return Channel.objects.filter(**{permission_type: PermissionType.ANONYMOUS})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        qs |= Channel.objects.filter(**{permission_type: PermissionType.AUTHENTICATED})
 | 
					        qs |= Channel.objects.filter(**{permission_type: PermissionType.AUTHENTICATED})
 | 
				
			||||||
        registration = await Registration.objects.aget(user_id=user.id)
 | 
					        registration = await Registration.objects.prefetch_related('user').aget(user_id=user.id)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if registration.is_admin:
 | 
					        if registration.is_admin:
 | 
				
			||||||
            return Channel.objects.all()
 | 
					            return Channel.objects.all()
 | 
				
			||||||
@@ -147,7 +160,7 @@ class Channel(models.Model):
 | 
				
			|||||||
    class Meta:
 | 
					    class Meta:
 | 
				
			||||||
        verbose_name = _("channel")
 | 
					        verbose_name = _("channel")
 | 
				
			||||||
        verbose_name_plural = _("channels")
 | 
					        verbose_name_plural = _("channels")
 | 
				
			||||||
        ordering = ('name',)
 | 
					        ordering = ('category', 'name',)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Message(models.Model):
 | 
					class Message(models.Model):
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,6 +6,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
const MAX_MESSAGES = 50
 | 
					const MAX_MESSAGES = 50
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const channel_categories = ['general', 'tournament', 'team', 'private']
 | 
				
			||||||
let channels = {}
 | 
					let channels = {}
 | 
				
			||||||
let messages = {}
 | 
					let messages = {}
 | 
				
			||||||
let selected_channel_id = null
 | 
					let selected_channel_id = null
 | 
				
			||||||
@@ -62,20 +63,27 @@ function sendMessage() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
function setChannels(new_channels) {
 | 
					function setChannels(new_channels) {
 | 
				
			||||||
    channels = {}
 | 
					    channels = {}
 | 
				
			||||||
    let navTab = document.getElementById('nav-channels-tab')
 | 
					    let categoryLists = {}
 | 
				
			||||||
    navTab.innerHTML = ''
 | 
					    for (let category of channel_categories) {
 | 
				
			||||||
 | 
					        categoryLists[category] = document.getElementById(`nav-${category}-channels-tab`)
 | 
				
			||||||
 | 
					        categoryLists[category].innerHTML = ''
 | 
				
			||||||
 | 
					        categoryLists[category].parentElement.classList.add('d-none')
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (let channel of new_channels) {
 | 
					    for (let channel of new_channels) {
 | 
				
			||||||
        channels[channel['id']] = channel
 | 
					        channels[channel['id']] = channel
 | 
				
			||||||
        if (!messages[channel['id']])
 | 
					        if (!messages[channel['id']])
 | 
				
			||||||
            messages[channel['id']] = new Map()
 | 
					            messages[channel['id']] = new Map()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let categoryList = categoryLists[channel['category']]
 | 
				
			||||||
 | 
					        categoryList.parentElement.classList.remove('d-none')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let navItem = document.createElement('li')
 | 
					        let navItem = document.createElement('li')
 | 
				
			||||||
        navItem.classList.add('list-group-item')
 | 
					        navItem.classList.add('list-group-item')
 | 
				
			||||||
        navItem.id = `tab-channel-${channel['id']}`
 | 
					        navItem.id = `tab-channel-${channel['id']}`
 | 
				
			||||||
        navItem.setAttribute('data-bs-dismiss', 'offcanvas')
 | 
					        navItem.setAttribute('data-bs-dismiss', 'offcanvas')
 | 
				
			||||||
        navItem.onclick = () => selectChannel(channel['id'])
 | 
					        navItem.onclick = () => selectChannel(channel['id'])
 | 
				
			||||||
        navTab.appendChild(navItem)
 | 
					        categoryList.appendChild(navItem)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let channelButton = document.createElement('button')
 | 
					        let channelButton = document.createElement('button')
 | 
				
			||||||
        channelButton.classList.add('nav-link')
 | 
					        channelButton.classList.add('nav-link')
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -3,13 +3,30 @@
 | 
				
			|||||||
<noscript>
 | 
					<noscript>
 | 
				
			||||||
    {% trans "JavaScript must be enabled on your browser to access chat." %}
 | 
					    {% trans "JavaScript must be enabled on your browser to access chat." %}
 | 
				
			||||||
</noscript>
 | 
					</noscript>
 | 
				
			||||||
<div class="offcanvas offcanvas-start" tabindex="-1" id="channelSelector" aria-labelledby="offcanvasExampleLabel">
 | 
					<div class="offcanvas offcanvas-start" tabindex="-1" id="channelSelector" aria-labelledby="offcanvasTitle">
 | 
				
			||||||
    <div class="offcanvas-header">
 | 
					    <div class="offcanvas-header">
 | 
				
			||||||
        <h4 class="offcanvas-title" id="offcanvasExampleLabel">{% trans "Chat channels" %}</h4>
 | 
					        <h3 class="offcanvas-title" id="offcanvasTitle">{% trans "Chat channels" %}</h3>
 | 
				
			||||||
        <button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
 | 
					        <button type="button" class="btn-close" data-bs-dismiss="offcanvas" aria-label="Close"></button>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
    <div class="offcanvas-body">
 | 
					    <div class="offcanvas-body">
 | 
				
			||||||
        <ul class="list-group list-group-flush" id="nav-channels-tab"></ul>
 | 
					        <ul class="list-group list-group-flush" id="nav-channels-tab">
 | 
				
			||||||
 | 
					            <li class="list-group-item d-none">
 | 
				
			||||||
 | 
					                <h4>{% trans "General channels" %}</h4>
 | 
				
			||||||
 | 
					                <ul class="list-group list-group-flush" id="nav-general-channels-tab"></ul>
 | 
				
			||||||
 | 
					            </li>
 | 
				
			||||||
 | 
					            <li class="list-group-item d-none">
 | 
				
			||||||
 | 
					                <h4>{% trans "Tournament channels" %}</h4>
 | 
				
			||||||
 | 
					                <ul class="list-group list-group-flush" id="nav-tournament-channels-tab"></ul>
 | 
				
			||||||
 | 
					            </li>
 | 
				
			||||||
 | 
					            <li class="list-group-item d-none">
 | 
				
			||||||
 | 
					                <h4>{% trans "Team channels" %}</h4>
 | 
				
			||||||
 | 
					                <ul class="list-group list-group-flush" id="nav-team-channels-tab"></ul>
 | 
				
			||||||
 | 
					            </li>
 | 
				
			||||||
 | 
					            <li class="list-group-item d-none">
 | 
				
			||||||
 | 
					                <h4>{% trans "Private channels" %}</h4>
 | 
				
			||||||
 | 
					                <ul class="list-group list-group-flush" id="nav-private-channels-tab"></ul>
 | 
				
			||||||
 | 
					            </li>
 | 
				
			||||||
 | 
					        </ul>
 | 
				
			||||||
    </div>
 | 
					    </div>
 | 
				
			||||||
</div>
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -7,7 +7,7 @@ msgid ""
 | 
				
			|||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
"Project-Id-Version: TFJM\n"
 | 
					"Project-Id-Version: TFJM\n"
 | 
				
			||||||
"Report-Msgid-Bugs-To: \n"
 | 
					"Report-Msgid-Bugs-To: \n"
 | 
				
			||||||
"POT-Creation-Date: 2024-04-28 11:56+0200\n"
 | 
					"POT-Creation-Date: 2024-04-28 13:08+0200\n"
 | 
				
			||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 | 
					"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
 | 
				
			||||||
"Last-Translator: Emmy D'Anello <emmy.danello@animath.fr>\n"
 | 
					"Last-Translator: Emmy D'Anello <emmy.danello@animath.fr>\n"
 | 
				
			||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
 | 
					"Language-Team: LANGUAGE <LL@li.org>\n"
 | 
				
			||||||
@@ -21,20 +21,40 @@ msgstr ""
 | 
				
			|||||||
msgid "API"
 | 
					msgid "API"
 | 
				
			||||||
msgstr "API"
 | 
					msgstr "API"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: chat/models.py:18 participation/models.py:35 participation/models.py:263
 | 
					#: chat/models.py:17
 | 
				
			||||||
 | 
					msgid "General channels"
 | 
				
			||||||
 | 
					msgstr "Canaux généraux"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: chat/models.py:18
 | 
				
			||||||
 | 
					msgid "Tournament channels"
 | 
				
			||||||
 | 
					msgstr "Canaux de tournois"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: chat/models.py:19
 | 
				
			||||||
 | 
					msgid "Team channels"
 | 
				
			||||||
 | 
					msgstr "Canaux d'équipes"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: chat/models.py:20
 | 
				
			||||||
 | 
					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
 | 
					#: participation/tables.py:18 participation/tables.py:34
 | 
				
			||||||
msgid "name"
 | 
					msgid "name"
 | 
				
			||||||
msgstr "nom"
 | 
					msgstr "nom"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: chat/models.py:23
 | 
					#: chat/models.py:29
 | 
				
			||||||
 | 
					msgid "category"
 | 
				
			||||||
 | 
					msgstr "catégorie"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#: chat/models.py:36
 | 
				
			||||||
msgid "read permission"
 | 
					msgid "read permission"
 | 
				
			||||||
msgstr "permission de lecture"
 | 
					msgstr "permission de lecture"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: chat/models.py:29
 | 
					#: chat/models.py:42
 | 
				
			||||||
msgid "write permission"
 | 
					msgid "write permission"
 | 
				
			||||||
msgstr "permission d'écriture"
 | 
					msgstr "permission d'écriture"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: chat/models.py:39 draw/admin.py:53 draw/admin.py:71 draw/admin.py:88
 | 
					#: 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
 | 
					#: draw/models.py:26 participation/admin.py:79 participation/admin.py:140
 | 
				
			||||||
#: participation/admin.py:171 participation/models.py:693
 | 
					#: participation/admin.py:171 participation/models.py:693
 | 
				
			||||||
#: participation/models.py:717 participation/models.py:935
 | 
					#: participation/models.py:717 participation/models.py:935
 | 
				
			||||||
@@ -43,7 +63,7 @@ msgstr "permission d'écriture"
 | 
				
			|||||||
msgid "tournament"
 | 
					msgid "tournament"
 | 
				
			||||||
msgstr "tournoi"
 | 
					msgstr "tournoi"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: chat/models.py:41
 | 
					#: chat/models.py:54
 | 
				
			||||||
msgid ""
 | 
					msgid ""
 | 
				
			||||||
"For a permission that concerns a tournament, indicates what is the concerned "
 | 
					"For a permission that concerns a tournament, indicates what is the concerned "
 | 
				
			||||||
"tournament."
 | 
					"tournament."
 | 
				
			||||||
@@ -51,21 +71,21 @@ msgstr ""
 | 
				
			|||||||
"Pour une permission qui concerne un tournoi, indique quel est le tournoi "
 | 
					"Pour une permission qui concerne un tournoi, indique quel est le tournoi "
 | 
				
			||||||
"concerné."
 | 
					"concerné."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: chat/models.py:50 draw/models.py:429 draw/models.py:456
 | 
					#: chat/models.py:63 draw/models.py:429 draw/models.py:456
 | 
				
			||||||
#: participation/admin.py:136 participation/admin.py:155
 | 
					#: participation/admin.py:136 participation/admin.py:155
 | 
				
			||||||
#: participation/models.py:1434 participation/models.py:1443
 | 
					#: participation/models.py:1434 participation/models.py:1443
 | 
				
			||||||
#: participation/tables.py:84
 | 
					#: participation/tables.py:84
 | 
				
			||||||
msgid "pool"
 | 
					msgid "pool"
 | 
				
			||||||
msgstr "poule"
 | 
					msgstr "poule"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: chat/models.py:52
 | 
					#: chat/models.py:65
 | 
				
			||||||
msgid ""
 | 
					msgid ""
 | 
				
			||||||
"For a permission that concerns a pool, indicates what is the concerned pool."
 | 
					"For a permission that concerns a pool, indicates what is the concerned pool."
 | 
				
			||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
"Pour une permission qui concerne une poule, indique quelle est la poule "
 | 
					"Pour une permission qui concerne une poule, indique quelle est la poule "
 | 
				
			||||||
"concernée."
 | 
					"concernée."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: chat/models.py:61 draw/templates/draw/tournament_content.html:277
 | 
					#: chat/models.py:74 draw/templates/draw/tournament_content.html:277
 | 
				
			||||||
#: participation/admin.py:167 participation/models.py:252
 | 
					#: participation/admin.py:167 participation/models.py:252
 | 
				
			||||||
#: participation/models.py:708
 | 
					#: participation/models.py:708
 | 
				
			||||||
#: participation/templates/participation/tournament_harmonize.html:15
 | 
					#: participation/templates/participation/tournament_harmonize.html:15
 | 
				
			||||||
@@ -75,18 +95,18 @@ msgstr ""
 | 
				
			|||||||
msgid "team"
 | 
					msgid "team"
 | 
				
			||||||
msgstr "équipe"
 | 
					msgstr "équipe"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: chat/models.py:63
 | 
					#: chat/models.py:76
 | 
				
			||||||
msgid ""
 | 
					msgid ""
 | 
				
			||||||
"For a permission that concerns a team, indicates what is the concerned team."
 | 
					"For a permission that concerns a team, indicates what is the concerned team."
 | 
				
			||||||
msgstr ""
 | 
					msgstr ""
 | 
				
			||||||
"Pour une permission qui concerne une équipe, indique quelle est l'équipe "
 | 
					"Pour une permission qui concerne une équipe, indique quelle est l'équipe "
 | 
				
			||||||
"concernée."
 | 
					"concernée."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: chat/models.py:67
 | 
					#: chat/models.py:80
 | 
				
			||||||
msgid "private"
 | 
					msgid "private"
 | 
				
			||||||
msgstr "privé"
 | 
					msgstr "privé"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: chat/models.py:69
 | 
					#: chat/models.py:82
 | 
				
			||||||
msgid ""
 | 
					msgid ""
 | 
				
			||||||
"If checked, only users who have been explicitly added to the channel will be "
 | 
					"If checked, only users who have been explicitly added to the channel will be "
 | 
				
			||||||
"able to access it."
 | 
					"able to access it."
 | 
				
			||||||
@@ -94,11 +114,11 @@ msgstr ""
 | 
				
			|||||||
"Si sélectionné, seul⋅es les utilisateur⋅rices qui ont été explicitement "
 | 
					"Si sélectionné, seul⋅es les utilisateur⋅rices qui ont été explicitement "
 | 
				
			||||||
"ajouté⋅es au canal pourront y accéder."
 | 
					"ajouté⋅es au canal pourront y accéder."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: chat/models.py:74
 | 
					#: chat/models.py:87
 | 
				
			||||||
msgid "invited users"
 | 
					msgid "invited users"
 | 
				
			||||||
msgstr "Utilisateur⋅rices invité"
 | 
					msgstr "Utilisateur⋅rices invité"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: chat/models.py:77
 | 
					#: chat/models.py:90
 | 
				
			||||||
msgid ""
 | 
					msgid ""
 | 
				
			||||||
"Extra users who have been invited to the channel, in addition to the "
 | 
					"Extra users who have been invited to the channel, in addition to the "
 | 
				
			||||||
"permitted group of the channel."
 | 
					"permitted group of the channel."
 | 
				
			||||||
@@ -106,40 +126,40 @@ msgstr ""
 | 
				
			|||||||
"Utilisateur⋅rices supplémentaires qui ont été invité⋅es au canal, en plus du "
 | 
					"Utilisateur⋅rices supplémentaires qui ont été invité⋅es au canal, en plus du "
 | 
				
			||||||
"groupe autorisé du canal."
 | 
					"groupe autorisé du canal."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: chat/models.py:82
 | 
					#: chat/models.py:95
 | 
				
			||||||
#, python-brace-format
 | 
					#, python-brace-format
 | 
				
			||||||
msgid "Channel {name}"
 | 
					msgid "Channel {name}"
 | 
				
			||||||
msgstr "Canal {name}"
 | 
					msgstr "Canal {name}"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: chat/models.py:148 chat/models.py:157
 | 
					#: chat/models.py:161 chat/models.py:170
 | 
				
			||||||
msgid "channel"
 | 
					msgid "channel"
 | 
				
			||||||
msgstr "canal"
 | 
					msgstr "canal"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: chat/models.py:149
 | 
					#: chat/models.py:162
 | 
				
			||||||
msgid "channels"
 | 
					msgid "channels"
 | 
				
			||||||
msgstr "canaux"
 | 
					msgstr "canaux"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: chat/models.py:163
 | 
					#: chat/models.py:176
 | 
				
			||||||
msgid "author"
 | 
					msgid "author"
 | 
				
			||||||
msgstr "auteur⋅rice"
 | 
					msgstr "auteur⋅rice"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: chat/models.py:170
 | 
					#: chat/models.py:183
 | 
				
			||||||
msgid "created at"
 | 
					msgid "created at"
 | 
				
			||||||
msgstr "créé le"
 | 
					msgstr "créé le"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: chat/models.py:175
 | 
					#: chat/models.py:188
 | 
				
			||||||
msgid "updated at"
 | 
					msgid "updated at"
 | 
				
			||||||
msgstr "modifié le"
 | 
					msgstr "modifié le"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: chat/models.py:180
 | 
					#: chat/models.py:193
 | 
				
			||||||
msgid "content"
 | 
					msgid "content"
 | 
				
			||||||
msgstr "contenu"
 | 
					msgstr "contenu"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: chat/models.py:243
 | 
					#: chat/models.py:256
 | 
				
			||||||
msgid "message"
 | 
					msgid "message"
 | 
				
			||||||
msgstr "message"
 | 
					msgstr "message"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: chat/models.py:244
 | 
					#: chat/models.py:257
 | 
				
			||||||
msgid "messages"
 | 
					msgid "messages"
 | 
				
			||||||
msgstr "messages"
 | 
					msgstr "messages"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -171,7 +191,7 @@ msgstr "Déconnexion"
 | 
				
			|||||||
msgid "Install app on home screen"
 | 
					msgid "Install app on home screen"
 | 
				
			||||||
msgstr "Installer l'application sur l'écran d'accueil"
 | 
					msgstr "Installer l'application sur l'écran d'accueil"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#: chat/templates/chat/content.html:54
 | 
					#: chat/templates/chat/content.html:55
 | 
				
			||||||
msgid "Fetch previous messages…"
 | 
					msgid "Fetch previous messages…"
 | 
				
			||||||
msgstr "Récupérer les messages précédents…"
 | 
					msgstr "Récupérer les messages précédents…"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user