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