From 1bacafd8b2973a2e75df9c6bbbe3f44b3e60b7a7 Mon Sep 17 00:00:00 2001 From: Mark Hoekveen Date: Tue, 23 Jul 2024 00:59:06 +0200 Subject: [PATCH] old playlist imports --- playlist/admin.py | 16 +++++++- playlist/models/track.py | 11 +++--- playlist/spotify.py | 11 ++++++ playlist/templates/Settings.html | 7 ++++ playlist/urls.py | 1 + playlist/utils.py | 32 +++++++++++++++- playlist/views.py | 65 ++++++++++++++++++-------------- 7 files changed, 107 insertions(+), 36 deletions(-) diff --git a/playlist/admin.py b/playlist/admin.py index d3c7142..b832f3d 100644 --- a/playlist/admin.py +++ b/playlist/admin.py @@ -1,4 +1,6 @@ from django.contrib import admin +from django.utils.http import urlencode +from django.shortcuts import redirect from .models import Track, Artist, Album, Background, Vote, Profile class TrackAdmin(admin.ModelAdmin): @@ -13,8 +15,20 @@ class VoteAdmin(admin.ModelAdmin): pass class ProfileAdmin(admin.ModelAdmin): pass +class AllTrackAdmin(admin.ModelAdmin): + list_display = ["name", "artist", "old", "from_playlist"] + list_filter = ["old", "from_playlist"] + def get_queryset(self, request): + return (Track.all_tracks.all()) + def changelist_view(self, request, extra_context=None): + if 'old__exact' not in request.GET: + default_filter = urlencode({'old__exact': '0'}) # 'True' or 'False' + return redirect(f"{request.path}?{default_filter}") + return super().changelist_view(request, extra_context=extra_context) -admin.site.register(Track, TrackAdmin) + +#admin.site.register(Track, TrackAdmin) +admin.site.register(Track, AllTrackAdmin) admin.site.register(Artist, ArtistAdmin) admin.site.register(Album, AlbumAdmin) admin.site.register(Background, BackgroundAdmin) diff --git a/playlist/models/track.py b/playlist/models/track.py index 3a3516e..a5b105a 100644 --- a/playlist/models/track.py +++ b/playlist/models/track.py @@ -45,19 +45,20 @@ class Track(models.Model): id = models.CharField(primary_key=True, max_length=128) - nominated_by = models.ForeignKey(User, null=True, default=None, on_delete=models.SET_NULL) + nominated_by = models.ForeignKey(User, blank=True, null=True, default=None, on_delete=models.SET_NULL) name = models.CharField(max_length=255) artists = models.ManyToManyField(Artist) - album = models.ForeignKey(Album, null=True, on_delete=models.SET_NULL) + album = models.ForeignKey(Album, blank=True, null=True, on_delete=models.SET_NULL) explicit = models.BooleanField(default=False) - duration_ms = models.PositiveIntegerField(null=True) - popularity = models.PositiveIntegerField(null=True) + duration_ms = models.PositiveIntegerField(blank=True, null=True) + popularity = models.PositiveIntegerField(blank=True, null=True) - banter = models.TextField(blank=True) + banter = models.TextField(null=True, blank=True) banter_done = models.BooleanField(default=False) old = models.BooleanField(default=False) + from_playlist = models.CharField(max_length=255, null=True, blank=True, default=None) objects = TrackManager() all_tracks = models.Manager() diff --git a/playlist/spotify.py b/playlist/spotify.py index ee530be..8eb2658 100644 --- a/playlist/spotify.py +++ b/playlist/spotify.py @@ -91,4 +91,15 @@ class Spotify(): r.raise_for_status() return r.json() + def get_playlist_info(self, playlist_id): + token = self.get_system_token() + url = 'https://api.spotify.com/v1/playlists/' + playlist_id + headers = { + 'Content-Type': 'application/json', + 'Authorization': 'Bearer ' + token + } + r = requests.get(url, headers=headers) + r.raise_for_status() + return r.json() + spt = Spotify() \ No newline at end of file diff --git a/playlist/templates/Settings.html b/playlist/templates/Settings.html index 496ed49..df858d0 100644 --- a/playlist/templates/Settings.html +++ b/playlist/templates/Settings.html @@ -13,6 +13,13 @@ Instellingen +
+ {% csrf_token %} +

Geef een playlist url om oude nummers te importeren:

+ + +
+ {% comment %} {% if sptDisplayName %}
{% csrf_token %} diff --git a/playlist/urls.py b/playlist/urls.py index f7d4d77..03218a5 100644 --- a/playlist/urls.py +++ b/playlist/urls.py @@ -9,6 +9,7 @@ urlpatterns = [ path('vote/undo', views.UndoView.as_view(), name="undo"), path('vote/skip', views.SkipView.as_view(), name="skip"), path('settings/', views.SettingsView.as_view(), name="settings"), + path('settings/playlist-import', views.PlaylistImportView.as_view(), name="playlist-import"), path('overview/', views.OverView.as_view(), name="overview"), path('overview/playlist', views.PlaylistListView.as_view(), name="playlist-list"), path('overview/playlist/', views.PlaylistDetailView.as_view(), name="playlist-detail"), diff --git a/playlist/utils.py b/playlist/utils.py index 788beba..1298079 100644 --- a/playlist/utils.py +++ b/playlist/utils.py @@ -1,4 +1,4 @@ -from .models import Track, Vote +from .models import Track, Vote, Album, Artist from random import choice, seed def from_json(cls, json): @@ -25,3 +25,33 @@ def get_unvoted(user): return (Track.objects.get(pk=random_track), skipped) except IndexError: return (None, False) + +def track_from_json(json): + """Creates the track, album and artist from spotify response.""" + # Album artists + album_artists = [] + for artist in json["album"]["artists"]: + album_artists.append(from_json(Artist, artist)) + del json["album"]["artists"] + + # Album + album = from_json(Album, json["album"]) + album.image_url = json["album"]["images"][0]["url"] + album.save() + del json["album"] + for artist in album_artists: + album.artists.add(artist) + + # Track artists + track_artists = [] + for artist in json["artists"]: + track_artists.append(from_json(Artist, artist)) + del json["artists"] + + # Track + track = from_json(Track, json) + for artist in track_artists: + track.artists.add(artist) + track.album = album + track.save() + return track diff --git a/playlist/views.py b/playlist/views.py index e60bc4f..c049fbd 100644 --- a/playlist/views.py +++ b/playlist/views.py @@ -11,7 +11,7 @@ from datetime import UTC, datetime from collections import OrderedDict from dotenv import load_dotenv from .models import Track, Artist, Album, Vote, Background, Profile, Playlist -from .utils import from_json, get_unvoted +from .utils import track_from_json, get_unvoted from .spotify import spt from .tasks import get_banter, get_and_dither_image @@ -28,6 +28,8 @@ class VoteView(LoginRequiredMixin, View): def get(self, request, undo=None): (track, skipped) = get_unvoted(request.user) if track and not track.album.image: + if not track.album.image_url: + get_and_dither_image("https://picsum.photos/256", track.album, "image") get_and_dither_image(track.album.image_url, track.album, "image") return TemplateResponse(request, "Vote.html", {"track": track, "undo": undo, "skipped": skipped}) def post(self, request): @@ -86,7 +88,7 @@ class NominateView(LoginRequiredMixin, View): get_banter.delay(track.id) return TemplateResponse(request, "Nominate.html", { "message_type": "warning", - "message": "Hey een klassieker.", + "message": f"Hey een klassieker, die stond al in {track.from_playlist}. Geen probleem, we proberen hem nog een keer dit jaar!", "message_title": str(track) }) return TemplateResponse(request, "Nominate.html", { @@ -101,31 +103,8 @@ class NominateView(LoginRequiredMixin, View): print(e) return TemplateResponse(request, "Nominate.html", {"message_type": "error", "message": "Fout bij het ophalen van het liedje."}) - # Album artists - album_artists = [] - for artist in json["album"]["artists"]: - album_artists.append(from_json(Artist, artist)) - del json["album"]["artists"] - - # Album - album = from_json(Album, json["album"]) - album.image_url = json["album"]["images"][0]["url"] - album.save() - del json["album"] - for artist in album_artists: - album.artists.add(artist) - - # Track artists - track_artists = [] - for artist in json["artists"]: - track_artists.append(from_json(Artist, artist)) - del json["artists"] - - # Track - track = from_json(Track, json) + track = track_from_json(json) track.nominated_by = request.user - for artist in track_artists: - track.artists.add(artist) track.save() dup = track.is_duplicate_of() if dup: @@ -135,8 +114,6 @@ class NominateView(LoginRequiredMixin, View): "message": "Die hadden we al knul.", "message_title": str(dup) }) - track.album = album - track.save() get_banter.delay(track.id) profile.quota -= 1 profile.save() @@ -246,7 +223,6 @@ class PlaylistListView(LoginRequiredMixin, View): return TemplateResponse(request, "PlaylistList.html") return self.get(request, count=count) - class PlaylistDetailView(LoginRequiredMixin, View): def get(self, request, count=None): context = {} @@ -281,3 +257,34 @@ class SpotifyCallbackView(LoginRequiredMixin, View): else: url = spt.get_oauth_redirect() return HttpResponseRedirect(url) + +class PlaylistImportView(LoginRequiredMixin, View): + def get(self, request): + return HttpResponseRedirect('/settings/') + def post(self, request): + print("...") + playlist_link = self.request.POST['playlist_link'] + m = re.match(r"^https:\/\/open.spotify.com\/playlist\/([a-zA-Z0-9]+)\??", playlist_link) + playlist_id = m.group(1) + print(playlist_id) + json = spt.get_playlist_info(playlist_id) + tracks = json["tracks"]["items"] + playlist_name = json["name"] + + for track in tracks: + track_id = track["track"]["id"] + try: + json = spt.get_song_info(track_id) + track = track_from_json(json) + dup = track.is_duplicate_of() + if dup: + print(f"{track} hadden we al") + track.delete() + else: + track.old = True + track.from_playlist = playlist_name + track.save() + except Exception as e: + print(e) + + return self.get(request) \ No newline at end of file