-{% if user.owned_group_set.exists or user.group_set.exists %}
- {% for group in user.owned_group_set.all %}
-
-
- {{ group.name }}
-
-
- {% endfor %}
- {% for group in user.group_set.all %}
-
-
- {{ group.name }} {{ group.owner }}
-
-
- {% endfor %}
-{% endif %}
+ {% inline_form group_form action="group_create" submit="Créer" %}
+{% endblock content %}
diff --git a/game/urls.py b/game/urls.py
index 2f4c3fa..ea51a07 100644
--- a/game/urls.py
+++ b/game/urls.py
@@ -3,6 +3,7 @@ from django.urls import path
from . import views
urlpatterns = [
+ path("home", views.HomeView.as_view(), name="home"),
path("group/create/", views.GroupCreateView.as_view(), name="group_create"),
path(
"group//update/", views.GroupUpdateView.as_view(), name="group_update"
diff --git a/game/views.py b/game/views.py
index ef10245..1581c8c 100644
--- a/game/views.py
+++ b/game/views.py
@@ -11,12 +11,22 @@ from django.db import IntegrityError
from django.db.models import Count, Q
from django.shortcuts import get_object_or_404, redirect
from django.views import View
+from django.views.generic import TemplateView
from django.views.generic.detail import DetailView, SingleObjectMixin
from django.views.generic.edit import CreateView, DeleteView, UpdateView
from . import forms, models, utils
+class HomeView(LoginRequiredMixin, TemplateView):
+ template_name = "game/home.html"
+
+ def get_context_data(self, **kwargs):
+ data = super().get_context_data(**kwargs)
+ data["group_form"] = forms.GroupForm()
+ return data
+
+
class OwnerFilterMixin(LoginRequiredMixin):
def get_queryset(self):
return super().get_queryset().filter(owner=self.request.user)
From c73ff2f16790f16c1b4c69311b5d41fcdff57503 Mon Sep 17 00:00:00 2001
From: "Edgar P. Burkhart"
Date: Sun, 15 Jun 2025 10:04:45 +0200
Subject: [PATCH 05/47] Refactor member query in GroupDetailView to filter by
group
---
game/views.py | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/game/views.py b/game/views.py
index 1581c8c..cec8875 100644
--- a/game/views.py
+++ b/game/views.py
@@ -81,7 +81,9 @@ class GroupDetailView(MemberFilterMixin, GroupMixin, DetailView):
.musicvideo_set.filter(owner=data["group"].owner, blacklisted=False)
.count()
)
- data["members"] = data["group"].members.through.objects.annotate(
+ data["members"] = models.Group.members.through.objects.filter(
+ group=data["group"]
+ ).annotate(
count=Count(
"user__musicvideo",
filter=Q(
From aafb7817c239d1141e6ab684bd7333338a138df8 Mon Sep 17 00:00:00 2001
From: "Edgar P. Burkhart"
Date: Sun, 15 Jun 2025 10:05:11 +0200
Subject: [PATCH 06/47] Bump version to 0.1.5 in pyproject.toml and uv.lock
---
pyproject.toml | 2 +-
uv.lock | 8 ++++----
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/pyproject.toml b/pyproject.toml
index 0b7faaa..ca8db5c 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -1,6 +1,6 @@
[project]
name = "musik"
-version = "0.1.4"
+version = "0.1.5"
description = "Le jeu de Musik."
readme = "README.md"
requires-python = ">=3.12"
diff --git a/uv.lock b/uv.lock
index 0f40f57..33d4f69 100644
--- a/uv.lock
+++ b/uv.lock
@@ -66,11 +66,11 @@ wheels = [
[[package]]
name = "certifi"
-version = "2025.4.26"
+version = "2025.6.15"
source = { registry = "https://pypi.org/simple" }
-sdist = { url = "https://files.pythonhosted.org/packages/e8/9e/c05b3920a3b7d20d3d3310465f50348e5b3694f4f88c6daf736eef3024c4/certifi-2025.4.26.tar.gz", hash = "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6", size = 160705, upload-time = "2025-04-26T02:12:29.51Z" }
+sdist = { url = "https://files.pythonhosted.org/packages/73/f7/f14b46d4bcd21092d7d3ccef689615220d8a08fb25e564b65d20738e672e/certifi-2025.6.15.tar.gz", hash = "sha256:d747aa5a8b9bbbb1bb8c22bb13e22bd1f18e9796defa16bab421f7f7a317323b", size = 158753, upload-time = "2025-06-15T02:45:51.329Z" }
wheels = [
- { url = "https://files.pythonhosted.org/packages/4a/7e/3db2bd1b1f9e95f7cddca6d6e75e2f2bd9f51b1246e546d88addca0106bd/certifi-2025.4.26-py3-none-any.whl", hash = "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3", size = 159618, upload-time = "2025-04-26T02:12:27.662Z" },
+ { url = "https://files.pythonhosted.org/packages/84/ae/320161bd181fc06471eed047ecce67b693fd7515b16d495d8932db763426/certifi-2025.6.15-py3-none-any.whl", hash = "sha256:2e0c7ce7cb5d8f8634ca55d2ba7e6ec2689a2fd6537d8dec1296a477a4910057", size = 157650, upload-time = "2025-06-15T02:45:49.977Z" },
]
[[package]]
@@ -423,7 +423,7 @@ wheels = [
[[package]]
name = "musik"
-version = "0.1.4"
+version = "0.1.5"
source = { virtual = "." }
dependencies = [
{ name = "celery" },
From da29634e579d32c797adbe56398ddb5d7d1a1dee Mon Sep 17 00:00:00 2001
From: "Edgar P. Burkhart"
Date: Sun, 15 Jun 2025 10:17:08 +0200
Subject: [PATCH 07/47] Update YouTube credentials handling to include channel
title in home template
---
game/templates/game/home.html | 2 ++
game/views.py | 10 +++++++++-
2 files changed, 11 insertions(+), 1 deletion(-)
diff --git a/game/templates/game/home.html b/game/templates/game/home.html
index fe97624..eb7e220 100644
--- a/game/templates/game/home.html
+++ b/game/templates/game/home.html
@@ -11,6 +11,8 @@
{% if not user.youtubecredentials.credentials %}
Me connecter au compte Youtube
+ {% else %}
+ Connecté au compte Youtube {{ user.youtubecredentials.credentials.channel_title }}.
{% endif %}
{% if user.owned_group_set.exists or user.group_set.exists %}
diff --git a/game/views.py b/game/views.py
index cec8875..cbcbdb8 100644
--- a/game/views.py
+++ b/game/views.py
@@ -1,6 +1,7 @@
import random
import google_auth_oauthlib
+import googleapiclient
from django.conf import settings
from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
@@ -363,6 +364,13 @@ class YoutubeCallbackView(LoginRequiredMixin, View):
flow.fetch_token(code=request.GET.get("code"))
credentials = flow.credentials
+
+ yt_api = googleapiclient.discovery.build(
+ "youtube", "v3", credentials=credentials
+ )
+ channel_request = yt_api.channels().list(part="snippet", mine=True)
+ res = channel_request.execute()
+
models.YoutubeCredentials.objects.update_or_create(
user=request.user,
defaults={
@@ -373,10 +381,10 @@ class YoutubeCallbackView(LoginRequiredMixin, View):
"client_id": credentials.client_id,
"client_secret": credentials.client_secret,
"granted_scopes": credentials.granted_scopes,
+ "channel_title": res["items"][0]["snippet"]["title"],
}
},
)
-
messages.add_message(request, messages.SUCCESS, "Connexion à Youtube réussie.")
return redirect("/")
From 28203bd630a2995ec1898a1a14ed15c65f582cb9 Mon Sep 17 00:00:00 2001
From: "Edgar P. Burkhart"
Date: Sun, 15 Jun 2025 10:19:46 +0200
Subject: [PATCH 08/47] Reorganize YouTube credentials display in home and form
templates for consistency
---
game/templates/game/home.html | 6 +++---
game/templates/game/musikgame_form.html | 7 +++++++
2 files changed, 10 insertions(+), 3 deletions(-)
diff --git a/game/templates/game/home.html b/game/templates/game/home.html
index eb7e220..27511b5 100644
--- a/game/templates/game/home.html
+++ b/game/templates/game/home.html
@@ -5,9 +5,6 @@
Musik
Bienvenue {{ user.username }} !
-
- Mes groupes
-
{% if not user.youtubecredentials.credentials %}
Me connecter au compte Youtube
@@ -15,6 +12,9 @@
Connecté au compte Youtube {{ user.youtubecredentials.credentials.channel_title }}.
{% endif %}
- {% if not user.youtubecredentials.credentials %}
- Me connecter au compte Youtube
+ {% if group.owner.youtubecredentials.credentials %}
+ Une playlist sera générée automatiquement sur le compte Youtube de {{ group.owner }} ({{ group.owner.youtubecredentials.title }}).
+ {% elif user == group.owner %}
+ Connecter mon compte Youtube
{% else %}
- Une playlist sera générée automatiquement sur le compte Youtube {{ user.youtubecredentials.title }}.
+ Aucune playlist Youtube ne sera générée car {{ group.owner }} n'a pas lié son compte Youtube.
{% endif %}
+ Musik Le jeu où ta playlist devient ton arme secrète !
+
+
+ Invite ta bande, ajoute tes sons fétiches, et c’est parti ! Une playlist Youtube apparaît, mélangeant les coups de cœur de tout le monde. Le jeu ? Écoute, devine qui a choisi quoi, et découvre les secrets musicaux de tes potes. Entre pièges, révélations et fous rires, Musik c’est le jeu parfait pour tester vos oreilles… et vos amitiés. Prêt à jouer le DJ incognito ?
+