Fix next play.
[clinton/xbmc-groove.git] / default.py
CommitLineData
2d388879 1# Copyright 2011 Stephen Denham
2
3# This file is part of xbmc-groove.
4#
5# xbmc-groove is free software: you can redistribute it and/or modify
6# it under the terms of the GNU General Public License as published by
7# the Free Software Foundation, either version 3 of the License, or
8# (at your option) any later version.
9#
10# xbmc-groove is distributed in the hope that it will be useful,
11# but WITHOUT ANY WARRANTY; without even the implied warranty of
12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13# GNU General Public License for more details.
14#
15# You should have received a copy of the GNU General Public License
16# along with xbmc-groove. If not, see <http://www.gnu.org/licenses/>.
17
18
f95afae7 19import urllib, sys, os, shutil, re, pickle, time, tempfile, xbmcaddon, xbmcplugin, xbmcgui, xbmc
2d388879 20
b26b96e6 21__addon__ = xbmcaddon.Addon('plugin.audio.groove')
2d388879 22__addonname__ = __addon__.getAddonInfo('name')
23__cwd__ = __addon__.getAddonInfo('path')
24__author__ = __addon__.getAddonInfo('author')
25__version__ = __addon__.getAddonInfo('version')
26__language__ = __addon__.getLocalizedString
9f9eadcd 27__debugging__ = __addon__.getSetting('debug')
5e72534b 28
8817bb2e 29MODE_SEARCH_SONGS = 1
30MODE_SEARCH_ALBUMS = 2
31MODE_SEARCH_ARTISTS = 3
86f629ea 32MODE_SEARCH_ARTISTS_ALBUMS = 4
33MODE_SEARCH_PLAYLISTS = 5
97289139 34MODE_ARTIST_POPULAR = 6
35MODE_POPULAR_SONGS = 7
36MODE_FAVORITES = 8
37MODE_PLAYLISTS = 9
38MODE_ALBUM = 10
39MODE_ARTIST = 11
40MODE_PLAYLIST = 12
41MODE_SONG_PAGE = 13
052028f1 42MODE_SIMILAR_ARTISTS = 14
43MODE_SONG = 15
44MODE_FAVORITE = 16
45MODE_UNFAVORITE = 17
46MODE_MAKE_PLAYLIST = 18
47MODE_REMOVE_PLAYLIST = 19
48MODE_RENAME_PLAYLIST = 20
49MODE_REMOVE_PLAYLIST_SONG = 21
50MODE_ADD_PLAYLIST_SONG = 22
7ea6f166 51
38df1fa5 52ACTION_MOVE_LEFT = 1
7ea6f166 53ACTION_MOVE_UP = 3
54ACTION_MOVE_DOWN = 4
55ACTION_PAGE_UP = 5
56ACTION_PAGE_DOWN = 6
57ACTION_SELECT_ITEM = 7
58ACTION_PREVIOUS_MENU = 10
8817bb2e 59
86f629ea 60# Formats for track labels
61ARTIST_ALBUM_NAME_LABEL = 0
62NAME_ALBUM_ARTIST_LABEL = 1
63
f95afae7 64# Stream marking time (seconds)
65STREAM_MARKING_TIME = 30
cd937dea 66
67# Timeout
68STREAM_TIMEOUT = 30
69
f95afae7 70songMarkTime = 0
71player = xbmc.Player()
72playTimer = None
73
2d388879 74baseDir = __cwd__
6ae708d0 75resDir = xbmc.translatePath(os.path.join(baseDir, 'resources'))
8817bb2e 76libDir = xbmc.translatePath(os.path.join(resDir, 'lib'))
77imgDir = xbmc.translatePath(os.path.join(resDir, 'img'))
2d388879 78cacheDir = os.path.join(xbmc.translatePath('special://masterprofile/addon_data/'), os.path.basename(baseDir))
7ce01be6 79thumbDirName = 'thumb'
191f20f2 80thumbDir = os.path.join(xbmc.translatePath('special://masterprofile/addon_data/'), os.path.basename(baseDir), thumbDirName)
4be42357 81
82baseModeUrl = 'plugin://plugin.audio.groove/'
e278f474 83playlistUrl = baseModeUrl + '?mode=' + str(MODE_PLAYLIST)
4be42357 84playlistsUrl = baseModeUrl + '?mode=' + str(MODE_PLAYLISTS)
85favoritesUrl = baseModeUrl + '?mode=' + str(MODE_FAVORITES)
86
b26b96e6 87searchArtistsAlbumsName = __language__(30006)
3d95dfcb 88
7ce01be6 89thumbDef = os.path.join(imgDir, 'default.tbn')
052028f1 90listBackground = os.path.join(imgDir, 'listbackground.png')
8817bb2e 91
92sys.path.append (libDir)
7ce01be6 93from GroovesharkAPI import GrooveAPI
f95afae7 94from threading import Event, Thread
7ce01be6 95
9f9eadcd 96if __debugging__ == 'true':
97 __debugging__ = True
98else:
99 __debugging__ = False
100
a3ad8f73 101try:
9f9eadcd 102 groovesharkApi = GrooveAPI(__debugging__)
7ce01be6 103 if groovesharkApi.pingService() != True:
b26b96e6 104 raise StandardError(__language__(30007))
a3ad8f73 105except:
b26b96e6 106 dialog = xbmcgui.Dialog(__language__(30008),__language__(30009),__language__(30010))
6d909a7d 107 dialog.ok(__language__(30008),__language__(30009))
a3ad8f73 108 sys.exit(-1)
109
f95afae7 110# Mark song as playing or played
cfad7202 111def markSong(songid, duration, streamKey, streamServerID):
f95afae7 112 global songMarkTime
113 global playTimer
114 global player
115 if player.isPlayingAudio():
116 tNow = player.getTime()
117 if tNow >= STREAM_MARKING_TIME and songMarkTime == 0:
cfad7202 118 groovesharkApi.markStreamKeyOver30Secs(streamKey, streamServerID)
f95afae7 119 songMarkTime = tNow
120 elif duration > tNow and duration - tNow < 2 and songMarkTime >= STREAM_MARKING_TIME:
121 playTimer.cancel()
122 songMarkTime = 0
cfad7202 123 groovesharkApi.markSongComplete(songid, streamKey, streamServerID)
f95afae7 124 else:
125 playTimer.cancel()
126 songMarkTime = 0
127
8817bb2e 128class _Info:
129 def __init__( self, *args, **kwargs ):
130 self.__dict__.update( kwargs )
e278f474 131
052028f1 132# Window dialog to select a grooveshark playlist
133class GroovesharkPlaylistSelect(xbmcgui.WindowDialog):
134
135 def __init__(self, items=[]):
136 gap = int(self.getHeight()/100)
137 w = int(self.getWidth()*0.5)
138 h = self.getHeight()-30*gap
139 rw = self.getWidth()
140 rh = self.getHeight()
141 x = rw/2 - w/2
142 y = rh/2 -h/2
143
144 self.imgBg = xbmcgui.ControlImage(x+gap, 5*gap+y, w-2*gap, h-5*gap, listBackground)
145 self.addControl(self.imgBg)
146
147 self.playlistControl = xbmcgui.ControlList(2*gap+x, y+3*gap+30, w-4*gap, h-10*gap, textColor='0xFFFFFFFF', selectedColor='0xFFFF4242', itemTextYOffset=0, itemHeight=50, alignmentY = 0)
148 self.addControl(self.playlistControl)
149
150 self.lastPos = 0
151 self.isSelecting = False
152 self.selected = -1
153 listitems = []
154 for playlist in items:
155 listitems.append(xbmcgui.ListItem(playlist[0]))
b26b96e6 156 listitems.append(xbmcgui.ListItem(__language__(30011)))
052028f1 157 self.playlistControl.addItems(listitems)
158 self.setFocus(self.playlistControl)
159 self.playlistControl.selectItem(0)
160 item = self.playlistControl.getListItem(self.lastPos)
161 item.select(True)
162
163 # Highlight selected item
164 def setHighlight(self):
165 if self.isSelecting:
166 return
167 else:
168 self.isSelecting = True
169
170 pos = self.playlistControl.getSelectedPosition()
171 if pos >= 0:
172 item = self.playlistControl.getListItem(self.lastPos)
173 item.select(False)
174 item = self.playlistControl.getListItem(pos)
175 item.select(True)
176 self.lastPos = pos
177 self.isSelecting = False
178
179 # Control - select
180 def onControl(self, control):
181 if control == self.playlistControl:
182 self.selected = self.playlistControl.getSelectedPosition()
183 self.close()
184
185 # Action - close or up/down
186 def onAction(self, action):
187 if action == ACTION_PREVIOUS_MENU:
188 self.selected = -1
189 self.close()
190 elif action == ACTION_MOVE_UP or action == ACTION_MOVE_DOWN or action == ACTION_PAGE_UP or action == ACTION_PAGE_DOWN == 6:
191 self.setFocus(self.playlistControl)
192 self.setHighlight()
f95afae7 193
194
195class PlayTimer(Thread):
196 # interval -- floating point number specifying the number of seconds to wait before executing function
197 # function -- the function (or callable object) to be executed
198
199 # iterations -- integer specifying the number of iterations to perform
200 # args -- list of positional arguments passed to function
201 # kwargs -- dictionary of keyword arguments passed to function
202
203 def __init__(self, interval, function, iterations=0, args=[], kwargs={}):
204 Thread.__init__(self)
205 self.interval = interval
206 self.function = function
207 self.iterations = iterations
208 self.args = args
209 self.kwargs = kwargs
210 self.finished = Event()
211
212 def run(self):
213 count = 0
214 while not self.finished.isSet() and (self.iterations <= 0 or count < self.iterations):
215 self.finished.wait(self.interval)
216 if not self.finished.isSet():
217 self.function(*self.args, **self.kwargs)
218 count += 1
219
220 def cancel(self):
221 self.finished.set()
222
223 def setIterations(self, iterations):
224 self.iterations = iterations
225
226
227 def getTime(self):
228 return self.iterations * self.interval
229
230
5e72534b 231class Grooveshark:
973b4c6c 232
7ea6f166 233 albumImg = xbmc.translatePath(os.path.join(imgDir, 'album.png'))
234 artistImg = xbmc.translatePath(os.path.join(imgDir, 'artist.png'))
86f629ea 235 artistsAlbumsImg = xbmc.translatePath(os.path.join(imgDir, 'artistsalbums.png'))
7ea6f166 236 favoritesImg = xbmc.translatePath(os.path.join(imgDir, 'favorites.png'))
237 playlistImg = xbmc.translatePath(os.path.join(imgDir, 'playlist.png'))
86f629ea 238 usersplaylistsImg = xbmc.translatePath(os.path.join(imgDir, 'usersplaylists.png'))
7ea6f166 239 popularSongsImg = xbmc.translatePath(os.path.join(imgDir, 'popularSongs.png'))
97289139 240 popularSongsArtistImg = xbmc.translatePath(os.path.join(imgDir, 'popularSongsArtist.png'))
7ea6f166 241 songImg = xbmc.translatePath(os.path.join(imgDir, 'song.png'))
242 defImg = xbmc.translatePath(os.path.join(imgDir, 'default.tbn'))
57ffc218 243 fanImg = xbmc.translatePath(os.path.join(baseDir, 'fanart.jpg'))
8817bb2e 244
2254a6b5 245 settings = xbmcaddon.Addon(id='plugin.audio.groove')
7ce01be6 246 songsearchlimit = int(settings.getSetting('songsearchlimit'))
247 albumsearchlimit = int(settings.getSetting('albumsearchlimit'))
248 artistsearchlimit = int(settings.getSetting('artistsearchlimit'))
97289139 249 songspagelimit = int(settings.getSetting('songspagelimit'))
2254a6b5 250 username = settings.getSetting('username')
251 password = settings.getSetting('password')
5e72534b 252
38df1fa5 253 userid = 0
4be42357 254
8817bb2e 255 def __init__( self ):
256 self._handle = int(sys.argv[1])
7ce01be6 257 if os.path.isdir(cacheDir) == False:
258 os.makedirs(cacheDir)
9f9eadcd 259 if __debugging__ :
5e72534b 260 xbmc.log(__language__(30012) + " " + cacheDir)
164e42d8 261 artDir = xbmc.translatePath(thumbDir)
262 if os.path.isdir(artDir) == False:
3a794693 263 os.makedirs(artDir)
9f9eadcd 264 if __debugging__ :
5e72534b 265 xbmc.log(__language__(30012) + " " + artDir)
052028f1 266
e278f474 267 # Top-level menu
8817bb2e 268 def categories(self):
2254a6b5 269
38df1fa5 270 self.userid = self._get_login()
b738088f 271
272 # Setup
6ae708d0 273 xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
6ae708d0 274
b26b96e6 275 self._add_dir(__language__(30013), '', MODE_SEARCH_SONGS, self.songImg, 0)
276 self._add_dir(__language__(30014), '', MODE_SEARCH_ALBUMS, self.albumImg, 0)
277 self._add_dir(__language__(30015), '', MODE_SEARCH_ARTISTS, self.artistImg, 0)
3d95dfcb 278 self._add_dir(searchArtistsAlbumsName, '', MODE_SEARCH_ARTISTS_ALBUMS, self.artistsAlbumsImg, 0)
f95afae7 279 # Not supported by key
280 #self._add_dir("Search for user's playlists...", '', MODE_SEARCH_PLAYLISTS, self.usersplaylistsImg, 0)
b26b96e6 281 self._add_dir(__language__(30016), '', MODE_ARTIST_POPULAR, self.popularSongsArtistImg, 0)
282 self._add_dir(__language__(30017), '', MODE_POPULAR_SONGS, self.popularSongsImg, 0)
38df1fa5 283 if (self.userid != 0):
b26b96e6 284 self._add_dir(__language__(30018), '', MODE_FAVORITES, self.favoritesImg, 0)
285 self._add_dir(__language__(30019), '', MODE_PLAYLISTS, self.playlistImg, 0)
e278f474 286
287 # Search for songs
8817bb2e 288 def searchSongs(self):
b26b96e6 289 query = self._get_keyboard(default="", heading=__language__(30020))
7ea6f166 290 if (query != ''):
7ce01be6 291 songs = groovesharkApi.getSongSearchResults(query, limit = self.songsearchlimit)
8817bb2e 292 if (len(songs) > 0):
6ae708d0 293 self._add_songs_directory(songs)
8817bb2e 294 else:
295 dialog = xbmcgui.Dialog()
b26b96e6 296 dialog.ok(__language__(30008), __language__(30021))
8817bb2e 297 self.categories()
7ea6f166 298 else:
299 self.categories()
8817bb2e 300
e278f474 301 # Search for albums
8817bb2e 302 def searchAlbums(self):
b26b96e6 303 query = self._get_keyboard(default="", heading=__language__(30022))
7ea6f166 304 if (query != ''):
7ce01be6 305 albums = groovesharkApi.getAlbumSearchResults(query, limit = self.albumsearchlimit)
8817bb2e 306 if (len(albums) > 0):
6ae708d0 307 self._add_albums_directory(albums)
8817bb2e 308 else:
309 dialog = xbmcgui.Dialog()
b26b96e6 310 dialog.ok(__language__(30008), __language__(30023))
8817bb2e 311 self.categories()
7ea6f166 312 else:
313 self.categories()
8817bb2e 314
e278f474 315 # Search for artists
8817bb2e 316 def searchArtists(self):
b26b96e6 317 query = self._get_keyboard(default="", heading=__language__(30024))
7ea6f166 318 if (query != ''):
7ce01be6 319 artists = groovesharkApi.getArtistSearchResults(query, limit = self.artistsearchlimit)
8817bb2e 320 if (len(artists) > 0):
6ae708d0 321 self._add_artists_directory(artists)
8817bb2e 322 else:
323 dialog = xbmcgui.Dialog()
b26b96e6 324 dialog.ok(__language__(30008), __language__(30025))
8817bb2e 325 self.categories()
7ea6f166 326 else:
327 self.categories()
86f629ea 328
329 # Search for playlists
330 def searchPlaylists(self):
b26b96e6 331 query = self._get_keyboard(default="", heading=__language__(30026))
86f629ea 332 if (query != ''):
f95afae7 333 playlists = groovesharkApi.getUserPlaylistsByUsername(query)
86f629ea 334 if (len(playlists) > 0):
335 self._add_playlists_directory(playlists)
336 else:
337 dialog = xbmcgui.Dialog()
b26b96e6 338 dialog.ok(__language__(30008), __language__(30027))
86f629ea 339 self.categories()
340 else:
341 self.categories()
342
343 # Search for artists albums
3d95dfcb 344 def searchArtistsAlbums(self, artistName = None):
345 if artistName == None or artistName == searchArtistsAlbumsName:
b26b96e6 346 query = self._get_keyboard(default="", heading=__language__(30028))
99f72740 347 else:
348 query = artistName
86f629ea 349 if (query != ''):
350 artists = groovesharkApi.getArtistSearchResults(query, limit = self.artistsearchlimit)
351 if (len(artists) > 0):
352 artist = artists[0]
353 artistID = artist[1]
9f9eadcd 354 if __debugging__ :
5e72534b 355 xbmc.log("Found " + artist[0] + "...")
8d7ba769 356 albums = groovesharkApi.getArtistAlbums(artistID, self.albumsearchlimit)
86f629ea 357 if (len(albums) > 0):
052028f1 358 self._add_albums_directory(albums, artistID)
86f629ea 359 else:
360 dialog = xbmcgui.Dialog()
b26b96e6 361 dialog.ok(__language__(30008), __language__(30029))
86f629ea 362 self.categories()
363 else:
364 dialog = xbmcgui.Dialog()
b26b96e6 365 dialog.ok(__language__(30008), __language__(30030))
86f629ea 366 self.categories()
367 else:
368 self.categories()
369
e278f474 370 # Get my favorites
8817bb2e 371 def favorites(self):
36cc00d7 372 userid = self._get_login()
373 if (userid != 0):
7ce01be6 374 favorites = groovesharkApi.getUserFavoriteSongs()
36cc00d7 375 if (len(favorites) > 0):
052028f1 376 self._add_songs_directory(favorites, isFavorites=True)
36cc00d7 377 else:
378 dialog = xbmcgui.Dialog()
b26b96e6 379 dialog.ok(__language__(30008), __language__(30031))
36cc00d7 380 self.categories()
8817bb2e 381
e278f474 382 # Get popular songs
36cc00d7 383 def popularSongs(self):
7ce01be6 384 popular = groovesharkApi.getPopularSongsToday(limit = self.songsearchlimit)
8817bb2e 385 if (len(popular) > 0):
6ae708d0 386 self._add_songs_directory(popular)
8817bb2e 387 else:
388 dialog = xbmcgui.Dialog()
b26b96e6 389 dialog.ok(__language__(30008), __language__(30032))
8817bb2e 390 self.categories()
36cc00d7 391
e278f474 392 # Get my playlists
8817bb2e 393 def playlists(self):
394 userid = self._get_login()
395 if (userid != 0):
7ce01be6 396 playlists = groovesharkApi.getUserPlaylists()
8817bb2e 397 if (len(playlists) > 0):
6ae708d0 398 self._add_playlists_directory(playlists)
8817bb2e 399 else:
400 dialog = xbmcgui.Dialog()
b26b96e6 401 dialog.ok(__language__(30008), __language__(30033))
8817bb2e 402 self.categories()
7ea6f166 403 else:
404 dialog = xbmcgui.Dialog()
b26b96e6 405 dialog.ok(__language__(30008), __language__(30034), __language__(30035))
7ea6f166 406
e278f474 407 # Make songs a favorite
8817bb2e 408 def favorite(self, songid):
409 userid = self._get_login()
410 if (userid != 0):
9f9eadcd 411 if __debugging__ :
5e72534b 412 xbmc.log("Favorite song: " + str(songid))
7ce01be6 413 groovesharkApi.addUserFavoriteSong(songID = songid)
b26b96e6 414 xbmc.executebuiltin('XBMC.Notification(' + __language__(30008) + ', ' + __language__(30036) + ', 1000, ' + thumbDef + ')')
8817bb2e 415 else:
416 dialog = xbmcgui.Dialog()
b26b96e6 417 dialog.ok(__language__(30008), __language__(30034), __language__(30037))
052028f1 418
419 # Remove song from favorites
420 def unfavorite(self, songid, prevMode=0):
f95afae7 421 userid = self._get_login()
052028f1 422 if (userid != 0):
9f9eadcd 423 if __debugging__ :
5e72534b 424 xbmc.log("Unfavorite song: " + str(songid) + ', previous mode was ' + str(prevMode))
f95afae7 425 groovesharkApi.removeUserFavoriteSongs(songIDs = songid)
b26b96e6 426 xbmc.executebuiltin('XBMC.Notification(' + __language__(30008) + ', ' + __language__(30038) + ', 1000, ' + thumbDef + ')')
052028f1 427 # Refresh to remove item from directory
428 if (int(prevMode) == MODE_FAVORITES):
429 xbmc.executebuiltin("Container.Refresh(" + favoritesUrl + ")")
430 else:
431 dialog = xbmcgui.Dialog()
b26b96e6 432 dialog.ok(__language__(30008), __language__(30034), __language__(30039))
052028f1 433
e278f474 434
435 # Show selected album
36cc00d7 436 def album(self, albumid):
7ce01be6 437 album = groovesharkApi.getAlbumSongs(albumid, limit = self.songsearchlimit)
86f629ea 438 self._add_songs_directory(album, trackLabelFormat=NAME_ALBUM_ARTIST_LABEL)
e278f474 439
440 # Show selected artist
8817bb2e 441 def artist(self, artistid):
7ce01be6 442 albums = groovesharkApi.getArtistAlbums(artistid, limit = self.albumsearchlimit)
5d3b12f2 443 self._add_albums_directory(albums, artistid, True)
8817bb2e 444
e278f474 445 # Show selected playlist
e6f8730b 446 def playlist(self, playlistid, playlistname):
8817bb2e 447 userid = self._get_login()
448 if (userid != 0):
e6f8730b 449 songs = groovesharkApi.getPlaylistSongs(playlistid)
052028f1 450 self._add_songs_directory(songs, trackLabelFormat=NAME_ALBUM_ARTIST_LABEL, playlistid=playlistid, playlistname=playlistname)
8817bb2e 451 else:
452 dialog = xbmcgui.Dialog()
b26b96e6 453 dialog.ok(__language__(30008), __language__(30034), __language__(30040))
8817bb2e 454
97289139 455 # Show popular songs of the artist
456 def artistPopularSongs(self):
b26b96e6 457 query = self._get_keyboard(default="", heading=__language__(30041))
97289139 458 if (query != ''):
459 artists = groovesharkApi.getArtistSearchResults(query, limit = self.artistsearchlimit)
460 if (len(artists) > 0):
461 artist = artists[0]
462 artistID = artist[1]
9f9eadcd 463 if __debugging__ :
5e72534b 464 xbmc.log("Found " + artist[0] + "...")
97289139 465 songs = groovesharkApi.getArtistPopularSongs(artistID, limit = self.songsearchlimit)
466 if (len(songs) > 0):
467 self._add_songs_directory(songs, trackLabelFormat=NAME_ALBUM_ARTIST_LABEL)
468 else:
469 dialog = xbmcgui.Dialog()
b26b96e6 470 dialog.ok(__language__(30008), __language__(30042))
97289139 471 self.categories()
472 else:
473 dialog = xbmcgui.Dialog()
b26b96e6 474 dialog.ok(__language__(30008), __language__(30043))
97289139 475 self.categories()
476 else:
477 self.categories()
478
e278f474 479 # Play a song
6ae708d0 480 def playSong(self, item):
f95afae7 481 global playTimer
482 global player
db319cef 483 player.stop()
f95afae7 484 if item != None:
f7eadea2 485 # Get stream as it could have expired
48e0c138 486 url = ''
9f9eadcd 487 songid = item.getProperty('songid')
48e0c138 488 stream = groovesharkApi.getSubscriberStreamKey(songid)
489 if stream != False:
490 url = stream['url']
9f9eadcd 491 key = stream['StreamKey']
492 server = stream['StreamServerID']
f7eadea2 493 duration = int(self._setDuration(stream['uSecs']))
48e0c138 494 if url != '':
495 item.setPath(url)
496 xbmcplugin.setResolvedUrl(handle=int(sys.argv[1]), succeeded=True, listitem=item)
9f9eadcd 497 if __debugging__ :
48e0c138 498 xbmc.log("Grooveshark playing: " + url)
499 # Wait for play then start timer
f7eadea2 500 xbmcplugin.setResolvedUrl(handle=int(sys.argv[1]), succeeded=True, listitem=item)
48e0c138 501 seconds = 0
502 while seconds < STREAM_TIMEOUT:
503 try:
504 if player.isPlayingAudio() == True:
505 if playTimer != None:
506 playTimer.cancel()
507 songMarkTime = 0
9f9eadcd 508 playTimer = PlayTimer(1, markSong, duration, [songid, duration, key, server])
48e0c138 509 playTimer.start()
510 break
511 except: pass
512 time.sleep(1)
513 seconds = seconds + 1
514 else:
515 xbmc.log("No song URL")
7ce01be6 516 else:
b26b96e6 517 xbmc.executebuiltin('XBMC.Notification(' + __language__(30008) + ', ' + __language__(30044) + ', 1000, ' + thumbDef + ')')
f95afae7 518
e278f474 519 # Make a song directory item
86f629ea 520 def songItem(self, songid, name, album, artist, coverart, trackLabelFormat=ARTIST_ALBUM_NAME_LABEL):
7ce01be6 521
f7eadea2 522 stream = groovesharkApi.getSubscriberStreamKey(songid)
523 if stream != False:
524 url = stream['url']
525 key = stream['StreamKey']
526 server = stream['StreamServerID']
527 duration = self._setDuration(stream['uSecs'])
528 songImg = self._get_icon(coverart, 'song-' + str(songid) + "-image")
529 if int(trackLabelFormat) == NAME_ALBUM_ARTIST_LABEL:
530 trackLabel = name + " - " + album + " - " + artist
531 else:
532 trackLabel = artist + " - " + album + " - " + name
533 item = xbmcgui.ListItem(label = trackLabel, thumbnailImage=songImg, iconImage=songImg)
534 item.setPath(url)
535 item.setInfo( type="music", infoLabels={ "title": name, "album": album, "artist": artist, "duration": duration} )
536 item.setProperty('mimetype', 'audio/mpeg')
537 item.setProperty("IsPlayable", "true")
538 item.setProperty('songid', str(songid))
539 item.setProperty('coverart', songImg)
540 item.setProperty('title', name)
541 item.setProperty('album', album)
542 item.setProperty('artist', artist)
543 item.setProperty('duration', str(duration))
544 item.setProperty('key', str(key))
545 item.setProperty('server', str(server))
546 return item
547 else:
548 xbmc.log("No song URL")
549 return None
2254a6b5 550
97289139 551 # Next page of songs
5e72534b 552 def songPage(self, offset, trackLabelFormat, playlistid = 0, playlistname = ''):
553 self._add_songs_directory([], trackLabelFormat, offset, playlistid = playlistid, playlistname = playlistname)
052028f1 554
555 # Make a playlist from an album
556 def makePlaylist(self, albumid, name):
f95afae7 557 userid = self._get_login()
052028f1 558 if (userid != 0):
559 re.split(' - ',name,1)
560 nameTokens = re.split(' - ',name,1) # suggested name
b26b96e6 561 name = self._get_keyboard(default=nameTokens[0], heading=__language__(30045))
052028f1 562 if name != '':
563 album = groovesharkApi.getAlbumSongs(albumid, limit = self.songsearchlimit)
564 songids = []
565 for song in album:
566 songids.append(song[1])
f95afae7 567 if groovesharkApi.createPlaylist(name, songids) == 0:
052028f1 568 dialog = xbmcgui.Dialog()
b26b96e6 569 dialog.ok(__language__(30008), __language__(30046), name)
052028f1 570 else:
b26b96e6 571 xbmc.executebuiltin('XBMC.Notification(' + __language__(30008) + ',' + __language__(30047)+ ', 1000, ' + thumbDef + ')')
052028f1 572 else:
573 dialog = xbmcgui.Dialog()
b26b96e6 574 dialog.ok(__language__(30008), __language__(30034), __language__(30048))
052028f1 575
576 # Rename a playlist
577 def renamePlaylist(self, playlistid, name):
f95afae7 578 userid = self._get_login()
052028f1 579 if (userid != 0):
b26b96e6 580 newname = self._get_keyboard(default=name, heading=__language__(30049))
052028f1 581 if newname == '':
582 return
f95afae7 583 elif groovesharkApi.playlistRename(playlistid, newname) == 0:
052028f1 584 dialog = xbmcgui.Dialog()
b26b96e6 585 dialog.ok(__language__(30008), __language__(30050), name)
052028f1 586 else:
587 # Refresh to show new item name
588 xbmc.executebuiltin("Container.Refresh")
589 else:
590 dialog = xbmcgui.Dialog()
b26b96e6 591 dialog.ok(__language__(30008), __language__(30034), __language__(30051))
052028f1 592
593 # Remove a playlist
594 def removePlaylist(self, playlistid, name):
595 dialog = xbmcgui.Dialog()
b26b96e6 596 if dialog.yesno(__language__(30008), name, __language__(30052)) == True:
f95afae7 597 userid = self._get_login()
052028f1 598 if (userid != 0):
f95afae7 599 if groovesharkApi.playlistDelete(playlistid) == 0:
052028f1 600 dialog = xbmcgui.Dialog()
b26b96e6 601 dialog.ok(__language__(30008), __language__(30053), name)
052028f1 602 else:
603 # Refresh to remove item from directory
604 xbmc.executebuiltin("Container.Refresh(" + playlistsUrl + ")")
605 else:
606 dialog = xbmcgui.Dialog()
b26b96e6 607 dialog.ok(__language__(30008), __language__(30034), __language__(30054))
052028f1 608
609 # Add song to playlist
610 def addPlaylistSong(self, songid):
f95afae7 611 userid = self._get_login()
052028f1 612 if (userid != 0):
613 playlists = groovesharkApi.getUserPlaylists()
614 if (len(playlists) > 0):
615 ret = 0
616 # Select the playlist
617 playlistSelect = GroovesharkPlaylistSelect(items=playlists)
618 playlistSelect.setFocus(playlistSelect.playlistControl)
619 playlistSelect.doModal()
620 i = playlistSelect.selected
621 del playlistSelect
622 if i > -1:
623 # Add a new playlist
624 if i >= len(playlists):
b26b96e6 625 name = self._get_keyboard(default='', heading=__language__(30055))
052028f1 626 if name != '':
627 songIds = []
628 songIds.append(songid)
f95afae7 629 if groovesharkApi.createPlaylist(name, songIds) == 0:
052028f1 630 dialog = xbmcgui.Dialog()
b26b96e6 631 dialog.ok(__language__(30008), __language__(30056), name)
052028f1 632 else:
b26b96e6 633 xbmc.executebuiltin('XBMC.Notification(' + __language__(30008) + ',' + __language__(30057) + ', 1000, ' + thumbDef + ')')
052028f1 634 # Existing playlist
635 else:
636 playlist = playlists[i]
637 playlistid = playlist[1]
9f9eadcd 638 if __debugging__ :
5e72534b 639 xbmc.log("Add song " + str(songid) + " to playlist " + str(playlistid))
f95afae7 640 songIDs=[]
641 songs = groovesharkApi.getPlaylistSongs(playlistid)
642 for song in songs:
643 songIDs.append(song[1])
644 songIDs.append(songid)
645 ret = groovesharkApi.setPlaylistSongs(playlistid, songIDs)
646 if ret == False:
052028f1 647 dialog = xbmcgui.Dialog()
b26b96e6 648 dialog.ok(__language__(30008), __language__(30058))
052028f1 649 else:
b26b96e6 650 xbmc.executebuiltin('XBMC.Notification(' + __language__(30008) + ',' + __language__(30059) + ', 1000, ' + thumbDef + ')')
052028f1 651 else:
652 dialog = xbmcgui.Dialog()
b26b96e6 653 dialog.ok(__language__(30008), __language__(30060))
052028f1 654 self.categories()
655 else:
656 dialog = xbmcgui.Dialog()
b26b96e6 657 dialog.ok(__language__(30008), __language__(30034), __language__(30061))
052028f1 658
659 # Remove song from playlist
f95afae7 660 def removePlaylistSong(self, playlistid, playlistname, songid):
e6f8730b 661 dialog = xbmcgui.Dialog()
b26b96e6 662 if dialog.yesno(__language__(30008), __language__(30062), __language__(30063)) == True:
f95afae7 663 userid = self._get_login()
052028f1 664 if (userid != 0):
f95afae7 665 songs = groovesharkApi.getPlaylistSongs(playlistID)
666 songIDs=[]
667 for song in songs:
668 if (song[1] != songid):
669 songIDs.append(song[1])
670 ret = groovesharkApi.setPlaylistSongs(playlistID, songIDs)
671 if ret == False:
052028f1 672 dialog = xbmcgui.Dialog()
b26b96e6 673 dialog.ok(__language__(30008), __language__(30064), __language__(30065))
052028f1 674 else:
675 # Refresh to remove item from directory
b26b96e6 676 xbmc.executebuiltin('XBMC.Notification(' + __language__(30008) + ',' + __language__(30066)+ ', 1000, ' + thumbDef + ')')
e6f8730b 677 xbmc.executebuiltin("Container.Update(" + playlistUrl + "&id="+str(playlistid) + "&name=" + playlistname + ")")
052028f1 678 else:
679 dialog = xbmcgui.Dialog()
b26b96e6 680 dialog.ok(__language__(30008), __language__(30034), __language__(30067))
052028f1 681
682 # Find similar artists to searched artist
683 def similarArtists(self, artistId):
f95afae7 684 similar = groovesharkApi.getSimilarArtists(artistId, limit = self.artistsearchlimit)
052028f1 685 if (len(similar) > 0):
686 self._add_artists_directory(similar)
687 else:
688 dialog = xbmcgui.Dialog()
b26b96e6 689 dialog.ok(__language__(30008), __language__(30068))
052028f1 690 self.categories()
5e72534b 691
e278f474 692 # Get keyboard input
8817bb2e 693 def _get_keyboard(self, default="", heading="", hidden=False):
3cfead3c 694 kb = xbmc.Keyboard(default, heading, hidden)
695 kb.doModal()
696 if (kb.isConfirmed()):
697 return unicode(kb.getText(), "utf-8")
698 return ''
8817bb2e 699
e278f474 700 # Login to grooveshark
f95afae7 701 def _get_login(self):
2254a6b5 702 if (self.username == "" or self.password == ""):
8817bb2e 703 dialog = xbmcgui.Dialog()
b26b96e6 704 dialog.ok(__language__(30008), __language__(30069), __language__(30070))
8817bb2e 705 return 0
706 else:
38df1fa5 707 if self.userid == 0:
f95afae7 708 uid = groovesharkApi.login(self.username, self.password)
38df1fa5 709 if (uid != 0):
38df1fa5 710 return uid
8817bb2e 711 else:
712 dialog = xbmcgui.Dialog()
b26b96e6 713 dialog.ok(__language__(30008), __language__(30069), __language__(30070))
8817bb2e 714 return 0
715
6ae708d0 716 # File download
7ce01be6 717 def _get_icon(self, url, songid):
718 if url != 'None':
719 localThumb = os.path.join(xbmc.translatePath(os.path.join(thumbDir, str(songid)))) + '.tbn'
720 try:
721 if os.path.isfile(localThumb) == False:
722 loc = urllib.URLopener()
723 loc.retrieve(url, localThumb)
724 except:
725 shutil.copy2(thumbDef, localThumb)
726 return os.path.join(os.path.join(thumbDir, str(songid))) + '.tbn'
727 else:
728 return thumbDef
e278f474 729
730 # Add songs to directory
5e72534b 731 def _add_songs_directory(self, songs, trackLabelFormat=ARTIST_ALBUM_NAME_LABEL, offset=0, playlistid=0, playlistname='', isFavorites=False):
97289139 732
733 totalSongs = len(songs)
5e72534b 734 offset = int(offset)
735 start = 0
736 end = totalSongs
97289139 737
738 # No pages needed
5e72534b 739 if offset == 0 and totalSongs <= self.songspagelimit:
9f9eadcd 740 if __debugging__ :
5e72534b 741 xbmc.log("Found " + str(totalSongs) + " songs...")
97289139 742 # Pages
743 else:
5e72534b 744 # Cache all next pages songs
745 if offset == 0:
97289139 746 self._setSavedSongs(songs)
747 else:
748 songs = self._getSavedSongs()
749 totalSongs = len(songs)
750
751 if totalSongs > 0:
5e72534b 752 start = offset
753 end = min(start + self.songspagelimit,totalSongs)
97289139 754
052028f1 755 id = 0
5e72534b 756 n = start
757 items = end - start
758 while n < end:
759 song = songs[n]
f7eadea2 760 name = song[0]
6ae708d0 761 songid = song[1]
f7eadea2 762 album = song[2]
763 artist = song[4]
764 coverart = song[6]
765 item = self.songItem(songid, name, album, artist, coverart, trackLabelFormat)
766 if item != None:
5e72534b 767 coverart = item.getProperty('coverart')
768 songname = song[0]
769 songalbum = song[2]
770 songartist = song[4]
771 u=sys.argv[0]+"?mode="+str(MODE_SONG)+"&name="+urllib.quote_plus(songname)+"&id="+str(songid) \
772 +"&album="+urllib.quote_plus(songalbum) \
773 +"&artist="+urllib.quote_plus(songartist) \
774 +"&coverart="+urllib.quote_plus(coverart)
775 fav=sys.argv[0]+"?mode="+str(MODE_FAVORITE)+"&name="+urllib.quote_plus(songname)+"&id="+str(songid)
776 unfav=sys.argv[0]+"?mode="+str(MODE_UNFAVORITE)+"&name="+urllib.quote_plus(songname)+"&id="+str(songid)+"&prevmode="
777 menuItems = []
778 if isFavorites == True:
779 unfav = unfav +str(MODE_FAVORITES)
780 else:
781 menuItems.append((__language__(30071), "XBMC.RunPlugin("+fav+")"))
782 menuItems.append((__language__(30072), "XBMC.RunPlugin("+unfav+")"))
783 if playlistid > 0:
784 rmplaylstsong=sys.argv[0]+"?playlistid="+str(playlistid)+"&id="+str(songid)+"&mode="+str(MODE_REMOVE_PLAYLIST_SONG)+"&name="+playlistname
785 menuItems.append((__language__(30073), "XBMC.RunPlugin("+rmplaylstsong+")"))
786 else:
787 addplaylstsong=sys.argv[0]+"?id="+str(songid)+"&mode="+str(MODE_ADD_PLAYLIST_SONG)
788 menuItems.append((__language__(30074), "XBMC.RunPlugin("+addplaylstsong+")"))
789 item.addContextMenuItems(menuItems, replaceItems=False)
790 xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=item,isFolder=False, totalItems=items)
791 id = id + 1
f95afae7 792 else:
5e72534b 793 end = min(end + 1,totalSongs)
9f9eadcd 794 if __debugging__ :
5e72534b 795 xbmc.log(song[0] + " does not exist.")
796 n = n + 1
97289139 797
5e72534b 798 if totalSongs > end:
799 u=sys.argv[0]+"?mode="+str(MODE_SONG_PAGE)+"&id=playlistid"+"&offset="+str(end)+"&label="+str(trackLabelFormat)+"&name="+playlistname
800 self._add_dir(__language__(30075) + '...', u, MODE_SONG_PAGE, self.songImg, 0, totalSongs - end)
cb06c186 801
8817bb2e 802 xbmcplugin.setContent(self._handle, 'songs')
31731635 803 xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
e278f474 804
805 # Add albums to directory
5d3b12f2 806 def _add_albums_directory(self, albums, artistid=0, isverified=False):
31731635 807 n = len(albums)
5e72534b 808 itemsExisting = n
9f9eadcd 809 if __debugging__ :
5e72534b 810 xbmc.log("Found " + str(n) + " albums...")
8817bb2e 811 i = 0
31731635 812 while i < n:
8817bb2e 813 album = albums[i]
8817bb2e 814 albumID = album[3]
5d3b12f2 815 if isverified or groovesharkApi.getDoesAlbumExist(albumID):
5e72534b 816 albumArtistName = album[0]
817 albumName = album[2]
818 albumImage = self._get_icon(album[4], 'album-' + str(albumID))
819 self._add_dir(albumName + " - " + albumArtistName, '', MODE_ALBUM, albumImage, albumID, itemsExisting)
820 else:
821 itemsExisting = itemsExisting - 1
8817bb2e 822 i = i + 1
f95afae7 823 # Not supported by key
824 #if artistid > 0:
825 # self._add_dir('Similar artists...', '', MODE_SIMILAR_ARTISTS, self.artistImg, artistid)
8817bb2e 826 xbmcplugin.setContent(self._handle, 'albums')
827 xbmcplugin.addSortMethod(self._handle, xbmcplugin.SORT_METHOD_ALBUM_IGNORE_THE)
31731635 828 xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
e278f474 829
830 # Add artists to directory
6ae708d0 831 def _add_artists_directory(self, artists):
31731635 832 n = len(artists)
5e72534b 833 itemsExisting = n
9f9eadcd 834 if __debugging__ :
5e72534b 835 xbmc.log("Found " + str(n) + " artists...")
8817bb2e 836 i = 0
31731635 837 while i < n:
8817bb2e 838 artist = artists[i]
8817bb2e 839 artistID = artist[1]
5e72534b 840 if groovesharkApi.getDoesArtistExist(artistID):
841 artistName = artist[0]
842 self._add_dir(artistName, '', MODE_ARTIST, self.artistImg, artistID, itemsExisting)
843 else:
844 itemsExisting = itemsExisting - 1
8817bb2e 845 i = i + 1
846 xbmcplugin.setContent(self._handle, 'artists')
847 xbmcplugin.addSortMethod(self._handle, xbmcplugin.SORT_METHOD_ARTIST_IGNORE_THE)
31731635 848 xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
e278f474 849
850 # Add playlists to directory
6ae708d0 851 def _add_playlists_directory(self, playlists):
31731635 852 n = len(playlists)
9f9eadcd 853 if __debugging__ :
5e72534b 854 xbmc.log("Found " + str(n) + " playlists...")
8817bb2e 855 i = 0
31731635 856 while i < n:
8817bb2e 857 playlist = playlists[i]
858 playlistName = playlist[0]
859 playlistID = playlist[1]
86f629ea 860 dir = self._add_dir(playlistName, '', MODE_PLAYLIST, self.playlistImg, playlistID, n)
8817bb2e 861 i = i + 1
862 xbmcplugin.setContent(self._handle, 'files')
86f629ea 863 xbmcplugin.addSortMethod(self._handle, xbmcplugin.SORT_METHOD_LABEL)
31731635 864 xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
3fcef5ba 865
e278f474 866 # Add whatever directory
31731635 867 def _add_dir(self, name, url, mode, iconimage, id, items=1):
052028f1 868
97289139 869 if url == '':
870 u=sys.argv[0]+"?mode="+str(mode)+"&name="+urllib.quote_plus(name)+"&id="+str(id)
871 else:
872 u = url
8817bb2e 873 dir=xbmcgui.ListItem(name, iconImage=iconimage, thumbnailImage=iconimage)
b738088f 874 dir.setInfo( type="Music", infoLabels={ "title": name } )
052028f1 875
876 # Custom menu items
f95afae7 877 menuItems = []
878 if mode == MODE_ALBUM:
879 mkplaylst=sys.argv[0]+"?mode="+str(MODE_MAKE_PLAYLIST)+"&name="+name+"&id="+str(id)
b26b96e6 880 menuItems.append((__language__(30076), "XBMC.RunPlugin("+mkplaylst+")"))
f95afae7 881 if mode == MODE_PLAYLIST:
882 rmplaylst=sys.argv[0]+"?mode="+str(MODE_REMOVE_PLAYLIST)+"&name="+urllib.quote_plus(name)+"&id="+str(id)
b26b96e6 883 menuItems.append((__language__(30077), "XBMC.RunPlugin("+rmplaylst+")"))
f95afae7 884 mvplaylst=sys.argv[0]+"?mode="+str(MODE_RENAME_PLAYLIST)+"&name="+urllib.quote_plus(name)+"&id="+str(id)
b26b96e6 885 menuItems.append((__language__(30078), "XBMC.RunPlugin("+mvplaylst+")"))
5e72534b 886
f95afae7 887 dir.addContextMenuItems(menuItems, replaceItems=False)
052028f1 888
31731635 889 return xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=dir,isFolder=True, totalItems=items)
97289139 890
891 def _getSavedSongs(self):
892 path = os.path.join(cacheDir, 'songs.dmp')
893 try:
894 f = open(path, 'rb')
895 songs = pickle.load(f)
896 f.close()
897 except:
898 songs = []
899 pass
900 return songs
901
902 def _setSavedSongs(self, songs):
903 try:
904 # Create the 'data' directory if it doesn't exist.
905 if not os.path.exists(cacheDir):
906 os.makedirs(cacheDir)
907 path = os.path.join(cacheDir, 'songs.dmp')
908 f = open(path, 'wb')
909 pickle.dump(songs, f, protocol=pickle.HIGHEST_PROTOCOL)
910 f.close()
911 except:
912 xbmc.log("An error occurred saving songs")
913 pass
f95afae7 914
9f9eadcd 915 # Duration to seconds
cfad7202 916 def _setDuration(self, usecs):
917 if usecs < 60000000:
918 usecs = usecs * 10 # Some durations are 10x to small
919 return usecs / 1000000
97289139 920
e278f474 921# Parse URL parameters
8817bb2e 922def get_params():
923 param=[]
924 paramstring=sys.argv[2]
9f9eadcd 925 if __debugging__ :
5e72534b 926 xbmc.log(paramstring)
8817bb2e 927 if len(paramstring)>=2:
928 params=sys.argv[2]
929 cleanedparams=params.replace('?','')
930 if (params[len(params)-1]=='/'):
931 params=params[0:len(params)-2]
932 pairsofparams=cleanedparams.split('&')
933 param={}
934 for i in range(len(pairsofparams)):
935 splitparams={}
936 splitparams=pairsofparams[i].split('=')
937 if (len(splitparams))==2:
938 param[splitparams[0]]=splitparams[1]
8817bb2e 939 return param
940
e278f474 941# Main
5e72534b 942grooveshark = Grooveshark();
e278f474 943
8817bb2e 944params=get_params()
8817bb2e 945mode=None
8817bb2e 946try: mode=int(params["mode"])
947except: pass
7ce01be6 948id=0
949try: id=int(params["id"])
950except: pass
052028f1 951name = None
952try: name=urllib.unquote_plus(params["name"])
953except: pass
e278f474 954
955# Call function for URL
8817bb2e 956if mode==None:
957 grooveshark.categories()
958
959elif mode==MODE_SEARCH_SONGS:
960 grooveshark.searchSongs()
961
962elif mode==MODE_SEARCH_ALBUMS:
963 grooveshark.searchAlbums()
964
965elif mode==MODE_SEARCH_ARTISTS:
966 grooveshark.searchArtists()
86f629ea 967
968elif mode==MODE_SEARCH_ARTISTS_ALBUMS:
a2e75b14 969 grooveshark.searchArtistsAlbums(name)
86f629ea 970
971elif mode==MODE_SEARCH_PLAYLISTS:
972 grooveshark.searchPlaylists()
8817bb2e 973
36cc00d7 974elif mode==MODE_POPULAR_SONGS:
975 grooveshark.popularSongs()
97289139 976
977elif mode==MODE_ARTIST_POPULAR:
a2e75b14 978 grooveshark.artistPopularSongs()
8817bb2e 979
8817bb2e 980elif mode==MODE_FAVORITES:
981 grooveshark.favorites()
982
e278f474 983elif mode==MODE_PLAYLISTS:
984 grooveshark.playlists()
97289139 985
986elif mode==MODE_SONG_PAGE:
5e72534b 987 try: offset=urllib.unquote_plus(params["offset"])
97289139 988 except: pass
989 try: label=urllib.unquote_plus(params["label"])
990 except: pass
5e72534b 991 grooveshark.songPage(offset, label, id, name)
e278f474 992
8817bb2e 993elif mode==MODE_SONG:
8817bb2e 994 try: album=urllib.unquote_plus(params["album"])
995 except: pass
996 try: artist=urllib.unquote_plus(params["artist"])
997 except: pass
7ce01be6 998 try: coverart=urllib.unquote_plus(params["coverart"])
8817bb2e 999 except: pass
7ce01be6 1000 song = grooveshark.songItem(id, name, album, artist, coverart)
3fcef5ba 1001 grooveshark.playSong(song)
8817bb2e 1002
1003elif mode==MODE_ARTIST:
4be42357 1004 grooveshark.artist(id)
8817bb2e 1005
1006elif mode==MODE_ALBUM:
4be42357 1007 grooveshark.album(id)
8817bb2e 1008
1009elif mode==MODE_PLAYLIST:
e6f8730b 1010 grooveshark.playlist(id, name)
8817bb2e 1011
1012elif mode==MODE_FAVORITE:
4be42357 1013 grooveshark.favorite(id)
97289139 1014
052028f1 1015elif mode==MODE_UNFAVORITE:
1016 try: prevMode=int(urllib.unquote_plus(params["prevmode"]))
1017 except:
1018 prevMode = 0
1019 grooveshark.unfavorite(id, prevMode)
1020
1021elif mode==MODE_SIMILAR_ARTISTS:
1022 grooveshark.similarArtists(id)
1023
1024elif mode==MODE_MAKE_PLAYLIST:
1025 grooveshark.makePlaylist(id, name)
1026
1027elif mode==MODE_REMOVE_PLAYLIST:
1028 grooveshark.removePlaylist(id, name)
1029
1030elif mode==MODE_RENAME_PLAYLIST:
1031 grooveshark.renamePlaylist(id, name)
1032
1033elif mode==MODE_REMOVE_PLAYLIST_SONG:
1034 try: playlistID=urllib.unquote_plus(params["playlistid"])
1035 except: pass
1036 grooveshark.removePlaylistSong(playlistID, name, id)
1037
1038elif mode==MODE_ADD_PLAYLIST_SONG:
1039 grooveshark.addPlaylistSong(id)
1040
e278f474 1041if mode < MODE_SONG:
8817bb2e 1042 xbmcplugin.endOfDirectory(int(sys.argv[1]))