Fixes.
authorstephendenham <stephendenham@2dec19e3-eb1d-4749-8193-008c8bba0994>
Sat, 13 Nov 2010 13:14:31 +0000 (13:14 +0000)
committerstephendenham <stephendenham@2dec19e3-eb1d-4749-8193-008c8bba0994>
Sat, 13 Nov 2010 13:14:31 +0000 (13:14 +0000)
git-svn-id: svn://svn.code.sf.net/p/xbmc-groove/code@2 2dec19e3-eb1d-4749-8193-008c8bba0994

default.py
resources/img/album.png
resources/img/artist.png
resources/img/favorites.png
resources/img/playlist.png
resources/img/popular.png
resources/img/song.png
resources/lib/GrooveAPI.py

index 49c0e85..3165eed 100644 (file)
@@ -22,17 +22,16 @@ MODE_SONG = 10
 MODE_FAVORITE = 11
 MODE_UNFAVORITE = 12
 
-songsearchlimit = 25
-albumsearchlimit = 15
-artistsearchlimit = 15
+songsearchlimit = 0
+albumsearchlimit = 0
+artistsearchlimit = 0
 
 lastID = 0
 
-rootDir = os.getcwd()
-
-resDir = xbmc.translatePath(os.path.join(rootDir, 'resources'))
+resDir = xbmc.translatePath(os.path.join(os.getcwd(), 'resources'))
 libDir = xbmc.translatePath(os.path.join(resDir,  'lib'))
 imgDir = xbmc.translatePath(os.path.join(resDir,  'img'))
+thumbDir = os.path.join('special://masterprofile/plugin_data/music', os.path.join(os.path.basename(os.getcwd()), 'thumb'))
 
 sys.path.append (libDir)
 from GrooveAPI import *
@@ -54,12 +53,20 @@ class Groveshark:
     songsearchlimit = xbmcplugin.getSetting('songsearchlimit')
     albumsearchlimit = xbmcplugin.getSetting('albumsearchlimit')
     artistsearchlimit = xbmcplugin.getSetting('artistsearchlimit')
-   
+
+    
     def __init__( self ):
         self._handle = int(sys.argv[1])
-    
+
     def categories(self):
+        
         userid = self._get_login()
+        
+        # Setup
+        groovesharkApi.setRemoveDuplicates(True)
+        if not os.path.exists(xbmc.translatePath(thumbDir)):
+            os.makedirs(xbmc.translatePath(thumbDir))
+
         self._addDir('Search songs', '', MODE_SEARCH_SONGS, self.songImg, 0)
         self._addDir('Search albums', '', MODE_SEARCH_ALBUMS, self.albumImg, 0)
         self._addDir('Search artists', '', MODE_SEARCH_ARTISTS, self.artistImg, 0)
@@ -71,7 +78,7 @@ class Groveshark:
     def searchSongs(self):
         query = self._get_keyboard(default="", heading="Search songs")
         if (query): 
-            songs = groovesharkApi.searchSongs(query, limit = songsearchlimit)
+            songs = groovesharkApi.searchSongs(query, limit = xbmcplugin.getSetting('songsearchlimit'))
             if (len(songs) > 0):
                 self._get_songs(songs)
             else:
@@ -82,7 +89,7 @@ class Groveshark:
     def searchAlbums(self):
         query = self._get_keyboard(default="", heading="Search albums")
         if (query): 
-            albums = groovesharkApi.searchAlbums(query, limit = albumsearchlimit)
+            albums = groovesharkApi.searchAlbums(query, limit = xbmcplugin.getSetting('albumsearchlimit'))
             if (len(albums) > 0):
                 self._get_albums(albums)
             else:
@@ -93,7 +100,7 @@ class Groveshark:
     def searchArtists(self):
         query = self._get_keyboard(default="", heading="Search artists")
         if (query): 
-            artists = groovesharkApi.searchArtists(query, limit = artistsearchlimit)
+            artists = groovesharkApi.searchArtists(query, limit = xbmcplugin.getSetting('artistsearchlimit'))
             if (len(artists) > 0):
                 self._get_artists(artists)
             else:
@@ -113,7 +120,7 @@ class Groveshark:
                 self.categories()
     
     def popular(self):
-        popular = groovesharkApi.popularGetSongs(limit = songsearchlimit)
+        popular = groovesharkApi.popularGetSongs(limit = xbmcplugin.getSetting('songsearchlimit'))
         if (len(popular) > 0):
             self._get_songs(popular)
         else:
@@ -135,7 +142,7 @@ class Groveshark:
     def favorite(self, songid):
         userid = self._get_login()
         if (userid != 0):
-            xbmc.log("Favorite song: " + str(songid))
+            xbmc.log("Favorite playSong: " + str(songid))
             groovesharkApi.favoriteSong(songID = songid)
         else:
             dialog = xbmcgui.Dialog()
@@ -144,33 +151,34 @@ class Groveshark:
     def unfavorite(self, songid):
         userid = self._get_login()
         if (userid != 0):
-            xbmc.log("Unfavorite song: " + str(songid))
+            xbmc.log("Unfavorite playSong: " + str(songid))
             groovesharkApi.unfavoriteSong(songID = songid)
         else:
             dialog = xbmcgui.Dialog()
             dialog.ok('Grooveshark', 'You must be logged in', 'to remove favorites.')
     
     def album(self,albumid):
-        album = groovesharkApi.albumGetSongs(albumId = albumid, limit = songsearchlimit)
+        album = groovesharkApi.albumGetSongs(albumId = albumid, limit = xbmcplugin.getSetting('songsearchlimit'))
         self._get_songs(album)
     
     def artist(self, artistid):
-        albums = groovesharkApi.artistGetAlbums(artistId = artistid, limit = albumsearchlimit)
+        albums = groovesharkApi.artistGetAlbums(artistId = artistid, limit = xbmcplugin.getSetting('albumsearchlimit'))
         self._get_albums(albums)
     
     def playlist(self, playlistid):
         userid = self._get_login()
         if (userid != 0):
-            songs = groovesharkApi.playlistGetSongs(playlistId = playlistid, limit = songsearchlimit)
+            songs = groovesharkApi.playlistGetSongs(playlistId = playlistid, limit = xbmcplugin.getSetting('songsearchlimit'))
             self._get_songs(songs)
         else:
             dialog = xbmcgui.Dialog()
             dialog.ok('Grooveshark', 'You must be logged in', 'to get playlists.')
             
-    def song(self, url, name, album, artist, duration):
-        xbmc.log("Playing: " + url)
-        songItem = xbmcgui.ListItem(name + " - " + artist, path=url)
-        songItem.setInfo( type="Music", infoLabels={ "Title": name, "Duration": duration, "Album": album, "Artist": artist} )
+    def playSong(self, url, name, album, artist, duration, thumb, image):
+        xbmc.log("Playing: " + url + ", image " + image)
+        songItem = xbmcgui.ListItem(label = name, path=url, thumbnailImage=thumb, iconImage=image)
+        songItem.setInfo( type="Music", infoLabels={ "title": name, "duration": duration, "album": album, "artist": artist} )
+        songItem.setProperty('mimetype', 'audio/mpeg')
         xbmc.Player().stop()
         xbmc.Player(xbmc.PLAYER_CORE_PAPLAYER).play(url, songItem, False)
         
@@ -191,10 +199,7 @@ class Groveshark:
         else:
             if groovesharkApi.loggedInStatus() == 1:
                 groovesharkApi.logout()
-            try:    
-                userid = groovesharkApi.loginExt(username, password)
-            except (LoginUnknownError):
-                userid = 0
+            userid = groovesharkApi.loginExt(username, password)
             if (userid != 0):
                 xbmc.log("Logged in")
                 return userid
@@ -213,12 +218,13 @@ class Groveshark:
             songDuration = song[2]
             songAlbum = song[3]
             songArtist = song[6]
+            songThumb = song[8]
             songImage = song[9]
-            xbmc.log(songName)
-            self._addSong(songID, songName, groovesharkApi.getStreamURL(songID), songDuration, songAlbum, songArtist, songImage)
+            songUrl = groovesharkApi.getStreamURL(songID)
+            xbmc.log(songName + ", " + songArtist + ", " + songAlbum)
+            self._addSong(songID, songName, songUrl, songDuration, songAlbum, songArtist, songThumb, songImage)
             i = i + 1
         xbmcplugin.setContent(self._handle, 'songs')
-        xbmcplugin.addSortMethod(self._handle, xbmcplugin.SORT_METHOD_TITLE_IGNORE_THE)
             
     def _get_albums(self, albums):
         xbmc.log("Found " + str(len(albums)) + " albums...")
@@ -261,30 +267,56 @@ class Groveshark:
         xbmcplugin.setContent(self._handle, 'files')
         xbmcplugin.addSortMethod(self._handle, xbmcplugin.SORT_METHOD_PLAYLIST_ORDER)
         
-    def _addSong(self, songid, songname, songurl, songduration, songalbum, songartist, songimage):
+    def _addSong(self, songid, songname, songurl, songduration, songalbum, songartist, songthumb, songimage):
+        songImg = self._getThumb(songimage, str(songid) + "-image")
+        if songImg == "":
+            songImg = songimage
+        songThm = self._getThumb(songthumb, str(songid) + "-thumb")
+        if songThm == "":
+            songThm = songthumb
         u=sys.argv[0]+"?url="+urllib.quote_plus(songurl)+"&mode="+str(MODE_SONG)+"&name="+urllib.quote_plus(songname)+"&id="+str(songid) \
         +"&album="+urllib.quote_plus(songalbum) \
         +"&artist="+urllib.quote_plus(songartist) \
-        +"&duration="+str(songduration)
-        songItem = xbmcgui.ListItem(songname + " - " + songartist, iconImage=songimage, thumbnailImage=songimage, path=songurl)
-        songItem.setInfo( type="Music", infoLabels={ "Title": songname, "Duration": songduration, "Album": songalbum, "Artist": songartist} )
+        +"&duration="+str(songduration) \
+        +"&thumb="+urllib.quote_plus(songThm) \
+        +"&image="+urllib.quote_plus(songImg)
+        xbmc.log("Artist is " + songartist + ", " + songThm + ", " + songThm)
+        songItem = xbmcgui.ListItem(label = songartist + " - " + songalbum + " - " + songname, iconImage=songImg, thumbnailImage=songThm, path=songurl)
+        songItem.setInfo( type="Music", infoLabels={ "title": songname, "duration": songduration, "album": songalbum, "artist": songartist} )
         fav=sys.argv[0]+"?url="+urllib.quote_plus(songurl)+"&mode="+str(MODE_FAVORITE)+"&name="+urllib.quote_plus(songname)+"&id="+str(songid)
         unfav=sys.argv[0]+"?url="+urllib.quote_plus(songurl)+"&mode="+str(MODE_UNFAVORITE)+"&name="+urllib.quote_plus(songname)+"&id="+str(songid)
         menuItems = []
         menuItems.append(("Grooveshark Favorite",      "XBMC.RunPlugin("+fav+")"))
         menuItems.append(("Not Grooveshark Favorite", "XBMC.RunPlugin("+unfav+")"))
         songItem.addContextMenuItems(menuItems, replaceItems=False)
-        return xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=songItem,isFolder=False)
+        xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=songItem,isFolder=False)
+        return songItem
       
     def _addDir(self, name, url, mode, iconimage, id):
         u=sys.argv[0]+"?url="+urllib.quote_plus(url)+"&mode="+str(mode)+"&name="+urllib.quote_plus(name)+"&id="+str(id)
         dir=xbmcgui.ListItem(name, iconImage=iconimage, thumbnailImage=iconimage)
-        dir.setInfo( type="Music", infoLabels={ "Title": name } )
+        dir.setInfo( type="Music", infoLabels={ "title": name } )
         # Codes from http://xbmc-scripting.googlecode.com/svn/trunk/Script%20Templates/common/gui/codes.py
         menuItems = []
         menuItems.append(("Select", "XBMC.executebuiltin(Action(7))"))
         dir.addContextMenuItems(menuItems, replaceItems=True)
         return xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=dir,isFolder=True)
+    
+    # File download            
+    def _getThumb(self, url, id):
+        # Get the channel icon
+        localThumb = os.path.join(xbmc.translatePath(os.path.join(thumbDir, str(id)))) + '.tbn'
+        try:
+            if os.path.isfile(localThumb) == False:
+                loc = urllib.URLopener()
+                loc.retrieve(url, localThumb)
+        except:
+            xbmc.log('URL download failed of ' + url + ' to ' + localThumb)
+            return ""
+
+        return os.path.join(os.path.join(thumbDir, str(id))) + '.tbn'
+     
+        
    
 def get_params():
     param=[]
@@ -354,7 +386,11 @@ elif mode==MODE_SONG:
     except: pass
     try: duration=int(params["duration"])
     except: pass
-    grooveshark.song(url, name, album, artist, duration)
+    try: thumb=urllib.unquote_plus(params["thumb"])
+    except: pass
+    try: image=urllib.unquote_plus(params["image"])
+    except: pass
+    grooveshark.playSong(url, name, album, artist, duration, thumb, image)
 
 elif mode==MODE_ARTIST:
     grooveshark.artist(lastID)
dissimilarity index 97%
index 5c9e994..3883f4f 100644 (file)
Binary files a/resources/img/album.png and b/resources/img/album.png differ
dissimilarity index 95%
index 43838cb..75a80ce 100644 (file)
Binary files a/resources/img/artist.png and b/resources/img/artist.png differ
dissimilarity index 95%
index 114cc40..f22180e 100644 (file)
Binary files a/resources/img/favorites.png and b/resources/img/favorites.png differ
dissimilarity index 97%
index f8747d0..a72dcae 100644 (file)
Binary files a/resources/img/playlist.png and b/resources/img/playlist.png differ
dissimilarity index 96%
index 81134a8..148c986 100644 (file)
Binary files a/resources/img/popular.png and b/resources/img/popular.png differ
dissimilarity index 98%
index 6765ec3..9f266e0 100644 (file)
Binary files a/resources/img/song.png and b/resources/img/song.png differ
index f4eb865..5cc37f7 100644 (file)
@@ -1,4 +1,4 @@
-import urllib2, md5, unicodedata, re, os, traceback, sys, pickle, socket
+import urllib2, md5, unicodedata, re, os, traceback, sys, pickle, socket, xbmc
 from operator import itemgetter, attrgetter
 
 class LoginTokensExceededError(Exception):
@@ -21,13 +21,8 @@ class SessionIDTryAgainError(Exception):
 
 class GrooveAPI:
        def __init__(self, enableDebug = False, isXbox = False):
-               if isXbox == True:
-                       import simplejson_xbox
-                       self.simplejson = simplejson_xbox
-                       print 'GrooveShark: Initialized as XBOX script'
-               else:
-                       import simplejson
-                       self.simplejson = simplejson
+               import simplejson
+               self.simplejson = simplejson
                timeout = 40
                socket.setdefaulttimeout(timeout)
                self.enableDebug = enableDebug
@@ -38,11 +33,13 @@ class GrooveAPI:
                self.frowns = []
                self.songIDsAlreadySeen = []
                self.recentArtists = []
-               self.rootDir = os.getcwd()
+               self.removeDuplicates = False
+               self.dataDir = 'plugin_data/music/'
+               self.confDir = xbmc.translatePath(os.path.join('special://masterprofile/' + self.dataDir, os.path.basename(os.getcwd())))
                self.sessionID = self.getSavedSession()
                self.debug('Saved sessionID: ' + self.sessionID)
-               self.sessionID = self.getSessionFromAPI()
-               self.debug('API sessionID: ' + self.sessionID)
+               #self.sessionID = self.getSessionFromAPI()
+               #self.debug('API sessionID: ' + self.sessionID)
                if self.sessionID == '':
                        self.sessionID = self.startSession()
                        self.debug('Start() sessionID: ' + self.sessionID)
@@ -64,10 +61,16 @@ class GrooveAPI:
        def debug(self, msg):
                if self.enableDebug == True:
                        print msg
+
+       def setRemoveDuplicates(self, enable):
+               if enable == True or enable == 'true' or enable == 'True':
+                       self.removeDuplicates = True
+               else:
+                       self.removeDuplicates = False
                        
        def getSavedSession(self):
                sessionID = ''
-               path = os.path.join(self.rootDir, 'data', 'session.txt')
+               path = os.path.join(self.confDir, 'session', 'session.txt')
 
                try:
                        f = open(path, 'rb')
@@ -81,10 +84,10 @@ class GrooveAPI:
 
        def saveSession(self):                  
                try:
-                       dir = os.path.join(self.rootDir, 'data')
+                       dir = os.path.join(self.confDir, 'session')
                        # Create the 'data' directory if it doesn't exist.
                        if not os.path.exists(dir):
-                               os.mkdir(dir)
+                               os.makedirs(dir)
                        path = os.path.join(dir, 'session.txt')
                        f = open(path, 'wb')
                        pickle.dump(self.sessionID, f, protocol=pickle.HIGHEST_PROTOCOL)
@@ -98,10 +101,10 @@ class GrooveAPI:
                        
        def saveSettings(self):                 
                try:
-                       dir = os.path.join(self.rootDir, 'data')
+                       dir = os.path.join(self.confDir, 'data')
                        # Create the 'data' directory if it doesn't exist.
                        if not os.path.exists(dir):
-                               os.mkdir(dir)
+                               os.makedirs(dir)
                        path = os.path.join(dir, 'settings1.txt')
                        f = open(path, 'wb')
                        pickle.dump(self.settings, f, protocol=pickle.HIGHEST_PROTOCOL)
@@ -115,14 +118,7 @@ class GrooveAPI:
 
        def callRemote(self, method, params={}):
                data = {'header': {'sessionID': self.sessionID}, 'method': method, 'parameters': params}
-               #data = {'header': {'sessionID': None}, 'method': method, 'parameters': params}
                data = self.simplejson.dumps(data)
-               #proxy_support = urllib2.ProxyHandler({"http" : "http://wwwproxy.kom.aau.dk:3128"})
-               ## build a new opener with proxy details
-               #opener = urllib2.build_opener(proxy_support, urllib2.HTTPHandler)
-               ## install it
-               #urllib2.install_opener(opener)
-               #print data
                req = urllib2.Request("http://api.grooveshark.com/ws/1.0/?json")
                req.add_header('Host', 'api.grooveshark.com')
                req.add_header('Content-type', 'text/json')
@@ -135,6 +131,15 @@ class GrooveAPI:
                        result = self.simplejson.loads(result)
                        if 'fault' in result:
                                self.debug(result)
+                               if result['fault']['code'] == 8: #Session ID has expired. Get a new and try again if possible.
+                                       self.debug(result['fault']['message'])
+                                       self.sessionID = self.startSession()
+                                       if self.sessionID != '':
+                                               self.saveSession()
+                                               return self.callRemote(method, params)
+                                       else:
+                                               self.debug('GrooveShark: SessionID expired, but unable to get new')
+                                               return []
                        return result
                except:
                        return []
@@ -210,6 +215,7 @@ class GrooveAPI:
                        else:
                                self.loggedIn = 1
                                return self.userId
+
                        
        def loginExt(self, username, password):
                if self.loggedIn == 1:
@@ -340,15 +346,6 @@ class GrooveAPI:
                        self.radioEnabled = 1
                        return 1
 
-       def autoplayStop(self):
-               result = self.callRemote("autoplay.stop", {})
-               if 'fault' in result:
-                       self.radioEnabled = 1
-                       return 0
-               else:
-                       self.radioEnabled = 0
-                       return 1
-
        def autoplayGetNextSongEx(self, seedArtists = [], frowns = [], songIDsAlreadySeen = [], recentArtists = []):
                result = self.callRemote("autoplay.getNextSongEx", {"seedArtists": seedArtists, "frowns": frowns, "songIDsAlreadySeen": songIDsAlreadySeen, "recentArtists": recentArtists})
                if 'fault' in result:
@@ -357,16 +354,19 @@ class GrooveAPI:
                        return result
        
        def radioGetNextSong(self):
-               if self.seedArtists == []:
-                       return []
+               radio = self.getSavedRadio()
+               if radio == None:
+                       return None
                else:
-                       result = self.autoplayGetNextSongEx(self.seedArtists, self.frowns, self.songIDsAlreadySeen, self.recentArtists)
-#                      print result
+                       seedArtists = []
+                       for song in radio['seedArtists']:
+                               seedArtists.append(song[7])
+                       result = self.autoplayGetNextSongEx(seedArtists, radio['frowns'], radio['songIDsAlreadySeen'], radio['recentArtists'])
                        if 'fault' in result:
                                return []
                        else:
                                song = self.parseSongs(result)
-                               self.radioAlreadySeen(song[0][1])
+                               self.radioSetAlreadyListenedSong(songId = song[0][1])
                                return song
 
        def radioFrown(self, songId):
@@ -375,8 +375,13 @@ class GrooveAPI:
        def radioAlreadySeen(self, songId):
                self.songIDsAlreadySeen.append(songId)
 
-       def radioAddArtist(self, artistId):
-               self.seedArtists.append(artistId)
+       def radioAddArtist(self, song = None, radioName = None):
+               radio = self.getSavedRadio(name = radioName)
+               if radio != None and song != None:
+                       radio['seedArtists'].append(song)
+                       return self.saveRadio(radio = radio)
+               else:
+                       return 0
 
        def radioStart(self, artists = [], frowns = []):
                for artist in artists:
@@ -400,6 +405,51 @@ class GrooveAPI:
        def radioTurnedOn(self):
                return self.radioEnabled
 
+       def radioSetAlreadyListenedSong(self, name = None, songId = ''):
+               radio = self.getSavedRadio(name = name)
+               if radio != None and songId != '':
+                       radio['songIDsAlreadySeen'].append(songId)
+                       while len(radio['songIDsAlreadySeen']) > 20:
+                               radio['songIDsAlreadySeen'].pop(0) # Trim
+                       return self.saveRadio(radio = radio)
+               else:
+                       return 0
+
+       def getSavedRadio(self, name = None):
+               if name == None:
+                       path = os.path.join(self.confDir, 'radio', 'default.txt')
+               else:
+                       path = os.path.join(self.confDir, 'radio', 'saved', name)
+               try:
+                       f = open(path, 'rb')
+                       radio = pickle.load(f)
+                       f.close()
+               except:
+                       radio = None
+               return radio
+
+       def saveRadio(self, name = None, radio = {}): #blaher
+               try:
+                       dir = os.path.join(self.confDir, 'radio')
+                       # Create the 'data' directory if it doesn't exist.
+                       if not os.path.exists(dir):
+                               os.mkdir(dir)
+                               os.mkdir(os.path.join(dir, 'saved'))
+                       if name == None:
+                               path = os.path.join(dir, 'default.txt')
+                       else:
+                               path = os.path.join(dir, 'saved', name)
+                       f = open(path, 'wb')
+                       pickle.dump(radio, f, protocol=pickle.HIGHEST_PROTOCOL)
+                       f.close()
+                       return 1
+               except IOError, e:
+                       print 'There was an error while saving the radio pickle (%s)' % e
+                       return 0
+               except:
+                       print "An unknown error occured during save radio: " + str(sys.exc_info()[0])
+                       return 0
+
        def favoriteSong(self, songID):
                return self.callRemote("song.favorite", {"songID": songID})
 
@@ -452,6 +502,10 @@ class GrooveAPI:
                list = self.parseAlbums(result)
                return list
                
+       def artistAbout(self, artistId):
+               result = self.callRemote("artist.about", {"artistID": artistId})
+               return result
+               
        def artistGetAlbums(self, artistId, limit, sortKey=2):
                result = self.callRemote("artist.getAlbums", {"artistID": artistId, "limit": limit})
                list = self.parseAlbums(result)
@@ -473,6 +527,19 @@ class GrooveAPI:
                list = self.parseSongs(result)
                return list
 
+       def artistGetSimilar(self, artistId, limit):
+               result = self.callRemote("artist.getSimilar", {"artistID": artistId, "limit": limit})
+               list = self.parseArtists(result)
+               return list
+
+       def songAbout(self, songId):
+               result = self.callRemote("song.about", {"songID": songId})
+               return result['result']['song']
+
+       def getVersion(self):
+               result = self.callRemote("service.getVersion", {})
+               return result
+
        def parseSongs(self, items):
                try:
                        if 'result' in items:
@@ -502,8 +569,9 @@ class GrooveAPI:
                                                        songName = s['songName'].encode('ascii', 'ignore')
                                                        albumName = s['albumName'].encode('ascii', 'ignore')
                                                        artistName = s['artistName'].encode('ascii', 'ignore')
-                                                       if (entry[0].lower() == songName.lower()) and (entry[3].lower() == albumName.lower()) and (entry[6].lower() == artistName.lower()):
-                                                               notIn = False
+                                                       if self.removeDuplicates == True:
+                                                               if (entry[0].lower() == songName.lower()) and (entry[3].lower() == albumName.lower()) and (entry[6].lower() == artistName.lower()):
+                                                                       notIn = False
                                                if notIn == True:
                                                        list.append([s['songName'].encode('ascii', 'ignore'),\
                                                        s['songID'],\
@@ -529,47 +597,74 @@ class GrooveAPI:
                        return []
 
        def parseArtists(self, items):
-               if 'result' in items:
-                       i = 0
-                       list = []
-                       artists = items['result']['artists']
-                       while(i < len(artists)):
-                               s = artists[i]
-                               list.append([s['artistName'].encode('ascii', 'ignore'),\
-                               s['artistID']])
-                               i = i + 1
-                       return list
-               else:
+               try:
+                       if 'result' in items:
+                               i = 0
+                               list = []
+                               artists = items['result']['artists']
+                               while(i < len(artists)):
+                                       s = artists[i]
+                                       try:
+                                               list.append([s['artistName'].encode('ascii', 'ignore'),\
+                                               s['artistID']])
+                                       except:
+                                               print 'GrooveShark: Could not parse album number: ' + str(i)
+                                               traceback.print_exc()
+                                       i = i + 1
+                               return list
+                       else:
+                               return []
+               except:
+                       print 'GrooveShark: Could not parse artists. Got this:'
+                       traceback.print_exc()
                        return []
 
        def parseAlbums(self, items):
-               if 'result' in items:
-                       i = 0
-                       list = []
-                       albums = items['result']['albums']
-                       while(i < len(albums)):
-                               s = albums[i]
-                               list.append([s['artistName'].encode('ascii', 'ignore'),\
-                               s['artistID'],\
-                               s['albumName'].encode('ascii', 'ignore'),\
-                               s['albumID'],\
-                               s['image']['tiny'].encode('ascii', 'ignore')])
-                               i = i + 1
-                       return list
-               else:
+               try:
+                       if 'result' in items:
+                               i = 0
+                               list = []
+                               albums = items['result']['albums']
+                               while(i < len(albums)):
+                                       s = albums[i]
+                                       try: # Avoid ascii ancoding errors
+                                               list.append([s['artistName'].encode('ascii', 'ignore'),\
+                                               s['artistID'],\
+                                               s['albumName'].encode('ascii', 'ignore'),\
+                                               s['albumID'],\
+                                               s['image']['tiny'].encode('ascii', 'ignore')])
+                                       except:
+                                               print 'GrooveShark: Could not parse album number: ' + str(i)
+                                               traceback.print_exc()
+                                       i = i + 1
+                               return list
+                       else:
+                               return []
+               except:
+                       print 'GrooveShark: Could not parse albums. Got this'
+                       traceback.print_exc()
                        return []
 
        def parsePlaylists(self, items):
-               if 'result' in items:
-                       i = 0
-                       list = []
-                       playlists = items['result']['playlists']
-                       while(i < len(playlists)):
-                               s = playlists[i]
-                               list.append([s['playlistID'],\
-                               s['playlistName'].encode('ascii', 'ignore'),\
-                               s['username'].encode('ascii', 'ignore')])
-                               i = i + 1
-                       return list
-               else:
+               try:
+                       if 'result' in items:
+                               i = 0
+                               list = []
+                               playlists = items['result']['playlists']
+                               while(i < len(playlists)):
+                                       s = playlists[i]
+                                       try: # Avoid ascii ancoding errors
+                                               list.append([s['playlistID'],\
+                                               s['playlistName'].encode('ascii', 'ignore'),\
+                                               s['username'].encode('ascii', 'ignore')])
+                                       except:
+                                               print 'GrooveShark: Could not parse playlist number: ' + str(i)
+                                               traceback.print_exc()
+                                       i = i + 1
+                               return list
+                       else:
+                               return []
+               except:
+                       print 'GrooveShark: Could not parse playlists. Got this:'
+                       print items
                        return []