1
0
mirror of https://gitlab.com/animath/si/plateforme.git synced 2025-06-22 07:18:25 +02: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:
Emmy D'Anello
2024-04-28 13:50:04 +02:00
parent 784002c085
commit a5c210e9b6
10 changed files with 273 additions and 35 deletions

View File

@ -8,8 +8,8 @@ from .models import Channel, Message
@admin.register(Channel)
class ChannelAdmin(admin.ModelAdmin):
list_display = ('name', 'read_access', 'write_access', 'tournament', 'pool', 'team', 'private',)
list_filter = ('read_access', 'write_access', 'tournament', 'private',)
list_display = ('name', 'category', 'read_access', 'write_access', 'tournament', 'private',)
list_filter = ('category', 'read_access', 'write_access', 'tournament', 'private',)
search_fields = ('name', 'tournament__name', 'team__name', 'team__trigram',)
autocomplete_fields = ('tournament', 'pool', 'team', 'invited', )

View File

@ -3,7 +3,6 @@
from channels.generic.websocket import AsyncJsonWebsocketConsumer
from django.contrib.auth.models import User
from participation.models import Team, Pool, Tournament
from registration.models import Registration
from .models import Channel, Message
@ -78,6 +77,7 @@ class ChatConsumer(AsyncJsonWebsocketConsumer):
{
'id': channel.id,
'name': channel.name,
'category': channel.category,
'read_access': True,
'write_access': await write_channels.acontains(channel),
}

View File

View File

View 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,
),
)

View File

@ -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",
),
),
]

View File

@ -13,11 +13,24 @@ from tfjm.permissions import PermissionType
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(
max_length=255,
verbose_name=_("name"),
)
category = models.CharField(
max_length=255,
verbose_name=_("category"),
choices=ChannelCategory,
default=ChannelCategory.GENERAL,
)
read_access = models.CharField(
max_length=16,
verbose_name=_("read permission"),
@ -90,7 +103,7 @@ class Channel(models.Model):
return Channel.objects.filter(**{permission_type: PermissionType.ANONYMOUS})
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:
return Channel.objects.all()
@ -147,7 +160,7 @@ class Channel(models.Model):
class Meta:
verbose_name = _("channel")
verbose_name_plural = _("channels")
ordering = ('name',)
ordering = ('category', 'name',)
class Message(models.Model):

View File

@ -6,6 +6,7 @@
const MAX_MESSAGES = 50
const channel_categories = ['general', 'tournament', 'team', 'private']
let channels = {}
let messages = {}
let selected_channel_id = null
@ -62,20 +63,27 @@ function sendMessage() {
function setChannels(new_channels) {
channels = {}
let navTab = document.getElementById('nav-channels-tab')
navTab.innerHTML = ''
let categoryLists = {}
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) {
channels[channel['id']] = channel
if (!messages[channel['id']])
messages[channel['id']] = new Map()
let categoryList = categoryLists[channel['category']]
categoryList.parentElement.classList.remove('d-none')
let navItem = document.createElement('li')
navItem.classList.add('list-group-item')
navItem.id = `tab-channel-${channel['id']}`
navItem.setAttribute('data-bs-dismiss', 'offcanvas')
navItem.onclick = () => selectChannel(channel['id'])
navTab.appendChild(navItem)
categoryList.appendChild(navItem)
let channelButton = document.createElement('button')
channelButton.classList.add('nav-link')

View File

@ -3,13 +3,30 @@
<noscript>
{% trans "JavaScript must be enabled on your browser to access chat." %}
</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">
<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>
</div>
<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>