d44a23643a9d3f888000c432a70509d56689f2b7
[clinton/xbmc-groove.git] / default.py
1 import urllib, sys, os, shutil, re, time, xbmcaddon, xbmcplugin, xbmcgui, xbmc, pickle
2 MODE_SEARCH_SONGS = 1
3 MODE_SEARCH_ALBUMS = 2
4 MODE_SEARCH_ARTISTS = 3
5 MODE_SEARCH_ARTISTS_ALBUMS = 4
6 MODE_SEARCH_PLAYLISTS = 5
7 MODE_ARTIST_POPULAR = 6
8 MODE_POPULAR_SONGS = 7
9 MODE_FAVORITES = 8
10 MODE_PLAYLISTS = 9
11 MODE_ALBUM = 10
12 MODE_ARTIST = 11
13 MODE_PLAYLIST = 12
14 MODE_SONG_PAGE = 13
15 MODE_SIMILAR_ARTISTS = 14
16 MODE_SONG = 15
17 MODE_FAVORITE = 16
18 MODE_UNFAVORITE = 17
19 MODE_MAKE_PLAYLIST = 18
20 MODE_REMOVE_PLAYLIST = 19
21 MODE_RENAME_PLAYLIST = 20
22 MODE_REMOVE_PLAYLIST_SONG = 21
23 MODE_ADD_PLAYLIST_SONG = 22
24
25 ACTION_MOVE_LEFT = 1
26 ACTION_MOVE_UP = 3
27 ACTION_MOVE_DOWN = 4
28 ACTION_PAGE_UP = 5
29 ACTION_PAGE_DOWN = 6
30 ACTION_SELECT_ITEM = 7
31 ACTION_PREVIOUS_MENU = 10
32
33 # Formats for track labels
34 ARTIST_ALBUM_NAME_LABEL = 0
35 NAME_ALBUM_ARTIST_LABEL = 1
36
37 baseDir = os.getcwd()
38 resDir = xbmc.translatePath(os.path.join(baseDir, 'resources'))
39 libDir = xbmc.translatePath(os.path.join(resDir, 'lib'))
40 imgDir = xbmc.translatePath(os.path.join(resDir, 'img'))
41 cacheDir = os.path.join(xbmc.translatePath('special://masterprofile/addon_data/'), os.path.basename(os.getcwd()))
42 thumbDirName = 'thumb'
43 thumbDir = os.path.join('special://masterprofile/addon_data/', os.path.basename(os.getcwd()), thumbDirName)
44
45 baseModeUrl = 'plugin://plugin.audio.groove/'
46 playlistUrl = baseModeUrl + '?mode=' + str(MODE_PLAYLIST)
47 playlistsUrl = baseModeUrl + '?mode=' + str(MODE_PLAYLISTS)
48 favoritesUrl = baseModeUrl + '?mode=' + str(MODE_FAVORITES)
49
50 searchArtistsAlbumsName = "Search for artist's albums..."
51
52 thumbDef = os.path.join(imgDir, 'default.tbn')
53 listBackground = os.path.join(imgDir, 'listbackground.png')
54
55 sys.path.append (libDir)
56 from GroovesharkAPI import GrooveAPI
57 from GroovesharkAPI import GrooveAPIv1
58
59 try:
60 groovesharkApi = GrooveAPI()
61 if groovesharkApi.pingService() != True:
62 raise StandardError('No Grooveshark service')
63 except:
64 dialog = xbmcgui.Dialog()
65 dialog.ok('Grooveshark XBMC', 'Unable to connect with Grooveshark.', 'Please try again later')
66 sys.exit(-1)
67
68
69 class _Info:
70 def __init__( self, *args, **kwargs ):
71 self.__dict__.update( kwargs )
72
73 # Window dialog to select a grooveshark playlist
74 class 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
135 class 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, version = 2):
347 userid = self._get_login()
348 if (userid != 0):
349 if version == 1:
350 songs = self.groovesharkApiv1.playlistGetSongs(playlistid)
351 else:
352 songs = groovesharkApi.getPlaylistSongs(playlistid)
353 self._add_songs_directory(songs, trackLabelFormat=NAME_ALBUM_ARTIST_LABEL, playlistid=playlistid, playlistname=playlistname)
354 else:
355 dialog = xbmcgui.Dialog()
356 dialog.ok('Grooveshark XBMC', 'You must be logged in', 'to get Grooveshark playlists.')
357
358 # Show popular songs of the artist
359 def artistPopularSongs(self):
360 query = self._get_keyboard(default="", heading="Artist")
361 if (query != ''):
362 artists = groovesharkApi.getArtistSearchResults(query, limit = self.artistsearchlimit)
363 if (len(artists) > 0):
364 artist = artists[0]
365 artistID = artist[1]
366 xbmc.log("Found " + artist[0] + "...")
367 songs = groovesharkApi.getArtistPopularSongs(artistID, limit = self.songsearchlimit)
368 if (len(songs) > 0):
369 self._add_songs_directory(songs, trackLabelFormat=NAME_ALBUM_ARTIST_LABEL)
370 else:
371 dialog = xbmcgui.Dialog()
372 dialog.ok('Grooveshark XBMC', 'No popular songs.')
373 self.categories()
374 else:
375 dialog = xbmcgui.Dialog()
376 dialog.ok('Grooveshark XBMC', 'No matching artists.')
377 self.categories()
378 else:
379 self.categories()
380
381 # Play a song
382 def playSong(self, item):
383 songid = item.getProperty('songid')
384 song = groovesharkApi.getSongURLFromSongID(songid)
385 if song != '':
386 item.setPath(song)
387 xbmc.log("Playing: " + song)
388 xbmcplugin.setResolvedUrl(handle=int(sys.argv[1]), succeeded=True, listitem=item)
389 else:
390 xbmc.executebuiltin('XBMC.Notification(Grooveshark XBMC, Unable to play song, 1000, ' + thumbDef + ')')
391
392 # Make a song directory item
393 def songItem(self, songid, name, album, artist, coverart, trackLabelFormat=ARTIST_ALBUM_NAME_LABEL):
394 songImg = self._get_icon(coverart, 'song-' + str(songid) + "-image")
395 if trackLabelFormat == NAME_ALBUM_ARTIST_LABEL:
396 trackLabel = name + " - " + album + " - " + artist
397 else:
398 trackLabel = artist + " - " + album + " - " + name
399 item = xbmcgui.ListItem(label = trackLabel, thumbnailImage=songImg, iconImage=songImg)
400 item.setInfo( type="music", infoLabels={ "title": name, "album": album, "artist": artist} )
401 item.setProperty('mimetype', 'audio/mpeg')
402 item.setProperty("IsPlayable", "true")
403 item.setProperty('songid', str(songid))
404 item.setProperty('coverart', songImg)
405 item.setProperty('title', name)
406 item.setProperty('album', album)
407 item.setProperty('artist', artist)
408
409 return item
410
411 # Next page of songs
412 def songPage(self, page, trackLabelFormat, playlistid = 0, playlistname = ''):
413 self._add_songs_directory([], trackLabelFormat, page, playlistid = playlistid, playlistname = playlistname)
414
415 # Make a playlist from an album
416 def makePlaylist(self, albumid, name):
417 userid = self._get_login(version = 1)
418 if (userid != 0):
419 re.split(' - ',name,1)
420 nameTokens = re.split(' - ',name,1) # suggested name
421 name = self._get_keyboard(default=nameTokens[0], heading="Grooveshark playlist name")
422 if name != '':
423 album = groovesharkApi.getAlbumSongs(albumid, limit = self.songsearchlimit)
424 songids = []
425 for song in album:
426 songids.append(song[1])
427 if self.groovesharkApiv1.playlistCreateUnique(name, songids) == 0:
428 dialog = xbmcgui.Dialog()
429 dialog.ok('Grooveshark XBMC', 'Cannot create Grooveshark playlist ', name)
430 else:
431 xbmc.executebuiltin('XBMC.Notification(Grooveshark XBMC, Grooveshark playlist created, 1000, ' + thumbDef + ')')
432 else:
433 dialog = xbmcgui.Dialog()
434 dialog.ok('Grooveshark XBMC', 'You must be logged in ', ' to create a Grooveshark playlist.')
435
436 # Rename a playlist
437 def renamePlaylist(self, playlistid, name):
438 userid = self._get_login(version = 1)
439 if (userid != 0):
440 newname = self._get_keyboard(default=name, heading="Grooveshark playlist name")
441 if newname == '':
442 return
443 elif self.groovesharkApiv1.playlistRename(playlistid, newname) == 0:
444 dialog = xbmcgui.Dialog()
445 dialog.ok('Grooveshark XBMC', 'Cannot rename Grooveshark playlist ', name)
446 else:
447 # Refresh to show new item name
448 xbmc.executebuiltin("Container.Refresh")
449 else:
450 dialog = xbmcgui.Dialog()
451 dialog.ok('Grooveshark XBMC', 'You must be logged in ', ' to rename a Grooveshark playlist.')
452
453 # Remove a playlist
454 def removePlaylist(self, playlistid, name):
455 dialog = xbmcgui.Dialog()
456 if dialog.yesno('Grooveshark XBMC', name, 'Delete this Grooveshark playlist?') == True:
457 userid = self._get_login(version = 1)
458 if (userid != 0):
459 if self.groovesharkApiv1.playlistDelete(playlistid) == 0:
460 dialog = xbmcgui.Dialog()
461 dialog.ok('Grooveshark XBMC', 'Cannot remove Grooveshark playlist ', name)
462 else:
463 # Refresh to remove item from directory
464 xbmc.executebuiltin("Container.Refresh(" + playlistsUrl + ")")
465 else:
466 dialog = xbmcgui.Dialog()
467 dialog.ok('Grooveshark XBMC', 'You must be logged in ', ' to delete a Grooveshark playlist.')
468
469 # Add song to playlist
470 def addPlaylistSong(self, songid):
471 userid = self._get_login(version = 1)
472 if (userid != 0):
473 playlists = groovesharkApi.getUserPlaylists()
474 if (len(playlists) > 0):
475 ret = 0
476 # Select the playlist
477 playlistSelect = GroovesharkPlaylistSelect(items=playlists)
478 playlistSelect.setFocus(playlistSelect.playlistControl)
479 playlistSelect.doModal()
480 i = playlistSelect.selected
481 del playlistSelect
482 if i > -1:
483 # Add a new playlist
484 if i >= len(playlists):
485 name = self._get_keyboard(default='', heading="Grooveshark playlist name")
486 if name != '':
487 songIds = []
488 songIds.append(songid)
489 if self.groovesharkApiv1.playlistCreateUnique(name, songIds) == 0:
490 dialog = xbmcgui.Dialog()
491 dialog.ok('Grooveshark XBMC', 'Cannot create Grooveshark playlist ', name)
492 else:
493 xbmc.executebuiltin('XBMC.Notification(Grooveshark XBMC, Grooveshark playlist created, 1000, ' + thumbDef + ')')
494 # Existing playlist
495 else:
496 playlist = playlists[i]
497 playlistid = playlist[1]
498 xbmc.log("Add song " + str(songid) + " to playlist " + str(playlistid))
499 ret = self.groovesharkApiv1.playlistAddSong(playlistid, songid, 0)
500 if ret == 0:
501 dialog = xbmcgui.Dialog()
502 dialog.ok('Grooveshark XBMC', 'Cannot add to playlist ')
503 else:
504 xbmc.executebuiltin('XBMC.Notification(Grooveshark XBMC, Added song to Grooveshark playlist, 1000, ' + thumbDef + ')')
505 else:
506 dialog = xbmcgui.Dialog()
507 dialog.ok('Grooveshark XBMC', 'You have no Grooveshark playlists.')
508 self.categories()
509 else:
510 dialog = xbmcgui.Dialog()
511 dialog.ok('Grooveshark XBMC', 'You must be logged in', 'to add a song to a Grooveshark playlist.')
512
513 # Remove song from playlist
514 def removePlaylistSong(self, playlistid, playlistname, songpos):
515 dialog = xbmcgui.Dialog(version = 1)
516 if dialog.yesno('Grooveshark XBMC', 'Delete this song from the Grooveshark playlist?') == True:
517 userid = self._get_login(version = 1)
518 if (userid != 0):
519 if self.groovesharkApiv1.playlistDeleteSong(playlistid, songpos) == 0:
520 dialog = xbmcgui.Dialog()
521 dialog.ok('Grooveshark XBMC', 'Failed to remove', 'song from Grooveshark playlist.')
522 else:
523 # Refresh to remove item from directory
524 xbmc.executebuiltin('XBMC.Notification(Grooveshark XBMC, Removed song from Grooveshark playlist, 1000, ' + thumbDef + ')')
525 xbmc.executebuiltin("Container.Update(" + playlistUrl + "&id="+str(playlistid) + "&name=" + playlistname + "&version=1)")
526 else:
527 dialog = xbmcgui.Dialog()
528 dialog.ok('Grooveshark XBMC', 'You must be logged in', 'to delete a song from a Grooveshark playlist.')
529
530 # Find similar artists to searched artist
531 def similarArtists(self, artistId):
532 similar = self.groovesharkApiv1.artistGetSimilar(artistId, limit = self.artistsearchlimit)
533 if (len(similar) > 0):
534 self._add_artists_directory(similar)
535 else:
536 dialog = xbmcgui.Dialog()
537 dialog.ok('Grooveshark XBMC', 'No similar artists.')
538 self.categories()
539
540 # Get keyboard input
541 def _get_keyboard(self, default="", heading="", hidden=False):
542 kb = xbmc.Keyboard(default, heading, hidden)
543 kb.doModal()
544 if (kb.isConfirmed()):
545 return unicode(kb.getText(), "utf-8")
546 return ''
547
548 # Login to grooveshark
549 def _get_login(self, version = 2):
550 if (self.username == "" or self.password == ""):
551 dialog = xbmcgui.Dialog()
552 dialog.ok('Grooveshark XBMC', 'Unable to login.', 'Check username and password in settings.')
553 return 0
554 else:
555 if self.userid == 0:
556 if version == 1:
557 uid = self.groovesharkApiv1.login(self.username, self.password)
558 else:
559 uid = groovesharkApi.login(self.username, self.password)
560 if (uid != 0):
561 return uid
562 else:
563 dialog = xbmcgui.Dialog()
564 dialog.ok('Grooveshark XBMC', 'Unable to login.', 'Check username and password in settings.')
565 return 0
566
567 # Get a song directory item
568 def _get_song_item(self, song, trackLabelFormat):
569 name = song[0]
570 songid = song[1]
571 album = song[2]
572 artist = song[4]
573 coverart = song[6]
574 return self.songItem(songid, name, album, artist, coverart, trackLabelFormat)
575
576 # File download
577 def _get_icon(self, url, songid):
578 if url != 'None':
579 localThumb = os.path.join(xbmc.translatePath(os.path.join(thumbDir, str(songid)))) + '.tbn'
580 try:
581 if os.path.isfile(localThumb) == False:
582 loc = urllib.URLopener()
583 loc.retrieve(url, localThumb)
584 except:
585 shutil.copy2(thumbDef, localThumb)
586 return os.path.join(os.path.join(thumbDir, str(songid))) + '.tbn'
587 else:
588 return thumbDef
589
590 # Add songs to directory
591 def _add_songs_directory(self, songs, trackLabelFormat=ARTIST_ALBUM_NAME_LABEL, page=0, playlistid=0, playlistname='', isFavorites=False):
592
593 totalSongs = len(songs)
594 page = int(page)
595
596 # No pages needed
597 if page == 0 and totalSongs <= self.songspagelimit:
598 xbmc.log("Found " + str(totalSongs) + " songs...")
599 # Pages
600 else:
601 # Cache all songs
602 if page == 0:
603 self._setSavedSongs(songs)
604 else:
605 songs = self._getSavedSongs()
606 totalSongs = len(songs)
607
608 if totalSongs > 0:
609 start = page * self.songspagelimit
610 end = start + self.songspagelimit
611 songs = songs[start:end]
612
613 id = 0
614 for song in songs:
615 item = self._get_song_item(song, trackLabelFormat)
616 coverart = item.getProperty('coverart')
617 songname = song[0]
618 songid = song[1]
619 songalbum = song[2]
620 songartist = song[4]
621 u=sys.argv[0]+"?mode="+str(MODE_SONG)+"&name="+urllib.quote_plus(songname)+"&id="+str(songid) \
622 +"&album="+urllib.quote_plus(songalbum) \
623 +"&artist="+urllib.quote_plus(songartist) \
624 +"&coverart="+urllib.quote_plus(coverart)
625 fav=sys.argv[0]+"?mode="+str(MODE_FAVORITE)+"&name="+urllib.quote_plus(songname)+"&id="+str(songid)
626 unfav=sys.argv[0]+"?mode="+str(MODE_UNFAVORITE)+"&name="+urllib.quote_plus(songname)+"&id="+str(songid)+"&prevmode="
627 menuItems = []
628 if isFavorites == True:
629 unfav = unfav +str(MODE_FAVORITES)
630 else:
631 menuItems.append(("Grooveshark favorite", "XBMC.RunPlugin("+fav+")"))
632 if self.sessionidv1 != '':
633 menuItems.append(("Not Grooveshark favorite", "XBMC.RunPlugin("+unfav+")"))
634 if playlistid > 0:
635 rmplaylstsong=sys.argv[0]+"?playlistid="+str(playlistid)+"&id="+str(id+1)+"&mode="+str(MODE_REMOVE_PLAYLIST_SONG)+"&name="+playlistname
636 menuItems.append(("Remove from Grooveshark playlist", "XBMC.RunPlugin("+rmplaylstsong+")"))
637 else:
638 addplaylstsong=sys.argv[0]+"?id="+str(songid)+"&mode="+str(MODE_ADD_PLAYLIST_SONG)
639 menuItems.append(("Add to Grooveshark playlist", "XBMC.RunPlugin("+addplaylstsong+")"))
640 item.addContextMenuItems(menuItems, replaceItems=False)
641 xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=item,isFolder=False, totalItems=len(songs))
642 id = id + 1
643
644 page = page + 1
645 if totalSongs > page * self.songspagelimit:
646 u=sys.argv[0]+"?mode="+str(MODE_SONG_PAGE)+"&id=playlistid"+"&page="+str(page)+"&label="+str(trackLabelFormat)+"&name="+playlistname
647 self._add_dir('More songs...', u, MODE_SONG_PAGE, self.songImg, 0, totalSongs - (page * self.songspagelimit))
648
649 xbmcplugin.setContent(self._handle, 'songs')
650 xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
651
652 # Add albums to directory
653 def _add_albums_directory(self, albums, artistid=0):
654 n = len(albums)
655 xbmc.log("Found " + str(n) + " albums...")
656 i = 0
657 while i < n:
658 album = albums[i]
659 albumArtistName = album[0]
660 albumName = album[2]
661 albumID = album[3]
662 albumImage = self._get_icon(album[4], 'album-' + str(albumID))
663 self._add_dir(albumName + " - " + albumArtistName, '', MODE_ALBUM, albumImage, albumID, n)
664 i = i + 1
665 if artistid > 0 and self.sessionidv1 != '':
666 self._add_dir('Similar artists...', '', MODE_SIMILAR_ARTISTS, self.artistImg, artistid)
667 xbmcplugin.setContent(self._handle, 'albums')
668 xbmcplugin.addSortMethod(self._handle, xbmcplugin.SORT_METHOD_ALBUM_IGNORE_THE)
669 xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
670
671 # Add artists to directory
672 def _add_artists_directory(self, artists):
673 n = len(artists)
674 xbmc.log("Found " + str(n) + " artists...")
675 i = 0
676 while i < n:
677 artist = artists[i]
678 artistName = artist[0]
679 artistID = artist[1]
680 self._add_dir(artistName, '', MODE_ARTIST, self.artistImg, artistID, n)
681 i = i + 1
682 xbmcplugin.setContent(self._handle, 'artists')
683 xbmcplugin.addSortMethod(self._handle, xbmcplugin.SORT_METHOD_ARTIST_IGNORE_THE)
684 xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
685
686 # Add playlists to directory
687 def _add_playlists_directory(self, playlists):
688 n = len(playlists)
689 xbmc.log("Found " + str(n) + " playlists...")
690 i = 0
691 while i < n:
692 playlist = playlists[i]
693 playlistName = playlist[0]
694 playlistID = playlist[1]
695 dir = self._add_dir(playlistName, '', MODE_PLAYLIST, self.playlistImg, playlistID, n)
696 i = i + 1
697 xbmcplugin.setContent(self._handle, 'files')
698 xbmcplugin.addSortMethod(self._handle, xbmcplugin.SORT_METHOD_LABEL)
699 xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
700
701 # Add whatever directory
702 def _add_dir(self, name, url, mode, iconimage, id, items=1):
703
704 if url == '':
705 u=sys.argv[0]+"?mode="+str(mode)+"&name="+urllib.quote_plus(name)+"&id="+str(id)
706 else:
707 u = url
708 dir=xbmcgui.ListItem(name, iconImage=iconimage, thumbnailImage=iconimage)
709 dir.setInfo( type="Music", infoLabels={ "title": name } )
710
711 # Custom menu items
712 if self.sessionidv1 != '':
713 menuItems = []
714 if mode == MODE_ALBUM:
715 mkplaylst=sys.argv[0]+"?mode="+str(MODE_MAKE_PLAYLIST)+"&name="+name+"&id="+str(id)
716 menuItems.append(("Make Grooveshark playlist", "XBMC.RunPlugin("+mkplaylst+")"))
717 if mode == MODE_PLAYLIST:
718 rmplaylst=sys.argv[0]+"?mode="+str(MODE_REMOVE_PLAYLIST)+"&name="+urllib.quote_plus(name)+"&id="+str(id)
719 menuItems.append(("Delete Grooveshark playlist", "XBMC.RunPlugin("+rmplaylst+")"))
720 mvplaylst=sys.argv[0]+"?mode="+str(MODE_RENAME_PLAYLIST)+"&name="+urllib.quote_plus(name)+"&id="+str(id)
721 menuItems.append(("Rename Grooveshark playlist", "XBMC.RunPlugin("+mvplaylst+")"))
722 dir.addContextMenuItems(menuItems, replaceItems=False)
723
724 return xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=dir,isFolder=True, totalItems=items)
725
726 def _getSavedSongs(self):
727 path = os.path.join(cacheDir, 'songs.dmp')
728 try:
729 f = open(path, 'rb')
730 songs = pickle.load(f)
731 f.close()
732 except:
733 songs = []
734 pass
735 return songs
736
737 def _setSavedSongs(self, songs):
738 try:
739 # Create the 'data' directory if it doesn't exist.
740 if not os.path.exists(cacheDir):
741 os.makedirs(cacheDir)
742 path = os.path.join(cacheDir, 'songs.dmp')
743 f = open(path, 'wb')
744 pickle.dump(songs, f, protocol=pickle.HIGHEST_PROTOCOL)
745 f.close()
746 except:
747 xbmc.log("An error occurred saving songs")
748 pass
749
750 # Parse URL parameters
751 def get_params():
752 param=[]
753 paramstring=sys.argv[2]
754 xbmc.log(paramstring)
755 if len(paramstring)>=2:
756 params=sys.argv[2]
757 cleanedparams=params.replace('?','')
758 if (params[len(params)-1]=='/'):
759 params=params[0:len(params)-2]
760 pairsofparams=cleanedparams.split('&')
761 param={}
762 for i in range(len(pairsofparams)):
763 splitparams={}
764 splitparams=pairsofparams[i].split('=')
765 if (len(splitparams))==2:
766 param[splitparams[0]]=splitparams[1]
767 return param
768
769 # Main
770 grooveshark = Groveshark();
771
772 params=get_params()
773 mode=None
774 try: mode=int(params["mode"])
775 except: pass
776 id=0
777 try: id=int(params["id"])
778 except: pass
779 name = None
780 try: name=urllib.unquote_plus(params["name"])
781 except: pass
782
783 # Call function for URL
784 if mode==None:
785 grooveshark.categories()
786
787 elif mode==MODE_SEARCH_SONGS:
788 grooveshark.searchSongs()
789
790 elif mode==MODE_SEARCH_ALBUMS:
791 grooveshark.searchAlbums()
792
793 elif mode==MODE_SEARCH_ARTISTS:
794 grooveshark.searchArtists()
795
796 elif mode==MODE_SEARCH_ARTISTS_ALBUMS:
797 grooveshark.searchArtistsAlbums(name)
798
799 elif mode==MODE_SEARCH_PLAYLISTS:
800 grooveshark.searchPlaylists()
801
802 elif mode==MODE_POPULAR_SONGS:
803 grooveshark.popularSongs()
804
805 elif mode==MODE_ARTIST_POPULAR:
806 grooveshark.artistPopularSongs()
807
808 elif mode==MODE_FAVORITES:
809 grooveshark.favorites()
810
811 elif mode==MODE_PLAYLISTS:
812 grooveshark.playlists()
813
814 elif mode==MODE_SONG_PAGE:
815 try: page=urllib.unquote_plus(params["page"])
816 except: pass
817 try: label=urllib.unquote_plus(params["label"])
818 except: pass
819 grooveshark.songPage(page, label, id, name)
820
821 elif mode==MODE_SONG:
822 try: album=urllib.unquote_plus(params["album"])
823 except: pass
824 try: artist=urllib.unquote_plus(params["artist"])
825 except: pass
826 try: coverart=urllib.unquote_plus(params["coverart"])
827 except: pass
828 song = grooveshark.songItem(id, name, album, artist, coverart)
829 grooveshark.playSong(song)
830
831 elif mode==MODE_ARTIST:
832 grooveshark.artist(id)
833
834 elif mode==MODE_ALBUM:
835 grooveshark.album(id)
836
837 elif mode==MODE_PLAYLIST:
838 version = 2
839 try: version=urllib.unquote_plus(params["version"])
840 except: pass
841 grooveshark.playlist(id, name, version)
842
843 elif mode==MODE_FAVORITE:
844 grooveshark.favorite(id)
845
846 elif mode==MODE_UNFAVORITE:
847 try: prevMode=int(urllib.unquote_plus(params["prevmode"]))
848 except:
849 prevMode = 0
850 grooveshark.unfavorite(id, prevMode)
851
852 elif mode==MODE_SIMILAR_ARTISTS:
853 grooveshark.similarArtists(id)
854
855 elif mode==MODE_MAKE_PLAYLIST:
856 grooveshark.makePlaylist(id, name)
857
858 elif mode==MODE_REMOVE_PLAYLIST:
859 grooveshark.removePlaylist(id, name)
860
861 elif mode==MODE_RENAME_PLAYLIST:
862 grooveshark.renamePlaylist(id, name)
863
864 elif mode==MODE_REMOVE_PLAYLIST_SONG:
865 try: playlistID=urllib.unquote_plus(params["playlistid"])
866 except: pass
867 grooveshark.removePlaylistSong(playlistID, name, id)
868
869 elif mode==MODE_ADD_PLAYLIST_SONG:
870 grooveshark.addPlaylistSong(id)
871
872 if mode < MODE_SONG:
873 xbmcplugin.endOfDirectory(int(sys.argv[1]))