Add search of artist's albums.
authorstephendenham <stephendenham@2dec19e3-eb1d-4749-8193-008c8bba0994>
Mon, 24 Jan 2011 15:22:58 +0000 (15:22 +0000)
committerstephendenham <stephendenham@2dec19e3-eb1d-4749-8193-008c8bba0994>
Mon, 24 Jan 2011 15:22:58 +0000 (15:22 +0000)
Sort playlists directory by name.
Track name first in album and playlist directory item labels.
Get other users' playlists.

git-svn-id: svn://svn.code.sf.net/p/xbmc-groove/code@38 2dec19e3-eb1d-4749-8193-008c8bba0994

addon.xml
changelog.txt
default.py
description.xml
resources/img/artistsalbums.png [new file with mode: 0644]
resources/img/usersplaylists.png [new file with mode: 0644]
resources/lib/GroovesharkAPI.py

index aa80611..4b1fb11 100644 (file)
--- a/addon.xml
+++ b/addon.xml
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <addon id="plugin.audio.groove" name="Grooveshark XBMC"
 <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
 <addon id="plugin.audio.groove" name="Grooveshark XBMC"
-       version="0.2.3" provider-name="Stephen Denham">
+       version="0.3.0" provider-name="Stephen Denham">
        <requires>
                <import addon="xbmc.python" version="1.0" />
        </requires>
        <requires>
                <import addon="xbmc.python" version="1.0" />
        </requires>
index 4679e0e..bd0b23e 100644 (file)
@@ -1,3 +1,10 @@
+0.3.0:
+
+Add search of artist's albums.
+Sort playlists directory by name.
+Track name first in album and playlist directory item labels.
+Get other users' playlists.
+
 0.2.3:
 
 Fix covert art directory creation. Again.
 0.2.3:
 
 Fix covert art directory creation. Again.
index 0c9e8c4..7fdcb3d 100644 (file)
@@ -2,14 +2,16 @@ import urllib, sys, os, shutil, re, time, xbmcaddon, xbmcplugin, xbmcgui, xbmc
 MODE_SEARCH_SONGS = 1
 MODE_SEARCH_ALBUMS = 2
 MODE_SEARCH_ARTISTS = 3
 MODE_SEARCH_SONGS = 1
 MODE_SEARCH_ALBUMS = 2
 MODE_SEARCH_ARTISTS = 3
-MODE_POPULAR_SONGS = 4
-MODE_FAVORITES = 5
-MODE_PLAYLISTS = 6
-MODE_ALBUM = 7
-MODE_ARTIST = 8
-MODE_PLAYLIST = 9
-MODE_SONG = 11
-MODE_FAVORITE = 12
+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
 
 ACTION_MOVE_LEFT = 1
 ACTION_MOVE_UP = 3
 
 ACTION_MOVE_LEFT = 1
 ACTION_MOVE_UP = 3
@@ -19,6 +21,10 @@ ACTION_PAGE_DOWN = 6
 ACTION_SELECT_ITEM = 7
 ACTION_PREVIOUS_MENU = 10
 
 ACTION_SELECT_ITEM = 7
 ACTION_PREVIOUS_MENU = 10
 
+# Formats for track labels
+ARTIST_ALBUM_NAME_LABEL = 0
+NAME_ALBUM_ARTIST_LABEL = 1
+
 baseDir = os.getcwd()
 resDir = xbmc.translatePath(os.path.join(baseDir, 'resources'))
 libDir = xbmc.translatePath(os.path.join(resDir,  'lib'))
 baseDir = os.getcwd()
 resDir = xbmc.translatePath(os.path.join(baseDir, 'resources'))
 libDir = xbmc.translatePath(os.path.join(resDir,  'lib'))
@@ -56,8 +62,10 @@ class Groveshark:
     
     albumImg = xbmc.translatePath(os.path.join(imgDir, 'album.png'))
     artistImg = xbmc.translatePath(os.path.join(imgDir, 'artist.png'))
     
     albumImg = xbmc.translatePath(os.path.join(imgDir, 'album.png'))
     artistImg = xbmc.translatePath(os.path.join(imgDir, 'artist.png'))
+    artistsAlbumsImg = xbmc.translatePath(os.path.join(imgDir, 'artistsalbums.png'))
     favoritesImg = xbmc.translatePath(os.path.join(imgDir, 'favorites.png'))
     playlistImg = xbmc.translatePath(os.path.join(imgDir, 'playlist.png'))
     favoritesImg = xbmc.translatePath(os.path.join(imgDir, 'favorites.png'))
     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'))
     songImg = xbmc.translatePath(os.path.join(imgDir, 'song.png'))
     defImg = xbmc.translatePath(os.path.join(imgDir, 'default.tbn'))
     popularSongsImg = xbmc.translatePath(os.path.join(imgDir, 'popularSongs.png'))
     songImg = xbmc.translatePath(os.path.join(imgDir, 'song.png'))
     defImg = xbmc.translatePath(os.path.join(imgDir, 'default.tbn'))
@@ -89,17 +97,19 @@ class Groveshark:
         # Setup
         xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
         
         # Setup
         xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
         
-        self._add_dir('Search songs...', '', MODE_SEARCH_SONGS, self.songImg, 0)
-        self._add_dir('Search albums...', '', MODE_SEARCH_ALBUMS, self.albumImg, 0)
-        self._add_dir('Search artists...', '', MODE_SEARCH_ARTISTS, self.artistImg, 0)
+        self._add_dir('Search for songs...', '', MODE_SEARCH_SONGS, self.songImg, 0)
+        self._add_dir('Search for albums...', '', MODE_SEARCH_ALBUMS, self.albumImg, 0)
+        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', '', MODE_POPULAR_SONGS, self.popularSongsImg, 0)
         if (self.userid != 0):
         self._add_dir('Popular songs', '', MODE_POPULAR_SONGS, self.popularSongsImg, 0)
         if (self.userid != 0):
-            self._add_dir('Favorites', '', MODE_FAVORITES, self.favoritesImg, 0)
-            self._add_dir('Playlists', '', MODE_PLAYLISTS, self.playlistImg, 0)
+            self._add_dir('My favorites', '', MODE_FAVORITES, self.favoritesImg, 0)
+            self._add_dir('My playlists', '', MODE_PLAYLISTS, self.playlistImg, 0)
 
     # Search for songs            
     def searchSongs(self):
 
     # Search for songs            
     def searchSongs(self):
-        query = self._get_keyboard(default="", heading="Search songs")
+        query = self._get_keyboard(default="", heading="Search for songs")
         if (query != ''):
             songs = groovesharkApi.getSongSearchResults(query, limit = self.songsearchlimit)
             if (len(songs) > 0):
         if (query != ''):
             songs = groovesharkApi.getSongSearchResults(query, limit = self.songsearchlimit)
             if (len(songs) > 0):
@@ -113,7 +123,7 @@ class Groveshark:
     
     # Search for albums
     def searchAlbums(self):
     
     # Search for albums
     def searchAlbums(self):
-        query = self._get_keyboard(default="", heading="Search albums")
+        query = self._get_keyboard(default="", heading="Search for albums")
         if (query != ''): 
             albums = groovesharkApi.getAlbumSearchResults(query, limit = self.albumsearchlimit)
             if (len(albums) > 0):
         if (query != ''): 
             albums = groovesharkApi.getAlbumSearchResults(query, limit = self.albumsearchlimit)
             if (len(albums) > 0):
@@ -127,7 +137,7 @@ class Groveshark:
     
     # Search for artists
     def searchArtists(self):
     
     # Search for artists
     def searchArtists(self):
-        query = self._get_keyboard(default="", heading="Search artists")
+        query = self._get_keyboard(default="", heading="Search for artists")
         if (query != ''): 
             artists = groovesharkApi.getArtistSearchResults(query, limit = self.artistsearchlimit)
             if (len(artists) > 0):
         if (query != ''): 
             artists = groovesharkApi.getArtistSearchResults(query, limit = self.artistsearchlimit)
             if (len(artists) > 0):
@@ -138,7 +148,44 @@ class Groveshark:
                 self.categories()
         else:
             self.categories()
                 self.categories()
         else:
             self.categories()
-                    
+
+    # Search for playlists
+    def searchPlaylists(self):
+        query = self._get_keyboard(default="", heading="Search for user's playlists")
+        if (query != ''): 
+            playlists = groovesharkApi.getUserPlaylistsEx(query)
+            if (len(playlists) > 0):
+                self._add_playlists_directory(playlists)
+            else:
+                dialog = xbmcgui.Dialog()
+                dialog.ok('Grooveshark XBMC', 'No Grooveshark playlists found.')
+                self.categories()
+        else:
+            self.categories()
+
+    # Search for artists albums
+    def searchArtistsAlbums(self):
+        query = self._get_keyboard(default="", heading="Search for artist's albums")
+        if (query != ''): 
+            artists = groovesharkApi.getArtistSearchResults(query, limit = self.artistsearchlimit)
+            if (len(artists) > 0):
+                artist = artists[0]
+                artistID = artist[1]
+                xbmc.log("Found " + artist[0] + "...")
+                albums = groovesharkApi.getArtistAlbums(artistID, limit = self.albumsearchlimit)
+                if (len(albums) > 0):
+                    self._add_albums_directory(albums)
+                else:
+                    dialog = xbmcgui.Dialog()
+                    dialog.ok('Grooveshark XBMC', 'No matching albums.')
+                    self.categories()
+            else:
+                dialog = xbmcgui.Dialog()
+                dialog.ok('Grooveshark XBMC', 'No matching artists.')
+                self.categories()
+        else:
+            self.categories()
+                  
     # Get my favorites
     def favorites(self):
         userid = self._get_login()
     # Get my favorites
     def favorites(self):
         userid = self._get_login()
@@ -190,7 +237,7 @@ class Groveshark:
     # Show selected album
     def album(self, albumid):
         album = groovesharkApi.getAlbumSongs(albumid, limit = self.songsearchlimit)
     # Show selected album
     def album(self, albumid):
         album = groovesharkApi.getAlbumSongs(albumid, limit = self.songsearchlimit)
-        self._add_songs_directory(album)
+        self._add_songs_directory(album, trackLabelFormat=NAME_ALBUM_ARTIST_LABEL)
 
     # Show selected artist
     def artist(self, artistid):
 
     # Show selected artist
     def artist(self, artistid):
@@ -202,7 +249,7 @@ class Groveshark:
         userid = self._get_login()
         if (userid != 0):
             songs = groovesharkApi.getPlaylistSongs(playlistid)
         userid = self._get_login()
         if (userid != 0):
             songs = groovesharkApi.getPlaylistSongs(playlistid)
-            self._add_songs_directory(songs)
+            self._add_songs_directory(songs, trackLabelFormat=NAME_ALBUM_ARTIST_LABEL)
         else:
             dialog = xbmcgui.Dialog()
             dialog.ok('Grooveshark XBMC', 'You must be logged in', 'to get Grooveshark playlists.')
         else:
             dialog = xbmcgui.Dialog()
             dialog.ok('Grooveshark XBMC', 'You must be logged in', 'to get Grooveshark playlists.')
@@ -219,9 +266,13 @@ class Groveshark:
             xbmc.executebuiltin('XBMC.Notification(Grooveshark XBMC, Unable to play song, 1000, ' + thumbDef + ')')
     
     # Make a song directory item
             xbmc.executebuiltin('XBMC.Notification(Grooveshark XBMC, Unable to play song, 1000, ' + thumbDef + ')')
     
     # Make a song directory item
-    def songItem(self, songid, name, album, artist, coverart):
+    def songItem(self, songid, name, album, artist, coverart, trackLabelFormat=ARTIST_ALBUM_NAME_LABEL):
         songImg = self._get_icon(coverart, 'song-' + str(songid) + "-image")
         songImg = self._get_icon(coverart, 'song-' + str(songid) + "-image")
-        item = xbmcgui.ListItem(label = artist + " - " + album + " - " + name, thumbnailImage=songImg, iconImage=songImg)
+        if trackLabelFormat == NAME_ALBUM_ARTIST_LABEL:
+            trackLabel = name + " - " + album + " - " + artist
+        else:
+            trackLabel = artist + " - " + album + " - " + name
+        item = xbmcgui.ListItem(label = trackLabel, thumbnailImage=songImg, iconImage=songImg)
         item.setInfo( type="music", infoLabels={ "title": name, "album": album, "artist": artist} )
         item.setProperty('mimetype', 'audio/mpeg')
         item.setProperty("IsPlayable", "true")
         item.setInfo( type="music", infoLabels={ "title": name, "album": album, "artist": artist} )
         item.setProperty('mimetype', 'audio/mpeg')
         item.setProperty("IsPlayable", "true")
@@ -258,13 +309,13 @@ class Groveshark:
                 return 0
     
     # Get a song directory item
                 return 0
     
     # Get a song directory item
-    def _get_song_item(self, song):
+    def _get_song_item(self, song, trackLabelFormat):
         name = song[0]
         songid = song[1]
         album = song[2]
         artist = song[4]
         coverart = song[6]
         name = song[0]
         songid = song[1]
         album = song[2]
         artist = song[4]
         coverart = song[6]
-        return self.songItem(songid, name, album, artist, coverart)            
+        return self.songItem(songid, name, album, artist, coverart, trackLabelFormat)            
         
     # File download            
     def _get_icon(self, url, songid):
         
     # File download            
     def _get_icon(self, url, songid):
@@ -281,13 +332,13 @@ class Groveshark:
             return thumbDef
     
     # Add songs to directory
             return thumbDef
     
     # Add songs to directory
-    def _add_songs_directory(self, songs):
+    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]
         n = len(songs)
         xbmc.log("Found " + str(n) + " songs...")
         i = 0
         while i < n:
             song = songs[i]
-            item = self._get_song_item(song)
+            item = self._get_song_item(song, trackLabelFormat)
             coverart = item.getProperty('coverart')
             songname = song[0]
             songid = song[1]
             coverart = item.getProperty('coverart')
             songname = song[0]
             songid = song[1]
@@ -348,10 +399,10 @@ class Groveshark:
             playlist = playlists[i]
             playlistName = playlist[0]
             playlistID = playlist[1]
             playlist = playlists[i]
             playlistName = playlist[0]
             playlistID = playlist[1]
-            self._add_dir(playlistName, '', MODE_PLAYLIST, self.playlistImg, playlistID, n)
+            dir = self._add_dir(playlistName, '', MODE_PLAYLIST, self.playlistImg, playlistID, n)
             i = i + 1  
         xbmcplugin.setContent(self._handle, 'files')
             i = i + 1  
         xbmcplugin.setContent(self._handle, 'files')
-        xbmcplugin.addSortMethod(self._handle, xbmcplugin.SORT_METHOD_PLAYLIST_ORDER)
+        xbmcplugin.addSortMethod(self._handle, xbmcplugin.SORT_METHOD_LABEL)
         xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
       
     # Add whatever directory
         xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
       
     # Add whatever directory
@@ -405,6 +456,12 @@ elif mode==MODE_SEARCH_ALBUMS:
 
 elif mode==MODE_SEARCH_ARTISTS:
     grooveshark.searchArtists()
 
 elif mode==MODE_SEARCH_ARTISTS:
     grooveshark.searchArtists()
+    
+elif mode==MODE_SEARCH_ARTISTS_ALBUMS:
+    grooveshark.searchArtistsAlbums()
+    
+elif mode==MODE_SEARCH_PLAYLISTS:
+    grooveshark.searchPlaylists() 
 
 elif mode==MODE_POPULAR_SONGS:
     grooveshark.popularSongs()
 
 elif mode==MODE_POPULAR_SONGS:
     grooveshark.popularSongs()
index 4cf1820..6503b7d 100644 (file)
@@ -18,7 +18,7 @@
        <title>Grooveshark XBMC.</title>
 
        <!-- (required) Major.minor.build -->
        <title>Grooveshark XBMC.</title>
 
        <!-- (required) Major.minor.build -->
-       <version>0.2.3</version>
+       <version>0.3.0</version>
 
        <!--
                (required) author name & email. at least one author name is required
 
        <!--
                (required) author name & email. at least one author name is required
diff --git a/resources/img/artistsalbums.png b/resources/img/artistsalbums.png
new file mode 100644 (file)
index 0000000..2b2e112
Binary files /dev/null and b/resources/img/artistsalbums.png differ
diff --git a/resources/img/usersplaylists.png b/resources/img/usersplaylists.png
new file mode 100644 (file)
index 0000000..cbee265
Binary files /dev/null and b/resources/img/usersplaylists.png differ
index 70eddfd..d571670 100644 (file)
@@ -433,6 +433,25 @@ class GrooveAPI:
                        return self._parsePlaylists(result)
                else:
                        return []
                        return self._parsePlaylists(result)
                else:
                        return []
+               
+       # Get userid from name
+       def _getUserIDFromUsername(self, username):
+               result = self._callRemote('getUserIDFromUsername', {'username' : username})
+               if 'result' in result and result['result']['UserID'] > 0:
+                       return result['result']['UserID']
+               else:
+                       return 0
+
+       # Gets the playlists of the logged-in user
+       def getUserPlaylistsEx(self, username):
+               userID = self._getUserIDFromUsername(username)
+               if (userID > 0):
+                       result = self._callRemote('getUserPlaylistsEx', {'userID' : userID})
+                       if 'result' in result and result['result']['playlists'] != None:
+                               playlists = result['result']['playlists']
+                               return self._parsePlaylists(playlists)
+               else:
+                       return []
 
        # Creates a playlist with songs
        def createPlaylist(self, name, songIDs):
 
        # Creates a playlist with songs
        def createPlaylist(self, name, songIDs):
@@ -553,17 +572,20 @@ class GrooveAPI:
                        return []
 
        def _parsePlaylists(self, items):
                        return []
 
        def _parsePlaylists(self, items):
+               i = 0
+               list = []
                if 'result' in items:
                if 'result' in items:
-                       i = 0
-                       list = []
                        playlists = items['result']
                        playlists = items['result']
-                       while(i < len(playlists)):
-                               s = playlists[i]
-                               list.append([s['Name'].encode('ascii', 'ignore'), s['PlaylistID']])
-                               i = i + 1
-                       return list
+               elif len(items) > 0:
+                       playlists = items
                else:
                        return []
                else:
                        return []
+               
+               while (i < len(playlists)):
+                       s = playlists[i]
+                       list.append([s['Name'].encode('ascii', 'ignore'), s['PlaylistID']])
+                       i = i + 1
+               return list
 
 # Test
 #import sys
 
 # Test
 #import sys
@@ -587,5 +609,6 @@ class GrooveAPI:
 #res = groovesharkApi.getPlaylistSongs(40902662)
 #res = groovesharkApi.addUserFavoriteSong('27425375')
 #res = groovesharkApi.logout()
 #res = groovesharkApi.getPlaylistSongs(40902662)
 #res = groovesharkApi.addUserFavoriteSong('27425375')
 #res = groovesharkApi.logout()
+#res = groovesharkApi.getUserPlaylistsEx('stephendenham')
 #
 #pprint.pprint(res)
 #
 #pprint.pprint(res)