import acoustid import spotipy import pymsgbox from spotipy.oauth2 import SpotifyClientCredentials class SongDataFinder(object): def __init__(self, acoustid_apikey): self.acoustid_apikey = acoustid_apikey self.spotifysearch = SpotifySearch() def _topresult(self, filename): # Use acoustID Webservice for basic information results = acoustid.match(self.acoustid_apikey, filename) try: for score, recording_id, title, artist in results: return (title, artist, score) except TypeError: # If we could not identify a match with MusicBrains return None # TODO: Match spotify results with artist and song name to improve results def matchFile(self, filename, userInput=True): try: title, artist, score = self._topresult(filename) print("") print("AcoustID Name: %s" % title) print("AcoustID Artist: %s" % artist) print("") self.spotifysearch.search("%s - %s" % (title, artist)) # Plug back in our acoustID results into spotify search return self.spotifysearch.selectResult(0) # Return the resulting spotify track except TypeError: # Again, If we could not identify a match # TODO: Work on the userInput exception handling... e.g. skip None Songs if userInput == True: pymsgbox.alert(text='Could not identify song automatically', title='Song ID Error', button='OK') userSongName = pymsgbox.prompt(text='Song Name', title='Enter Song Name') userSongArtist = pymsgbox.prompt(text='Artist', title='Enter Artist Name') self.spotifysearch.search("%s - %s" % (userSongName, userSongArtist)) # Search spotify with user entered values return self.spotifysearch.selectResult(0) # Return the resulting spotify track else: return None class SpotifySearch(object): def __init__(self): self.client_credentials_manager = SpotifyClientCredentials() self.spotify = spotipy.Spotify(client_credentials_manager=self.client_credentials_manager) def search(self, query): self.results = self.spotify.search(query) def selectResult(self, index): if index < self.getNumberOfResults(): return SpotifyTrack(self.results["tracks"]["items"][index]) else: print("Index is too high") return None def getNumberOfResults(self): return len(self.results["tracks"]["items"]) def getTrackNames(self): trackNames = [] for track in self.results["tracks"]["items"]: trackNames.append(track[name]) return trackNames def getTrackAlbums(self): trackAlbums = [] for track in self.results["tracks"]["items"]: trackAlbums.append(track["album"]["name"]) return trackAlbums def getTrackArtists(self): trackArtists = [] for track in self.results["tracks"]["items"]: trackArtists.append(track["artists"]["name"][0]) # There might be more than one artist, figure how to handle this return trackArtists def getExplicitRatings(self): explicitRatings = [] for track in self.results["tracks"]["items"]: explicitRatings.append[track["explicit"]] return explicitRatings def getTrackIDs(self): trackIDs = [] for track in self.results["tracks"]["items"]: trackIDs.append(track["id"]) class SpotifyTrack(object): def __init__(self, trackJSON): self.trackdata = trackJSON def getName(self): return self.trackdata["name"] def getAlbum(self): return self.trackdata["album"]["name"] def getAlbumArt(self): return self.trackdata["album"]["images"][0]["url"] def getArtists(self): return self.trackdata["artists"] def getMainArtist(self): return self.trackdata["artists"][0]["name"] def getMainArtistGenre(self): uri = self.trackdata["artists"][0]["uri"] client_credentials_manager = SpotifyClientCredentials() spotify = spotipy.Spotify(client_credentials_manager=client_credentials_manager) artistdata = spotify.artist(uri) try: return artistdata["genres"][0] except IndexError: return None def getTrackNumber(self): return self.trackdata["track_number"] def getLength(self): return self.trackdata["duration_ms"] def getExplicitRating(self): return bool(self.trackdata["explicit"]) def getSpotifyID(self): return self.trackdata["id"]