Retry URL.
[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
27
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
c8c5206a 66# Retry URL
67STREAM_RETRY = 10
f95afae7 68
69songMarkTime = 0
70player = xbmc.Player()
71playTimer = None
72
2d388879 73baseDir = __cwd__
6ae708d0 74resDir = xbmc.translatePath(os.path.join(baseDir, 'resources'))
8817bb2e 75libDir = xbmc.translatePath(os.path.join(resDir, 'lib'))
76imgDir = xbmc.translatePath(os.path.join(resDir, 'img'))
2d388879 77cacheDir = os.path.join(xbmc.translatePath('special://masterprofile/addon_data/'), os.path.basename(baseDir))
7ce01be6 78thumbDirName = 'thumb'
2d388879 79thumbDir = os.path.join('special://masterprofile/addon_data/', os.path.basename(baseDir), thumbDirName)
4be42357 80
81baseModeUrl = 'plugin://plugin.audio.groove/'
e278f474 82playlistUrl = baseModeUrl + '?mode=' + str(MODE_PLAYLIST)
4be42357 83playlistsUrl = baseModeUrl + '?mode=' + str(MODE_PLAYLISTS)
84favoritesUrl = baseModeUrl + '?mode=' + str(MODE_FAVORITES)
85
b26b96e6 86searchArtistsAlbumsName = __language__(30006)
3d95dfcb 87
7ce01be6 88thumbDef = os.path.join(imgDir, 'default.tbn')
052028f1 89listBackground = os.path.join(imgDir, 'listbackground.png')
8817bb2e 90
91sys.path.append (libDir)
7ce01be6 92from GroovesharkAPI import GrooveAPI
f95afae7 93from threading import Event, Thread
7ce01be6 94
a3ad8f73 95try:
96 groovesharkApi = GrooveAPI()
7ce01be6 97 if groovesharkApi.pingService() != True:
b26b96e6 98 raise StandardError(__language__(30007))
a3ad8f73 99except:
b26b96e6 100 dialog = xbmcgui.Dialog(__language__(30008),__language__(30009),__language__(30010))
2d388879 101 dialog.ok()
a3ad8f73 102 sys.exit(-1)
103
f95afae7 104# Mark song as playing or played
105def markSong(songid, duration):
106 global songMarkTime
107 global playTimer
108 global player
109 if player.isPlayingAudio():
110 tNow = player.getTime()
111 if tNow >= STREAM_MARKING_TIME and songMarkTime == 0:
112 groovesharkApi.markStreamKeyOver30Secs()
113 songMarkTime = tNow
114 elif duration > tNow and duration - tNow < 2 and songMarkTime >= STREAM_MARKING_TIME:
115 playTimer.cancel()
116 songMarkTime = 0
117 groovesharkApi.markSongComplete(songid)
118 else:
119 playTimer.cancel()
120 songMarkTime = 0
121
8817bb2e 122class _Info:
123 def __init__( self, *args, **kwargs ):
124 self.__dict__.update( kwargs )
e278f474 125
052028f1 126# Window dialog to select a grooveshark playlist
127class GroovesharkPlaylistSelect(xbmcgui.WindowDialog):
128
129 def __init__(self, items=[]):
130 gap = int(self.getHeight()/100)
131 w = int(self.getWidth()*0.5)
132 h = self.getHeight()-30*gap
133 rw = self.getWidth()
134 rh = self.getHeight()
135 x = rw/2 - w/2
136 y = rh/2 -h/2
137
138 self.imgBg = xbmcgui.ControlImage(x+gap, 5*gap+y, w-2*gap, h-5*gap, listBackground)
139 self.addControl(self.imgBg)
140
141 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)
142 self.addControl(self.playlistControl)
143
144 self.lastPos = 0
145 self.isSelecting = False
146 self.selected = -1
147 listitems = []
148 for playlist in items:
149 listitems.append(xbmcgui.ListItem(playlist[0]))
b26b96e6 150 listitems.append(xbmcgui.ListItem(__language__(30011)))
052028f1 151 self.playlistControl.addItems(listitems)
152 self.setFocus(self.playlistControl)
153 self.playlistControl.selectItem(0)
154 item = self.playlistControl.getListItem(self.lastPos)
155 item.select(True)
156
157 # Highlight selected item
158 def setHighlight(self):
159 if self.isSelecting:
160 return
161 else:
162 self.isSelecting = True
163
164 pos = self.playlistControl.getSelectedPosition()
165 if pos >= 0:
166 item = self.playlistControl.getListItem(self.lastPos)
167 item.select(False)
168 item = self.playlistControl.getListItem(pos)
169 item.select(True)
170 self.lastPos = pos
171 self.isSelecting = False
172
173 # Control - select
174 def onControl(self, control):
175 if control == self.playlistControl:
176 self.selected = self.playlistControl.getSelectedPosition()
177 self.close()
178
179 # Action - close or up/down
180 def onAction(self, action):
181 if action == ACTION_PREVIOUS_MENU:
182 self.selected = -1
183 self.close()
184 elif action == ACTION_MOVE_UP or action == ACTION_MOVE_DOWN or action == ACTION_PAGE_UP or action == ACTION_PAGE_DOWN == 6:
185 self.setFocus(self.playlistControl)
186 self.setHighlight()
f95afae7 187
188
189class PlayTimer(Thread):
190 # interval -- floating point number specifying the number of seconds to wait before executing function
191 # function -- the function (or callable object) to be executed
192
193 # iterations -- integer specifying the number of iterations to perform
194 # args -- list of positional arguments passed to function
195 # kwargs -- dictionary of keyword arguments passed to function
196
197 def __init__(self, interval, function, iterations=0, args=[], kwargs={}):
198 Thread.__init__(self)
199 self.interval = interval
200 self.function = function
201 self.iterations = iterations
202 self.args = args
203 self.kwargs = kwargs
204 self.finished = Event()
205
206 def run(self):
207 count = 0
208 while not self.finished.isSet() and (self.iterations <= 0 or count < self.iterations):
209 self.finished.wait(self.interval)
210 if not self.finished.isSet():
211 self.function(*self.args, **self.kwargs)
212 count += 1
213
214 def cancel(self):
215 self.finished.set()
216
217 def setIterations(self, iterations):
218 self.iterations = iterations
219
220
221 def getTime(self):
222 return self.iterations * self.interval
223
224
5e72534b 225class Grooveshark:
973b4c6c 226
7ea6f166 227 albumImg = xbmc.translatePath(os.path.join(imgDir, 'album.png'))
228 artistImg = xbmc.translatePath(os.path.join(imgDir, 'artist.png'))
86f629ea 229 artistsAlbumsImg = xbmc.translatePath(os.path.join(imgDir, 'artistsalbums.png'))
7ea6f166 230 favoritesImg = xbmc.translatePath(os.path.join(imgDir, 'favorites.png'))
231 playlistImg = xbmc.translatePath(os.path.join(imgDir, 'playlist.png'))
86f629ea 232 usersplaylistsImg = xbmc.translatePath(os.path.join(imgDir, 'usersplaylists.png'))
7ea6f166 233 popularSongsImg = xbmc.translatePath(os.path.join(imgDir, 'popularSongs.png'))
97289139 234 popularSongsArtistImg = xbmc.translatePath(os.path.join(imgDir, 'popularSongsArtist.png'))
7ea6f166 235 songImg = xbmc.translatePath(os.path.join(imgDir, 'song.png'))
236 defImg = xbmc.translatePath(os.path.join(imgDir, 'default.tbn'))
2254a6b5 237 fanImg = xbmc.translatePath(os.path.join(baseDir, 'fanart.png'))
8817bb2e 238
2254a6b5 239 settings = xbmcaddon.Addon(id='plugin.audio.groove')
7ce01be6 240 songsearchlimit = int(settings.getSetting('songsearchlimit'))
241 albumsearchlimit = int(settings.getSetting('albumsearchlimit'))
242 artistsearchlimit = int(settings.getSetting('artistsearchlimit'))
97289139 243 songspagelimit = int(settings.getSetting('songspagelimit'))
2254a6b5 244 username = settings.getSetting('username')
245 password = settings.getSetting('password')
5e72534b 246
38df1fa5 247 userid = 0
4be42357 248
8817bb2e 249 def __init__( self ):
250 self._handle = int(sys.argv[1])
5e72534b 251 self.setDebug()
7ce01be6 252 if os.path.isdir(cacheDir) == False:
253 os.makedirs(cacheDir)
5e72534b 254 if self.debug:
255 xbmc.log(__language__(30012) + " " + cacheDir)
164e42d8 256 artDir = xbmc.translatePath(thumbDir)
257 if os.path.isdir(artDir) == False:
3a794693 258 os.makedirs(artDir)
5e72534b 259 if self.debug:
260 xbmc.log(__language__(30012) + " " + artDir)
052028f1 261
e278f474 262 # Top-level menu
8817bb2e 263 def categories(self):
2254a6b5 264
38df1fa5 265 self.userid = self._get_login()
b738088f 266
267 # Setup
6ae708d0 268 xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
6ae708d0 269
b26b96e6 270 self._add_dir(__language__(30013), '', MODE_SEARCH_SONGS, self.songImg, 0)
271 self._add_dir(__language__(30014), '', MODE_SEARCH_ALBUMS, self.albumImg, 0)
272 self._add_dir(__language__(30015), '', MODE_SEARCH_ARTISTS, self.artistImg, 0)
3d95dfcb 273 self._add_dir(searchArtistsAlbumsName, '', MODE_SEARCH_ARTISTS_ALBUMS, self.artistsAlbumsImg, 0)
f95afae7 274 # Not supported by key
275 #self._add_dir("Search for user's playlists...", '', MODE_SEARCH_PLAYLISTS, self.usersplaylistsImg, 0)
b26b96e6 276 self._add_dir(__language__(30016), '', MODE_ARTIST_POPULAR, self.popularSongsArtistImg, 0)
277 self._add_dir(__language__(30017), '', MODE_POPULAR_SONGS, self.popularSongsImg, 0)
38df1fa5 278 if (self.userid != 0):
b26b96e6 279 self._add_dir(__language__(30018), '', MODE_FAVORITES, self.favoritesImg, 0)
280 self._add_dir(__language__(30019), '', MODE_PLAYLISTS, self.playlistImg, 0)
e278f474 281
282 # Search for songs
8817bb2e 283 def searchSongs(self):
b26b96e6 284 query = self._get_keyboard(default="", heading=__language__(30020))
7ea6f166 285 if (query != ''):
7ce01be6 286 songs = groovesharkApi.getSongSearchResults(query, limit = self.songsearchlimit)
8817bb2e 287 if (len(songs) > 0):
6ae708d0 288 self._add_songs_directory(songs)
8817bb2e 289 else:
290 dialog = xbmcgui.Dialog()
b26b96e6 291 dialog.ok(__language__(30008), __language__(30021))
8817bb2e 292 self.categories()
7ea6f166 293 else:
294 self.categories()
8817bb2e 295
e278f474 296 # Search for albums
8817bb2e 297 def searchAlbums(self):
b26b96e6 298 query = self._get_keyboard(default="", heading=__language__(30022))
7ea6f166 299 if (query != ''):
7ce01be6 300 albums = groovesharkApi.getAlbumSearchResults(query, limit = self.albumsearchlimit)
8817bb2e 301 if (len(albums) > 0):
6ae708d0 302 self._add_albums_directory(albums)
8817bb2e 303 else:
304 dialog = xbmcgui.Dialog()
b26b96e6 305 dialog.ok(__language__(30008), __language__(30023))
8817bb2e 306 self.categories()
7ea6f166 307 else:
308 self.categories()
8817bb2e 309
e278f474 310 # Search for artists
8817bb2e 311 def searchArtists(self):
b26b96e6 312 query = self._get_keyboard(default="", heading=__language__(30024))
7ea6f166 313 if (query != ''):
7ce01be6 314 artists = groovesharkApi.getArtistSearchResults(query, limit = self.artistsearchlimit)
8817bb2e 315 if (len(artists) > 0):
6ae708d0 316 self._add_artists_directory(artists)
8817bb2e 317 else:
318 dialog = xbmcgui.Dialog()
b26b96e6 319 dialog.ok(__language__(30008), __language__(30025))
8817bb2e 320 self.categories()
7ea6f166 321 else:
322 self.categories()
86f629ea 323
324 # Search for playlists
325 def searchPlaylists(self):
b26b96e6 326 query = self._get_keyboard(default="", heading=__language__(30026))
86f629ea 327 if (query != ''):
f95afae7 328 playlists = groovesharkApi.getUserPlaylistsByUsername(query)
86f629ea 329 if (len(playlists) > 0):
330 self._add_playlists_directory(playlists)
331 else:
332 dialog = xbmcgui.Dialog()
b26b96e6 333 dialog.ok(__language__(30008), __language__(30027))
86f629ea 334 self.categories()
335 else:
336 self.categories()
337
338 # Search for artists albums
3d95dfcb 339 def searchArtistsAlbums(self, artistName = None):
340 if artistName == None or artistName == searchArtistsAlbumsName:
b26b96e6 341 query = self._get_keyboard(default="", heading=__language__(30028))
99f72740 342 else:
343 query = artistName
86f629ea 344 if (query != ''):
345 artists = groovesharkApi.getArtistSearchResults(query, limit = self.artistsearchlimit)
346 if (len(artists) > 0):
347 artist = artists[0]
348 artistID = artist[1]
5e72534b 349 if self.debug:
350 xbmc.log("Found " + artist[0] + "...")
86f629ea 351 albums = groovesharkApi.getArtistAlbums(artistID, limit = self.albumsearchlimit)
352 if (len(albums) > 0):
052028f1 353 self._add_albums_directory(albums, artistID)
86f629ea 354 else:
355 dialog = xbmcgui.Dialog()
b26b96e6 356 dialog.ok(__language__(30008), __language__(30029))
86f629ea 357 self.categories()
358 else:
359 dialog = xbmcgui.Dialog()
b26b96e6 360 dialog.ok(__language__(30008), __language__(30030))
86f629ea 361 self.categories()
362 else:
363 self.categories()
364
e278f474 365 # Get my favorites
8817bb2e 366 def favorites(self):
36cc00d7 367 userid = self._get_login()
368 if (userid != 0):
7ce01be6 369 favorites = groovesharkApi.getUserFavoriteSongs()
36cc00d7 370 if (len(favorites) > 0):
052028f1 371 self._add_songs_directory(favorites, isFavorites=True)
36cc00d7 372 else:
373 dialog = xbmcgui.Dialog()
b26b96e6 374 dialog.ok(__language__(30008), __language__(30031))
36cc00d7 375 self.categories()
8817bb2e 376
e278f474 377 # Get popular songs
36cc00d7 378 def popularSongs(self):
7ce01be6 379 popular = groovesharkApi.getPopularSongsToday(limit = self.songsearchlimit)
8817bb2e 380 if (len(popular) > 0):
6ae708d0 381 self._add_songs_directory(popular)
8817bb2e 382 else:
383 dialog = xbmcgui.Dialog()
b26b96e6 384 dialog.ok(__language__(30008), __language__(30032))
8817bb2e 385 self.categories()
36cc00d7 386
e278f474 387 # Get my playlists
8817bb2e 388 def playlists(self):
389 userid = self._get_login()
390 if (userid != 0):
7ce01be6 391 playlists = groovesharkApi.getUserPlaylists()
8817bb2e 392 if (len(playlists) > 0):
6ae708d0 393 self._add_playlists_directory(playlists)
8817bb2e 394 else:
395 dialog = xbmcgui.Dialog()
b26b96e6 396 dialog.ok(__language__(30008), __language__(30033))
8817bb2e 397 self.categories()
7ea6f166 398 else:
399 dialog = xbmcgui.Dialog()
b26b96e6 400 dialog.ok(__language__(30008), __language__(30034), __language__(30035))
7ea6f166 401
e278f474 402 # Make songs a favorite
8817bb2e 403 def favorite(self, songid):
404 userid = self._get_login()
405 if (userid != 0):
5e72534b 406 if self.debug:
407 xbmc.log("Favorite song: " + str(songid))
7ce01be6 408 groovesharkApi.addUserFavoriteSong(songID = songid)
b26b96e6 409 xbmc.executebuiltin('XBMC.Notification(' + __language__(30008) + ', ' + __language__(30036) + ', 1000, ' + thumbDef + ')')
8817bb2e 410 else:
411 dialog = xbmcgui.Dialog()
b26b96e6 412 dialog.ok(__language__(30008), __language__(30034), __language__(30037))
052028f1 413
414 # Remove song from favorites
415 def unfavorite(self, songid, prevMode=0):
f95afae7 416 userid = self._get_login()
052028f1 417 if (userid != 0):
5e72534b 418 if self.debug:
419 xbmc.log("Unfavorite song: " + str(songid) + ', previous mode was ' + str(prevMode))
f95afae7 420 groovesharkApi.removeUserFavoriteSongs(songIDs = songid)
b26b96e6 421 xbmc.executebuiltin('XBMC.Notification(' + __language__(30008) + ', ' + __language__(30038) + ', 1000, ' + thumbDef + ')')
052028f1 422 # Refresh to remove item from directory
423 if (int(prevMode) == MODE_FAVORITES):
424 xbmc.executebuiltin("Container.Refresh(" + favoritesUrl + ")")
425 else:
426 dialog = xbmcgui.Dialog()
b26b96e6 427 dialog.ok(__language__(30008), __language__(30034), __language__(30039))
052028f1 428
e278f474 429
430 # Show selected album
36cc00d7 431 def album(self, albumid):
7ce01be6 432 album = groovesharkApi.getAlbumSongs(albumid, limit = self.songsearchlimit)
86f629ea 433 self._add_songs_directory(album, trackLabelFormat=NAME_ALBUM_ARTIST_LABEL)
e278f474 434
435 # Show selected artist
8817bb2e 436 def artist(self, artistid):
7ce01be6 437 albums = groovesharkApi.getArtistAlbums(artistid, limit = self.albumsearchlimit)
052028f1 438 self._add_albums_directory(albums, artistid)
8817bb2e 439
e278f474 440 # Show selected playlist
e6f8730b 441 def playlist(self, playlistid, playlistname):
8817bb2e 442 userid = self._get_login()
443 if (userid != 0):
e6f8730b 444 songs = groovesharkApi.getPlaylistSongs(playlistid)
052028f1 445 self._add_songs_directory(songs, trackLabelFormat=NAME_ALBUM_ARTIST_LABEL, playlistid=playlistid, playlistname=playlistname)
8817bb2e 446 else:
447 dialog = xbmcgui.Dialog()
b26b96e6 448 dialog.ok(__language__(30008), __language__(30034), __language__(30040))
8817bb2e 449
97289139 450 # Show popular songs of the artist
451 def artistPopularSongs(self):
b26b96e6 452 query = self._get_keyboard(default="", heading=__language__(30041))
97289139 453 if (query != ''):
454 artists = groovesharkApi.getArtistSearchResults(query, limit = self.artistsearchlimit)
455 if (len(artists) > 0):
456 artist = artists[0]
457 artistID = artist[1]
5e72534b 458 if self.debug:
459 xbmc.log("Found " + artist[0] + "...")
97289139 460 songs = groovesharkApi.getArtistPopularSongs(artistID, limit = self.songsearchlimit)
461 if (len(songs) > 0):
462 self._add_songs_directory(songs, trackLabelFormat=NAME_ALBUM_ARTIST_LABEL)
463 else:
464 dialog = xbmcgui.Dialog()
b26b96e6 465 dialog.ok(__language__(30008), __language__(30042))
97289139 466 self.categories()
467 else:
468 dialog = xbmcgui.Dialog()
b26b96e6 469 dialog.ok(__language__(30008), __language__(30043))
97289139 470 self.categories()
471 else:
472 self.categories()
473
e278f474 474 # Play a song
6ae708d0 475 def playSong(self, item):
f95afae7 476 global playTimer
477 global player
478 if item != None:
479 songid = item.getProperty('songid')
5e72534b 480 url = item.getProperty('url')
481 if url == '':
482 stream = groovesharkApi.getSubscriberStreamKey(songid)
483 url = stream['url']
f95afae7 484 item.setPath(url)
5e72534b 485 if self.debug:
486 xbmc.log("Grooveshark playing: " + url)
7ce01be6 487 xbmcplugin.setResolvedUrl(handle=int(sys.argv[1]), succeeded=True, listitem=item)
f95afae7 488 # Wait for play then start time
489 seconds = 0
490 while seconds < STREAM_MARKING_TIME:
491 try:
492 if player.isPlayingAudio() == True:
493 if playTimer != None:
494 playTimer.cancel()
495 songMarkTime = 0
496 duration = int(item.getProperty('duration'))
497 playTimer = PlayTimer(1, markSong, duration, [songid, duration])
498 playTimer.start()
499 break
500 except: pass
501 time.sleep(1)
502 seconds = seconds + 1
c8c5206a 503 if (seconds == STREAM_RETRY):
504 stream = groovesharkApi.getSubscriberStreamKey(songid)
505 url = stream['url']
506 item.setPath(url)
507 xbmcplugin.setResolvedUrl(handle=int(sys.argv[1]), succeeded=True, listitem=item)
7ce01be6 508 else:
b26b96e6 509 xbmc.executebuiltin('XBMC.Notification(' + __language__(30008) + ', ' + __language__(30044) + ', 1000, ' + thumbDef + ')')
f95afae7 510
e278f474 511 # Make a song directory item
86f629ea 512 def songItem(self, songid, name, album, artist, coverart, trackLabelFormat=ARTIST_ALBUM_NAME_LABEL):
7ce01be6 513 songImg = self._get_icon(coverart, 'song-' + str(songid) + "-image")
2cb26bea 514 if int(trackLabelFormat) == NAME_ALBUM_ARTIST_LABEL:
86f629ea 515 trackLabel = name + " - " + album + " - " + artist
516 else:
517 trackLabel = artist + " - " + album + " - " + name
5e72534b 518 stream = self._getSongStream(songid)
519 duration = stream['duration']
520 url = stream['url']
86f629ea 521 item = xbmcgui.ListItem(label = trackLabel, thumbnailImage=songImg, iconImage=songImg)
f95afae7 522 item.setInfo( type="music", infoLabels={ "title": name, "album": album, "artist": artist, "duration": duration} )
2254a6b5 523 item.setProperty('mimetype', 'audio/mpeg')
524 item.setProperty("IsPlayable", "true")
7ce01be6 525 item.setProperty('songid', str(songid))
526 item.setProperty('coverart', songImg)
527 item.setProperty('title', name)
528 item.setProperty('album', album)
529 item.setProperty('artist', artist)
f95afae7 530 item.setProperty('duration', str(duration))
5e72534b 531 item.setProperty('url', str(url))
7ce01be6 532
6ae708d0 533 return item
2254a6b5 534
97289139 535 # Next page of songs
5e72534b 536 def songPage(self, offset, trackLabelFormat, playlistid = 0, playlistname = ''):
537 self._add_songs_directory([], trackLabelFormat, offset, playlistid = playlistid, playlistname = playlistname)
052028f1 538
539 # Make a playlist from an album
540 def makePlaylist(self, albumid, name):
f95afae7 541 userid = self._get_login()
052028f1 542 if (userid != 0):
543 re.split(' - ',name,1)
544 nameTokens = re.split(' - ',name,1) # suggested name
b26b96e6 545 name = self._get_keyboard(default=nameTokens[0], heading=__language__(30045))
052028f1 546 if name != '':
547 album = groovesharkApi.getAlbumSongs(albumid, limit = self.songsearchlimit)
548 songids = []
549 for song in album:
550 songids.append(song[1])
f95afae7 551 if groovesharkApi.createPlaylist(name, songids) == 0:
052028f1 552 dialog = xbmcgui.Dialog()
b26b96e6 553 dialog.ok(__language__(30008), __language__(30046), name)
052028f1 554 else:
b26b96e6 555 xbmc.executebuiltin('XBMC.Notification(' + __language__(30008) + ',' + __language__(30047)+ ', 1000, ' + thumbDef + ')')
052028f1 556 else:
557 dialog = xbmcgui.Dialog()
b26b96e6 558 dialog.ok(__language__(30008), __language__(30034), __language__(30048))
052028f1 559
560 # Rename a playlist
561 def renamePlaylist(self, playlistid, name):
f95afae7 562 userid = self._get_login()
052028f1 563 if (userid != 0):
b26b96e6 564 newname = self._get_keyboard(default=name, heading=__language__(30049))
052028f1 565 if newname == '':
566 return
f95afae7 567 elif groovesharkApi.playlistRename(playlistid, newname) == 0:
052028f1 568 dialog = xbmcgui.Dialog()
b26b96e6 569 dialog.ok(__language__(30008), __language__(30050), name)
052028f1 570 else:
571 # Refresh to show new item name
572 xbmc.executebuiltin("Container.Refresh")
573 else:
574 dialog = xbmcgui.Dialog()
b26b96e6 575 dialog.ok(__language__(30008), __language__(30034), __language__(30051))
052028f1 576
577 # Remove a playlist
578 def removePlaylist(self, playlistid, name):
579 dialog = xbmcgui.Dialog()
b26b96e6 580 if dialog.yesno(__language__(30008), name, __language__(30052)) == True:
f95afae7 581 userid = self._get_login()
052028f1 582 if (userid != 0):
f95afae7 583 if groovesharkApi.playlistDelete(playlistid) == 0:
052028f1 584 dialog = xbmcgui.Dialog()
b26b96e6 585 dialog.ok(__language__(30008), __language__(30053), name)
052028f1 586 else:
587 # Refresh to remove item from directory
588 xbmc.executebuiltin("Container.Refresh(" + playlistsUrl + ")")
589 else:
590 dialog = xbmcgui.Dialog()
b26b96e6 591 dialog.ok(__language__(30008), __language__(30034), __language__(30054))
052028f1 592
593 # Add song to playlist
594 def addPlaylistSong(self, songid):
f95afae7 595 userid = self._get_login()
052028f1 596 if (userid != 0):
597 playlists = groovesharkApi.getUserPlaylists()
598 if (len(playlists) > 0):
599 ret = 0
600 # Select the playlist
601 playlistSelect = GroovesharkPlaylistSelect(items=playlists)
602 playlistSelect.setFocus(playlistSelect.playlistControl)
603 playlistSelect.doModal()
604 i = playlistSelect.selected
605 del playlistSelect
606 if i > -1:
607 # Add a new playlist
608 if i >= len(playlists):
b26b96e6 609 name = self._get_keyboard(default='', heading=__language__(30055))
052028f1 610 if name != '':
611 songIds = []
612 songIds.append(songid)
f95afae7 613 if groovesharkApi.createPlaylist(name, songIds) == 0:
052028f1 614 dialog = xbmcgui.Dialog()
b26b96e6 615 dialog.ok(__language__(30008), __language__(30056), name)
052028f1 616 else:
b26b96e6 617 xbmc.executebuiltin('XBMC.Notification(' + __language__(30008) + ',' + __language__(30057) + ', 1000, ' + thumbDef + ')')
052028f1 618 # Existing playlist
619 else:
620 playlist = playlists[i]
621 playlistid = playlist[1]
5e72534b 622 if self.debug:
623 xbmc.log("Add song " + str(songid) + " to playlist " + str(playlistid))
f95afae7 624 songIDs=[]
625 songs = groovesharkApi.getPlaylistSongs(playlistid)
626 for song in songs:
627 songIDs.append(song[1])
628 songIDs.append(songid)
629 ret = groovesharkApi.setPlaylistSongs(playlistid, songIDs)
630 if ret == False:
052028f1 631 dialog = xbmcgui.Dialog()
b26b96e6 632 dialog.ok(__language__(30008), __language__(30058))
052028f1 633 else:
b26b96e6 634 xbmc.executebuiltin('XBMC.Notification(' + __language__(30008) + ',' + __language__(30059) + ', 1000, ' + thumbDef + ')')
052028f1 635 else:
636 dialog = xbmcgui.Dialog()
b26b96e6 637 dialog.ok(__language__(30008), __language__(30060))
052028f1 638 self.categories()
639 else:
640 dialog = xbmcgui.Dialog()
b26b96e6 641 dialog.ok(__language__(30008), __language__(30034), __language__(30061))
052028f1 642
643 # Remove song from playlist
f95afae7 644 def removePlaylistSong(self, playlistid, playlistname, songid):
e6f8730b 645 dialog = xbmcgui.Dialog()
b26b96e6 646 if dialog.yesno(__language__(30008), __language__(30062), __language__(30063)) == True:
f95afae7 647 userid = self._get_login()
052028f1 648 if (userid != 0):
f95afae7 649 songs = groovesharkApi.getPlaylistSongs(playlistID)
650 songIDs=[]
651 for song in songs:
652 if (song[1] != songid):
653 songIDs.append(song[1])
654 ret = groovesharkApi.setPlaylistSongs(playlistID, songIDs)
655 if ret == False:
052028f1 656 dialog = xbmcgui.Dialog()
b26b96e6 657 dialog.ok(__language__(30008), __language__(30064), __language__(30065))
052028f1 658 else:
659 # Refresh to remove item from directory
b26b96e6 660 xbmc.executebuiltin('XBMC.Notification(' + __language__(30008) + ',' + __language__(30066)+ ', 1000, ' + thumbDef + ')')
e6f8730b 661 xbmc.executebuiltin("Container.Update(" + playlistUrl + "&id="+str(playlistid) + "&name=" + playlistname + ")")
052028f1 662 else:
663 dialog = xbmcgui.Dialog()
b26b96e6 664 dialog.ok(__language__(30008), __language__(30034), __language__(30067))
052028f1 665
666 # Find similar artists to searched artist
667 def similarArtists(self, artistId):
f95afae7 668 similar = groovesharkApi.getSimilarArtists(artistId, limit = self.artistsearchlimit)
052028f1 669 if (len(similar) > 0):
670 self._add_artists_directory(similar)
671 else:
672 dialog = xbmcgui.Dialog()
b26b96e6 673 dialog.ok(__language__(30008), __language__(30068))
052028f1 674 self.categories()
5e72534b 675
676 # Debug
677 def setDebug(self):
678 self.debug = self.settings.getSetting('debug')
679 if self.debug:
680 xbmc.log("Debug is on")
681
682 # Debug
683 def getDebug(self):
684 return self.debug
97289139 685
e278f474 686 # Get keyboard input
8817bb2e 687 def _get_keyboard(self, default="", heading="", hidden=False):
3cfead3c 688 kb = xbmc.Keyboard(default, heading, hidden)
689 kb.doModal()
690 if (kb.isConfirmed()):
691 return unicode(kb.getText(), "utf-8")
692 return ''
8817bb2e 693
e278f474 694 # Login to grooveshark
f95afae7 695 def _get_login(self):
2254a6b5 696 if (self.username == "" or self.password == ""):
8817bb2e 697 dialog = xbmcgui.Dialog()
b26b96e6 698 dialog.ok(__language__(30008), __language__(30069), __language__(30070))
8817bb2e 699 return 0
700 else:
38df1fa5 701 if self.userid == 0:
f95afae7 702 uid = groovesharkApi.login(self.username, self.password)
38df1fa5 703 if (uid != 0):
38df1fa5 704 return uid
8817bb2e 705 else:
706 dialog = xbmcgui.Dialog()
b26b96e6 707 dialog.ok(__language__(30008), __language__(30069), __language__(30070))
8817bb2e 708 return 0
709
e278f474 710 # Get a song directory item
86f629ea 711 def _get_song_item(self, song, trackLabelFormat):
6ae708d0 712 name = song[0]
7ce01be6 713 songid = song[1]
714 album = song[2]
715 artist = song[4]
716 coverart = song[6]
86f629ea 717 return self.songItem(songid, name, album, artist, coverart, trackLabelFormat)
6ae708d0 718
719 # File download
7ce01be6 720 def _get_icon(self, url, songid):
721 if url != 'None':
722 localThumb = os.path.join(xbmc.translatePath(os.path.join(thumbDir, str(songid)))) + '.tbn'
723 try:
724 if os.path.isfile(localThumb) == False:
725 loc = urllib.URLopener()
726 loc.retrieve(url, localThumb)
727 except:
728 shutil.copy2(thumbDef, localThumb)
729 return os.path.join(os.path.join(thumbDir, str(songid))) + '.tbn'
730 else:
731 return thumbDef
e278f474 732
733 # Add songs to directory
5e72534b 734 def _add_songs_directory(self, songs, trackLabelFormat=ARTIST_ALBUM_NAME_LABEL, offset=0, playlistid=0, playlistname='', isFavorites=False):
97289139 735
736 totalSongs = len(songs)
5e72534b 737 offset = int(offset)
738 start = 0
739 end = totalSongs
97289139 740
741 # No pages needed
5e72534b 742 if offset == 0 and totalSongs <= self.songspagelimit:
743 if self.debug:
744 xbmc.log("Found " + str(totalSongs) + " songs...")
97289139 745 # Pages
746 else:
5e72534b 747 # Cache all next pages songs
748 if offset == 0:
97289139 749 self._setSavedSongs(songs)
750 else:
751 songs = self._getSavedSongs()
752 totalSongs = len(songs)
753
754 if totalSongs > 0:
5e72534b 755 start = offset
756 end = min(start + self.songspagelimit,totalSongs)
97289139 757
052028f1 758 id = 0
5e72534b 759 n = start
760 items = end - start
761 while n < end:
762 song = songs[n]
6ae708d0 763 songid = song[1]
5e72534b 764 stream = self._getSongStream(songid)
765 if stream['url'] != '':
766 item = self._get_song_item(song, trackLabelFormat)
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)
794 if self.debug:
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
052028f1 806 def _add_albums_directory(self, albums, artistid=0):
31731635 807 n = len(albums)
5e72534b 808 itemsExisting = n
809 if self.debug:
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]
5e72534b 815 if groovesharkApi.getDoesAlbumExist(albumID):
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
834 if self.debug:
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)
5e72534b 853 if self.debug:
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
5e72534b 915 def _getSongStream(self, songid):
f95afae7 916 id = int(songid)
f95afae7 917 duration = -1
5e72534b 918 streams = []
919 url = ''
920 path = os.path.join(cacheDir, 'streams.dmp')
f95afae7 921 try:
922 f = open(path, 'rb')
5e72534b 923 streams = pickle.load(f)
924 for song in streams:
f95afae7 925 if song[0] == id:
926 duration = song[1]
5e72534b 927 url = song[2]
928 break;
f95afae7 929 f.close()
930 except:
931 pass
932
5e72534b 933 if duration < 0 and groovesharkApi.getDoesSongExist(songid):
f95afae7 934 stream = groovesharkApi.getSubscriberStreamKey(songid)
5e72534b 935 url = stream['url']
f95afae7 936 usecs = stream['uSecs']
937 if usecs < 60000000:
938 usecs = usecs * 10 # Some durations are 10x to small
939 duration = usecs / 1000000
5e72534b 940 song = [id, duration, url]
941 streams.append(song)
942 self._setSongStream(streams)
f95afae7 943
5e72534b 944 return {'duration':duration, 'url':url}
945
946 def _setSongStream(self, streams):
f95afae7 947 try:
948 # Create the 'data' directory if it doesn't exist.
949 if not os.path.exists(cacheDir):
950 os.makedirs(cacheDir)
5e72534b 951 path = os.path.join(cacheDir, 'streams.dmp')
f95afae7 952 f = open(path, 'wb')
5e72534b 953 pickle.dump(streams, f, protocol=pickle.HIGHEST_PROTOCOL)
f95afae7 954 f.close()
955 except:
5e72534b 956 xbmc.log("An error occurred saving streams")
f95afae7 957 pass
958
97289139 959
e278f474 960# Parse URL parameters
8817bb2e 961def get_params():
962 param=[]
963 paramstring=sys.argv[2]
5e72534b 964 if grooveshark.getDebug():
965 xbmc.log(paramstring)
8817bb2e 966 if len(paramstring)>=2:
967 params=sys.argv[2]
968 cleanedparams=params.replace('?','')
969 if (params[len(params)-1]=='/'):
970 params=params[0:len(params)-2]
971 pairsofparams=cleanedparams.split('&')
972 param={}
973 for i in range(len(pairsofparams)):
974 splitparams={}
975 splitparams=pairsofparams[i].split('=')
976 if (len(splitparams))==2:
977 param[splitparams[0]]=splitparams[1]
8817bb2e 978 return param
979
e278f474 980# Main
5e72534b 981grooveshark = Grooveshark();
982grooveshark.setDebug()
983groovesharkApi.setDebug(grooveshark.getDebug())
e278f474 984
8817bb2e 985params=get_params()
8817bb2e 986mode=None
8817bb2e 987try: mode=int(params["mode"])
988except: pass
7ce01be6 989id=0
990try: id=int(params["id"])
991except: pass
052028f1 992name = None
993try: name=urllib.unquote_plus(params["name"])
994except: pass
e278f474 995
996# Call function for URL
8817bb2e 997if mode==None:
998 grooveshark.categories()
999
1000elif mode==MODE_SEARCH_SONGS:
1001 grooveshark.searchSongs()
1002
1003elif mode==MODE_SEARCH_ALBUMS:
1004 grooveshark.searchAlbums()
1005
1006elif mode==MODE_SEARCH_ARTISTS:
1007 grooveshark.searchArtists()
86f629ea 1008
1009elif mode==MODE_SEARCH_ARTISTS_ALBUMS:
a2e75b14 1010 grooveshark.searchArtistsAlbums(name)
86f629ea 1011
1012elif mode==MODE_SEARCH_PLAYLISTS:
1013 grooveshark.searchPlaylists()
8817bb2e 1014
36cc00d7 1015elif mode==MODE_POPULAR_SONGS:
1016 grooveshark.popularSongs()
97289139 1017
1018elif mode==MODE_ARTIST_POPULAR:
a2e75b14 1019 grooveshark.artistPopularSongs()
8817bb2e 1020
8817bb2e 1021elif mode==MODE_FAVORITES:
1022 grooveshark.favorites()
1023
e278f474 1024elif mode==MODE_PLAYLISTS:
1025 grooveshark.playlists()
97289139 1026
1027elif mode==MODE_SONG_PAGE:
5e72534b 1028 try: offset=urllib.unquote_plus(params["offset"])
97289139 1029 except: pass
1030 try: label=urllib.unquote_plus(params["label"])
1031 except: pass
5e72534b 1032 grooveshark.songPage(offset, label, id, name)
e278f474 1033
8817bb2e 1034elif mode==MODE_SONG:
8817bb2e 1035 try: album=urllib.unquote_plus(params["album"])
1036 except: pass
1037 try: artist=urllib.unquote_plus(params["artist"])
1038 except: pass
7ce01be6 1039 try: coverart=urllib.unquote_plus(params["coverart"])
8817bb2e 1040 except: pass
7ce01be6 1041 song = grooveshark.songItem(id, name, album, artist, coverart)
3fcef5ba 1042 grooveshark.playSong(song)
8817bb2e 1043
1044elif mode==MODE_ARTIST:
4be42357 1045 grooveshark.artist(id)
8817bb2e 1046
1047elif mode==MODE_ALBUM:
4be42357 1048 grooveshark.album(id)
8817bb2e 1049
1050elif mode==MODE_PLAYLIST:
e6f8730b 1051 grooveshark.playlist(id, name)
8817bb2e 1052
1053elif mode==MODE_FAVORITE:
4be42357 1054 grooveshark.favorite(id)
97289139 1055
052028f1 1056elif mode==MODE_UNFAVORITE:
1057 try: prevMode=int(urllib.unquote_plus(params["prevmode"]))
1058 except:
1059 prevMode = 0
1060 grooveshark.unfavorite(id, prevMode)
1061
1062elif mode==MODE_SIMILAR_ARTISTS:
1063 grooveshark.similarArtists(id)
1064
1065elif mode==MODE_MAKE_PLAYLIST:
1066 grooveshark.makePlaylist(id, name)
1067
1068elif mode==MODE_REMOVE_PLAYLIST:
1069 grooveshark.removePlaylist(id, name)
1070
1071elif mode==MODE_RENAME_PLAYLIST:
1072 grooveshark.renamePlaylist(id, name)
1073
1074elif mode==MODE_REMOVE_PLAYLIST_SONG:
1075 try: playlistID=urllib.unquote_plus(params["playlistid"])
1076 except: pass
1077 grooveshark.removePlaylistSong(playlistID, name, id)
1078
1079elif mode==MODE_ADD_PLAYLIST_SONG:
1080 grooveshark.addPlaylistSong(id)
1081
e278f474 1082if mode < MODE_SONG:
8817bb2e 1083 xbmcplugin.endOfDirectory(int(sys.argv[1]))