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