Playlist stuff.
[clinton/xbmc-groove.git] / default.py
CommitLineData
97289139 1import urllib, sys, os, shutil, re, time, xbmcaddon, xbmcplugin, xbmcgui, xbmc, pickle
8817bb2e 2MODE_SEARCH_SONGS = 1
3MODE_SEARCH_ALBUMS = 2
4MODE_SEARCH_ARTISTS = 3
86f629ea 5MODE_SEARCH_ARTISTS_ALBUMS = 4
6MODE_SEARCH_PLAYLISTS = 5
97289139 7MODE_ARTIST_POPULAR = 6
8MODE_POPULAR_SONGS = 7
9MODE_FAVORITES = 8
10MODE_PLAYLISTS = 9
11MODE_ALBUM = 10
12MODE_ARTIST = 11
13MODE_PLAYLIST = 12
14MODE_SONG_PAGE = 13
052028f1 15MODE_SIMILAR_ARTISTS = 14
16MODE_SONG = 15
17MODE_FAVORITE = 16
18MODE_UNFAVORITE = 17
19MODE_MAKE_PLAYLIST = 18
20MODE_REMOVE_PLAYLIST = 19
21MODE_RENAME_PLAYLIST = 20
22MODE_REMOVE_PLAYLIST_SONG = 21
23MODE_ADD_PLAYLIST_SONG = 22
7ea6f166 24
38df1fa5 25ACTION_MOVE_LEFT = 1
7ea6f166 26ACTION_MOVE_UP = 3
27ACTION_MOVE_DOWN = 4
28ACTION_PAGE_UP = 5
29ACTION_PAGE_DOWN = 6
30ACTION_SELECT_ITEM = 7
31ACTION_PREVIOUS_MENU = 10
8817bb2e 32
86f629ea 33# Formats for track labels
34ARTIST_ALBUM_NAME_LABEL = 0
35NAME_ALBUM_ARTIST_LABEL = 1
36
6ae708d0 37baseDir = os.getcwd()
38resDir = xbmc.translatePath(os.path.join(baseDir, 'resources'))
8817bb2e 39libDir = xbmc.translatePath(os.path.join(resDir, 'lib'))
40imgDir = xbmc.translatePath(os.path.join(resDir, 'img'))
7ce01be6 41cacheDir = os.path.join(xbmc.translatePath('special://masterprofile/addon_data/'), os.path.basename(os.getcwd()))
42thumbDirName = 'thumb'
43thumbDir = os.path.join('special://masterprofile/addon_data/', os.path.basename(os.getcwd()), thumbDirName)
4be42357 44
45baseModeUrl = 'plugin://plugin.audio.groove/'
e278f474 46playlistUrl = baseModeUrl + '?mode=' + str(MODE_PLAYLIST)
4be42357 47playlistsUrl = baseModeUrl + '?mode=' + str(MODE_PLAYLISTS)
48favoritesUrl = baseModeUrl + '?mode=' + str(MODE_FAVORITES)
49
3d95dfcb 50searchArtistsAlbumsName = "Search for artist's albums..."
51
7ce01be6 52thumbDef = os.path.join(imgDir, 'default.tbn')
052028f1 53listBackground = os.path.join(imgDir, 'listbackground.png')
8817bb2e 54
55sys.path.append (libDir)
7ce01be6 56from GroovesharkAPI import GrooveAPI
052028f1 57from GroovesharkAPI import GrooveAPIv1
7ce01be6 58
a3ad8f73 59try:
60 groovesharkApi = GrooveAPI()
7ce01be6 61 if groovesharkApi.pingService() != True:
62 raise StandardError('No Grooveshark service')
a3ad8f73 63except:
64 dialog = xbmcgui.Dialog()
65 dialog.ok('Grooveshark XBMC', 'Unable to connect with Grooveshark.', 'Please try again later')
66 sys.exit(-1)
67
8817bb2e 68
69class _Info:
70 def __init__( self, *args, **kwargs ):
71 self.__dict__.update( kwargs )
e278f474 72
052028f1 73# Window dialog to select a grooveshark playlist
74class GroovesharkPlaylistSelect(xbmcgui.WindowDialog):
75
76 def __init__(self, items=[]):
77 gap = int(self.getHeight()/100)
78 w = int(self.getWidth()*0.5)
79 h = self.getHeight()-30*gap
80 rw = self.getWidth()
81 rh = self.getHeight()
82 x = rw/2 - w/2
83 y = rh/2 -h/2
84
85 self.imgBg = xbmcgui.ControlImage(x+gap, 5*gap+y, w-2*gap, h-5*gap, listBackground)
86 self.addControl(self.imgBg)
87
88 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)
89 self.addControl(self.playlistControl)
90
91 self.lastPos = 0
92 self.isSelecting = False
93 self.selected = -1
94 listitems = []
95 for playlist in items:
96 listitems.append(xbmcgui.ListItem(playlist[0]))
97 listitems.append(xbmcgui.ListItem('New...'))
98 self.playlistControl.addItems(listitems)
99 self.setFocus(self.playlistControl)
100 self.playlistControl.selectItem(0)
101 item = self.playlistControl.getListItem(self.lastPos)
102 item.select(True)
103
104 # Highlight selected item
105 def setHighlight(self):
106 if self.isSelecting:
107 return
108 else:
109 self.isSelecting = True
110
111 pos = self.playlistControl.getSelectedPosition()
112 if pos >= 0:
113 item = self.playlistControl.getListItem(self.lastPos)
114 item.select(False)
115 item = self.playlistControl.getListItem(pos)
116 item.select(True)
117 self.lastPos = pos
118 self.isSelecting = False
119
120 # Control - select
121 def onControl(self, control):
122 if control == self.playlistControl:
123 self.selected = self.playlistControl.getSelectedPosition()
124 self.close()
125
126 # Action - close or up/down
127 def onAction(self, action):
128 if action == ACTION_PREVIOUS_MENU:
129 self.selected = -1
130 self.close()
131 elif action == ACTION_MOVE_UP or action == ACTION_MOVE_DOWN or action == ACTION_PAGE_UP or action == ACTION_PAGE_DOWN == 6:
132 self.setFocus(self.playlistControl)
133 self.setHighlight()
7ce01be6 134
8817bb2e 135class Groveshark:
973b4c6c 136
7ea6f166 137 albumImg = xbmc.translatePath(os.path.join(imgDir, 'album.png'))
138 artistImg = xbmc.translatePath(os.path.join(imgDir, 'artist.png'))
86f629ea 139 artistsAlbumsImg = xbmc.translatePath(os.path.join(imgDir, 'artistsalbums.png'))
7ea6f166 140 favoritesImg = xbmc.translatePath(os.path.join(imgDir, 'favorites.png'))
141 playlistImg = xbmc.translatePath(os.path.join(imgDir, 'playlist.png'))
86f629ea 142 usersplaylistsImg = xbmc.translatePath(os.path.join(imgDir, 'usersplaylists.png'))
7ea6f166 143 popularSongsImg = xbmc.translatePath(os.path.join(imgDir, 'popularSongs.png'))
97289139 144 popularSongsArtistImg = xbmc.translatePath(os.path.join(imgDir, 'popularSongsArtist.png'))
7ea6f166 145 songImg = xbmc.translatePath(os.path.join(imgDir, 'song.png'))
146 defImg = xbmc.translatePath(os.path.join(imgDir, 'default.tbn'))
2254a6b5 147 fanImg = xbmc.translatePath(os.path.join(baseDir, 'fanart.png'))
8817bb2e 148
2254a6b5 149 settings = xbmcaddon.Addon(id='plugin.audio.groove')
7ce01be6 150 songsearchlimit = int(settings.getSetting('songsearchlimit'))
151 albumsearchlimit = int(settings.getSetting('albumsearchlimit'))
152 artistsearchlimit = int(settings.getSetting('artistsearchlimit'))
97289139 153 songspagelimit = int(settings.getSetting('songspagelimit'))
2254a6b5 154 username = settings.getSetting('username')
155 password = settings.getSetting('password')
052028f1 156 sessionidv1 = settings.getSetting('sessionidv1')
38df1fa5 157 userid = 0
4be42357 158
8817bb2e 159 def __init__( self ):
160 self._handle = int(sys.argv[1])
7ce01be6 161 if os.path.isdir(cacheDir) == False:
162 os.makedirs(cacheDir)
163 xbmc.log("Made " + cacheDir)
164e42d8 164 artDir = xbmc.translatePath(thumbDir)
165 if os.path.isdir(artDir) == False:
3a794693 166 os.makedirs(artDir)
167 xbmc.log("Made " + artDir)
052028f1 168
169 self.groovesharkApiv1 = GrooveAPIv1(self.sessionidv1)
170
e278f474 171 # Top-level menu
8817bb2e 172 def categories(self):
2254a6b5 173
38df1fa5 174 self.userid = self._get_login()
b738088f 175
176 # Setup
6ae708d0 177 xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
6ae708d0 178
86f629ea 179 self._add_dir('Search for songs...', '', MODE_SEARCH_SONGS, self.songImg, 0)
180 self._add_dir('Search for albums...', '', MODE_SEARCH_ALBUMS, self.albumImg, 0)
181 self._add_dir('Search for artists...', '', MODE_SEARCH_ARTISTS, self.artistImg, 0)
3d95dfcb 182 self._add_dir(searchArtistsAlbumsName, '', MODE_SEARCH_ARTISTS_ALBUMS, self.artistsAlbumsImg, 0)
86f629ea 183 self._add_dir("Search for user's playlists...", '', MODE_SEARCH_PLAYLISTS, self.usersplaylistsImg, 0)
97289139 184 self._add_dir('Popular songs for artist...', '', MODE_ARTIST_POPULAR, self.popularSongsArtistImg, 0)
36cc00d7 185 self._add_dir('Popular songs', '', MODE_POPULAR_SONGS, self.popularSongsImg, 0)
38df1fa5 186 if (self.userid != 0):
86f629ea 187 self._add_dir('My favorites', '', MODE_FAVORITES, self.favoritesImg, 0)
188 self._add_dir('My playlists', '', MODE_PLAYLISTS, self.playlistImg, 0)
e278f474 189
190 # Search for songs
8817bb2e 191 def searchSongs(self):
86f629ea 192 query = self._get_keyboard(default="", heading="Search for songs")
7ea6f166 193 if (query != ''):
7ce01be6 194 songs = groovesharkApi.getSongSearchResults(query, limit = self.songsearchlimit)
8817bb2e 195 if (len(songs) > 0):
6ae708d0 196 self._add_songs_directory(songs)
8817bb2e 197 else:
198 dialog = xbmcgui.Dialog()
38df1fa5 199 dialog.ok('Grooveshark XBMC', 'No matching songs.')
8817bb2e 200 self.categories()
7ea6f166 201 else:
202 self.categories()
8817bb2e 203
e278f474 204 # Search for albums
8817bb2e 205 def searchAlbums(self):
86f629ea 206 query = self._get_keyboard(default="", heading="Search for albums")
7ea6f166 207 if (query != ''):
7ce01be6 208 albums = groovesharkApi.getAlbumSearchResults(query, limit = self.albumsearchlimit)
8817bb2e 209 if (len(albums) > 0):
6ae708d0 210 self._add_albums_directory(albums)
8817bb2e 211 else:
212 dialog = xbmcgui.Dialog()
38df1fa5 213 dialog.ok('Grooveshark XBMC', 'No matching albums.')
8817bb2e 214 self.categories()
7ea6f166 215 else:
216 self.categories()
8817bb2e 217
e278f474 218 # Search for artists
8817bb2e 219 def searchArtists(self):
86f629ea 220 query = self._get_keyboard(default="", heading="Search for artists")
7ea6f166 221 if (query != ''):
7ce01be6 222 artists = groovesharkApi.getArtistSearchResults(query, limit = self.artistsearchlimit)
8817bb2e 223 if (len(artists) > 0):
6ae708d0 224 self._add_artists_directory(artists)
8817bb2e 225 else:
226 dialog = xbmcgui.Dialog()
38df1fa5 227 dialog.ok('Grooveshark XBMC', 'No matching artists.')
8817bb2e 228 self.categories()
7ea6f166 229 else:
230 self.categories()
86f629ea 231
232 # Search for playlists
233 def searchPlaylists(self):
97289139 234 query = self._get_keyboard(default="", heading="Username")
86f629ea 235 if (query != ''):
236 playlists = groovesharkApi.getUserPlaylistsEx(query)
237 if (len(playlists) > 0):
238 self._add_playlists_directory(playlists)
239 else:
240 dialog = xbmcgui.Dialog()
241 dialog.ok('Grooveshark XBMC', 'No Grooveshark playlists found.')
242 self.categories()
243 else:
244 self.categories()
245
246 # Search for artists albums
3d95dfcb 247 def searchArtistsAlbums(self, artistName = None):
248 if artistName == None or artistName == searchArtistsAlbumsName:
99f72740 249 query = self._get_keyboard(default="", heading="Search for artist's albums")
250 else:
251 query = artistName
86f629ea 252 if (query != ''):
253 artists = groovesharkApi.getArtistSearchResults(query, limit = self.artistsearchlimit)
254 if (len(artists) > 0):
255 artist = artists[0]
256 artistID = artist[1]
257 xbmc.log("Found " + artist[0] + "...")
258 albums = groovesharkApi.getArtistAlbums(artistID, limit = self.albumsearchlimit)
259 if (len(albums) > 0):
052028f1 260 self._add_albums_directory(albums, artistID)
86f629ea 261 else:
262 dialog = xbmcgui.Dialog()
263 dialog.ok('Grooveshark XBMC', 'No matching albums.')
264 self.categories()
265 else:
266 dialog = xbmcgui.Dialog()
267 dialog.ok('Grooveshark XBMC', 'No matching artists.')
268 self.categories()
269 else:
270 self.categories()
271
e278f474 272 # Get my favorites
8817bb2e 273 def favorites(self):
36cc00d7 274 userid = self._get_login()
275 if (userid != 0):
7ce01be6 276 favorites = groovesharkApi.getUserFavoriteSongs()
36cc00d7 277 if (len(favorites) > 0):
052028f1 278 self._add_songs_directory(favorites, isFavorites=True)
36cc00d7 279 else:
280 dialog = xbmcgui.Dialog()
38df1fa5 281 dialog.ok('Grooveshark XBMC', 'You have no favorites.')
36cc00d7 282 self.categories()
8817bb2e 283
e278f474 284 # Get popular songs
36cc00d7 285 def popularSongs(self):
7ce01be6 286 popular = groovesharkApi.getPopularSongsToday(limit = self.songsearchlimit)
8817bb2e 287 if (len(popular) > 0):
6ae708d0 288 self._add_songs_directory(popular)
8817bb2e 289 else:
290 dialog = xbmcgui.Dialog()
38df1fa5 291 dialog.ok('Grooveshark XBMC', 'No popular songs.')
8817bb2e 292 self.categories()
36cc00d7 293
e278f474 294 # Get my playlists
8817bb2e 295 def playlists(self):
296 userid = self._get_login()
297 if (userid != 0):
7ce01be6 298 playlists = groovesharkApi.getUserPlaylists()
8817bb2e 299 if (len(playlists) > 0):
6ae708d0 300 self._add_playlists_directory(playlists)
8817bb2e 301 else:
302 dialog = xbmcgui.Dialog()
38df1fa5 303 dialog.ok('Grooveshark XBMC', 'You have no Grooveshark playlists.')
8817bb2e 304 self.categories()
7ea6f166 305 else:
306 dialog = xbmcgui.Dialog()
38df1fa5 307 dialog.ok('Grooveshark XBMC', 'You must be logged in ', ' to see your Grooveshark playlists.')
7ea6f166 308
e278f474 309 # Make songs a favorite
8817bb2e 310 def favorite(self, songid):
311 userid = self._get_login()
312 if (userid != 0):
406ab447 313 xbmc.log("Favorite song: " + str(songid))
7ce01be6 314 groovesharkApi.addUserFavoriteSong(songID = songid)
38df1fa5 315 xbmc.executebuiltin('XBMC.Notification(Grooveshark XBMC, Added to favorites, 1000, ' + thumbDef + ')')
8817bb2e 316 else:
317 dialog = xbmcgui.Dialog()
38df1fa5 318 dialog.ok('Grooveshark XBMC', 'You must be logged in', 'to add favorites.')
052028f1 319
320 # Remove song from favorites
321 def unfavorite(self, songid, prevMode=0):
322 userid = self._get_login(version = 1)
323 if (userid != 0):
324 xbmc.log("Unfavorite song: " + str(songid) + ', previous mode was ' + str(prevMode))
325 self.groovesharkApiv1.unfavorite(songID = songid)
326 xbmc.executebuiltin('XBMC.Notification(Grooveshark XBMC, Removed from Grooveshark favorites, 1000, ' + thumbDef + ')')
327 # Refresh to remove item from directory
328 if (int(prevMode) == MODE_FAVORITES):
329 xbmc.executebuiltin("Container.Refresh(" + favoritesUrl + ")")
330 else:
331 dialog = xbmcgui.Dialog()
332 dialog.ok('Grooveshark XBMC', 'You must be logged in', 'to remove Grooveshark favorites.')
333
e278f474 334
335 # Show selected album
36cc00d7 336 def album(self, albumid):
7ce01be6 337 album = groovesharkApi.getAlbumSongs(albumid, limit = self.songsearchlimit)
86f629ea 338 self._add_songs_directory(album, trackLabelFormat=NAME_ALBUM_ARTIST_LABEL)
e278f474 339
340 # Show selected artist
8817bb2e 341 def artist(self, artistid):
7ce01be6 342 albums = groovesharkApi.getArtistAlbums(artistid, limit = self.albumsearchlimit)
052028f1 343 self._add_albums_directory(albums, artistid)
8817bb2e 344
e278f474 345 # Show selected playlist
e6f8730b 346 def playlist(self, playlistid, playlistname):
8817bb2e 347 userid = self._get_login()
348 if (userid != 0):
e6f8730b 349 songs = groovesharkApi.getPlaylistSongs(playlistid)
052028f1 350 self._add_songs_directory(songs, trackLabelFormat=NAME_ALBUM_ARTIST_LABEL, playlistid=playlistid, playlistname=playlistname)
8817bb2e 351 else:
352 dialog = xbmcgui.Dialog()
38df1fa5 353 dialog.ok('Grooveshark XBMC', 'You must be logged in', 'to get Grooveshark playlists.')
8817bb2e 354
97289139 355 # Show popular songs of the artist
356 def artistPopularSongs(self):
357 query = self._get_keyboard(default="", heading="Artist")
358 if (query != ''):
359 artists = groovesharkApi.getArtistSearchResults(query, limit = self.artistsearchlimit)
360 if (len(artists) > 0):
361 artist = artists[0]
362 artistID = artist[1]
363 xbmc.log("Found " + artist[0] + "...")
364 songs = groovesharkApi.getArtistPopularSongs(artistID, limit = self.songsearchlimit)
365 if (len(songs) > 0):
366 self._add_songs_directory(songs, trackLabelFormat=NAME_ALBUM_ARTIST_LABEL)
367 else:
368 dialog = xbmcgui.Dialog()
369 dialog.ok('Grooveshark XBMC', 'No popular songs.')
370 self.categories()
371 else:
372 dialog = xbmcgui.Dialog()
373 dialog.ok('Grooveshark XBMC', 'No matching artists.')
374 self.categories()
375 else:
376 self.categories()
377
e278f474 378 # Play a song
6ae708d0 379 def playSong(self, item):
7ce01be6 380 songid = item.getProperty('songid')
381 song = groovesharkApi.getSongURLFromSongID(songid)
cbb0985e 382 if song != '':
7ce01be6 383 item.setPath(song)
384 xbmc.log("Playing: " + song)
385 xbmcplugin.setResolvedUrl(handle=int(sys.argv[1]), succeeded=True, listitem=item)
386 else:
cbb0985e 387 xbmc.executebuiltin('XBMC.Notification(Grooveshark XBMC, Unable to play song, 1000, ' + thumbDef + ')')
3fcef5ba 388
e278f474 389 # Make a song directory item
86f629ea 390 def songItem(self, songid, name, album, artist, coverart, trackLabelFormat=ARTIST_ALBUM_NAME_LABEL):
7ce01be6 391 songImg = self._get_icon(coverart, 'song-' + str(songid) + "-image")
2cb26bea 392 if int(trackLabelFormat) == NAME_ALBUM_ARTIST_LABEL:
86f629ea 393 trackLabel = name + " - " + album + " - " + artist
394 else:
395 trackLabel = artist + " - " + album + " - " + name
396 item = xbmcgui.ListItem(label = trackLabel, thumbnailImage=songImg, iconImage=songImg)
7ce01be6 397 item.setInfo( type="music", infoLabels={ "title": name, "album": album, "artist": artist} )
2254a6b5 398 item.setProperty('mimetype', 'audio/mpeg')
399 item.setProperty("IsPlayable", "true")
7ce01be6 400 item.setProperty('songid', str(songid))
401 item.setProperty('coverart', songImg)
402 item.setProperty('title', name)
403 item.setProperty('album', album)
404 item.setProperty('artist', artist)
405
6ae708d0 406 return item
2254a6b5 407
97289139 408 # Next page of songs
052028f1 409 def songPage(self, page, trackLabelFormat, playlistid = 0, playlistname = ''):
410 self._add_songs_directory([], trackLabelFormat, page, playlistid = playlistid, playlistname = playlistname)
411
412 # Make a playlist from an album
413 def makePlaylist(self, albumid, name):
414 userid = self._get_login(version = 1)
415 if (userid != 0):
416 re.split(' - ',name,1)
417 nameTokens = re.split(' - ',name,1) # suggested name
418 name = self._get_keyboard(default=nameTokens[0], heading="Grooveshark playlist name")
419 if name != '':
420 album = groovesharkApi.getAlbumSongs(albumid, limit = self.songsearchlimit)
421 songids = []
422 for song in album:
423 songids.append(song[1])
424 if self.groovesharkApiv1.playlistCreateUnique(name, songids) == 0:
425 dialog = xbmcgui.Dialog()
426 dialog.ok('Grooveshark XBMC', 'Cannot create Grooveshark playlist ', name)
427 else:
428 xbmc.executebuiltin('XBMC.Notification(Grooveshark XBMC, Grooveshark playlist created, 1000, ' + thumbDef + ')')
429 else:
430 dialog = xbmcgui.Dialog()
431 dialog.ok('Grooveshark XBMC', 'You must be logged in ', ' to create a Grooveshark playlist.')
432
433 # Rename a playlist
434 def renamePlaylist(self, playlistid, name):
435 userid = self._get_login(version = 1)
436 if (userid != 0):
437 newname = self._get_keyboard(default=name, heading="Grooveshark playlist name")
438 if newname == '':
439 return
440 elif self.groovesharkApiv1.playlistRename(playlistid, newname) == 0:
441 dialog = xbmcgui.Dialog()
442 dialog.ok('Grooveshark XBMC', 'Cannot rename Grooveshark playlist ', name)
443 else:
444 # Refresh to show new item name
445 xbmc.executebuiltin("Container.Refresh")
446 else:
447 dialog = xbmcgui.Dialog()
448 dialog.ok('Grooveshark XBMC', 'You must be logged in ', ' to rename a Grooveshark playlist.')
449
450 # Remove a playlist
451 def removePlaylist(self, playlistid, name):
452 dialog = xbmcgui.Dialog()
453 if dialog.yesno('Grooveshark XBMC', name, 'Delete this Grooveshark playlist?') == True:
454 userid = self._get_login(version = 1)
455 if (userid != 0):
456 if self.groovesharkApiv1.playlistDelete(playlistid) == 0:
457 dialog = xbmcgui.Dialog()
458 dialog.ok('Grooveshark XBMC', 'Cannot remove Grooveshark playlist ', name)
459 else:
460 # Refresh to remove item from directory
461 xbmc.executebuiltin("Container.Refresh(" + playlistsUrl + ")")
462 else:
463 dialog = xbmcgui.Dialog()
464 dialog.ok('Grooveshark XBMC', 'You must be logged in ', ' to delete a Grooveshark playlist.')
465
466 # Add song to playlist
467 def addPlaylistSong(self, songid):
468 userid = self._get_login(version = 1)
469 if (userid != 0):
470 playlists = groovesharkApi.getUserPlaylists()
471 if (len(playlists) > 0):
472 ret = 0
473 # Select the playlist
474 playlistSelect = GroovesharkPlaylistSelect(items=playlists)
475 playlistSelect.setFocus(playlistSelect.playlistControl)
476 playlistSelect.doModal()
477 i = playlistSelect.selected
478 del playlistSelect
479 if i > -1:
480 # Add a new playlist
481 if i >= len(playlists):
482 name = self._get_keyboard(default='', heading="Grooveshark playlist name")
483 if name != '':
484 songIds = []
485 songIds.append(songid)
486 if self.groovesharkApiv1.playlistCreateUnique(name, songIds) == 0:
487 dialog = xbmcgui.Dialog()
488 dialog.ok('Grooveshark XBMC', 'Cannot create Grooveshark playlist ', name)
489 else:
490 xbmc.executebuiltin('XBMC.Notification(Grooveshark XBMC, Grooveshark playlist created, 1000, ' + thumbDef + ')')
491 # Existing playlist
492 else:
493 playlist = playlists[i]
494 playlistid = playlist[1]
495 xbmc.log("Add song " + str(songid) + " to playlist " + str(playlistid))
496 ret = self.groovesharkApiv1.playlistAddSong(playlistid, songid, 0)
497 if ret == 0:
498 dialog = xbmcgui.Dialog()
499 dialog.ok('Grooveshark XBMC', 'Cannot add to playlist ')
500 else:
501 xbmc.executebuiltin('XBMC.Notification(Grooveshark XBMC, Added song to Grooveshark playlist, 1000, ' + thumbDef + ')')
502 else:
503 dialog = xbmcgui.Dialog()
504 dialog.ok('Grooveshark XBMC', 'You have no Grooveshark playlists.')
505 self.categories()
506 else:
507 dialog = xbmcgui.Dialog()
508 dialog.ok('Grooveshark XBMC', 'You must be logged in', 'to add a song to a Grooveshark playlist.')
509
510 # Remove song from playlist
511 def removePlaylistSong(self, playlistid, playlistname, songpos):
e6f8730b 512 dialog = xbmcgui.Dialog()
513 if dialog.yesno('Grooveshark XBMC', 'Delete this song from', 'the Grooveshark playlist?') == True:
052028f1 514 userid = self._get_login(version = 1)
515 if (userid != 0):
516 if self.groovesharkApiv1.playlistDeleteSong(playlistid, songpos) == 0:
517 dialog = xbmcgui.Dialog()
518 dialog.ok('Grooveshark XBMC', 'Failed to remove', 'song from Grooveshark playlist.')
519 else:
520 # Refresh to remove item from directory
521 xbmc.executebuiltin('XBMC.Notification(Grooveshark XBMC, Removed song from Grooveshark playlist, 1000, ' + thumbDef + ')')
e6f8730b 522 xbmc.executebuiltin("Container.Update(" + playlistUrl + "&id="+str(playlistid) + "&name=" + playlistname + ")")
052028f1 523 else:
524 dialog = xbmcgui.Dialog()
525 dialog.ok('Grooveshark XBMC', 'You must be logged in', 'to delete a song from a Grooveshark playlist.')
526
527 # Find similar artists to searched artist
528 def similarArtists(self, artistId):
529 similar = self.groovesharkApiv1.artistGetSimilar(artistId, limit = self.artistsearchlimit)
530 if (len(similar) > 0):
531 self._add_artists_directory(similar)
532 else:
533 dialog = xbmcgui.Dialog()
534 dialog.ok('Grooveshark XBMC', 'No similar artists.')
535 self.categories()
97289139 536
e278f474 537 # Get keyboard input
8817bb2e 538 def _get_keyboard(self, default="", heading="", hidden=False):
3cfead3c 539 kb = xbmc.Keyboard(default, heading, hidden)
540 kb.doModal()
541 if (kb.isConfirmed()):
542 return unicode(kb.getText(), "utf-8")
543 return ''
8817bb2e 544
e278f474 545 # Login to grooveshark
052028f1 546 def _get_login(self, version = 2):
2254a6b5 547 if (self.username == "" or self.password == ""):
8817bb2e 548 dialog = xbmcgui.Dialog()
38df1fa5 549 dialog.ok('Grooveshark XBMC', 'Unable to login.', 'Check username and password in settings.')
8817bb2e 550 return 0
551 else:
38df1fa5 552 if self.userid == 0:
052028f1 553 if version == 1:
554 uid = self.groovesharkApiv1.login(self.username, self.password)
555 else:
556 uid = groovesharkApi.login(self.username, self.password)
38df1fa5 557 if (uid != 0):
38df1fa5 558 return uid
8817bb2e 559 else:
560 dialog = xbmcgui.Dialog()
38df1fa5 561 dialog.ok('Grooveshark XBMC', 'Unable to login.', 'Check username and password in settings.')
8817bb2e 562 return 0
563
e278f474 564 # Get a song directory item
86f629ea 565 def _get_song_item(self, song, trackLabelFormat):
6ae708d0 566 name = song[0]
7ce01be6 567 songid = song[1]
568 album = song[2]
569 artist = song[4]
570 coverart = song[6]
86f629ea 571 return self.songItem(songid, name, album, artist, coverart, trackLabelFormat)
6ae708d0 572
573 # File download
7ce01be6 574 def _get_icon(self, url, songid):
575 if url != 'None':
576 localThumb = os.path.join(xbmc.translatePath(os.path.join(thumbDir, str(songid)))) + '.tbn'
577 try:
578 if os.path.isfile(localThumb) == False:
579 loc = urllib.URLopener()
580 loc.retrieve(url, localThumb)
581 except:
582 shutil.copy2(thumbDef, localThumb)
583 return os.path.join(os.path.join(thumbDir, str(songid))) + '.tbn'
584 else:
585 return thumbDef
e278f474 586
587 # Add songs to directory
052028f1 588 def _add_songs_directory(self, songs, trackLabelFormat=ARTIST_ALBUM_NAME_LABEL, page=0, playlistid=0, playlistname='', isFavorites=False):
97289139 589
590 totalSongs = len(songs)
591 page = int(page)
592
593 # No pages needed
594 if page == 0 and totalSongs <= self.songspagelimit:
595 xbmc.log("Found " + str(totalSongs) + " songs...")
596 # Pages
597 else:
598 # Cache all songs
599 if page == 0:
600 self._setSavedSongs(songs)
601 else:
602 songs = self._getSavedSongs()
603 totalSongs = len(songs)
604
605 if totalSongs > 0:
606 start = page * self.songspagelimit
607 end = start + self.songspagelimit
608 songs = songs[start:end]
609
052028f1 610 id = 0
97289139 611 for song in songs:
86f629ea 612 item = self._get_song_item(song, trackLabelFormat)
7ce01be6 613 coverart = item.getProperty('coverart')
6ae708d0 614 songname = song[0]
615 songid = song[1]
7ce01be6 616 songalbum = song[2]
617 songartist = song[4]
e278f474 618 u=sys.argv[0]+"?mode="+str(MODE_SONG)+"&name="+urllib.quote_plus(songname)+"&id="+str(songid) \
6ae708d0 619 +"&album="+urllib.quote_plus(songalbum) \
620 +"&artist="+urllib.quote_plus(songartist) \
7ce01be6 621 +"&coverart="+urllib.quote_plus(coverart)
e278f474 622 fav=sys.argv[0]+"?mode="+str(MODE_FAVORITE)+"&name="+urllib.quote_plus(songname)+"&id="+str(songid)
052028f1 623 unfav=sys.argv[0]+"?mode="+str(MODE_UNFAVORITE)+"&name="+urllib.quote_plus(songname)+"&id="+str(songid)+"&prevmode="
6ae708d0 624 menuItems = []
052028f1 625 if isFavorites == True:
626 unfav = unfav +str(MODE_FAVORITES)
627 else:
628 menuItems.append(("Grooveshark favorite", "XBMC.RunPlugin("+fav+")"))
629 if self.sessionidv1 != '':
630 menuItems.append(("Not Grooveshark favorite", "XBMC.RunPlugin("+unfav+")"))
631 if playlistid > 0:
632 rmplaylstsong=sys.argv[0]+"?playlistid="+str(playlistid)+"&id="+str(id+1)+"&mode="+str(MODE_REMOVE_PLAYLIST_SONG)+"&name="+playlistname
633 menuItems.append(("Remove from Grooveshark playlist", "XBMC.RunPlugin("+rmplaylstsong+")"))
634 else:
635 addplaylstsong=sys.argv[0]+"?id="+str(songid)+"&mode="+str(MODE_ADD_PLAYLIST_SONG)
636 menuItems.append(("Add to Grooveshark playlist", "XBMC.RunPlugin("+addplaylstsong+")"))
6ae708d0 637 item.addContextMenuItems(menuItems, replaceItems=False)
97289139 638 xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=item,isFolder=False, totalItems=len(songs))
052028f1 639 id = id + 1
97289139 640
641 page = page + 1
642 if totalSongs > page * self.songspagelimit:
052028f1 643 u=sys.argv[0]+"?mode="+str(MODE_SONG_PAGE)+"&id=playlistid"+"&page="+str(page)+"&label="+str(trackLabelFormat)+"&name="+playlistname
97289139 644 self._add_dir('More songs...', u, MODE_SONG_PAGE, self.songImg, 0, totalSongs - (page * self.songspagelimit))
cb06c186 645
8817bb2e 646 xbmcplugin.setContent(self._handle, 'songs')
31731635 647 xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
e278f474 648
649 # Add albums to directory
052028f1 650 def _add_albums_directory(self, albums, artistid=0):
31731635 651 n = len(albums)
652 xbmc.log("Found " + str(n) + " albums...")
8817bb2e 653 i = 0
31731635 654 while i < n:
8817bb2e 655 album = albums[i]
656 albumArtistName = album[0]
657 albumName = album[2]
658 albumID = album[3]
2254a6b5 659 albumImage = self._get_icon(album[4], 'album-' + str(albumID))
31731635 660 self._add_dir(albumName + " - " + albumArtistName, '', MODE_ALBUM, albumImage, albumID, n)
8817bb2e 661 i = i + 1
052028f1 662 if artistid > 0 and self.sessionidv1 != '':
663 self._add_dir('Similar artists...', '', MODE_SIMILAR_ARTISTS, self.artistImg, artistid)
8817bb2e 664 xbmcplugin.setContent(self._handle, 'albums')
665 xbmcplugin.addSortMethod(self._handle, xbmcplugin.SORT_METHOD_ALBUM_IGNORE_THE)
31731635 666 xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
e278f474 667
668 # Add artists to directory
6ae708d0 669 def _add_artists_directory(self, artists):
31731635 670 n = len(artists)
671 xbmc.log("Found " + str(n) + " artists...")
8817bb2e 672 i = 0
31731635 673 while i < n:
8817bb2e 674 artist = artists[i]
675 artistName = artist[0]
676 artistID = artist[1]
31731635 677 self._add_dir(artistName, '', MODE_ARTIST, self.artistImg, artistID, n)
8817bb2e 678 i = i + 1
679 xbmcplugin.setContent(self._handle, 'artists')
680 xbmcplugin.addSortMethod(self._handle, xbmcplugin.SORT_METHOD_ARTIST_IGNORE_THE)
31731635 681 xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
e278f474 682
683 # Add playlists to directory
6ae708d0 684 def _add_playlists_directory(self, playlists):
31731635 685 n = len(playlists)
686 xbmc.log("Found " + str(n) + " playlists...")
8817bb2e 687 i = 0
31731635 688 while i < n:
8817bb2e 689 playlist = playlists[i]
690 playlistName = playlist[0]
691 playlistID = playlist[1]
86f629ea 692 dir = self._add_dir(playlistName, '', MODE_PLAYLIST, self.playlistImg, playlistID, n)
8817bb2e 693 i = i + 1
694 xbmcplugin.setContent(self._handle, 'files')
86f629ea 695 xbmcplugin.addSortMethod(self._handle, xbmcplugin.SORT_METHOD_LABEL)
31731635 696 xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
3fcef5ba 697
e278f474 698 # Add whatever directory
31731635 699 def _add_dir(self, name, url, mode, iconimage, id, items=1):
052028f1 700
97289139 701 if url == '':
702 u=sys.argv[0]+"?mode="+str(mode)+"&name="+urllib.quote_plus(name)+"&id="+str(id)
703 else:
704 u = url
8817bb2e 705 dir=xbmcgui.ListItem(name, iconImage=iconimage, thumbnailImage=iconimage)
b738088f 706 dir.setInfo( type="Music", infoLabels={ "title": name } )
052028f1 707
708 # Custom menu items
709 if self.sessionidv1 != '':
710 menuItems = []
711 if mode == MODE_ALBUM:
712 mkplaylst=sys.argv[0]+"?mode="+str(MODE_MAKE_PLAYLIST)+"&name="+name+"&id="+str(id)
713 menuItems.append(("Make Grooveshark playlist", "XBMC.RunPlugin("+mkplaylst+")"))
714 if mode == MODE_PLAYLIST:
715 rmplaylst=sys.argv[0]+"?mode="+str(MODE_REMOVE_PLAYLIST)+"&name="+urllib.quote_plus(name)+"&id="+str(id)
716 menuItems.append(("Delete Grooveshark playlist", "XBMC.RunPlugin("+rmplaylst+")"))
717 mvplaylst=sys.argv[0]+"?mode="+str(MODE_RENAME_PLAYLIST)+"&name="+urllib.quote_plus(name)+"&id="+str(id)
718 menuItems.append(("Rename Grooveshark playlist", "XBMC.RunPlugin("+mvplaylst+")"))
719 dir.addContextMenuItems(menuItems, replaceItems=False)
720
31731635 721 return xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=dir,isFolder=True, totalItems=items)
97289139 722
723 def _getSavedSongs(self):
724 path = os.path.join(cacheDir, 'songs.dmp')
725 try:
726 f = open(path, 'rb')
727 songs = pickle.load(f)
728 f.close()
729 except:
730 songs = []
731 pass
732 return songs
733
734 def _setSavedSongs(self, songs):
735 try:
736 # Create the 'data' directory if it doesn't exist.
737 if not os.path.exists(cacheDir):
738 os.makedirs(cacheDir)
739 path = os.path.join(cacheDir, 'songs.dmp')
740 f = open(path, 'wb')
741 pickle.dump(songs, f, protocol=pickle.HIGHEST_PROTOCOL)
742 f.close()
743 except:
744 xbmc.log("An error occurred saving songs")
745 pass
746
e278f474 747# Parse URL parameters
8817bb2e 748def get_params():
749 param=[]
750 paramstring=sys.argv[2]
e278f474 751 xbmc.log(paramstring)
8817bb2e 752 if len(paramstring)>=2:
753 params=sys.argv[2]
754 cleanedparams=params.replace('?','')
755 if (params[len(params)-1]=='/'):
756 params=params[0:len(params)-2]
757 pairsofparams=cleanedparams.split('&')
758 param={}
759 for i in range(len(pairsofparams)):
760 splitparams={}
761 splitparams=pairsofparams[i].split('=')
762 if (len(splitparams))==2:
763 param[splitparams[0]]=splitparams[1]
8817bb2e 764 return param
765
e278f474 766# Main
8817bb2e 767grooveshark = Groveshark();
e278f474 768
8817bb2e 769params=get_params()
8817bb2e 770mode=None
8817bb2e 771try: mode=int(params["mode"])
772except: pass
7ce01be6 773id=0
774try: id=int(params["id"])
775except: pass
052028f1 776name = None
777try: name=urllib.unquote_plus(params["name"])
778except: pass
e278f474 779
780# Call function for URL
8817bb2e 781if mode==None:
782 grooveshark.categories()
783
784elif mode==MODE_SEARCH_SONGS:
785 grooveshark.searchSongs()
786
787elif mode==MODE_SEARCH_ALBUMS:
788 grooveshark.searchAlbums()
789
790elif mode==MODE_SEARCH_ARTISTS:
791 grooveshark.searchArtists()
86f629ea 792
793elif mode==MODE_SEARCH_ARTISTS_ALBUMS:
a2e75b14 794 grooveshark.searchArtistsAlbums(name)
86f629ea 795
796elif mode==MODE_SEARCH_PLAYLISTS:
797 grooveshark.searchPlaylists()
8817bb2e 798
36cc00d7 799elif mode==MODE_POPULAR_SONGS:
800 grooveshark.popularSongs()
97289139 801
802elif mode==MODE_ARTIST_POPULAR:
a2e75b14 803 grooveshark.artistPopularSongs()
8817bb2e 804
8817bb2e 805elif mode==MODE_FAVORITES:
806 grooveshark.favorites()
807
e278f474 808elif mode==MODE_PLAYLISTS:
809 grooveshark.playlists()
97289139 810
811elif mode==MODE_SONG_PAGE:
812 try: page=urllib.unquote_plus(params["page"])
813 except: pass
814 try: label=urllib.unquote_plus(params["label"])
815 except: pass
052028f1 816 grooveshark.songPage(page, label, id, name)
e278f474 817
8817bb2e 818elif mode==MODE_SONG:
8817bb2e 819 try: album=urllib.unquote_plus(params["album"])
820 except: pass
821 try: artist=urllib.unquote_plus(params["artist"])
822 except: pass
7ce01be6 823 try: coverart=urllib.unquote_plus(params["coverart"])
8817bb2e 824 except: pass
7ce01be6 825 song = grooveshark.songItem(id, name, album, artist, coverart)
3fcef5ba 826 grooveshark.playSong(song)
8817bb2e 827
828elif mode==MODE_ARTIST:
4be42357 829 grooveshark.artist(id)
8817bb2e 830
831elif mode==MODE_ALBUM:
4be42357 832 grooveshark.album(id)
8817bb2e 833
834elif mode==MODE_PLAYLIST:
e6f8730b 835 grooveshark.playlist(id, name)
8817bb2e 836
837elif mode==MODE_FAVORITE:
4be42357 838 grooveshark.favorite(id)
97289139 839
052028f1 840elif mode==MODE_UNFAVORITE:
841 try: prevMode=int(urllib.unquote_plus(params["prevmode"]))
842 except:
843 prevMode = 0
844 grooveshark.unfavorite(id, prevMode)
845
846elif mode==MODE_SIMILAR_ARTISTS:
847 grooveshark.similarArtists(id)
848
849elif mode==MODE_MAKE_PLAYLIST:
850 grooveshark.makePlaylist(id, name)
851
852elif mode==MODE_REMOVE_PLAYLIST:
853 grooveshark.removePlaylist(id, name)
854
855elif mode==MODE_RENAME_PLAYLIST:
856 grooveshark.renamePlaylist(id, name)
857
858elif mode==MODE_REMOVE_PLAYLIST_SONG:
859 try: playlistID=urllib.unquote_plus(params["playlistid"])
860 except: pass
861 grooveshark.removePlaylistSong(playlistID, name, id)
862
863elif mode==MODE_ADD_PLAYLIST_SONG:
864 grooveshark.addPlaylistSong(id)
865
e278f474 866if mode < MODE_SONG:
8817bb2e 867 xbmcplugin.endOfDirectory(int(sys.argv[1]))