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