Cache streams.
[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
a9e5e6c4 486 item.select(True)
48e0c138 487 url = ''
9f9eadcd 488 songid = item.getProperty('songid')
48e0c138 489 stream = groovesharkApi.getSubscriberStreamKey(songid)
490 if stream != False:
491 url = stream['url']
9f9eadcd 492 key = stream['StreamKey']
493 server = stream['StreamServerID']
f7eadea2 494 duration = int(self._setDuration(stream['uSecs']))
a9e5e6c4 495 stream = [songid, duration, url, key, server]
496 self._setSongStream(stream)
497 if url != '':
498 item.setPath(url)
499 xbmcplugin.setResolvedUrl(handle=int(sys.argv[1]), succeeded=True, listitem=item)
500 if __debugging__ :
501 xbmc.log("Grooveshark playing: " + url)
502 # Wait for play then start timer
503 seconds = 0
504 while seconds < STREAM_TIMEOUT:
505 try:
506 if player.isPlayingAudio() == True:
507 if playTimer != None:
508 playTimer.cancel()
509 songMarkTime = 0
510 playTimer = PlayTimer(1, markSong, self._setDuration(duration), [songid, duration, key, server])
511 playTimer.start()
512 break
513 except: pass
514 time.sleep(1)
515 seconds = seconds + 1
516 else:
517 xbmc.log("No song URL")
48e0c138 518 else:
a9e5e6c4 519 xbmc.log("No song stream")
7ce01be6 520 else:
b26b96e6 521 xbmc.executebuiltin('XBMC.Notification(' + __language__(30008) + ', ' + __language__(30044) + ', 1000, ' + thumbDef + ')')
f95afae7 522
e278f474 523 # Make a song directory item
86f629ea 524 def songItem(self, songid, name, album, artist, coverart, trackLabelFormat=ARTIST_ALBUM_NAME_LABEL):
7ce01be6 525
a9e5e6c4 526 stream = self._getSongStream(songid)
f7eadea2 527 if stream != False:
a9e5e6c4 528 duration = stream[1]
529 url = stream[2]
530 key = stream[3]
531 server = stream[4]
f7eadea2 532 songImg = self._get_icon(coverart, 'song-' + str(songid) + "-image")
533 if int(trackLabelFormat) == NAME_ALBUM_ARTIST_LABEL:
534 trackLabel = name + " - " + album + " - " + artist
535 else:
536 trackLabel = artist + " - " + album + " - " + name
537 item = xbmcgui.ListItem(label = trackLabel, thumbnailImage=songImg, iconImage=songImg)
538 item.setPath(url)
539 item.setInfo( type="music", infoLabels={ "title": name, "album": album, "artist": artist, "duration": duration} )
540 item.setProperty('mimetype', 'audio/mpeg')
541 item.setProperty("IsPlayable", "true")
542 item.setProperty('songid', str(songid))
543 item.setProperty('coverart', songImg)
544 item.setProperty('title', name)
545 item.setProperty('album', album)
546 item.setProperty('artist', artist)
547 item.setProperty('duration', str(duration))
548 item.setProperty('key', str(key))
549 item.setProperty('server', str(server))
550 return item
551 else:
552 xbmc.log("No song URL")
553 return None
2254a6b5 554
97289139 555 # Next page of songs
5e72534b 556 def songPage(self, offset, trackLabelFormat, playlistid = 0, playlistname = ''):
557 self._add_songs_directory([], trackLabelFormat, offset, playlistid = playlistid, playlistname = playlistname)
052028f1 558
559 # Make a playlist from an album
560 def makePlaylist(self, albumid, name):
f95afae7 561 userid = self._get_login()
052028f1 562 if (userid != 0):
563 re.split(' - ',name,1)
564 nameTokens = re.split(' - ',name,1) # suggested name
b26b96e6 565 name = self._get_keyboard(default=nameTokens[0], heading=__language__(30045))
052028f1 566 if name != '':
567 album = groovesharkApi.getAlbumSongs(albumid, limit = self.songsearchlimit)
568 songids = []
569 for song in album:
570 songids.append(song[1])
f95afae7 571 if groovesharkApi.createPlaylist(name, songids) == 0:
052028f1 572 dialog = xbmcgui.Dialog()
b26b96e6 573 dialog.ok(__language__(30008), __language__(30046), name)
052028f1 574 else:
b26b96e6 575 xbmc.executebuiltin('XBMC.Notification(' + __language__(30008) + ',' + __language__(30047)+ ', 1000, ' + thumbDef + ')')
052028f1 576 else:
577 dialog = xbmcgui.Dialog()
b26b96e6 578 dialog.ok(__language__(30008), __language__(30034), __language__(30048))
052028f1 579
580 # Rename a playlist
581 def renamePlaylist(self, playlistid, name):
f95afae7 582 userid = self._get_login()
052028f1 583 if (userid != 0):
b26b96e6 584 newname = self._get_keyboard(default=name, heading=__language__(30049))
052028f1 585 if newname == '':
586 return
f95afae7 587 elif groovesharkApi.playlistRename(playlistid, newname) == 0:
052028f1 588 dialog = xbmcgui.Dialog()
b26b96e6 589 dialog.ok(__language__(30008), __language__(30050), name)
052028f1 590 else:
591 # Refresh to show new item name
592 xbmc.executebuiltin("Container.Refresh")
593 else:
594 dialog = xbmcgui.Dialog()
b26b96e6 595 dialog.ok(__language__(30008), __language__(30034), __language__(30051))
052028f1 596
597 # Remove a playlist
598 def removePlaylist(self, playlistid, name):
599 dialog = xbmcgui.Dialog()
b26b96e6 600 if dialog.yesno(__language__(30008), name, __language__(30052)) == True:
f95afae7 601 userid = self._get_login()
052028f1 602 if (userid != 0):
f95afae7 603 if groovesharkApi.playlistDelete(playlistid) == 0:
052028f1 604 dialog = xbmcgui.Dialog()
b26b96e6 605 dialog.ok(__language__(30008), __language__(30053), name)
052028f1 606 else:
607 # Refresh to remove item from directory
608 xbmc.executebuiltin("Container.Refresh(" + playlistsUrl + ")")
609 else:
610 dialog = xbmcgui.Dialog()
b26b96e6 611 dialog.ok(__language__(30008), __language__(30034), __language__(30054))
052028f1 612
613 # Add song to playlist
614 def addPlaylistSong(self, songid):
f95afae7 615 userid = self._get_login()
052028f1 616 if (userid != 0):
617 playlists = groovesharkApi.getUserPlaylists()
618 if (len(playlists) > 0):
619 ret = 0
620 # Select the playlist
621 playlistSelect = GroovesharkPlaylistSelect(items=playlists)
622 playlistSelect.setFocus(playlistSelect.playlistControl)
623 playlistSelect.doModal()
624 i = playlistSelect.selected
625 del playlistSelect
626 if i > -1:
627 # Add a new playlist
628 if i >= len(playlists):
b26b96e6 629 name = self._get_keyboard(default='', heading=__language__(30055))
052028f1 630 if name != '':
631 songIds = []
632 songIds.append(songid)
f95afae7 633 if groovesharkApi.createPlaylist(name, songIds) == 0:
052028f1 634 dialog = xbmcgui.Dialog()
b26b96e6 635 dialog.ok(__language__(30008), __language__(30056), name)
052028f1 636 else:
b26b96e6 637 xbmc.executebuiltin('XBMC.Notification(' + __language__(30008) + ',' + __language__(30057) + ', 1000, ' + thumbDef + ')')
052028f1 638 # Existing playlist
639 else:
640 playlist = playlists[i]
641 playlistid = playlist[1]
9f9eadcd 642 if __debugging__ :
5e72534b 643 xbmc.log("Add song " + str(songid) + " to playlist " + str(playlistid))
f95afae7 644 songIDs=[]
645 songs = groovesharkApi.getPlaylistSongs(playlistid)
646 for song in songs:
647 songIDs.append(song[1])
648 songIDs.append(songid)
649 ret = groovesharkApi.setPlaylistSongs(playlistid, songIDs)
650 if ret == False:
052028f1 651 dialog = xbmcgui.Dialog()
b26b96e6 652 dialog.ok(__language__(30008), __language__(30058))
052028f1 653 else:
b26b96e6 654 xbmc.executebuiltin('XBMC.Notification(' + __language__(30008) + ',' + __language__(30059) + ', 1000, ' + thumbDef + ')')
052028f1 655 else:
656 dialog = xbmcgui.Dialog()
b26b96e6 657 dialog.ok(__language__(30008), __language__(30060))
052028f1 658 self.categories()
659 else:
660 dialog = xbmcgui.Dialog()
b26b96e6 661 dialog.ok(__language__(30008), __language__(30034), __language__(30061))
052028f1 662
663 # Remove song from playlist
f95afae7 664 def removePlaylistSong(self, playlistid, playlistname, songid):
e6f8730b 665 dialog = xbmcgui.Dialog()
b26b96e6 666 if dialog.yesno(__language__(30008), __language__(30062), __language__(30063)) == True:
f95afae7 667 userid = self._get_login()
052028f1 668 if (userid != 0):
f95afae7 669 songs = groovesharkApi.getPlaylistSongs(playlistID)
670 songIDs=[]
671 for song in songs:
672 if (song[1] != songid):
673 songIDs.append(song[1])
674 ret = groovesharkApi.setPlaylistSongs(playlistID, songIDs)
675 if ret == False:
052028f1 676 dialog = xbmcgui.Dialog()
b26b96e6 677 dialog.ok(__language__(30008), __language__(30064), __language__(30065))
052028f1 678 else:
679 # Refresh to remove item from directory
b26b96e6 680 xbmc.executebuiltin('XBMC.Notification(' + __language__(30008) + ',' + __language__(30066)+ ', 1000, ' + thumbDef + ')')
e6f8730b 681 xbmc.executebuiltin("Container.Update(" + playlistUrl + "&id="+str(playlistid) + "&name=" + playlistname + ")")
052028f1 682 else:
683 dialog = xbmcgui.Dialog()
b26b96e6 684 dialog.ok(__language__(30008), __language__(30034), __language__(30067))
052028f1 685
686 # Find similar artists to searched artist
687 def similarArtists(self, artistId):
f95afae7 688 similar = groovesharkApi.getSimilarArtists(artistId, limit = self.artistsearchlimit)
052028f1 689 if (len(similar) > 0):
690 self._add_artists_directory(similar)
691 else:
692 dialog = xbmcgui.Dialog()
b26b96e6 693 dialog.ok(__language__(30008), __language__(30068))
052028f1 694 self.categories()
5e72534b 695
e278f474 696 # Get keyboard input
8817bb2e 697 def _get_keyboard(self, default="", heading="", hidden=False):
3cfead3c 698 kb = xbmc.Keyboard(default, heading, hidden)
699 kb.doModal()
700 if (kb.isConfirmed()):
701 return unicode(kb.getText(), "utf-8")
702 return ''
8817bb2e 703
e278f474 704 # Login to grooveshark
f95afae7 705 def _get_login(self):
2254a6b5 706 if (self.username == "" or self.password == ""):
8817bb2e 707 dialog = xbmcgui.Dialog()
b26b96e6 708 dialog.ok(__language__(30008), __language__(30069), __language__(30070))
8817bb2e 709 return 0
710 else:
38df1fa5 711 if self.userid == 0:
f95afae7 712 uid = groovesharkApi.login(self.username, self.password)
38df1fa5 713 if (uid != 0):
38df1fa5 714 return uid
8817bb2e 715 else:
716 dialog = xbmcgui.Dialog()
b26b96e6 717 dialog.ok(__language__(30008), __language__(30069), __language__(30070))
8817bb2e 718 return 0
719
6ae708d0 720 # File download
7ce01be6 721 def _get_icon(self, url, songid):
722 if url != 'None':
723 localThumb = os.path.join(xbmc.translatePath(os.path.join(thumbDir, str(songid)))) + '.tbn'
724 try:
725 if os.path.isfile(localThumb) == False:
726 loc = urllib.URLopener()
727 loc.retrieve(url, localThumb)
728 except:
729 shutil.copy2(thumbDef, localThumb)
730 return os.path.join(os.path.join(thumbDir, str(songid))) + '.tbn'
731 else:
732 return thumbDef
e278f474 733
734 # Add songs to directory
5e72534b 735 def _add_songs_directory(self, songs, trackLabelFormat=ARTIST_ALBUM_NAME_LABEL, offset=0, playlistid=0, playlistname='', isFavorites=False):
97289139 736
737 totalSongs = len(songs)
5e72534b 738 offset = int(offset)
739 start = 0
740 end = totalSongs
97289139 741
742 # No pages needed
5e72534b 743 if offset == 0 and totalSongs <= self.songspagelimit:
9f9eadcd 744 if __debugging__ :
5e72534b 745 xbmc.log("Found " + str(totalSongs) + " songs...")
97289139 746 # Pages
747 else:
5e72534b 748 # Cache all next pages songs
749 if offset == 0:
97289139 750 self._setSavedSongs(songs)
751 else:
752 songs = self._getSavedSongs()
753 totalSongs = len(songs)
754
755 if totalSongs > 0:
5e72534b 756 start = offset
757 end = min(start + self.songspagelimit,totalSongs)
97289139 758
052028f1 759 id = 0
5e72534b 760 n = start
761 items = end - start
762 while n < end:
763 song = songs[n]
f7eadea2 764 name = song[0]
6ae708d0 765 songid = song[1]
f7eadea2 766 album = song[2]
767 artist = song[4]
768 coverart = song[6]
769 item = self.songItem(songid, name, album, artist, coverart, trackLabelFormat)
770 if item != None:
5e72534b 771 coverart = item.getProperty('coverart')
772 songname = song[0]
773 songalbum = song[2]
774 songartist = song[4]
775 u=sys.argv[0]+"?mode="+str(MODE_SONG)+"&name="+urllib.quote_plus(songname)+"&id="+str(songid) \
776 +"&album="+urllib.quote_plus(songalbum) \
777 +"&artist="+urllib.quote_plus(songartist) \
778 +"&coverart="+urllib.quote_plus(coverart)
779 fav=sys.argv[0]+"?mode="+str(MODE_FAVORITE)+"&name="+urllib.quote_plus(songname)+"&id="+str(songid)
780 unfav=sys.argv[0]+"?mode="+str(MODE_UNFAVORITE)+"&name="+urllib.quote_plus(songname)+"&id="+str(songid)+"&prevmode="
781 menuItems = []
782 if isFavorites == True:
783 unfav = unfav +str(MODE_FAVORITES)
784 else:
785 menuItems.append((__language__(30071), "XBMC.RunPlugin("+fav+")"))
786 menuItems.append((__language__(30072), "XBMC.RunPlugin("+unfav+")"))
787 if playlistid > 0:
788 rmplaylstsong=sys.argv[0]+"?playlistid="+str(playlistid)+"&id="+str(songid)+"&mode="+str(MODE_REMOVE_PLAYLIST_SONG)+"&name="+playlistname
789 menuItems.append((__language__(30073), "XBMC.RunPlugin("+rmplaylstsong+")"))
790 else:
791 addplaylstsong=sys.argv[0]+"?id="+str(songid)+"&mode="+str(MODE_ADD_PLAYLIST_SONG)
792 menuItems.append((__language__(30074), "XBMC.RunPlugin("+addplaylstsong+")"))
793 item.addContextMenuItems(menuItems, replaceItems=False)
794 xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=item,isFolder=False, totalItems=items)
795 id = id + 1
f95afae7 796 else:
5e72534b 797 end = min(end + 1,totalSongs)
9f9eadcd 798 if __debugging__ :
5e72534b 799 xbmc.log(song[0] + " does not exist.")
800 n = n + 1
97289139 801
5e72534b 802 if totalSongs > end:
803 u=sys.argv[0]+"?mode="+str(MODE_SONG_PAGE)+"&id=playlistid"+"&offset="+str(end)+"&label="+str(trackLabelFormat)+"&name="+playlistname
804 self._add_dir(__language__(30075) + '...', u, MODE_SONG_PAGE, self.songImg, 0, totalSongs - end)
cb06c186 805
8817bb2e 806 xbmcplugin.setContent(self._handle, 'songs')
31731635 807 xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
e278f474 808
809 # Add albums to directory
5d3b12f2 810 def _add_albums_directory(self, albums, artistid=0, isverified=False):
31731635 811 n = len(albums)
5e72534b 812 itemsExisting = n
9f9eadcd 813 if __debugging__ :
5e72534b 814 xbmc.log("Found " + str(n) + " albums...")
8817bb2e 815 i = 0
31731635 816 while i < n:
8817bb2e 817 album = albums[i]
8817bb2e 818 albumID = album[3]
5d3b12f2 819 if isverified or groovesharkApi.getDoesAlbumExist(albumID):
5e72534b 820 albumArtistName = album[0]
821 albumName = album[2]
822 albumImage = self._get_icon(album[4], 'album-' + str(albumID))
823 self._add_dir(albumName + " - " + albumArtistName, '', MODE_ALBUM, albumImage, albumID, itemsExisting)
824 else:
825 itemsExisting = itemsExisting - 1
8817bb2e 826 i = i + 1
f95afae7 827 # Not supported by key
828 #if artistid > 0:
829 # self._add_dir('Similar artists...', '', MODE_SIMILAR_ARTISTS, self.artistImg, artistid)
8817bb2e 830 xbmcplugin.setContent(self._handle, 'albums')
831 xbmcplugin.addSortMethod(self._handle, xbmcplugin.SORT_METHOD_ALBUM_IGNORE_THE)
31731635 832 xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
e278f474 833
834 # Add artists to directory
6ae708d0 835 def _add_artists_directory(self, artists):
31731635 836 n = len(artists)
5e72534b 837 itemsExisting = n
9f9eadcd 838 if __debugging__ :
5e72534b 839 xbmc.log("Found " + str(n) + " artists...")
8817bb2e 840 i = 0
31731635 841 while i < n:
8817bb2e 842 artist = artists[i]
8817bb2e 843 artistID = artist[1]
5e72534b 844 if groovesharkApi.getDoesArtistExist(artistID):
845 artistName = artist[0]
846 self._add_dir(artistName, '', MODE_ARTIST, self.artistImg, artistID, itemsExisting)
847 else:
848 itemsExisting = itemsExisting - 1
8817bb2e 849 i = i + 1
850 xbmcplugin.setContent(self._handle, 'artists')
851 xbmcplugin.addSortMethod(self._handle, xbmcplugin.SORT_METHOD_ARTIST_IGNORE_THE)
31731635 852 xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
e278f474 853
854 # Add playlists to directory
6ae708d0 855 def _add_playlists_directory(self, playlists):
31731635 856 n = len(playlists)
9f9eadcd 857 if __debugging__ :
5e72534b 858 xbmc.log("Found " + str(n) + " playlists...")
8817bb2e 859 i = 0
31731635 860 while i < n:
8817bb2e 861 playlist = playlists[i]
862 playlistName = playlist[0]
863 playlistID = playlist[1]
86f629ea 864 dir = self._add_dir(playlistName, '', MODE_PLAYLIST, self.playlistImg, playlistID, n)
8817bb2e 865 i = i + 1
866 xbmcplugin.setContent(self._handle, 'files')
86f629ea 867 xbmcplugin.addSortMethod(self._handle, xbmcplugin.SORT_METHOD_LABEL)
31731635 868 xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
3fcef5ba 869
e278f474 870 # Add whatever directory
31731635 871 def _add_dir(self, name, url, mode, iconimage, id, items=1):
052028f1 872
97289139 873 if url == '':
874 u=sys.argv[0]+"?mode="+str(mode)+"&name="+urllib.quote_plus(name)+"&id="+str(id)
875 else:
876 u = url
8817bb2e 877 dir=xbmcgui.ListItem(name, iconImage=iconimage, thumbnailImage=iconimage)
b738088f 878 dir.setInfo( type="Music", infoLabels={ "title": name } )
052028f1 879
880 # Custom menu items
f95afae7 881 menuItems = []
882 if mode == MODE_ALBUM:
883 mkplaylst=sys.argv[0]+"?mode="+str(MODE_MAKE_PLAYLIST)+"&name="+name+"&id="+str(id)
b26b96e6 884 menuItems.append((__language__(30076), "XBMC.RunPlugin("+mkplaylst+")"))
f95afae7 885 if mode == MODE_PLAYLIST:
886 rmplaylst=sys.argv[0]+"?mode="+str(MODE_REMOVE_PLAYLIST)+"&name="+urllib.quote_plus(name)+"&id="+str(id)
b26b96e6 887 menuItems.append((__language__(30077), "XBMC.RunPlugin("+rmplaylst+")"))
f95afae7 888 mvplaylst=sys.argv[0]+"?mode="+str(MODE_RENAME_PLAYLIST)+"&name="+urllib.quote_plus(name)+"&id="+str(id)
b26b96e6 889 menuItems.append((__language__(30078), "XBMC.RunPlugin("+mvplaylst+")"))
5e72534b 890
f95afae7 891 dir.addContextMenuItems(menuItems, replaceItems=False)
052028f1 892
31731635 893 return xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=dir,isFolder=True, totalItems=items)
97289139 894
895 def _getSavedSongs(self):
896 path = os.path.join(cacheDir, 'songs.dmp')
897 try:
898 f = open(path, 'rb')
899 songs = pickle.load(f)
900 f.close()
901 except:
902 songs = []
903 pass
904 return songs
905
906 def _setSavedSongs(self, songs):
907 try:
908 # Create the 'data' directory if it doesn't exist.
909 if not os.path.exists(cacheDir):
910 os.makedirs(cacheDir)
911 path = os.path.join(cacheDir, 'songs.dmp')
912 f = open(path, 'wb')
913 pickle.dump(songs, f, protocol=pickle.HIGHEST_PROTOCOL)
914 f.close()
915 except:
916 xbmc.log("An error occurred saving songs")
917 pass
f95afae7 918
9f9eadcd 919 # Duration to seconds
cfad7202 920 def _setDuration(self, usecs):
921 if usecs < 60000000:
922 usecs = usecs * 10 # Some durations are 10x to small
a9e5e6c4 923 return int(usecs / 1000000)
924
925 def _getSongStream(self, songid):
926 id = int(songid)
927 stream = None
928 streams = []
929 path = os.path.join(cacheDir, 'streams.dmp')
930 try:
931 f = open(path, 'rb')
932 streams = pickle.load(f)
933 for song in streams:
934 if song[0] == id:
935 duration = song[1]
936 url = song[2]
937 key = song[3]
938 server = song[4]
939 stream = [id, duration, url, key, server]
940 if __debugging__ :
941 xbmc.log("Found " + str(id) + " in cache")
942 break;
943 f.close()
944 except:
945 pass
946
947 # Not in cache
948 if stream == None:
949 stream = groovesharkApi.getSubscriberStreamKey(songid)
950 if stream != False and stream['url'] != '':
951 duration = self._setDuration(stream['uSecs'])
952 url = stream['url']
953 key = stream['StreamKey']
954 server = stream['StreamServerID']
955 stream = [id, duration, url, key, server]
956 self._addSongStream(stream, streams)
957
958 return stream
959
960 def _addSongStream(self, stream, streams):
961 try:
962 streams.append(stream)
963 # Create the cache directory if it doesn't exist.
964 if not os.path.exists(cacheDir):
965 os.makedirs(cacheDir)
966 path = os.path.join(cacheDir, 'streams.dmp')
967 f = open(path, 'wb')
968 pickle.dump(streams, f, protocol=pickle.HIGHEST_PROTOCOL)
969 f.close()
970 except:
971 xbmc.log("An error occurred adding stream")
972 pass
973
974 def _setSongStream(self, stream):
975 id = int(stream[0])
976 stream[1] = self._setDuration(stream[1])
977 streams = []
978 path = os.path.join(cacheDir, 'streams.dmp')
979 try:
980 f = open(path, 'wb')
981 streams = pickle.load(f)
982 i = 0
983 for song in streams:
984 if song[0] == id:
985 streams[i] = stream
986 if __debugging__ :
987 xbmc.log("Added " + str(id) + " to cache")
988 pickle.dump(streams, f, protocol=pickle.HIGHEST_PROTOCOL)
989 break;
990 i = i + 1
991 f.close()
992 except:
993 xbmc.log("An error occurred setting stream")
994
97289139 995
e278f474 996# Parse URL parameters
8817bb2e 997def get_params():
998 param=[]
999 paramstring=sys.argv[2]
9f9eadcd 1000 if __debugging__ :
5e72534b 1001 xbmc.log(paramstring)
8817bb2e 1002 if len(paramstring)>=2:
1003 params=sys.argv[2]
1004 cleanedparams=params.replace('?','')
1005 if (params[len(params)-1]=='/'):
1006 params=params[0:len(params)-2]
1007 pairsofparams=cleanedparams.split('&')
1008 param={}
1009 for i in range(len(pairsofparams)):
1010 splitparams={}
1011 splitparams=pairsofparams[i].split('=')
1012 if (len(splitparams))==2:
1013 param[splitparams[0]]=splitparams[1]
8817bb2e 1014 return param
1015
e278f474 1016# Main
5e72534b 1017grooveshark = Grooveshark();
e278f474 1018
8817bb2e 1019params=get_params()
8817bb2e 1020mode=None
8817bb2e 1021try: mode=int(params["mode"])
1022except: pass
7ce01be6 1023id=0
1024try: id=int(params["id"])
1025except: pass
052028f1 1026name = None
1027try: name=urllib.unquote_plus(params["name"])
1028except: pass
e278f474 1029
1030# Call function for URL
8817bb2e 1031if mode==None:
1032 grooveshark.categories()
1033
1034elif mode==MODE_SEARCH_SONGS:
1035 grooveshark.searchSongs()
1036
1037elif mode==MODE_SEARCH_ALBUMS:
1038 grooveshark.searchAlbums()
1039
1040elif mode==MODE_SEARCH_ARTISTS:
1041 grooveshark.searchArtists()
86f629ea 1042
1043elif mode==MODE_SEARCH_ARTISTS_ALBUMS:
a2e75b14 1044 grooveshark.searchArtistsAlbums(name)
86f629ea 1045
1046elif mode==MODE_SEARCH_PLAYLISTS:
1047 grooveshark.searchPlaylists()
8817bb2e 1048
36cc00d7 1049elif mode==MODE_POPULAR_SONGS:
1050 grooveshark.popularSongs()
97289139 1051
1052elif mode==MODE_ARTIST_POPULAR:
a2e75b14 1053 grooveshark.artistPopularSongs()
8817bb2e 1054
8817bb2e 1055elif mode==MODE_FAVORITES:
1056 grooveshark.favorites()
1057
e278f474 1058elif mode==MODE_PLAYLISTS:
1059 grooveshark.playlists()
97289139 1060
1061elif mode==MODE_SONG_PAGE:
5e72534b 1062 try: offset=urllib.unquote_plus(params["offset"])
97289139 1063 except: pass
1064 try: label=urllib.unquote_plus(params["label"])
1065 except: pass
5e72534b 1066 grooveshark.songPage(offset, label, id, name)
e278f474 1067
8817bb2e 1068elif mode==MODE_SONG:
8817bb2e 1069 try: album=urllib.unquote_plus(params["album"])
1070 except: pass
1071 try: artist=urllib.unquote_plus(params["artist"])
1072 except: pass
7ce01be6 1073 try: coverart=urllib.unquote_plus(params["coverart"])
8817bb2e 1074 except: pass
7ce01be6 1075 song = grooveshark.songItem(id, name, album, artist, coverart)
3fcef5ba 1076 grooveshark.playSong(song)
8817bb2e 1077
1078elif mode==MODE_ARTIST:
4be42357 1079 grooveshark.artist(id)
8817bb2e 1080
1081elif mode==MODE_ALBUM:
4be42357 1082 grooveshark.album(id)
8817bb2e 1083
1084elif mode==MODE_PLAYLIST:
e6f8730b 1085 grooveshark.playlist(id, name)
8817bb2e 1086
1087elif mode==MODE_FAVORITE:
4be42357 1088 grooveshark.favorite(id)
97289139 1089
052028f1 1090elif mode==MODE_UNFAVORITE:
1091 try: prevMode=int(urllib.unquote_plus(params["prevmode"]))
1092 except:
1093 prevMode = 0
1094 grooveshark.unfavorite(id, prevMode)
1095
1096elif mode==MODE_SIMILAR_ARTISTS:
1097 grooveshark.similarArtists(id)
1098
1099elif mode==MODE_MAKE_PLAYLIST:
1100 grooveshark.makePlaylist(id, name)
1101
1102elif mode==MODE_REMOVE_PLAYLIST:
1103 grooveshark.removePlaylist(id, name)
1104
1105elif mode==MODE_RENAME_PLAYLIST:
1106 grooveshark.renamePlaylist(id, name)
1107
1108elif mode==MODE_REMOVE_PLAYLIST_SONG:
1109 try: playlistID=urllib.unquote_plus(params["playlistid"])
1110 except: pass
1111 grooveshark.removePlaylistSong(playlistID, name, id)
1112
1113elif mode==MODE_ADD_PLAYLIST_SONG:
1114 grooveshark.addPlaylistSong(id)
1115
e278f474 1116if mode < MODE_SONG:
8817bb2e 1117 xbmcplugin.endOfDirectory(int(sys.argv[1]))