1 import urllib
, urllib2
, re
, xbmcplugin
, xbmcgui
, xbmc
, sys
, os
, time
, pprint
, shutil
, xbmcaddon
5 MODE_SEARCH_ARTISTS
= 3
12 MODE_SIMILAR_ARTISTS
= 10
16 MODE_MAKE_PLAYLIST
= 14
17 MODE_REMOVE_PLAYLIST
= 15
18 MODE_RENAME_PLAYLIST
= 16
19 MODE_REMOVE_PLAYLIST_SONG
= 17
22 resDir
= xbmc
.translatePath(os
.path
.join(baseDir
, 'resources'))
23 libDir
= xbmc
.translatePath(os
.path
.join(resDir
, 'lib'))
24 imgDir
= xbmc
.translatePath(os
.path
.join(resDir
, 'img'))
25 thumbDir
= os
.path
.join('special://masterprofile/addon_data/', os
.path
.join(os
.path
.basename(os
.getcwd()), 'thumb'))
27 baseModeUrl
= 'plugin://plugin.audio.groove/'
28 playlistUrl
= baseModeUrl
+ '?url=&mode=' + str(MODE_PLAYLIST
)
29 playlistsUrl
= baseModeUrl
+ '?mode=' + str(MODE_PLAYLISTS
)
30 favoritesUrl
= baseModeUrl
+ '?mode=' + str(MODE_FAVORITES
)
32 thumbDef
= os
.path
.join(os
.path
.basename(os
.getcwd()), 'default.tbn')
34 sys
.path
.append (libDir
)
35 from GrooveAPI
import *
36 groovesharkApi
= GrooveAPI()
39 def __init__( self
, *args
, **kwargs
):
40 self
.__dict
__.update( kwargs
)
44 albumImg
= xbmc
.translatePath(os
.path
.join(imgDir
, 'album.png'))
45 artistImg
= xbmc
.translatePath(os
.path
.join(imgDir
, 'artist.png'))
46 favoritesImg
= xbmc
.translatePath(os
.path
.join(imgDir
, 'favorites.png'))
47 playlistImg
= xbmc
.translatePath(os
.path
.join(imgDir
, 'playlist.png'))
48 popularSongsImg
= xbmc
.translatePath(os
.path
.join(imgDir
, 'popularSongs.png'))
49 songImg
= xbmc
.translatePath(os
.path
.join(imgDir
, 'song.png'))
50 defImg
= xbmc
.translatePath(os
.path
.join(imgDir
, 'default.tbn'))
51 fanImg
= xbmc
.translatePath(os
.path
.join(baseDir
, 'fanart.png'))
53 settings
= xbmcaddon
.Addon(id='plugin.audio.groove')
54 songsearchlimit
= settings
.getSetting('songsearchlimit')
55 albumsearchlimit
= settings
.getSetting('albumsearchlimit')
56 artistsearchlimit
= settings
.getSetting('artistsearchlimit')
57 username
= settings
.getSetting('username')
58 password
= settings
.getSetting('password')
61 self
._handle
= int(sys
.argv
[1])
65 xbmc
.log(self
.username
+ ", limits: " + str(self
.songsearchlimit
) + ", " + str(self
.albumsearchlimit
) + ", " + str(self
.artistsearchlimit
))
67 userid
= self
._get
_login
()
70 xbmcplugin
.setPluginFanart(int(sys
.argv
[1]), self
.fanImg
)
71 if os
.path
.isdir(thumbDir
) == False:
74 self
._add
_dir
('Search songs', '', MODE_SEARCH_SONGS
, self
.songImg
, 0)
75 self
._add
_dir
('Search albums', '', MODE_SEARCH_ALBUMS
, self
.albumImg
, 0)
76 self
._add
_dir
('Search artists', '', MODE_SEARCH_ARTISTS
, self
.artistImg
, 0)
77 self
._add
_dir
('Popular songs', '', MODE_POPULAR_SONGS
, self
.popularSongsImg
, 0)
79 self
._add
_dir
('Favorites', '', MODE_FAVORITES
, self
.favoritesImg
, 0)
80 self
._add
_dir
('Playlists', '', MODE_PLAYLISTS
, self
.playlistImg
, 0)
82 def searchSongs(self
):
83 query
= self
._get
_keyboard
(default
="", heading
="Search songs")
85 groovesharkApi
.setRemoveDuplicates(True)
86 songs
= groovesharkApi
.searchSongs(query
, limit
= self
.songsearchlimit
)
88 self
._add
_songs
_directory
(songs
)
90 dialog
= xbmcgui
.Dialog()
91 dialog
.ok('Grooveshark', 'No matching songs.')
94 def searchAlbums(self
):
95 query
= self
._get
_keyboard
(default
="", heading
="Search albums")
97 albums
= groovesharkApi
.searchAlbums(query
, limit
= self
.albumsearchlimit
)
99 self
._add
_albums
_directory
(albums
)
101 dialog
= xbmcgui
.Dialog()
102 dialog
.ok('Grooveshark', 'No matching albums.')
105 def searchArtists(self
):
106 query
= self
._get
_keyboard
(default
="", heading
="Search artists")
108 artists
= groovesharkApi
.searchArtists(query
, limit
= self
.artistsearchlimit
)
109 if (len(artists
) > 0):
110 self
._add
_artists
_directory
(artists
)
112 dialog
= xbmcgui
.Dialog()
113 dialog
.ok('Grooveshark', 'No matching artists.')
117 userid
= self
._get
_login
()
119 favorites
= groovesharkApi
.userGetFavoriteSongs(userid
)
120 if (len(favorites
) > 0):
121 self
._add
_songs
_directory
(favorites
, isFavorites
=True)
123 dialog
= xbmcgui
.Dialog()
124 dialog
.ok('Grooveshark', 'You have no favorites.')
127 def popularSongs(self
):
128 popular
= groovesharkApi
.popularGetSongs(limit
= self
.songsearchlimit
)
129 if (len(popular
) > 0):
130 self
._add
_songs
_directory
(popular
)
132 dialog
= xbmcgui
.Dialog()
133 dialog
.ok('Grooveshark', 'No popular songs.')
136 def popularAlbums(self
):
137 popular
= groovesharkApi
.popularGetAlbums(limit
= self
.albumsearchlimit
)
138 if (len(popular
) > 0):
139 self
._add
_albums
_directory
(popular
)
141 dialog
= xbmcgui
.Dialog()
142 dialog
.ok('Grooveshark', 'No popular albums.')
145 def popularArtists(self
):
146 popular
= groovesharkApi
.popularGetArtists(limit
= self
.artistsearchlimit
)
147 if (len(popular
) > 0):
148 self
._add
_artists
_directory
(popular
)
150 dialog
= xbmcgui
.Dialog()
151 dialog
.ok('Grooveshark', 'No popular artists.')
155 userid
= self
._get
_login
()
157 playlists
= groovesharkApi
.userGetPlaylists()
158 if (len(playlists
) > 0):
159 self
._add
_playlists
_directory
(playlists
)
161 dialog
= xbmcgui
.Dialog()
162 dialog
.ok('Grooveshark', 'You have no playlists.')
165 def favorite(self
, songid
):
166 userid
= self
._get
_login
()
168 xbmc
.log("Favorite song: " + str(songid
))
169 groovesharkApi
.favoriteSong(songID
= songid
)
170 xbmc
.executebuiltin('XBMC.Notification(Grooveshark, Added to favorites, 1000, ' + thumbDef
+ ')')
172 dialog
= xbmcgui
.Dialog()
173 dialog
.ok('Grooveshark', 'You must be logged in', 'to add favorites.')
175 def unfavorite(self
, songid
, prevMode
):
176 userid
= self
._get
_login
()
178 xbmc
.log("Unfavorite song: " + str(songid
) + ', previous mode was ' + str(prevMode
))
179 groovesharkApi
.unfavoriteSong(songID
= songid
)
180 xbmc
.executebuiltin('XBMC.Notification(Grooveshark, Removed from favorites, 1000, ' + thumbDef
+ ')')
181 if (int(prevMode
) == MODE_FAVORITES
):
182 xbmc
.executebuiltin("Container.Update(" + favoritesUrl
+ ",replace)")
184 dialog
= xbmcgui
.Dialog()
185 dialog
.ok('Grooveshark', 'You must be logged in', 'to remove favorites.')
187 def frown(self
, songid
):
188 userid
= self
._get
_login
()
190 xbmc
.log("Frown song: " + str(songid
))
191 if groovesharkApi
.radioFrown(songId
= songid
) != True:
192 xbmc
.log("Unable to frown song " + str(songid
))
194 xbmc
.executebuiltin('XBMC.Notification(Grooveshark, Frowned, 1000, ' + thumbDef
+ ')')
196 dialog
= xbmcgui
.Dialog()
197 dialog
.ok('Grooveshark', 'You must be logged in', 'to frown a song.')
199 def similarArtists(self
, artistId
):
200 similar
= groovesharkApi
.artistGetSimilar(artistId
, limit
= self
.artistsearchlimit
)
201 if (len(similar
) > 0):
202 self
._add
_artists
_directory
(similar
)
204 dialog
= xbmcgui
.Dialog()
205 dialog
.ok('Grooveshark', 'No similar artists.')
208 def makePlaylist(self
, albumid
, name
):
209 userid
= self
._get
_login
()
211 re
.split(' - ',name
,1)
212 nameTokens
= re
.split(' - ',name
,1)
213 name
= self
._get
_keyboard
(default
=nameTokens
[0], heading
="Playlist name")
215 groovesharkApi
.setRemoveDuplicates(True)
216 album
= groovesharkApi
.albumGetSongs(albumid
, self
.songsearchlimit
)
219 songids
.append(song
[1])
220 id = groovesharkApi
.playlistCreateUnique(name
, songids
)
222 dialog
= xbmcgui
.Dialog()
223 dialog
.ok('Grooveshark', 'Cannot create playlist ', name
)
225 xbmc
.executebuiltin('XBMC.Notification(Grooveshark, Playlist created, 1000, ' + thumbDef
+ ')')
227 dialog
= xbmcgui
.Dialog()
228 dialog
.ok('Grooveshark', 'You must be logged in ', ' to create a playlist.')
230 def removePlaylist(self
, playlistid
, name
):
231 dialog
= xbmcgui
.Dialog()
232 if dialog
.yesno('Grooveshark', name
, 'Delete this playlist?') == True:
233 userid
= self
._get
_login
()
235 groovesharkApi
.playlistDelete(playlistid
)
236 xbmc
.executebuiltin("Container.Update(" + playlistsUrl
+ ",replace)")
238 dialog
= xbmcgui
.Dialog()
239 dialog
.ok('Grooveshark', 'You must be logged in ', ' to delete a playlist.')
241 def removePlaylistSong(self
, playlistid
, playlistname
, songpos
):
242 dialog
= xbmcgui
.Dialog()
243 if dialog
.yesno('Grooveshark', 'Delete this song from the playlist?') == True:
244 userid
= self
._get
_login
()
246 if groovesharkApi
.playlistDeleteSong(playlistid
, songpos
) == 0:
247 dialog
= xbmcgui
.Dialog()
248 dialog
.ok('Grooveshark', 'Failed to remove ', ' song from playlist.')
250 xbmc
.executebuiltin("Container.Update(" + playlistUrl
+ "&id="+str(playlistid
) + "&name=" + playlistname
+ ",replace)")
252 dialog
= xbmcgui
.Dialog()
253 dialog
.ok('Grooveshark', 'You must be logged in ', ' to delete a song from a playlist.')
255 def renamePlaylist(self
, playlistid
, name
):
256 userid
= self
._get
_login
()
258 newname
= self
._get
_keyboard
(default
=name
, heading
="Playlist name")
261 elif groovesharkApi
.playlistRename(playlistid
, newname
) == 0:
262 dialog
= xbmcgui
.Dialog()
263 dialog
.ok('Grooveshark', 'Cannot rename playlist ', name
)
265 xbmc
.executebuiltin("Container.Refresh")
267 dialog
= xbmcgui
.Dialog()
268 dialog
.ok('Grooveshark', 'You must be logged in ', ' to rename a playlist.')
270 def album(self
, albumid
):
271 groovesharkApi
.setRemoveDuplicates(True)
272 album
= groovesharkApi
.albumGetSongs(albumId
= albumid
, limit
= self
.songsearchlimit
)
273 self
._add
_songs
_directory
(album
)
275 def artist(self
, artistid
):
276 albums
= groovesharkApi
.artistGetAlbums(artistId
= artistid
, limit
= self
.albumsearchlimit
)
277 self
._add
_albums
_directory
(albums
, artistid
)
279 def playlist(self
, playlistid
, playlistname
):
280 userid
= self
._get
_login
()
282 songs
= groovesharkApi
.playlistGetSongs(playlistId
= playlistid
, limit
= self
.songsearchlimit
)
283 self
._add
_songs
_directory
(songs
, playlistid
, playlistname
)
285 dialog
= xbmcgui
.Dialog()
286 dialog
.ok('Grooveshark', 'You must be logged in', 'to get playlists.')
288 def playSong(self
, item
):
289 url
= item
.getProperty('url')
290 xbmc
.log("Playing: " + url
)
291 xbmcplugin
.setResolvedUrl(handle
=int(sys
.argv
[1]), succeeded
=True, listitem
=item
)
293 def songItem(self
, id, name
, album
, artist
, duration
, thumb
, image
):
294 url
= groovesharkApi
.getStreamURL(id)
295 # Only try to get the image
297 songImg
= self
._get
_icon
(image
, 'song-' + str(id) + "-image")
300 songThm
= self
._get
_icon
(thumb
, 'song-' + str(id) + "-thumb")
302 item
= xbmcgui
.ListItem(label
= artist
+ " - " + album
+ " - " + name
, path
=url
, thumbnailImage
=songThm
, iconImage
=songImg
)
303 item
.setInfo( type="music", infoLabels
={ "title": name
, "duration": duration
, "album": album
, "artist": artist
} )
304 item
.setProperty('mimetype', 'audio/mpeg')
305 item
.setProperty("IsPlayable", "true")
306 item
.setProperty('url', url
)
307 item
.setProperty('thumb', songThm
)
308 item
.setProperty('image', songImg
)
312 def _get_keyboard(self
, default
="", heading
="", hidden
=False):
313 kb
= xbmc
.Keyboard(default
, heading
, hidden
)
315 if (kb
.isConfirmed()):
316 return unicode(kb
.getText(), "utf-8")
319 def _get_login(self
):
320 if (self
.username
== "" or self
.password
== ""):
321 dialog
= xbmcgui
.Dialog()
322 dialog
.ok('Grooveshark', 'Unable to login.', 'Check username and password in settings.')
325 if groovesharkApi
.loggedInStatus() == 1:
326 groovesharkApi
.logout()
327 userid
= groovesharkApi
.loginExt(self
.username
, self
.password
)
329 xbmc
.log("Logged in")
332 dialog
= xbmcgui
.Dialog()
333 dialog
.ok('Grooveshark', 'Unable to login.', 'Check username and password in settings.')
336 def _get_song_item(self
, song
):
344 return self
.songItem(id, name
, album
, artist
, duration
, thumb
, image
)
347 def _get_icon(self
, url
, id):
348 localThumb
= os
.path
.join(xbmc
.translatePath(os
.path
.join(thumbDir
, str(id)))) + '.tbn'
350 if os
.path
.isfile(localThumb
) == False:
351 xbmc
.log('Downloading ' + url
+ ' to ' + localThumb
)
352 loc
= urllib
.URLopener()
353 loc
.retrieve(url
, localThumb
)
355 xbmc
.log('URL download failed of ' + url
+ ' to ' + localThumb
)
358 return os
.path
.join(os
.path
.join(thumbDir
, str(id))) + '.tbn'
360 def _add_songs_directory(self
, songs
, playlistid
=0, playlistname
='', isFavorites
=False):
362 xbmc
.log("Found " + str(n
) + " songs...")
366 item
= self
._get
_song
_item
(song
)
367 songurl
= item
.getProperty('url')
368 songthumb
= item
.getProperty('thumb')
369 songimage
= item
.getProperty('image')
372 songduration
= song
[2]
375 u
=sys
.argv
[0]+"?url="+urllib
.quote_plus(songurl
) \
376 +"&mode="+str(MODE_SONG
)+"&name="+urllib
.quote_plus(songname
)+"&id=" \
378 +"&album="+urllib
.quote_plus(songalbum
) \
379 +"&artist="+urllib
.quote_plus(songartist
) \
380 +"&duration="+str(songduration
) \
381 +"&thumb="+urllib
.quote_plus(songthumb
) \
382 +"&image="+urllib
.quote_plus(songimage
)
383 fav
=sys
.argv
[0]+"?url="+urllib
.quote_plus(songurl
)+"&mode="+str(MODE_FAVORITE
)+"&name="+urllib
.quote_plus(songname
)+"&id="+str(songid
)
384 unfav
=sys
.argv
[0]+"?url="+urllib
.quote_plus(songurl
)+"&mode="+str(MODE_UNFAVORITE
)+"&name="+urllib
.quote_plus(songname
)+"&id="+str(songid
)+"&prevmode="
386 if isFavorites
== True:
387 unfav
= unfav
+str(MODE_FAVORITES
)
389 menuItems
.append(("Grooveshark Favorite", "XBMC.RunPlugin("+fav
+")"))
390 menuItems
.append(("Not Grooveshark Favorite", "XBMC.RunPlugin("+unfav
+")"))
392 rmplaylstsong
=sys
.argv
[0]+"?playlistid="+str(playlistid
)+"&id="+str(i
+1)+"&mode="+str(MODE_REMOVE_PLAYLIST_SONG
)+"&name="+playlistname
393 menuItems
.append(("Remove from playlist", "XBMC.RunPlugin("+rmplaylstsong
+")"))
394 item
.addContextMenuItems(menuItems
, replaceItems
=False)
395 xbmcplugin
.addDirectoryItem(handle
=int(sys
.argv
[1]),url
=u
,listitem
=item
,isFolder
=False,totalItems
=n
)
397 xbmcplugin
.setContent(self
._handle
, 'songs')
398 xbmcplugin
.setPluginFanart(int(sys
.argv
[1]), self
.fanImg
)
400 def _add_albums_directory(self
, albums
, artistid
=0):
402 xbmc
.log("Found " + str(n
) + " albums...")
406 albumArtistName
= album
[0]
409 albumImage
= self
._get
_icon
(album
[4], 'album-' + str(albumID
))
410 self
._add
_dir
(albumName
+ " - " + albumArtistName
, '', MODE_ALBUM
, albumImage
, albumID
, n
)
413 self
._add
_dir
('Similar artists...', '', MODE_SIMILAR_ARTISTS
, self
.artistImg
, artistid
)
414 xbmcplugin
.setContent(self
._handle
, 'albums')
415 xbmcplugin
.addSortMethod(self
._handle
, xbmcplugin
.SORT_METHOD_ALBUM_IGNORE_THE
)
416 xbmcplugin
.setPluginFanart(int(sys
.argv
[1]), self
.fanImg
)
418 def _add_artists_directory(self
, artists
):
420 xbmc
.log("Found " + str(n
) + " artists...")
424 artistName
= artist
[0]
426 self
._add
_dir
(artistName
, '', MODE_ARTIST
, self
.artistImg
, artistID
, n
)
428 xbmcplugin
.setContent(self
._handle
, 'artists')
429 xbmcplugin
.addSortMethod(self
._handle
, xbmcplugin
.SORT_METHOD_ARTIST_IGNORE_THE
)
430 xbmcplugin
.setPluginFanart(int(sys
.argv
[1]), self
.fanImg
)
432 def _add_playlists_directory(self
, playlists
):
434 xbmc
.log("Found " + str(n
) + " playlists...")
437 playlist
= playlists
[i
]
438 playlistName
= playlist
[0]
439 playlistID
= playlist
[1]
440 self
._add
_dir
(playlistName
, '', MODE_PLAYLIST
, self
.playlistImg
, playlistID
, n
)
442 xbmcplugin
.setContent(self
._handle
, 'files')
443 xbmcplugin
.addSortMethod(self
._handle
, xbmcplugin
.SORT_METHOD_PLAYLIST_ORDER
)
444 xbmcplugin
.setPluginFanart(int(sys
.argv
[1]), self
.fanImg
)
446 def _add_dir(self
, name
, url
, mode
, iconimage
, id, items
=1):
447 u
=sys
.argv
[0]+"?url="+urllib
.quote_plus(url
)+"&mode="+str(mode
)+"&name="+urllib
.quote_plus(name
)+"&id="+str(id)
448 dir=xbmcgui
.ListItem(name
, iconImage
=iconimage
, thumbnailImage
=iconimage
)
449 dir.setInfo( type="Music", infoLabels
={ "title": name
} )
450 # Codes from http://xbmc-scripting.googlecode.com/svn/trunk/Script%20Templates/common/gui/codes.py
452 menuItems
.append(("Select", "XBMC.executebuiltin(Action(7))"))
453 if mode
== MODE_ALBUM
:
454 mkplaylst
=sys
.argv
[0]+"?mode="+str(MODE_MAKE_PLAYLIST
)+"&name="+name
+"&id="+str(id)
455 menuItems
.append(("Make Grooveshark playlist", "XBMC.RunPlugin("+mkplaylst
+")"))
456 if mode
== MODE_PLAYLIST
:
457 rmplaylst
=sys
.argv
[0]+"?mode="+str(MODE_REMOVE_PLAYLIST
)+"&name="+urllib
.quote_plus(name
)+"&id="+str(id)
458 menuItems
.append(("Delete playlist", "XBMC.RunPlugin("+rmplaylst
+")"))
459 mvplaylst
=sys
.argv
[0]+"?mode="+str(MODE_RENAME_PLAYLIST
)+"&name="+urllib
.quote_plus(name
)+"&id="+str(id)
460 menuItems
.append(("Rename playlist", "XBMC.RunPlugin("+mvplaylst
+")"))
461 dir.addContextMenuItems(menuItems
, replaceItems
=True)
462 return xbmcplugin
.addDirectoryItem(handle
=int(sys
.argv
[1]),url
=u
,listitem
=dir,isFolder
=True, totalItems
=items
)
467 paramstring
=sys
.argv
[2]
468 if len(paramstring
)>=2:
470 cleanedparams
=params
.replace('?','')
471 if (params
[len(params
)-1]=='/'):
472 params
=params
[0:len(params
)-2]
473 pairsofparams
=cleanedparams
.split('&')
475 for i
in range(len(pairsofparams
)):
477 splitparams
=pairsofparams
[i
].split('=')
478 if (len(splitparams
))==2:
479 param
[splitparams
[0]]=splitparams
[1]
483 grooveshark
= Groveshark();
491 try: url
=urllib
.unquote_plus(params
["url"])
493 try: name
=urllib
.unquote_plus(params
["name"])
495 try: mode
=int(params
["mode"])
497 try: id=int(params
["id"])
501 grooveshark
.categories()
503 elif mode
==MODE_SEARCH_SONGS
:
504 grooveshark
.searchSongs()
506 elif mode
==MODE_SEARCH_ALBUMS
:
507 grooveshark
.searchAlbums()
509 elif mode
==MODE_SEARCH_ARTISTS
:
510 grooveshark
.searchArtists()
512 elif mode
==MODE_POPULAR_SONGS
:
513 grooveshark
.popularSongs()
515 elif mode
==MODE_PLAYLISTS
:
516 grooveshark
.playlists()
518 elif mode
==MODE_FAVORITES
:
519 grooveshark
.favorites()
521 elif mode
==MODE_SONG
:
522 try: album
=urllib
.unquote_plus(params
["album"])
524 try: artist
=urllib
.unquote_plus(params
["artist"])
526 try: duration
=int(params
["duration"])
528 try: thumb
=urllib
.unquote_plus(params
["thumb"])
530 try: image
=urllib
.unquote_plus(params
["image"])
532 song
= grooveshark
.songItem(id, name
, album
, artist
, duration
, thumb
, image
)
533 grooveshark
.playSong(song
)
535 elif mode
==MODE_ARTIST
:
536 grooveshark
.artist(id)
538 elif mode
==MODE_ALBUM
:
539 grooveshark
.album(id)
541 elif mode
==MODE_PLAYLIST
:
542 grooveshark
.playlist(id, name
)
544 elif mode
==MODE_FAVORITE
:
545 grooveshark
.favorite(id)
547 elif mode
==MODE_UNFAVORITE
:
548 try: prevMode
=urllib
.unquote_plus(params
["prevmode"])
550 grooveshark
.unfavorite(id, prevMode
)
552 elif mode
==MODE_SIMILAR_ARTISTS
:
553 grooveshark
.similarArtists(id)
555 elif mode
==MODE_MAKE_PLAYLIST
:
556 grooveshark
.makePlaylist(id, name
)
558 elif mode
==MODE_REMOVE_PLAYLIST
:
559 grooveshark
.removePlaylist(id, name
)
561 elif mode
==MODE_RENAME_PLAYLIST
:
562 grooveshark
.renamePlaylist(id, name
)
564 elif mode
==MODE_REMOVE_PLAYLIST_SONG
:
565 try: playlistID
=urllib
.unquote_plus(params
["playlistid"])
567 grooveshark
.removePlaylistSong(playlistID
, name
, id)
569 if (mode
< MODE_SONG
):
570 xbmcplugin
.endOfDirectory(int(sys
.argv
[1]))