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