Get artist's most popular songs.
[clinton/xbmc-groove.git] / default.py
index 7fdcb3d..f515407 100644 (file)
@@ -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]))