From 972891390d3458abe0bdf5b0ec58627cdafd4ea1 Mon Sep 17 00:00:00 2001 From: stephendenham Date: Tue, 25 Jan 2011 16:30:24 +0000 Subject: [PATCH] Get artist's most popular songs. Allow multiple pages in songs directory. git-svn-id: svn://svn.code.sf.net/p/xbmc-groove/code@39 2dec19e3-eb1d-4749-8193-008c8bba0994 --- changelog.txt | 9 +- default.py | 132 +++++++++++++++++++++---- resources/img/popularSongsArtist.png | Bin 0 -> 43086 bytes resources/language/English/strings.xml | 1 + resources/lib/GroovesharkAPI.py | 46 ++++++--- resources/settings.xml | 1 + 6 files changed, 154 insertions(+), 35 deletions(-) create mode 100644 resources/img/popularSongsArtist.png diff --git a/changelog.txt b/changelog.txt index bd0b23e..c7d5e5b 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,9 +1,12 @@ 0.3.0: -Add search of artist's albums. +Get artist's albums. +Get artist's most popular songs. +Get other user's playlists. + Sort playlists directory by name. -Track name first in album and playlist directory item labels. -Get other users' playlists. +Put track name first in the album and playlist directory item labels. +Allow multiple pages in the songs directory (help prevent slow retrieval of very big lists). 0.2.3: diff --git a/default.py b/default.py index 7fdcb3d..f515407 100644 --- a/default.py +++ b/default.py @@ -1,17 +1,19 @@ -import urllib, sys, os, shutil, re, time, xbmcaddon, xbmcplugin, xbmcgui, xbmc +import urllib, sys, os, shutil, re, time, xbmcaddon, xbmcplugin, xbmcgui, xbmc, pickle MODE_SEARCH_SONGS = 1 MODE_SEARCH_ALBUMS = 2 MODE_SEARCH_ARTISTS = 3 MODE_SEARCH_ARTISTS_ALBUMS = 4 MODE_SEARCH_PLAYLISTS = 5 -MODE_POPULAR_SONGS = 6 -MODE_FAVORITES = 7 -MODE_PLAYLISTS = 8 -MODE_ALBUM = 9 -MODE_ARTIST = 10 -MODE_PLAYLIST = 11 -MODE_SONG = 12 -MODE_FAVORITE = 13 +MODE_ARTIST_POPULAR = 6 +MODE_POPULAR_SONGS = 7 +MODE_FAVORITES = 8 +MODE_PLAYLISTS = 9 +MODE_ALBUM = 10 +MODE_ARTIST = 11 +MODE_PLAYLIST = 12 +MODE_SONG_PAGE = 13 +MODE_SONG = 14 +MODE_FAVORITE = 15 ACTION_MOVE_LEFT = 1 ACTION_MOVE_UP = 3 @@ -67,6 +69,7 @@ class Groveshark: playlistImg = xbmc.translatePath(os.path.join(imgDir, 'playlist.png')) usersplaylistsImg = xbmc.translatePath(os.path.join(imgDir, 'usersplaylists.png')) popularSongsImg = xbmc.translatePath(os.path.join(imgDir, 'popularSongs.png')) + popularSongsArtistImg = xbmc.translatePath(os.path.join(imgDir, 'popularSongsArtist.png')) songImg = xbmc.translatePath(os.path.join(imgDir, 'song.png')) defImg = xbmc.translatePath(os.path.join(imgDir, 'default.tbn')) fanImg = xbmc.translatePath(os.path.join(baseDir, 'fanart.png')) @@ -75,6 +78,7 @@ class Groveshark: songsearchlimit = int(settings.getSetting('songsearchlimit')) albumsearchlimit = int(settings.getSetting('albumsearchlimit')) artistsearchlimit = int(settings.getSetting('artistsearchlimit')) + songspagelimit = int(settings.getSetting('songspagelimit')) username = settings.getSetting('username') password = settings.getSetting('password') userid = 0 @@ -102,6 +106,7 @@ class Groveshark: self._add_dir('Search for artists...', '', MODE_SEARCH_ARTISTS, self.artistImg, 0) self._add_dir("Search for artist's albums...", '', MODE_SEARCH_ARTISTS_ALBUMS, self.artistsAlbumsImg, 0) self._add_dir("Search for user's playlists...", '', MODE_SEARCH_PLAYLISTS, self.usersplaylistsImg, 0) + self._add_dir('Popular songs for artist...', '', MODE_ARTIST_POPULAR, self.popularSongsArtistImg, 0) self._add_dir('Popular songs', '', MODE_POPULAR_SONGS, self.popularSongsImg, 0) if (self.userid != 0): self._add_dir('My favorites', '', MODE_FAVORITES, self.favoritesImg, 0) @@ -151,7 +156,7 @@ class Groveshark: # Search for playlists def searchPlaylists(self): - query = self._get_keyboard(default="", heading="Search for user's playlists") + query = self._get_keyboard(default="", heading="Username") if (query != ''): playlists = groovesharkApi.getUserPlaylistsEx(query) if (len(playlists) > 0): @@ -254,6 +259,29 @@ class Groveshark: dialog = xbmcgui.Dialog() dialog.ok('Grooveshark XBMC', 'You must be logged in', 'to get Grooveshark playlists.') + # Show popular songs of the artist + def artistPopularSongs(self): + query = self._get_keyboard(default="", heading="Artist") + if (query != ''): + artists = groovesharkApi.getArtistSearchResults(query, limit = self.artistsearchlimit) + if (len(artists) > 0): + artist = artists[0] + artistID = artist[1] + xbmc.log("Found " + artist[0] + "...") + songs = groovesharkApi.getArtistPopularSongs(artistID, limit = self.songsearchlimit) + if (len(songs) > 0): + self._add_songs_directory(songs, trackLabelFormat=NAME_ALBUM_ARTIST_LABEL) + else: + dialog = xbmcgui.Dialog() + dialog.ok('Grooveshark XBMC', 'No popular songs.') + self.categories() + else: + dialog = xbmcgui.Dialog() + dialog.ok('Grooveshark XBMC', 'No matching artists.') + self.categories() + else: + self.categories() + # Play a song def playSong(self, item): songid = item.getProperty('songid') @@ -284,6 +312,10 @@ class Groveshark: return item + # Next page of songs + def songPage(self, page, trackLabelFormat): + self._add_songs_directory([], trackLabelFormat, page) + # Get keyboard input def _get_keyboard(self, default="", heading="", hidden=False): kb = xbmc.Keyboard(default, heading, hidden) @@ -332,12 +364,29 @@ class Groveshark: return thumbDef # Add songs to directory - def _add_songs_directory(self, songs, trackLabelFormat=ARTIST_ALBUM_NAME_LABEL): - n = len(songs) - xbmc.log("Found " + str(n) + " songs...") - i = 0 - while i < n: - song = songs[i] + def _add_songs_directory(self, songs, trackLabelFormat=ARTIST_ALBUM_NAME_LABEL, page=0): + + totalSongs = len(songs) + page = int(page) + + # No pages needed + if page == 0 and totalSongs <= self.songspagelimit: + xbmc.log("Found " + str(totalSongs) + " songs...") + # Pages + else: + # Cache all songs + if page == 0: + self._setSavedSongs(songs) + else: + songs = self._getSavedSongs() + totalSongs = len(songs) + + if totalSongs > 0: + start = page * self.songspagelimit + end = start + self.songspagelimit + songs = songs[start:end] + + for song in songs: item = self._get_song_item(song, trackLabelFormat) coverart = item.getProperty('coverart') songname = song[0] @@ -352,8 +401,12 @@ class Groveshark: menuItems = [] menuItems.append(("Grooveshark favorite", "XBMC.RunPlugin("+fav+")")) item.addContextMenuItems(menuItems, replaceItems=False) - xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=item,isFolder=False, totalItems=n) - i = i + 1 + xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=item,isFolder=False, totalItems=len(songs)) + + page = page + 1 + if totalSongs > page * self.songspagelimit: + u=sys.argv[0]+"?mode="+str(MODE_SONG_PAGE)+"&id=0"+"&page="+str(page)+"&label="+str(trackLabelFormat) + self._add_dir('More songs...', u, MODE_SONG_PAGE, self.songImg, 0, totalSongs - (page * self.songspagelimit)) xbmcplugin.setContent(self._handle, 'songs') xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg) @@ -407,11 +460,38 @@ class Groveshark: # Add whatever directory def _add_dir(self, name, url, mode, iconimage, id, items=1): - - u=sys.argv[0]+"?mode="+str(mode)+"&name="+urllib.quote_plus(name)+"&id="+str(id) + if url == '': + u=sys.argv[0]+"?mode="+str(mode)+"&name="+urllib.quote_plus(name)+"&id="+str(id) + else: + u = url dir=xbmcgui.ListItem(name, iconImage=iconimage, thumbnailImage=iconimage) dir.setInfo( type="Music", infoLabels={ "title": name } ) return xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=dir,isFolder=True, totalItems=items) + + def _getSavedSongs(self): + path = os.path.join(cacheDir, 'songs.dmp') + try: + f = open(path, 'rb') + songs = pickle.load(f) + f.close() + except: + songs = [] + pass + return songs + + def _setSavedSongs(self, songs): + try: + # Create the 'data' directory if it doesn't exist. + if not os.path.exists(cacheDir): + os.makedirs(cacheDir) + path = os.path.join(cacheDir, 'songs.dmp') + f = open(path, 'wb') + pickle.dump(songs, f, protocol=pickle.HIGHEST_PROTOCOL) + f.close() + except: + xbmc.log("An error occurred saving songs") + pass + # Parse URL parameters @@ -465,12 +545,22 @@ elif mode==MODE_SEARCH_PLAYLISTS: elif mode==MODE_POPULAR_SONGS: grooveshark.popularSongs() + +elif mode==MODE_ARTIST_POPULAR: + grooveshark.artistPopularSongs() elif mode==MODE_FAVORITES: grooveshark.favorites() elif mode==MODE_PLAYLISTS: grooveshark.playlists() + +elif mode==MODE_SONG_PAGE: + try: page=urllib.unquote_plus(params["page"]) + except: pass + try: label=urllib.unquote_plus(params["label"]) + except: pass + grooveshark.songPage(page, label) elif mode==MODE_SONG: try: name=urllib.unquote_plus(params["name"]) @@ -495,6 +585,6 @@ elif mode==MODE_PLAYLIST: elif mode==MODE_FAVORITE: grooveshark.favorite(id) - + if mode < MODE_SONG: xbmcplugin.endOfDirectory(int(sys.argv[1])) diff --git a/resources/img/popularSongsArtist.png b/resources/img/popularSongsArtist.png new file mode 100644 index 0000000000000000000000000000000000000000..00c6d0b9335f72751601ce874490f9aeb204b76f GIT binary patch literal 43086 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 R&KLjy002ovPDHLkV1g(%b~yk5 literal 0 HcmV?d00001 diff --git a/resources/language/English/strings.xml b/resources/language/English/strings.xml index 6fea7bc..ca757da 100644 --- a/resources/language/English/strings.xml +++ b/resources/language/English/strings.xml @@ -5,4 +5,5 @@ Song search limit Album search limit Artist search limit + Number of songs per page \ No newline at end of file diff --git a/resources/lib/GroovesharkAPI.py b/resources/lib/GroovesharkAPI.py index d571670..85dc5a1 100644 --- a/resources/lib/GroovesharkAPI.py +++ b/resources/lib/GroovesharkAPI.py @@ -377,7 +377,15 @@ class GrooveAPI: return self._parseSongs(result) else: return [] - + + # Get artist's popular songs + def getArtistPopularSongs(self, artistID, limit = SONG_LIMIT): + result = self._callRemote('getArtistPopularSongs', {'artistID' : artistID}) + if 'result' in result: + return self._parseSongs(result, limit) + else: + return [] + # Gets the popular songs def getPopularSongsToday(self, limit=SONG_LIMIT): result = self._callRemote('getPopularSongsToday', {'limit' : limit}) @@ -490,19 +498,34 @@ class GrooveAPI: if 'result' in items: i = 0 list = [] - if 'songs' in items['result']: - l = len(items['result']['songs']) - index = 'songs' - elif 'song' in items['result']: - l = 1 - index = 'song' - else: - l = len(items['result']) - index = '' + index = '' + l = -1 + try: + if 'songs' in items['result'][0]: + l = len(items['result'][0]['songs']) + index = 'songs[]' + except: pass + try: + if l < 0 and 'songs' in items['result']: + l = len(items['result']['songs']) + index = 'songs' + except: pass + try: + if l < 0 and 'song' in items['result']: + l = 1 + index = 'song' + except: pass + try: + if l < 0: + l = len(items['result']) + except: pass + if limit > 0 and l > limit: l = limit while(i < l): - if index == 'songs': + if index == 'songs[]': + s = items['result'][0]['songs'][i] + elif index == 'songs': s = items['result'][index][i] elif index == 'song': s = items['result'][index] @@ -610,5 +633,6 @@ class GrooveAPI: #res = groovesharkApi.addUserFavoriteSong('27425375') #res = groovesharkApi.logout() #res = groovesharkApi.getUserPlaylistsEx('stephendenham') +#res = groovesharkApi.getArtistPopularSongs('3707') # #pprint.pprint(res) diff --git a/resources/settings.xml b/resources/settings.xml index 69a0dc8..818c243 100644 --- a/resources/settings.xml +++ b/resources/settings.xml @@ -4,4 +4,5 @@ + -- 2.20.1