From 0234f39f94cce269ecd989c5e27efff87201ac44 Mon Sep 17 00:00:00 2001 From: "Matt.Wang" Date: Thu, 30 Sep 2021 20:31:02 +0800 Subject: [PATCH] wip: pycast --- docker-compose.yml | 2 ++ requirements/base.txt | 2 ++ src/events/api/serializers.py | 8 ++++++ src/events/api/urls.py | 1 + src/events/api/views.py | 44 ++++++++++++++++++++++++++++++++ src/pycontw2016/settings/base.py | 4 +++ 6 files changed, 61 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index 217bf6d36..d647c6358 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -33,6 +33,8 @@ services: EMAIL_URL: ${EMAIL_URL} DSN_URL: ${DSN_URL} GTM_TRACK_ID: ${GTM_TRACK_ID} + SPOTIPY_CLIENT_ID: ${SPOTIPY_CLIENT_ID} + SPOTIPY_CLIENT_SECRET: ${SPOTIPY_CLIENT_SECRET} SLACK_WEBHOOK_URL: ${SLACK_WEBHOOK_URL} volumes: diff --git a/requirements/base.txt b/requirements/base.txt index e0167b507..4d2b7372d 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -90,6 +90,8 @@ sorl-thumbnail==12.6.2 # http://www.grantjenks.com/docs/sortedcontainers/ sortedcontainers==2.1.0 +spotipy + # Tabulate, an utility for pretty-print tabular data # https://bitbucket.org/astanin/python-tabulate tabulate==0.8.6 diff --git a/src/events/api/serializers.py b/src/events/api/serializers.py index 80c435bce..d86c1faae 100644 --- a/src/events/api/serializers.py +++ b/src/events/api/serializers.py @@ -221,3 +221,11 @@ class Meta: "youtube_id", "social_item" ] + + +class PyCastAPISerializer(serializers.Serializer): + id = serializers.CharField() + title = serializers.CharField() + duration = serializers.IntegerField() + description = serializers.CharField() + release_date = serializers.CharField() diff --git a/src/events/api/urls.py b/src/events/api/urls.py index 76dc43b98..6f52f209f 100644 --- a/src/events/api/urls.py +++ b/src/events/api/urls.py @@ -9,4 +9,5 @@ path('keynotes/', views.KeynoteEventListAPIView.as_view()), path('speeches/', views.SpeechListAPIView.as_view()), path('speeches///', views.SpeechDetailAPIView.as_view()), + path('pycast/', views.PyCastAPIView.as_view()), ] diff --git a/src/events/api/views.py b/src/events/api/views.py index 12a40d434..ab3145fec 100644 --- a/src/events/api/views.py +++ b/src/events/api/views.py @@ -1,10 +1,13 @@ import collections from typing import List, Union +import time from rest_framework.generics import RetrieveAPIView, ListAPIView from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.permissions import IsAuthenticated +import spotipy +from spotipy.oauth2 import SpotifyClientCredentials from django.conf import settings from django.db.models import Count @@ -308,3 +311,44 @@ class KeynoteEventListAPIView(ListAPIView): queryset = KeynoteEvent.objects.all() serializer_class = serializers.KeynoteEventSerializer + + +class PyCastAPIView(APIView): + sp_client = None + show = {} + updated_at = time.time() + pycast_show_id = '63C4CNtJywIKizNFHRrIGv' + + def get_sp_client(self): + if self.sp_client: + return self.sp_client + try: + auth_manager = SpotifyClientCredentials() + self.sp_client = spotipy.Spotify(auth_manager=auth_manager) + except spotipy.oauth2.SpotifyOauthError: + raise Http404 + return self.sp_client + + def get(self, request): + sp_client = self.get_sp_client() + + now = time.time() + if not self.show or (now - self.updated_at) > 6 * 60 * 60: + self.show = sp_client.show(self.pycast_show_id, market="TW") + self.updated_at = now + + if not self.show.get('episodes') or \ + not self.show['episodes'].get('items'): + raise Http404 + + episodes = [] + for episode in self.show['episodes']['items']: + episodes.append({ + 'id': episode['id'], + 'title': episode['name'], + 'description': episode['html_description'], + 'duration': episode['duration_ms'], + 'release_date': episode['release_date'], + }) + results = serializers.PyCastAPISerializer(episodes, many=True).data + return Response(results) diff --git a/src/pycontw2016/settings/base.py b/src/pycontw2016/settings/base.py index 07eb6dc99..3534cb820 100644 --- a/src/pycontw2016/settings/base.py +++ b/src/pycontw2016/settings/base.py @@ -334,3 +334,7 @@ def node_bin(name): # (see the repo at https://github.com/pycontw/pycontw-2021) and this config # provides the url hosting the frontend. FRONTEND_HOST = 'https://staging.pycon.tw' + +# For calling spotify web API using spotipy +SPOTIPY_CLIENT_ID = env('SPOTIPY_CLIENT_ID', default='dummy') +SPOTIPY_CLIENT_SECRET = env('SPOTIPY_CLIENT_SECRET', default='dummy')