1 import urllib
, sys
, os
, shutil
, re
, time
, xbmcaddon
, xbmcplugin
, xbmcgui
, xbmc
4 MODE_SEARCH_ARTISTS
= 3
19 ACTION_SELECT_ITEM
= 7
20 ACTION_PREVIOUS_MENU
= 10
23 resDir
= xbmc
.translatePath(os
.path
.join(baseDir
, 'resources'))
24 libDir
= xbmc
.translatePath(os
.path
.join(resDir
, 'lib'))
25 imgDir
= xbmc
.translatePath(os
.path
.join(resDir
, 'img'))
26 cacheDir
= os
.path
.join(xbmc
.translatePath('special://masterprofile/addon_data/'), os
.path
.basename(os
.getcwd()))
27 thumbDirName
= 'thumb'
28 thumbDir
= os
.path
.join('special://masterprofile/addon_data/', os
.path
.basename(os
.getcwd()), thumbDirName
)
30 baseModeUrl
= 'plugin://plugin.audio.groove/'
31 playlistUrl
= baseModeUrl
+ '?mode=' + str(MODE_PLAYLIST
)
32 playlistsUrl
= baseModeUrl
+ '?mode=' + str(MODE_PLAYLISTS
)
33 favoritesUrl
= baseModeUrl
+ '?mode=' + str(MODE_FAVORITES
)
35 thumbDef
= os
.path
.join(imgDir
, 'default.tbn')
37 sys
.path
.append (libDir
)
38 from GroovesharkAPI
import GrooveAPI
41 groovesharkApi
= GrooveAPI()
42 if groovesharkApi
.pingService() != True:
43 raise StandardError('No Grooveshark service')
45 dialog
= xbmcgui
.Dialog()
46 dialog
.ok('Grooveshark XBMC', 'Unable to connect with Grooveshark.', 'Please try again later')
51 def __init__( self
, *args
, **kwargs
):
52 self
.__dict
__.update( kwargs
)
57 albumImg
= xbmc
.translatePath(os
.path
.join(imgDir
, 'album.png'))
58 artistImg
= xbmc
.translatePath(os
.path
.join(imgDir
, 'artist.png'))
59 favoritesImg
= xbmc
.translatePath(os
.path
.join(imgDir
, 'favorites.png'))
60 playlistImg
= xbmc
.translatePath(os
.path
.join(imgDir
, 'playlist.png'))
61 popularSongsImg
= xbmc
.translatePath(os
.path
.join(imgDir
, 'popularSongs.png'))
62 songImg
= xbmc
.translatePath(os
.path
.join(imgDir
, 'song.png'))
63 defImg
= xbmc
.translatePath(os
.path
.join(imgDir
, 'default.tbn'))
64 fanImg
= xbmc
.translatePath(os
.path
.join(baseDir
, 'fanart.png'))
66 settings
= xbmcaddon
.Addon(id='plugin.audio.groove')
67 songsearchlimit
= int(settings
.getSetting('songsearchlimit'))
68 albumsearchlimit
= int(settings
.getSetting('albumsearchlimit'))
69 artistsearchlimit
= int(settings
.getSetting('artistsearchlimit'))
70 username
= settings
.getSetting('username')
71 password
= settings
.getSetting('password')
75 self
._handle
= int(sys
.argv
[1])
76 if os
.path
.isdir(cacheDir
) == False:
78 xbmc
.log("Made " + cacheDir
)
79 if os
.path
.isdir(thumbDir
) == False:
81 xbmc
.log("Made " + thumbDir
)
86 self
.userid
= self
._get
_login
()
89 xbmcplugin
.setPluginFanart(int(sys
.argv
[1]), self
.fanImg
)
91 self
._add
_dir
('Search songs...', '', MODE_SEARCH_SONGS
, self
.songImg
, 0)
92 self
._add
_dir
('Search albums...', '', MODE_SEARCH_ALBUMS
, self
.albumImg
, 0)
93 self
._add
_dir
('Search artists...', '', MODE_SEARCH_ARTISTS
, self
.artistImg
, 0)
94 self
._add
_dir
('Popular songs', '', MODE_POPULAR_SONGS
, self
.popularSongsImg
, 0)
95 if (self
.userid
!= 0):
96 self
._add
_dir
('Favorites', '', MODE_FAVORITES
, self
.favoritesImg
, 0)
97 self
._add
_dir
('Playlists', '', MODE_PLAYLISTS
, self
.playlistImg
, 0)
100 def searchSongs(self
):
101 query
= self
._get
_keyboard
(default
="", heading
="Search songs")
103 songs
= groovesharkApi
.getSongSearchResults(query
, limit
= self
.songsearchlimit
)
105 self
._add
_songs
_directory
(songs
)
107 dialog
= xbmcgui
.Dialog()
108 dialog
.ok('Grooveshark XBMC', 'No matching songs.')
114 def searchAlbums(self
):
115 query
= self
._get
_keyboard
(default
="", heading
="Search albums")
117 albums
= groovesharkApi
.getAlbumSearchResults(query
, limit
= self
.albumsearchlimit
)
118 if (len(albums
) > 0):
119 self
._add
_albums
_directory
(albums
)
121 dialog
= xbmcgui
.Dialog()
122 dialog
.ok('Grooveshark XBMC', 'No matching albums.')
128 def searchArtists(self
):
129 query
= self
._get
_keyboard
(default
="", heading
="Search artists")
131 artists
= groovesharkApi
.getArtistSearchResults(query
, limit
= self
.artistsearchlimit
)
132 if (len(artists
) > 0):
133 self
._add
_artists
_directory
(artists
)
135 dialog
= xbmcgui
.Dialog()
136 dialog
.ok('Grooveshark XBMC', 'No matching artists.')
143 userid
= self
._get
_login
()
145 favorites
= groovesharkApi
.getUserFavoriteSongs()
146 if (len(favorites
) > 0):
147 self
._add
_songs
_directory
(favorites
)
149 dialog
= xbmcgui
.Dialog()
150 dialog
.ok('Grooveshark XBMC', 'You have no favorites.')
154 def popularSongs(self
):
155 popular
= groovesharkApi
.getPopularSongsToday(limit
= self
.songsearchlimit
)
156 if (len(popular
) > 0):
157 self
._add
_songs
_directory
(popular
)
159 dialog
= xbmcgui
.Dialog()
160 dialog
.ok('Grooveshark XBMC', 'No popular songs.')
165 userid
= self
._get
_login
()
167 playlists
= groovesharkApi
.getUserPlaylists()
168 if (len(playlists
) > 0):
169 self
._add
_playlists
_directory
(playlists
)
171 dialog
= xbmcgui
.Dialog()
172 dialog
.ok('Grooveshark XBMC', 'You have no Grooveshark playlists.')
175 dialog
= xbmcgui
.Dialog()
176 dialog
.ok('Grooveshark XBMC', 'You must be logged in ', ' to see your Grooveshark playlists.')
178 # Make songs a favorite
179 def favorite(self
, songid
):
180 userid
= self
._get
_login
()
182 xbmc
.log("Favorite song: " + str(songid
))
183 groovesharkApi
.addUserFavoriteSong(songID
= songid
)
184 xbmc
.executebuiltin('XBMC.Notification(Grooveshark XBMC, Added to favorites, 1000, ' + thumbDef
+ ')')
186 dialog
= xbmcgui
.Dialog()
187 dialog
.ok('Grooveshark XBMC', 'You must be logged in', 'to add favorites.')
189 # Show selected album
190 def album(self
, albumid
):
191 album
= groovesharkApi
.getAlbumSongs(albumid
, limit
= self
.songsearchlimit
)
192 self
._add
_songs
_directory
(album
)
194 # Show selected artist
195 def artist(self
, artistid
):
196 albums
= groovesharkApi
.getArtistAlbums(artistid
, limit
= self
.albumsearchlimit
)
197 self
._add
_albums
_directory
(albums
)
199 # Show selected playlist
200 def playlist(self
, playlistid
):
201 userid
= self
._get
_login
()
203 songs
= groovesharkApi
.getPlaylistSongs(playlistid
)
204 self
._add
_songs
_directory
(songs
)
206 dialog
= xbmcgui
.Dialog()
207 dialog
.ok('Grooveshark XBMC', 'You must be logged in', 'to get Grooveshark playlists.')
210 def playSong(self
, item
):
211 songid
= item
.getProperty('songid')
212 song
= groovesharkApi
.getSongURLFromSongID(songid
)
215 xbmc
.log("Playing: " + song
)
216 xbmcplugin
.setResolvedUrl(handle
=int(sys
.argv
[1]), succeeded
=True, listitem
=item
)
218 xbmc
.executebuiltin('XBMC.Notification(Grooveshark XBMC, Unable to play song, 1000, ' + thumbDef
+ ')')
220 # Make a song directory item
221 def songItem(self
, songid
, name
, album
, artist
, coverart
):
222 songImg
= self
._get
_icon
(coverart
, 'song-' + str(songid
) + "-image")
223 item
= xbmcgui
.ListItem(label
= artist
+ " - " + album
+ " - " + name
, thumbnailImage
=songImg
, iconImage
=songImg
)
224 item
.setInfo( type="music", infoLabels
={ "title": name
, "album": album
, "artist": artist
} )
225 item
.setProperty('mimetype', 'audio/mpeg')
226 item
.setProperty("IsPlayable", "true")
227 item
.setProperty('songid', str(songid
))
228 item
.setProperty('coverart', songImg
)
229 item
.setProperty('title', name
)
230 item
.setProperty('album', album
)
231 item
.setProperty('artist', artist
)
236 def _get_keyboard(self
, default
="", heading
="", hidden
=False):
237 kb
= xbmc
.Keyboard(default
, heading
, hidden
)
239 if (kb
.isConfirmed()):
240 return unicode(kb
.getText(), "utf-8")
243 # Login to grooveshark
244 def _get_login(self
):
245 if (self
.username
== "" or self
.password
== ""):
246 dialog
= xbmcgui
.Dialog()
247 dialog
.ok('Grooveshark XBMC', 'Unable to login.', 'Check username and password in settings.')
251 uid
= groovesharkApi
.login(self
.username
, self
.password
)
255 dialog
= xbmcgui
.Dialog()
256 dialog
.ok('Grooveshark XBMC', 'Unable to login.', 'Check username and password in settings.')
259 # Get a song directory item
260 def _get_song_item(self
, song
):
266 return self
.songItem(songid
, name
, album
, artist
, coverart
)
269 def _get_icon(self
, url
, songid
):
271 localThumb
= os
.path
.join(xbmc
.translatePath(os
.path
.join(thumbDir
, str(songid
)))) + '.tbn'
273 if os
.path
.isfile(localThumb
) == False:
274 loc
= urllib
.URLopener()
275 loc
.retrieve(url
, localThumb
)
277 shutil
.copy2(thumbDef
, localThumb
)
278 return os
.path
.join(os
.path
.join(thumbDir
, str(songid
))) + '.tbn'
282 # Add songs to directory
283 def _add_songs_directory(self
, songs
):
285 xbmc
.log("Found " + str(n
) + " songs...")
289 item
= self
._get
_song
_item
(song
)
290 coverart
= item
.getProperty('coverart')
295 u
=sys
.argv
[0]+"?mode="+str(MODE_SONG
)+"&name="+urllib
.quote_plus(songname
)+"&id="+str(songid
) \
296 +"&album="+urllib
.quote_plus(songalbum
) \
297 +"&artist="+urllib
.quote_plus(songartist
) \
298 +"&coverart="+urllib
.quote_plus(coverart
)
299 fav
=sys
.argv
[0]+"?mode="+str(MODE_FAVORITE
)+"&name="+urllib
.quote_plus(songname
)+"&id="+str(songid
)
301 menuItems
.append(("Grooveshark favorite", "XBMC.RunPlugin("+fav
+")"))
302 item
.addContextMenuItems(menuItems
, replaceItems
=False)
303 xbmcplugin
.addDirectoryItem(handle
=int(sys
.argv
[1]),url
=u
,listitem
=item
,isFolder
=False, totalItems
=n
)
306 xbmcplugin
.setContent(self
._handle
, 'songs')
307 xbmcplugin
.setPluginFanart(int(sys
.argv
[1]), self
.fanImg
)
309 # Add albums to directory
310 def _add_albums_directory(self
, albums
):
312 xbmc
.log("Found " + str(n
) + " albums...")
316 albumArtistName
= album
[0]
319 albumImage
= self
._get
_icon
(album
[4], 'album-' + str(albumID
))
320 self
._add
_dir
(albumName
+ " - " + albumArtistName
, '', MODE_ALBUM
, albumImage
, albumID
, n
)
322 xbmcplugin
.setContent(self
._handle
, 'albums')
323 xbmcplugin
.addSortMethod(self
._handle
, xbmcplugin
.SORT_METHOD_ALBUM_IGNORE_THE
)
324 xbmcplugin
.setPluginFanart(int(sys
.argv
[1]), self
.fanImg
)
326 # Add artists to directory
327 def _add_artists_directory(self
, artists
):
329 xbmc
.log("Found " + str(n
) + " artists...")
333 artistName
= artist
[0]
335 self
._add
_dir
(artistName
, '', MODE_ARTIST
, self
.artistImg
, artistID
, n
)
337 xbmcplugin
.setContent(self
._handle
, 'artists')
338 xbmcplugin
.addSortMethod(self
._handle
, xbmcplugin
.SORT_METHOD_ARTIST_IGNORE_THE
)
339 xbmcplugin
.setPluginFanart(int(sys
.argv
[1]), self
.fanImg
)
341 # Add playlists to directory
342 def _add_playlists_directory(self
, playlists
):
344 xbmc
.log("Found " + str(n
) + " playlists...")
347 playlist
= playlists
[i
]
348 playlistName
= playlist
[0]
349 playlistID
= playlist
[1]
350 self
._add
_dir
(playlistName
, '', MODE_PLAYLIST
, self
.playlistImg
, playlistID
, n
)
352 xbmcplugin
.setContent(self
._handle
, 'files')
353 xbmcplugin
.addSortMethod(self
._handle
, xbmcplugin
.SORT_METHOD_PLAYLIST_ORDER
)
354 xbmcplugin
.setPluginFanart(int(sys
.argv
[1]), self
.fanImg
)
356 # Add whatever directory
357 def _add_dir(self
, name
, url
, mode
, iconimage
, id, items
=1):
359 u
=sys
.argv
[0]+"?mode="+str(mode
)+"&name="+urllib
.quote_plus(name
)+"&id="+str(id)
360 dir=xbmcgui
.ListItem(name
, iconImage
=iconimage
, thumbnailImage
=iconimage
)
361 dir.setInfo( type="Music", infoLabels
={ "title": name
} )
362 return xbmcplugin
.addDirectoryItem(handle
=int(sys
.argv
[1]),url
=u
,listitem
=dir,isFolder
=True, totalItems
=items
)
365 # Parse URL parameters
368 paramstring
=sys
.argv
[2]
369 xbmc
.log(paramstring
)
370 if len(paramstring
)>=2:
372 cleanedparams
=params
.replace('?','')
373 if (params
[len(params
)-1]=='/'):
374 params
=params
[0:len(params
)-2]
375 pairsofparams
=cleanedparams
.split('&')
377 for i
in range(len(pairsofparams
)):
379 splitparams
=pairsofparams
[i
].split('=')
380 if (len(splitparams
))==2:
381 param
[splitparams
[0]]=splitparams
[1]
385 grooveshark
= Groveshark();
389 try: mode
=int(params
["mode"])
392 try: id=int(params
["id"])
395 # Call function for URL
397 grooveshark
.categories()
399 elif mode
==MODE_SEARCH_SONGS
:
400 grooveshark
.searchSongs()
402 elif mode
==MODE_SEARCH_ALBUMS
:
403 grooveshark
.searchAlbums()
405 elif mode
==MODE_SEARCH_ARTISTS
:
406 grooveshark
.searchArtists()
408 elif mode
==MODE_POPULAR_SONGS
:
409 grooveshark
.popularSongs()
411 elif mode
==MODE_FAVORITES
:
412 grooveshark
.favorites()
414 elif mode
==MODE_PLAYLISTS
:
415 grooveshark
.playlists()
417 elif mode
==MODE_SONG
:
418 try: name
=urllib
.unquote_plus(params
["name"])
420 try: album
=urllib
.unquote_plus(params
["album"])
422 try: artist
=urllib
.unquote_plus(params
["artist"])
424 try: coverart
=urllib
.unquote_plus(params
["coverart"])
426 song
= grooveshark
.songItem(id, name
, album
, artist
, coverart
)
427 grooveshark
.playSong(song
)
429 elif mode
==MODE_ARTIST
:
430 grooveshark
.artist(id)
432 elif mode
==MODE_ALBUM
:
433 grooveshark
.album(id)
435 elif mode
==MODE_PLAYLIST
:
436 grooveshark
.playlist(id)
438 elif mode
==MODE_FAVORITE
:
439 grooveshark
.favorite(id)
442 xbmcplugin
.endOfDirectory(int(sys
.argv
[1]))