Playlist stuff.
[clinton/xbmc-groove.git] / default.py
... / ...
CommitLineData
1import urllib, sys, os, shutil, re, time, xbmcaddon, xbmcplugin, xbmcgui, xbmc, pickle
2MODE_SEARCH_SONGS = 1
3MODE_SEARCH_ALBUMS = 2
4MODE_SEARCH_ARTISTS = 3
5MODE_SEARCH_ARTISTS_ALBUMS = 4
6MODE_SEARCH_PLAYLISTS = 5
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
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
24
25ACTION_MOVE_LEFT = 1
26ACTION_MOVE_UP = 3
27ACTION_MOVE_DOWN = 4
28ACTION_PAGE_UP = 5
29ACTION_PAGE_DOWN = 6
30ACTION_SELECT_ITEM = 7
31ACTION_PREVIOUS_MENU = 10
32
33# Formats for track labels
34ARTIST_ALBUM_NAME_LABEL = 0
35NAME_ALBUM_ARTIST_LABEL = 1
36
37baseDir = os.getcwd()
38resDir = xbmc.translatePath(os.path.join(baseDir, 'resources'))
39libDir = xbmc.translatePath(os.path.join(resDir, 'lib'))
40imgDir = xbmc.translatePath(os.path.join(resDir, 'img'))
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)
44
45baseModeUrl = 'plugin://plugin.audio.groove/'
46playlistUrl = baseModeUrl + '?mode=' + str(MODE_PLAYLIST)
47playlistsUrl = baseModeUrl + '?mode=' + str(MODE_PLAYLISTS)
48favoritesUrl = baseModeUrl + '?mode=' + str(MODE_FAVORITES)
49
50searchArtistsAlbumsName = "Search for artist's albums..."
51
52thumbDef = os.path.join(imgDir, 'default.tbn')
53listBackground = os.path.join(imgDir, 'listbackground.png')
54
55sys.path.append (libDir)
56from GroovesharkAPI import GrooveAPI
57from GroovesharkAPI import GrooveAPIv1
58
59try:
60 groovesharkApi = GrooveAPI()
61 if groovesharkApi.pingService() != True:
62 raise StandardError('No Grooveshark service')
63except:
64 dialog = xbmcgui.Dialog()
65 dialog.ok('Grooveshark XBMC', 'Unable to connect with Grooveshark.', 'Please try again later')
66 sys.exit(-1)
67
68
69class _Info:
70 def __init__( self, *args, **kwargs ):
71 self.__dict__.update( kwargs )
72
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()
134
135class Groveshark:
136
137 albumImg = xbmc.translatePath(os.path.join(imgDir, 'album.png'))
138 artistImg = xbmc.translatePath(os.path.join(imgDir, 'artist.png'))
139 artistsAlbumsImg = xbmc.translatePath(os.path.join(imgDir, 'artistsalbums.png'))
140 favoritesImg = xbmc.translatePath(os.path.join(imgDir, 'favorites.png'))
141 playlistImg = xbmc.translatePath(os.path.join(imgDir, 'playlist.png'))
142 usersplaylistsImg = xbmc.translatePath(os.path.join(imgDir, 'usersplaylists.png'))
143 popularSongsImg = xbmc.translatePath(os.path.join(imgDir, 'popularSongs.png'))
144 popularSongsArtistImg = xbmc.translatePath(os.path.join(imgDir, 'popularSongsArtist.png'))
145 songImg = xbmc.translatePath(os.path.join(imgDir, 'song.png'))
146 defImg = xbmc.translatePath(os.path.join(imgDir, 'default.tbn'))
147 fanImg = xbmc.translatePath(os.path.join(baseDir, 'fanart.png'))
148
149 settings = xbmcaddon.Addon(id='plugin.audio.groove')
150 songsearchlimit = int(settings.getSetting('songsearchlimit'))
151 albumsearchlimit = int(settings.getSetting('albumsearchlimit'))
152 artistsearchlimit = int(settings.getSetting('artistsearchlimit'))
153 songspagelimit = int(settings.getSetting('songspagelimit'))
154 username = settings.getSetting('username')
155 password = settings.getSetting('password')
156 sessionidv1 = settings.getSetting('sessionidv1')
157 userid = 0
158
159 def __init__( self ):
160 self._handle = int(sys.argv[1])
161 if os.path.isdir(cacheDir) == False:
162 os.makedirs(cacheDir)
163 xbmc.log("Made " + cacheDir)
164 artDir = xbmc.translatePath(thumbDir)
165 if os.path.isdir(artDir) == False:
166 os.makedirs(artDir)
167 xbmc.log("Made " + artDir)
168
169 self.groovesharkApiv1 = GrooveAPIv1(self.sessionidv1)
170
171 # Top-level menu
172 def categories(self):
173
174 self.userid = self._get_login()
175
176 # Setup
177 xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
178
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)
182 self._add_dir(searchArtistsAlbumsName, '', MODE_SEARCH_ARTISTS_ALBUMS, self.artistsAlbumsImg, 0)
183 self._add_dir("Search for user's playlists...", '', MODE_SEARCH_PLAYLISTS, self.usersplaylistsImg, 0)
184 self._add_dir('Popular songs for artist...', '', MODE_ARTIST_POPULAR, self.popularSongsArtistImg, 0)
185 self._add_dir('Popular songs', '', MODE_POPULAR_SONGS, self.popularSongsImg, 0)
186 if (self.userid != 0):
187 self._add_dir('My favorites', '', MODE_FAVORITES, self.favoritesImg, 0)
188 self._add_dir('My playlists', '', MODE_PLAYLISTS, self.playlistImg, 0)
189
190 # Search for songs
191 def searchSongs(self):
192 query = self._get_keyboard(default="", heading="Search for songs")
193 if (query != ''):
194 songs = groovesharkApi.getSongSearchResults(query, limit = self.songsearchlimit)
195 if (len(songs) > 0):
196 self._add_songs_directory(songs)
197 else:
198 dialog = xbmcgui.Dialog()
199 dialog.ok('Grooveshark XBMC', 'No matching songs.')
200 self.categories()
201 else:
202 self.categories()
203
204 # Search for albums
205 def searchAlbums(self):
206 query = self._get_keyboard(default="", heading="Search for albums")
207 if (query != ''):
208 albums = groovesharkApi.getAlbumSearchResults(query, limit = self.albumsearchlimit)
209 if (len(albums) > 0):
210 self._add_albums_directory(albums)
211 else:
212 dialog = xbmcgui.Dialog()
213 dialog.ok('Grooveshark XBMC', 'No matching albums.')
214 self.categories()
215 else:
216 self.categories()
217
218 # Search for artists
219 def searchArtists(self):
220 query = self._get_keyboard(default="", heading="Search for artists")
221 if (query != ''):
222 artists = groovesharkApi.getArtistSearchResults(query, limit = self.artistsearchlimit)
223 if (len(artists) > 0):
224 self._add_artists_directory(artists)
225 else:
226 dialog = xbmcgui.Dialog()
227 dialog.ok('Grooveshark XBMC', 'No matching artists.')
228 self.categories()
229 else:
230 self.categories()
231
232 # Search for playlists
233 def searchPlaylists(self):
234 query = self._get_keyboard(default="", heading="Username")
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
247 def searchArtistsAlbums(self, artistName = None):
248 if artistName == None or artistName == searchArtistsAlbumsName:
249 query = self._get_keyboard(default="", heading="Search for artist's albums")
250 else:
251 query = artistName
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):
260 self._add_albums_directory(albums, artistID)
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
272 # Get my favorites
273 def favorites(self):
274 userid = self._get_login()
275 if (userid != 0):
276 favorites = groovesharkApi.getUserFavoriteSongs()
277 if (len(favorites) > 0):
278 self._add_songs_directory(favorites, isFavorites=True)
279 else:
280 dialog = xbmcgui.Dialog()
281 dialog.ok('Grooveshark XBMC', 'You have no favorites.')
282 self.categories()
283
284 # Get popular songs
285 def popularSongs(self):
286 popular = groovesharkApi.getPopularSongsToday(limit = self.songsearchlimit)
287 if (len(popular) > 0):
288 self._add_songs_directory(popular)
289 else:
290 dialog = xbmcgui.Dialog()
291 dialog.ok('Grooveshark XBMC', 'No popular songs.')
292 self.categories()
293
294 # Get my playlists
295 def playlists(self):
296 userid = self._get_login()
297 if (userid != 0):
298 playlists = groovesharkApi.getUserPlaylists()
299 if (len(playlists) > 0):
300 self._add_playlists_directory(playlists)
301 else:
302 dialog = xbmcgui.Dialog()
303 dialog.ok('Grooveshark XBMC', 'You have no Grooveshark playlists.')
304 self.categories()
305 else:
306 dialog = xbmcgui.Dialog()
307 dialog.ok('Grooveshark XBMC', 'You must be logged in ', ' to see your Grooveshark playlists.')
308
309 # Make songs a favorite
310 def favorite(self, songid):
311 userid = self._get_login()
312 if (userid != 0):
313 xbmc.log("Favorite song: " + str(songid))
314 groovesharkApi.addUserFavoriteSong(songID = songid)
315 xbmc.executebuiltin('XBMC.Notification(Grooveshark XBMC, Added to favorites, 1000, ' + thumbDef + ')')
316 else:
317 dialog = xbmcgui.Dialog()
318 dialog.ok('Grooveshark XBMC', 'You must be logged in', 'to add favorites.')
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
334
335 # Show selected album
336 def album(self, albumid):
337 album = groovesharkApi.getAlbumSongs(albumid, limit = self.songsearchlimit)
338 self._add_songs_directory(album, trackLabelFormat=NAME_ALBUM_ARTIST_LABEL)
339
340 # Show selected artist
341 def artist(self, artistid):
342 albums = groovesharkApi.getArtistAlbums(artistid, limit = self.albumsearchlimit)
343 self._add_albums_directory(albums, artistid)
344
345 # Show selected playlist
346 def playlist(self, playlistid, playlistname):
347 userid = self._get_login()
348 if (userid != 0):
349 songs = groovesharkApi.getPlaylistSongs(playlistid)
350 self._add_songs_directory(songs, trackLabelFormat=NAME_ALBUM_ARTIST_LABEL, playlistid=playlistid, playlistname=playlistname)
351 else:
352 dialog = xbmcgui.Dialog()
353 dialog.ok('Grooveshark XBMC', 'You must be logged in', 'to get Grooveshark playlists.')
354
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
378 # Play a song
379 def playSong(self, item):
380 songid = item.getProperty('songid')
381 song = groovesharkApi.getSongURLFromSongID(songid)
382 if song != '':
383 item.setPath(song)
384 xbmc.log("Playing: " + song)
385 xbmcplugin.setResolvedUrl(handle=int(sys.argv[1]), succeeded=True, listitem=item)
386 else:
387 xbmc.executebuiltin('XBMC.Notification(Grooveshark XBMC, Unable to play song, 1000, ' + thumbDef + ')')
388
389 # Make a song directory item
390 def songItem(self, songid, name, album, artist, coverart, trackLabelFormat=ARTIST_ALBUM_NAME_LABEL):
391 songImg = self._get_icon(coverart, 'song-' + str(songid) + "-image")
392 if int(trackLabelFormat) == NAME_ALBUM_ARTIST_LABEL:
393 trackLabel = name + " - " + album + " - " + artist
394 else:
395 trackLabel = artist + " - " + album + " - " + name
396 item = xbmcgui.ListItem(label = trackLabel, thumbnailImage=songImg, iconImage=songImg)
397 item.setInfo( type="music", infoLabels={ "title": name, "album": album, "artist": artist} )
398 item.setProperty('mimetype', 'audio/mpeg')
399 item.setProperty("IsPlayable", "true")
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
406 return item
407
408 # Next page of songs
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):
512 dialog = xbmcgui.Dialog()
513 if dialog.yesno('Grooveshark XBMC', 'Delete this song from', 'the Grooveshark playlist?') == True:
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 + ')')
522 xbmc.executebuiltin("Container.Update(" + playlistUrl + "&id="+str(playlistid) + "&name=" + playlistname + ")")
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()
536
537 # Get keyboard input
538 def _get_keyboard(self, default="", heading="", hidden=False):
539 kb = xbmc.Keyboard(default, heading, hidden)
540 kb.doModal()
541 if (kb.isConfirmed()):
542 return unicode(kb.getText(), "utf-8")
543 return ''
544
545 # Login to grooveshark
546 def _get_login(self, version = 2):
547 if (self.username == "" or self.password == ""):
548 dialog = xbmcgui.Dialog()
549 dialog.ok('Grooveshark XBMC', 'Unable to login.', 'Check username and password in settings.')
550 return 0
551 else:
552 if self.userid == 0:
553 if version == 1:
554 uid = self.groovesharkApiv1.login(self.username, self.password)
555 else:
556 uid = groovesharkApi.login(self.username, self.password)
557 if (uid != 0):
558 return uid
559 else:
560 dialog = xbmcgui.Dialog()
561 dialog.ok('Grooveshark XBMC', 'Unable to login.', 'Check username and password in settings.')
562 return 0
563
564 # Get a song directory item
565 def _get_song_item(self, song, trackLabelFormat):
566 name = song[0]
567 songid = song[1]
568 album = song[2]
569 artist = song[4]
570 coverart = song[6]
571 return self.songItem(songid, name, album, artist, coverart, trackLabelFormat)
572
573 # File download
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
586
587 # Add songs to directory
588 def _add_songs_directory(self, songs, trackLabelFormat=ARTIST_ALBUM_NAME_LABEL, page=0, playlistid=0, playlistname='', isFavorites=False):
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
610 id = 0
611 for song in songs:
612 item = self._get_song_item(song, trackLabelFormat)
613 coverart = item.getProperty('coverart')
614 songname = song[0]
615 songid = song[1]
616 songalbum = song[2]
617 songartist = song[4]
618 u=sys.argv[0]+"?mode="+str(MODE_SONG)+"&name="+urllib.quote_plus(songname)+"&id="+str(songid) \
619 +"&album="+urllib.quote_plus(songalbum) \
620 +"&artist="+urllib.quote_plus(songartist) \
621 +"&coverart="+urllib.quote_plus(coverart)
622 fav=sys.argv[0]+"?mode="+str(MODE_FAVORITE)+"&name="+urllib.quote_plus(songname)+"&id="+str(songid)
623 unfav=sys.argv[0]+"?mode="+str(MODE_UNFAVORITE)+"&name="+urllib.quote_plus(songname)+"&id="+str(songid)+"&prevmode="
624 menuItems = []
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+")"))
637 item.addContextMenuItems(menuItems, replaceItems=False)
638 xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=item,isFolder=False, totalItems=len(songs))
639 id = id + 1
640
641 page = page + 1
642 if totalSongs > page * self.songspagelimit:
643 u=sys.argv[0]+"?mode="+str(MODE_SONG_PAGE)+"&id=playlistid"+"&page="+str(page)+"&label="+str(trackLabelFormat)+"&name="+playlistname
644 self._add_dir('More songs...', u, MODE_SONG_PAGE, self.songImg, 0, totalSongs - (page * self.songspagelimit))
645
646 xbmcplugin.setContent(self._handle, 'songs')
647 xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
648
649 # Add albums to directory
650 def _add_albums_directory(self, albums, artistid=0):
651 n = len(albums)
652 xbmc.log("Found " + str(n) + " albums...")
653 i = 0
654 while i < n:
655 album = albums[i]
656 albumArtistName = album[0]
657 albumName = album[2]
658 albumID = album[3]
659 albumImage = self._get_icon(album[4], 'album-' + str(albumID))
660 self._add_dir(albumName + " - " + albumArtistName, '', MODE_ALBUM, albumImage, albumID, n)
661 i = i + 1
662 if artistid > 0 and self.sessionidv1 != '':
663 self._add_dir('Similar artists...', '', MODE_SIMILAR_ARTISTS, self.artistImg, artistid)
664 xbmcplugin.setContent(self._handle, 'albums')
665 xbmcplugin.addSortMethod(self._handle, xbmcplugin.SORT_METHOD_ALBUM_IGNORE_THE)
666 xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
667
668 # Add artists to directory
669 def _add_artists_directory(self, artists):
670 n = len(artists)
671 xbmc.log("Found " + str(n) + " artists...")
672 i = 0
673 while i < n:
674 artist = artists[i]
675 artistName = artist[0]
676 artistID = artist[1]
677 self._add_dir(artistName, '', MODE_ARTIST, self.artistImg, artistID, n)
678 i = i + 1
679 xbmcplugin.setContent(self._handle, 'artists')
680 xbmcplugin.addSortMethod(self._handle, xbmcplugin.SORT_METHOD_ARTIST_IGNORE_THE)
681 xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
682
683 # Add playlists to directory
684 def _add_playlists_directory(self, playlists):
685 n = len(playlists)
686 xbmc.log("Found " + str(n) + " playlists...")
687 i = 0
688 while i < n:
689 playlist = playlists[i]
690 playlistName = playlist[0]
691 playlistID = playlist[1]
692 dir = self._add_dir(playlistName, '', MODE_PLAYLIST, self.playlistImg, playlistID, n)
693 i = i + 1
694 xbmcplugin.setContent(self._handle, 'files')
695 xbmcplugin.addSortMethod(self._handle, xbmcplugin.SORT_METHOD_LABEL)
696 xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
697
698 # Add whatever directory
699 def _add_dir(self, name, url, mode, iconimage, id, items=1):
700
701 if url == '':
702 u=sys.argv[0]+"?mode="+str(mode)+"&name="+urllib.quote_plus(name)+"&id="+str(id)
703 else:
704 u = url
705 dir=xbmcgui.ListItem(name, iconImage=iconimage, thumbnailImage=iconimage)
706 dir.setInfo( type="Music", infoLabels={ "title": name } )
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
721 return xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=dir,isFolder=True, totalItems=items)
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
747# Parse URL parameters
748def get_params():
749 param=[]
750 paramstring=sys.argv[2]
751 xbmc.log(paramstring)
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]
764 return param
765
766# Main
767grooveshark = Groveshark();
768
769params=get_params()
770mode=None
771try: mode=int(params["mode"])
772except: pass
773id=0
774try: id=int(params["id"])
775except: pass
776name = None
777try: name=urllib.unquote_plus(params["name"])
778except: pass
779
780# Call function for URL
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()
792
793elif mode==MODE_SEARCH_ARTISTS_ALBUMS:
794 grooveshark.searchArtistsAlbums(name)
795
796elif mode==MODE_SEARCH_PLAYLISTS:
797 grooveshark.searchPlaylists()
798
799elif mode==MODE_POPULAR_SONGS:
800 grooveshark.popularSongs()
801
802elif mode==MODE_ARTIST_POPULAR:
803 grooveshark.artistPopularSongs()
804
805elif mode==MODE_FAVORITES:
806 grooveshark.favorites()
807
808elif mode==MODE_PLAYLISTS:
809 grooveshark.playlists()
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
816 grooveshark.songPage(page, label, id, name)
817
818elif mode==MODE_SONG:
819 try: album=urllib.unquote_plus(params["album"])
820 except: pass
821 try: artist=urllib.unquote_plus(params["artist"])
822 except: pass
823 try: coverart=urllib.unquote_plus(params["coverart"])
824 except: pass
825 song = grooveshark.songItem(id, name, album, artist, coverart)
826 grooveshark.playSong(song)
827
828elif mode==MODE_ARTIST:
829 grooveshark.artist(id)
830
831elif mode==MODE_ALBUM:
832 grooveshark.album(id)
833
834elif mode==MODE_PLAYLIST:
835 grooveshark.playlist(id, name)
836
837elif mode==MODE_FAVORITE:
838 grooveshark.favorite(id)
839
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
866if mode < MODE_SONG:
867 xbmcplugin.endOfDirectory(int(sys.argv[1]))