From: stephendenham Date: Tue, 25 Jan 2011 16:30:24 +0000 (+0000) Subject: Get artist's most popular songs. X-Git-Url: https://git.hcoop.net/clinton/xbmc-groove.git/commitdiff_plain/972891390d3458abe0bdf5b0ec58627cdafd4ea1 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 --- 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 0000000..00c6d0b Binary files /dev/null and b/resources/img/popularSongsArtist.png differ 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 @@ +