2020-09-27 12:32:05 +00:00
|
|
|
import re
|
|
|
|
|
2020-10-09 11:58:42 +00:00
|
|
|
from corres2math.lists import get_sympa_client
|
2020-09-27 12:32:05 +00:00
|
|
|
from django.core.exceptions import ObjectDoesNotExist
|
2020-09-21 15:53:07 +00:00
|
|
|
from django.core.validators import RegexValidator
|
2020-09-21 13:41:55 +00:00
|
|
|
from django.db import models
|
2020-09-21 15:53:07 +00:00
|
|
|
from django.db.models import Index
|
2020-10-15 12:55:45 +00:00
|
|
|
from django.urls import reverse_lazy
|
2020-09-23 21:20:44 +00:00
|
|
|
from django.utils.crypto import get_random_string
|
2020-09-24 09:15:54 +00:00
|
|
|
from django.utils.text import format_lazy
|
2020-09-21 15:53:07 +00:00
|
|
|
from django.utils.translation import gettext_lazy as _
|
2020-09-21 13:41:55 +00:00
|
|
|
|
2020-09-21 15:53:07 +00:00
|
|
|
|
|
|
|
class Team(models.Model):
|
|
|
|
name = models.CharField(
|
|
|
|
max_length=255,
|
|
|
|
verbose_name=_("name"),
|
|
|
|
unique=True,
|
|
|
|
)
|
|
|
|
|
|
|
|
trigram = models.CharField(
|
|
|
|
max_length=3,
|
|
|
|
verbose_name=_("trigram"),
|
2020-09-23 21:20:44 +00:00
|
|
|
help_text=_("The trigram must be composed of three uppercase letters."),
|
2020-09-21 15:53:07 +00:00
|
|
|
unique=True,
|
|
|
|
validators=[RegexValidator("[A-Z]{3}")],
|
|
|
|
)
|
|
|
|
|
|
|
|
access_code = models.CharField(
|
|
|
|
max_length=6,
|
|
|
|
verbose_name=_("access code"),
|
|
|
|
help_text=_("The access code let other people to join the team."),
|
|
|
|
)
|
|
|
|
|
2020-09-22 16:24:51 +00:00
|
|
|
grant_animath_access_videos = models.BooleanField(
|
|
|
|
verbose_name=_("Grant Animath to publish my video"),
|
|
|
|
help_text=_("Give the authorisation to publish the video on the main website to promote the action."),
|
|
|
|
default=False,
|
|
|
|
)
|
|
|
|
|
2020-10-09 11:49:09 +00:00
|
|
|
def create_mailing_list(self):
|
|
|
|
get_sympa_client().create_list(
|
|
|
|
f"equipe-{self.trigram.lower()}",
|
|
|
|
f"Équipe {self.name} ({self.trigram})",
|
|
|
|
"hotline", # TODO Use a custom sympa template
|
|
|
|
f"Liste de diffusion pour contacter l'équipe {self.name} des Correspondances",
|
|
|
|
"education",
|
|
|
|
)
|
|
|
|
|
|
|
|
def delete_mailing_list(self):
|
|
|
|
get_sympa_client().delete_list(f"equipe-{self.trigram}")
|
|
|
|
|
2020-09-23 21:20:44 +00:00
|
|
|
def save(self, *args, **kwargs):
|
|
|
|
if not self.access_code:
|
|
|
|
self.access_code = get_random_string(6)
|
2020-10-09 11:49:09 +00:00
|
|
|
self.create_mailing_list()
|
2020-10-11 15:10:59 +00:00
|
|
|
|
2020-09-23 21:20:44 +00:00
|
|
|
return super().save(*args, **kwargs)
|
|
|
|
|
2020-10-15 10:57:20 +00:00
|
|
|
def get_absolute_url(self):
|
|
|
|
return reverse_lazy("participation:team_detail", args=(self.pk,))
|
|
|
|
|
2020-09-21 15:53:07 +00:00
|
|
|
def __str__(self):
|
|
|
|
return _("Team {name} ({trigram})").format(name=self.name, trigram=self.trigram)
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
verbose_name = _("team")
|
|
|
|
verbose_name_plural = _("teams")
|
|
|
|
indexes = [
|
|
|
|
Index(fields=("trigram", )),
|
|
|
|
]
|
|
|
|
|
|
|
|
|
|
|
|
class Participation(models.Model):
|
|
|
|
team = models.OneToOneField(
|
|
|
|
Team,
|
|
|
|
on_delete=models.CASCADE,
|
|
|
|
verbose_name=_("team"),
|
|
|
|
)
|
|
|
|
|
|
|
|
problem = models.IntegerField(
|
2020-09-24 09:15:54 +00:00
|
|
|
choices=[(i, format_lazy(_("Problem #{problem:d}"), problem=i)) for i in range(1, 5)],
|
2020-09-21 15:53:07 +00:00
|
|
|
null=True,
|
|
|
|
default=None,
|
|
|
|
verbose_name=_("problem number"),
|
|
|
|
)
|
|
|
|
|
2020-10-11 14:00:43 +00:00
|
|
|
valid = models.BooleanField(
|
|
|
|
null=True,
|
|
|
|
default=None,
|
|
|
|
verbose_name=_("valid"),
|
|
|
|
help_text=_("The video got the validation of the administrators."),
|
|
|
|
)
|
|
|
|
|
2020-09-27 12:32:05 +00:00
|
|
|
solution = models.OneToOneField(
|
2020-09-21 15:53:07 +00:00
|
|
|
"participation.Video",
|
|
|
|
on_delete=models.SET_NULL,
|
2020-09-27 12:32:05 +00:00
|
|
|
related_name="participation_solution",
|
2020-09-21 15:53:07 +00:00
|
|
|
null=True,
|
|
|
|
default=None,
|
|
|
|
verbose_name=_("solution video"),
|
|
|
|
)
|
|
|
|
|
|
|
|
received_participation = models.OneToOneField(
|
|
|
|
"participation.Participation",
|
|
|
|
on_delete=models.PROTECT,
|
|
|
|
related_name="sent_participation",
|
|
|
|
null=True,
|
|
|
|
default=None,
|
|
|
|
verbose_name=_("received participation"),
|
|
|
|
)
|
|
|
|
|
2020-09-27 12:32:05 +00:00
|
|
|
synthesis = models.OneToOneField(
|
2020-09-21 15:53:07 +00:00
|
|
|
"participation.Video",
|
|
|
|
on_delete=models.SET_NULL,
|
2020-09-27 12:32:05 +00:00
|
|
|
related_name="participation_synthesis",
|
2020-09-21 15:53:07 +00:00
|
|
|
null=True,
|
|
|
|
default=None,
|
|
|
|
verbose_name=_("synthesis video"),
|
|
|
|
)
|
|
|
|
|
2020-10-15 10:57:20 +00:00
|
|
|
def get_absolute_url(self):
|
2020-10-15 12:55:45 +00:00
|
|
|
return reverse_lazy("participation:participation_detail", args=(self.pk,))
|
2020-10-15 10:57:20 +00:00
|
|
|
|
2020-09-21 15:53:07 +00:00
|
|
|
def __str__(self):
|
|
|
|
return _("Participation of the team {name} ({trigram})").format(name=self.team.name, trigram=self.team.trigram)
|
|
|
|
|
|
|
|
class Meta:
|
|
|
|
verbose_name = _("participation")
|
|
|
|
verbose_name_plural = _("participations")
|
|
|
|
|
|
|
|
|
|
|
|
class Video(models.Model):
|
|
|
|
link = models.URLField(
|
|
|
|
verbose_name=_("link"),
|
|
|
|
help_text=_("The full video link."),
|
|
|
|
)
|
|
|
|
|
|
|
|
valid = models.BooleanField(
|
|
|
|
null=True,
|
|
|
|
default=None,
|
|
|
|
verbose_name=_("valid"),
|
|
|
|
help_text=_("The video got the validation of the administrators."),
|
|
|
|
)
|
|
|
|
|
2020-09-27 12:32:05 +00:00
|
|
|
@property
|
|
|
|
def participation(self):
|
|
|
|
try:
|
|
|
|
return self.participation_solution
|
|
|
|
except ObjectDoesNotExist:
|
|
|
|
return self.participation_synthesis
|
|
|
|
|
|
|
|
@property
|
|
|
|
def platform(self):
|
|
|
|
if "youtube.com" in self.link or "youtu.be" in self.link:
|
|
|
|
return "youtube"
|
|
|
|
return "unknown"
|
|
|
|
|
|
|
|
@property
|
|
|
|
def youtube_code(self):
|
|
|
|
return re.compile("(https?://|)(www\\.|)(youtube\\.com/watch\\?v=|youtu\\.be/)([a-zA-Z0-9-_]*)?.*?")\
|
|
|
|
.match("https://www.youtube.com/watch?v=73nsrixx7eI").group(4)
|
|
|
|
|
2020-09-21 15:53:07 +00:00
|
|
|
def __str__(self):
|
|
|
|
return _("Video of team {name} ({trigram})")\
|
2020-09-24 09:44:43 +00:00
|
|
|
.format(name=self.participation.team.name, trigram=self.participation.team.trigram)
|
2020-09-21 15:53:07 +00:00
|
|
|
|
|
|
|
class Meta:
|
|
|
|
verbose_name = _("video")
|
|
|
|
verbose_name_plural = _("videos")
|