Add playlist field to MusikGame model and update YouTube credentials handling in views

This commit is contained in:
Edgar P. Burkhart 2025-06-13 23:08:41 +02:00
parent 4b2f695afb
commit 122ae40570
Signed by: edpibu
GPG key ID: 9833D3C5A25BD227
8 changed files with 128 additions and 4 deletions

View file

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

View file

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

View file

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

View file

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

View file

@ -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})

View file

@ -2,7 +2,7 @@
<h2>Mes groupes</h2>
<p>
<a href="{% url "group_create" %}" role="button"><i class="ri-add-box-fill"></i> Créer un groupe</a>
{% if not user.youtubecredentials %}
{% if not user.youtubecredentials.credentials %}
<a href="{% url "youtube_login" %}" role="button"><i class="ri-youtube-fill"></i> Me connecter au compte Youtube</a>
{% endif %}
</p>

View file

@ -3,6 +3,13 @@
<h1>
<i class="ri-play-circle-fill"></i> {{ musikgame.date }}
</h1>
{% if musikgame.playlist %}
<p>
<a target="_blank"
href="https://youtube.com/playlist?list={{ musikgame.playlist }}"
role="button"><i class="ri-youtube-fill"></i> Playlist</a>
</p>
{% endif %}
<h2>
<i class="ri-group-2-fill"></i> Joueurs
</h2>

View file

@ -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("/")