from django.contrib.auth.models import User from django.db import models from django.db.models.functions import Lower from django.db.models.signals import post_delete, post_save from django.dispatch import receiver from django.urls import reverse from . import tasks class YoutubeCredentials(models.Model): user = models.OneToOneField(User, on_delete=models.CASCADE) credentials = models.JSONField() class Group(models.Model): name = models.CharField(verbose_name="Nom du groupe") owner = models.ForeignKey( User, on_delete=models.CASCADE, related_name="owned_group_set" ) members = models.ManyToManyField(User, blank=True) def get_absolute_url(self): return reverse("group_detail", kwargs={"pk": self.pk}) def is_owner(self, user): return user == self.owner def is_leader(self, user): return ( self.is_owner(user) or self.members.through.objects.filter( lead__is_leader=True, user=user ).exists() ) def is_member(self, user): return self.is_owner(user) or self.members.filter(user=user).exists() class Meta: constraints = [ models.UniqueConstraint(Lower("name"), "owner", name="unique_group_name") ] class GroupLeader(models.Model): member = models.OneToOneField( Group.members.through, on_delete=models.CASCADE, related_name="lead" ) is_leader = models.BooleanField(default=False) class MusicVideo(models.Model): yt_id = models.CharField(max_length=16) title = models.CharField(blank=True) date_added = models.DateTimeField(auto_now_add=True) owner = models.ForeignKey(User, on_delete=models.CASCADE) group = models.ForeignKey(Group, on_delete=models.CASCADE) blacklisted = models.BooleanField(default=False) class Meta: constraints = [ models.UniqueConstraint( fields=("yt_id", "owner", "group"), name="unique_music_in_group" ) ] class MusikGame(models.Model): group = models.ForeignKey(Group, on_delete=models.CASCADE) date = models.DateTimeField(auto_now_add=True) n = models.PositiveIntegerField(default=2, verbose_name="Nombre de musiques") players = models.ManyToManyField(User, verbose_name="Joueurs") playlist = models.CharField(blank=True, verbose_name="Playlist YouTube") playlist_loading = models.BooleanField(default=False) def get_absolute_url(self): return reverse("game_detail", kwargs={"pk": self.pk}) @receiver(post_save, sender=MusikGame) def generateYoutubePlaylist(sender, instance, created, **kwargs): if not instance.playlist_loading or instance.playlist: return if creds := instance.group.owner.youtubecredentials: tasks.generate_playlist.delay_on_commit(creds.credentials, instance.pk) @receiver(post_delete, sender=MusikGame) def deleteYoutubePlaylist(sender, instance, using, **kwargs): if not instance.playlist: return if creds := instance.group.owner.youtubecredentials: tasks.delete_playlist.delay_on_commit(creds.credentials, instance.playlist) class MusicGameOrder(models.Model): game = models.ForeignKey(MusikGame, on_delete=models.CASCADE) player = models.ForeignKey(User, on_delete=models.CASCADE) music_video = models.ForeignKey(MusicVideo, on_delete=models.CASCADE) order = models.PositiveIntegerField() class Meta: constraints = [ models.UniqueConstraint( fields=("game", "player", "music_video"), name="unique_music_in_game" ), models.UniqueConstraint(fields=("game", "order"), name="unique_order"), ] ordering = ["order"]