Repository: beetbox/beets

Issue:
Support writing ISRC to tracks in Spotify plugin
Support ISRC track field in Spotify plugin.

The difficulty is that we currently if I'm not mistaken, only get a "Simplified Track Object" track object from Spotify while fetching album info: https://developer.spotify.com/documentation/web-api/reference/get-an-album -> look for this in the docs:

![Screenshot 2023-11-10 at 09 48 10](https://github.com/beetbox/beets/assets/2733783/e9a8fceb-3c84-41c3-b87d-0c6e1b15da12)

I wanted to instantly open a PR to just add external_ids.isrc to the plugin but it's just not there in the response we currently get from the albums endpoint. We would need an additional request to this endpoint to get it: https://developer.spotify.com/documentation/web-api/reference/get-track

Because we need this data:

![Screenshot 2023-11-10 at 09 51 16](https://github.com/beetbox/beets/assets/2733783/cd1ee3bd-7016-432e-9956-6db31eba12b6)

There might be a better way, maybe asking the albums endpoint to include that field. Not sure if that's possible.











Discussion:
@arsaboo help me out: Where would you see this additional fetch in the code? I'm unsure if I want to get my hands dirty on that plugin yet :-) Maybe you are quicker ;-)
FYI MusicBrainz often contains this info as well and beets fetches is as well and writes it to tracks. Also the Deezer plugin fetches it, it's easier with the Deezer API I guess, since it is included with the album's response we get already: https://github.com/beetbox/beets/blob/708a04d4a88eb955f261a21f0b1146c9e2ae0a55/beetsplug/deezer.py#L165C21-L165C21

Update: Hey but wait, deezer plug _does_ an additional fetch for the tracks already: https://github.com/beetbox/beets/blob/708a04d4a88eb955f261a21f0b1146c9e2ae0a55/beetsplug/deezer.py#L111C17-L111C17

Spotify plug doesn't do that extra-fetch for tracks details!

Resolving patch:
diff --git a/beetsplug/spotify.py b/beetsplug/spotify.py
--- a/beetsplug/spotify.py
+++ b/beetsplug/spotify.py
@@ -658,8 +658,11 @@ def _fetch_info(self, items, write, force):
                 self._log.debug("No track_id present for: {}", item)
                 continue
 
-            popularity = self.track_popularity(spotify_track_id)
+            popularity, isrc, ean, upc = self.track_info(spotify_track_id)
             item["spotify_track_popularity"] = popularity
+            item["isrc"] = isrc
+            item["ean"] = ean
+            item["upc"] = upc
             audio_features = self.track_audio_features(spotify_track_id)
             if audio_features is None:
                 self._log.info("No audio features found for: {}", item)
@@ -674,13 +677,22 @@ def _fetch_info(self, items, write, force):
             if write:
                 item.try_write()
 
-    def track_popularity(self, track_id=None):
-        """Fetch a track popularity by its Spotify ID."""
+    def track_info(self, track_id=None):
+        """Fetch a track's popularity and external IDs using its Spotify ID."""
         track_data = self._handle_response(
             requests.get, self.track_url + track_id
         )
-        self._log.debug("track_data: {}", track_data.get("popularity"))
-        return track_data.get("popularity")
+        self._log.debug(
+            "track_popularity: {} and track_isrc: {}",
+            track_data.get("popularity"),
+            track_data.get("external_ids").get("isrc"),
+        )
+        return (
+            track_data.get("popularity"),
+            track_data.get("external_ids").get("isrc"),
+            track_data.get("external_ids").get("ean"),
+            track_data.get("external_ids").get("upc"),
+        )
 
     def track_audio_features(self, track_id=None):
         """Fetch track audio features by its Spotify ID."""


Test patch: