From 7d6e19ba5d788415983b3fa99f0ee2a7cb476a8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jannes=20H=C3=B6ke?= <mail@jhoeke.de> Date: Tue, 23 Jan 2024 22:31:16 +0100 Subject: [PATCH] =?UTF-8?q?=E2=9A=A1=EF=B8=8F=20Rewrite=20Spotify=20ID=20d?= =?UTF-8?q?iscovery=20We=20now=20have=20over=20500=20podcasts=20in=20our?= =?UTF-8?q?=20account,=20loading=20them=20all=20in=20batches=20of=2050=20t?= =?UTF-8?q?akes=20over=2030=20seconds,=20which=20is=20the=20Heroku=20timeo?= =?UTF-8?q?ut?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- okr/admin/podcasts.py | 51 +++++++++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/okr/admin/podcasts.py b/okr/admin/podcasts.py index 2b0e245..a7814e7 100644 --- a/okr/admin/podcasts.py +++ b/okr/admin/podcasts.py @@ -32,7 +32,7 @@ from .base import ProductAdmin from .mixins import UnrequiredFieldsMixin, large_table from ..scrapers.podcasts import feed -from ..scrapers.podcasts.spotify_api import spotify_api, fetch_all +from ..scrapers.podcasts.spotify_api import spotify_api class FeedForm(forms.ModelForm): @@ -48,6 +48,11 @@ class Meta: fields = ["feed_url"] feed_url = forms.URLField(label="Feed URL") + spotify_id = forms.CharField( + label="Spotify ID", + help_text="Nicht erforderlich. Die Spotify ID kann hier manuell angegeben werden, falls die automatische Erkennung nicht funktioniert.", + required=False, + ) def clean(self) -> Dict[str, Any]: try: @@ -72,15 +77,6 @@ def clean(self) -> Dict[str, Any]: # We do it here so we can raise a validation error if the Spotify API is not available try: licensed_podcasts = spotify_api.licensed_podcasts() - sleep(0.5) - self.spotify_podcasts = fetch_all( - functools.partial(spotify_api.shows, market="DE"), - list( - uri.replace("spotify:show:", "") - for uri in licensed_podcasts["shows"].keys() - ), - "shows", - ) except Exception as e: logger.exception(e) capture_exception(e) @@ -88,6 +84,36 @@ def clean(self) -> Dict[str, Any]: "Spotify API nicht erreichbar. Bitte versuchen Sie es später erneut." ) from e + licensed_ids = list( + uri.replace("spotify:show:", "") + for uri in licensed_podcasts["shows"].keys() + ) + + spotify_id = None + + if self.cleaned_data["spotify_id"] in licensed_ids: + spotify_id = self.cleaned_data["spotify_id"] + elif ( + self.cleaned_data["spotify_id"] + and self.cleaned_data["spotify_id"] not in licensed_ids + ): + raise ValidationError( + "Die angegebene Spotify ID ist nicht nicht bekannt. Bitte geben Sie eine andere ID an oder lassen Sie das Feld frei, um eine automatische Zuordnung zu versuchen." + ) + # Try searching for the podcast name in the Spotify API + else: + results = spotify_api.search(feed_dict.feed.title, type="show", market="DE") + for item in results["shows"]["items"]: + logger.info("Found Spotify podcast: {}", item) + if item is None: + continue + + if item["name"] == feed_dict.feed.title and item["id"] in licensed_ids: + spotify_id = item["id"] + break + + self._spotify_id = spotify_id + return super().clean() def save(self, commit: bool) -> Any: @@ -99,10 +125,7 @@ def save(self, commit: bool) -> Any: self.instance.description = d.feed.description self.instance.itunes_category = d.feed.itunes_category self.instance.itunes_subcategory = d.feed.itunes_subcategory - self.instance.spotify_id = next( - (p["id"] for p in self.spotify_podcasts if p and p["name"] == d.feed.title), - None, - ) + self.instance.spotify_id = self._spotify_id return super().save(commit=commit)