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