diff --git a/game/migrations/0009_alter_youtubecredentials_credentials.py b/game/migrations/0009_alter_youtubecredentials_credentials.py new file mode 100644 index 0000000..7c8ac8a --- /dev/null +++ b/game/migrations/0009_alter_youtubecredentials_credentials.py @@ -0,0 +1,17 @@ +# Generated by Django 5.2.3 on 2025-06-13 20:50 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("game", "0008_youtubecredentials"), + ] + + operations = [ + migrations.AlterField( + model_name="youtubecredentials", + name="credentials", + field=models.CharField(), + ), + ] diff --git a/game/migrations/0010_alter_youtubecredentials_credentials.py b/game/migrations/0010_alter_youtubecredentials_credentials.py new file mode 100644 index 0000000..8565c40 --- /dev/null +++ b/game/migrations/0010_alter_youtubecredentials_credentials.py @@ -0,0 +1,17 @@ +# Generated by Django 5.2.3 on 2025-06-13 20:58 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("game", "0009_alter_youtubecredentials_credentials"), + ] + + operations = [ + migrations.AlterField( + model_name="youtubecredentials", + name="credentials", + field=models.JSONField(), + ), + ] diff --git a/game/migrations/0011_musikgame_playlist.py b/game/migrations/0011_musikgame_playlist.py new file mode 100644 index 0000000..49b1132 --- /dev/null +++ b/game/migrations/0011_musikgame_playlist.py @@ -0,0 +1,17 @@ +# Generated by Django 5.2.3 on 2025-06-13 21:01 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("game", "0010_alter_youtubecredentials_credentials"), + ] + + operations = [ + migrations.AddField( + model_name="musikgame", + name="playlist", + field=models.URLField(blank=True, verbose_name="Playlist YouTube"), + ), + ] diff --git a/game/migrations/0012_alter_musikgame_playlist.py b/game/migrations/0012_alter_musikgame_playlist.py new file mode 100644 index 0000000..3c33e77 --- /dev/null +++ b/game/migrations/0012_alter_musikgame_playlist.py @@ -0,0 +1,17 @@ +# Generated by Django 5.2.3 on 2025-06-13 21:03 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("game", "0011_musikgame_playlist"), + ] + + operations = [ + migrations.AlterField( + model_name="musikgame", + name="playlist", + field=models.CharField(blank=True, verbose_name="Playlist YouTube"), + ), + ] diff --git a/game/models.py b/game/models.py index 25e905c..8383915 100644 --- a/game/models.py +++ b/game/models.py @@ -39,6 +39,7 @@ class MusikGame(models.Model): 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") def get_absolute_url(self): return reverse("game_detail", kwargs={"pk": self.pk}) diff --git a/game/templates/game/home.html b/game/templates/game/home.html index 6c78861..74352e1 100644 --- a/game/templates/game/home.html +++ b/game/templates/game/home.html @@ -2,7 +2,7 @@

Mes groupes

Créer un groupe - {% if not user.youtubecredentials %} + {% if not user.youtubecredentials.credentials %} Me connecter au compte Youtube {% endif %}

diff --git a/game/templates/game/musikgame_detail.html b/game/templates/game/musikgame_detail.html index 8a2d195..4d08293 100644 --- a/game/templates/game/musikgame_detail.html +++ b/game/templates/game/musikgame_detail.html @@ -3,6 +3,13 @@

{{ musikgame.date }}

+ {% if musikgame.playlist %} +

+ Playlist +

+ {% endif %}

Joueurs

diff --git a/game/views.py b/game/views.py index 38ec076..e84fe56 100644 --- a/game/views.py +++ b/game/views.py @@ -1,6 +1,8 @@ import random +import google.oauth2.credentials import google_auth_oauthlib +import googleapiclient.discovery from django.conf import settings from django.contrib.auth.mixins import LoginRequiredMixin from django.db.models import Count, Q @@ -131,6 +133,42 @@ class GameCreateView(LoginRequiredMixin, CreateView): models.MusicGameOrder.objects.create( game=form.instance, player=player, music_video=music, order=order ) + + if creds := self.request.user.youtubecredentials: + credentials = google.oauth2.credentials.Credentials(**creds.credentials) + yt_api = googleapiclient.discovery.build( + "youtube", "v3", credentials=credentials + ) + pl_request = yt_api.playlists().insert( + part="snippet,status", + body={ + "snippet": { + "title": f"Musik – {group.name} – {form.instance.date.strftime('%x')}", + "description": "Playlist générée par Musik", + }, + "status": { + "privacyStatus": "private", + }, + }, + ) + pl_response = pl_request.execute() + pl_id = pl_response.get("id") + form.instance.playlist = pl_id + form.instance.save() + for _, music in pm_list: + request = yt_api.playlistItems().insert( + part="snippet", + body={ + "snippet": { + "playlistId": pl_id, + "resourceId": { + "kind": "youtube#video", + "videoId": music.yt_id, + }, + } + }, + ) + request.execute() return res @@ -173,8 +211,18 @@ class YoutubeCallbackView(LoginRequiredMixin, View): flow.fetch_token(code=request.GET.get("code")) - credentials = models.YoutubeCredentials( - user=request.user, credentials=flow.credentials.to_json() + credentials = flow.credentials + models.YoutubeCredentials.objects.update_or_create( + user=request.user, + defaults={ + "credentials": { + "token": credentials.token, + "refresh_token": credentials.refresh_token, + "token_uri": credentials.token_uri, + "client_id": credentials.client_id, + "client_secret": credentials.client_secret, + "granted_scopes": credentials.granted_scopes, + } + }, ) - credentials.save() return redirect("/")