1 import urllib
, urllib2
, re
, xbmcplugin
, xbmcgui
, xbmc
, sys
, os
4 __plugin__
= "Grooveshark"
5 __author__
= "Stephen Denham"
10 __XBMC_Revision__
= ""
13 MODE_SEARCH_ALBUMS
= 2
14 MODE_SEARCH_ARTISTS
= 3
31 resDir
= xbmc
.translatePath(os
.path
.join(os
.getcwd(), 'resources'))
32 libDir
= xbmc
.translatePath(os
.path
.join(resDir
, 'lib'))
33 imgDir
= xbmc
.translatePath(os
.path
.join(resDir
, 'img'))
34 thumbDir
= os
.path
.join('special://masterprofile/plugin_data/music', os
.path
.basename(os
.getcwd()))
36 sys
.path
.append (libDir
)
37 from GrooveAPI
import *
38 groovesharkApi
= GrooveAPI()
41 def __init__( self
, *args
, **kwargs
):
42 self
.__dict
__.update( kwargs
)
46 albumImg
= xbmc
.translatePath(os
.path
.join(imgDir
, 'album.png'))
47 artistImg
= xbmc
.translatePath(os
.path
.join(imgDir
, 'artist.png'))
48 favoritesImg
= xbmc
.translatePath(os
.path
.join(imgDir
, 'favorites.png'))
49 playlistImg
= xbmc
.translatePath(os
.path
.join(imgDir
, 'playlist.png'))
50 popularImg
= xbmc
.translatePath(os
.path
.join(imgDir
, 'popular.png'))
51 songImg
= xbmc
.translatePath(os
.path
.join(imgDir
, 'song.png'))
53 songsearchlimit
= xbmcplugin
.getSetting('songsearchlimit')
54 albumsearchlimit
= xbmcplugin
.getSetting('albumsearchlimit')
55 artistsearchlimit
= xbmcplugin
.getSetting('artistsearchlimit')
59 self
._handle
= int(sys
.argv
[1])
63 userid
= self
._get
_login
()
66 groovesharkApi
.setRemoveDuplicates(True)
68 self
._addDir
('Search songs', '', MODE_SEARCH_SONGS
, self
.songImg
, 0)
69 self
._addDir
('Search albums', '', MODE_SEARCH_ALBUMS
, self
.albumImg
, 0)
70 self
._addDir
('Search artists', '', MODE_SEARCH_ARTISTS
, self
.artistImg
, 0)
71 self
._addDir
('Popular', '', MODE_POPULAR
, self
.popularImg
, 0)
73 self
._addDir
('Favorites', '', MODE_FAVORITES
, self
.favoritesImg
, 0)
74 self
._addDir
('Playlists', '', MODE_PLAYLISTS
, self
.playlistImg
, 0)
76 def searchSongs(self
):
77 query
= self
._get
_keyboard
(default
="", heading
="Search songs")
79 songs
= groovesharkApi
.searchSongs(query
, limit
= xbmcplugin
.getSetting('songsearchlimit'))
81 self
._get
_songs
(songs
)
83 dialog
= xbmcgui
.Dialog()
84 dialog
.ok('Grooveshark', 'No matching songs.')
87 def searchAlbums(self
):
88 query
= self
._get
_keyboard
(default
="", heading
="Search albums")
90 albums
= groovesharkApi
.searchAlbums(query
, limit
= xbmcplugin
.getSetting('albumsearchlimit'))
92 self
._get
_albums
(albums
)
94 dialog
= xbmcgui
.Dialog()
95 dialog
.ok('Grooveshark', 'No matching albums.')
98 def searchArtists(self
):
99 query
= self
._get
_keyboard
(default
="", heading
="Search artists")
101 artists
= groovesharkApi
.searchArtists(query
, limit
= xbmcplugin
.getSetting('artistsearchlimit'))
102 if (len(artists
) > 0):
103 self
._get
_artists
(artists
)
105 dialog
= xbmcgui
.Dialog()
106 dialog
.ok('Grooveshark', 'No matching artists.')
110 userid
= self
._get
_login
()
112 favorites
= groovesharkApi
.userGetFavoriteSongs(userid
)
113 if (len(favorites
) > 0):
114 self
._get
_songs
(favorites
)
116 dialog
= xbmcgui
.Dialog()
117 dialog
.ok('Grooveshark', 'You have no favorites.')
121 popular
= groovesharkApi
.popularGetSongs(limit
= xbmcplugin
.getSetting('songsearchlimit'))
122 if (len(popular
) > 0):
123 self
._get
_songs
(popular
)
125 dialog
= xbmcgui
.Dialog()
126 dialog
.ok('Grooveshark', 'No popular songs.')
130 userid
= self
._get
_login
()
132 playlists
= groovesharkApi
.userGetPlaylists()
133 if (len(playlists
) > 0):
134 self
._get
_playlists
(playlists
)
136 dialog
= xbmcgui
.Dialog()
137 dialog
.ok('Grooveshark', 'You have no playlists.')
140 def favorite(self
, songid
):
141 userid
= self
._get
_login
()
143 xbmc
.log("Favorite playSong: " + str(songid
))
144 groovesharkApi
.favoriteSong(songID
= songid
)
146 dialog
= xbmcgui
.Dialog()
147 dialog
.ok('Grooveshark', 'You must be logged in', 'to add favorites.')
149 def unfavorite(self
, songid
):
150 userid
= self
._get
_login
()
152 xbmc
.log("Unfavorite playSong: " + str(songid
))
153 groovesharkApi
.unfavoriteSong(songID
= songid
)
155 dialog
= xbmcgui
.Dialog()
156 dialog
.ok('Grooveshark', 'You must be logged in', 'to remove favorites.')
158 def album(self
,albumid
):
159 album
= groovesharkApi
.albumGetSongs(albumId
= albumid
, limit
= xbmcplugin
.getSetting('songsearchlimit'))
160 self
._get
_songs
(album
)
162 def artist(self
, artistid
):
163 albums
= groovesharkApi
.artistGetAlbums(artistId
= artistid
, limit
= xbmcplugin
.getSetting('albumsearchlimit'))
164 self
._get
_albums
(albums
)
166 def playlist(self
, playlistid
):
167 userid
= self
._get
_login
()
169 songs
= groovesharkApi
.playlistGetSongs(playlistId
= playlistid
, limit
= xbmcplugin
.getSetting('songsearchlimit'))
170 self
._get
_songs
(songs
)
172 dialog
= xbmcgui
.Dialog()
173 dialog
.ok('Grooveshark', 'You must be logged in', 'to get playlists.')
175 def playSong(self
, url
, name
, album
, artist
, duration
, thumb
, image
):
176 xbmc
.log("Playing: " + url
)
177 songItem
= xbmcgui
.ListItem(label
= name
, path
=url
, thumbnailImage
=thumb
, iconImage
=image
)
178 songItem
.setInfo( type="Music", infoLabels
={ "title": name
, "duration": duration
, "album": album
, "artist": artist
} )
179 songItem
.setProperty('mimetype', 'audio/mpeg')
181 xbmc
.Player(xbmc
.PLAYER_CORE_PAPLAYER
).play(url
, songItem
, False)
183 def _get_keyboard(self
, default
="", heading
="", hidden
=False):
184 kb
= xbmc
.Keyboard(default
, heading
, hidden
)
186 if (kb
.isConfirmed()):
187 return unicode(kb
.getText(), "utf-8")
190 def _get_login(self
):
191 username
= xbmcplugin
.getSetting('username')
192 password
= xbmcplugin
.getSetting('password')
193 if (username
== "" or password
== ""):
194 dialog
= xbmcgui
.Dialog()
195 dialog
.ok('Grooveshark', 'Unable to login.', 'Check username and password in settings.')
198 if groovesharkApi
.loggedInStatus() == 1:
199 groovesharkApi
.logout()
200 userid
= groovesharkApi
.loginExt(username
, password
)
202 xbmc
.log("Logged in")
205 dialog
= xbmcgui
.Dialog()
206 dialog
.ok('Grooveshark', 'Unable to login.', 'Check username and password in settings.')
209 def _get_songs(self
, songs
):
210 xbmc
.log("Found " + str(len(songs
)) + " songs...")
212 while i
< len(songs
):
216 songDuration
= song
[2]
221 songUrl
= groovesharkApi
.getStreamURL(songID
)
222 self
._addSong
(songID
, songName
, songUrl
, songDuration
, songAlbum
, songArtist
, songThumb
, songImage
)
224 xbmcplugin
.setContent(self
._handle
, 'songs')
226 def _get_albums(self
, albums
):
227 xbmc
.log("Found " + str(len(albums
)) + " albums...")
229 while i
< len(albums
):
231 albumArtistName
= album
[0]
234 albumImage
= album
[4]
235 self
._addDir
(albumName
+ " - " + albumArtistName
, '', MODE_ALBUM
, albumImage
, albumID
)
237 xbmcplugin
.setContent(self
._handle
, 'albums')
238 xbmcplugin
.addSortMethod(self
._handle
, xbmcplugin
.SORT_METHOD_ALBUM_IGNORE_THE
)
240 def _get_artists(self
, artists
):
241 xbmc
.log("Found " + str(len(artists
)) + " artists...")
243 while i
< len(artists
):
245 artistName
= artist
[0]
247 self
._addDir
(artistName
, '', MODE_ARTIST
, self
.artistImg
, artistID
)
249 xbmcplugin
.setContent(self
._handle
, 'artists')
250 xbmcplugin
.addSortMethod(self
._handle
, xbmcplugin
.SORT_METHOD_ARTIST_IGNORE_THE
)
252 def _get_playlists(self
, playlists
):
253 xbmc
.log("Found " + str(len(playlists
)) + " playlists...")
255 while i
< len(playlists
):
256 playlist
= playlists
[i
]
257 playlistName
= playlist
[0]
258 playlistID
= playlist
[1]
259 self
._addDir
(playlistName
, '', MODE_PLAYLIST
, self
.playlistImg
, playlistID
, )
261 xbmcplugin
.setContent(self
._handle
, 'files')
262 xbmcplugin
.addSortMethod(self
._handle
, xbmcplugin
.SORT_METHOD_PLAYLIST_ORDER
)
264 def _addSong(self
, songid
, songname
, songurl
, songduration
, songalbum
, songartist
, songthumb
, songimage
):
265 songImg
= self
._getThumb
(songimage
, str(songid
) + "-image")
268 songThm
= self
._getThumb
(songthumb
, str(songid
) + "-thumb")
271 u
=sys
.argv
[0]+"?url="+urllib
.quote_plus(songurl
)+"&mode="+str(MODE_SONG
)+"&name="+urllib
.quote_plus(songname
)+"&id="+str(songid
) \
272 +"&album="+urllib
.quote_plus(songalbum
) \
273 +"&artist="+urllib
.quote_plus(songartist
) \
274 +"&duration="+str(songduration
) \
275 +"&thumb="+urllib
.quote_plus(songThm
) \
276 +"&image="+urllib
.quote_plus(songImg
)
277 songItem
= xbmcgui
.ListItem(label
= songartist
+ " - " + songalbum
+ " - " + songname
, iconImage
=songImg
, thumbnailImage
=songThm
, path
=songurl
)
278 songItem
.setInfo( type="Music", infoLabels
={ "title": songname
, "duration": songduration
, "album": songalbum
, "artist": songartist
} )
279 fav
=sys
.argv
[0]+"?url="+urllib
.quote_plus(songurl
)+"&mode="+str(MODE_FAVORITE
)+"&name="+urllib
.quote_plus(songname
)+"&id="+str(songid
)
280 unfav
=sys
.argv
[0]+"?url="+urllib
.quote_plus(songurl
)+"&mode="+str(MODE_UNFAVORITE
)+"&name="+urllib
.quote_plus(songname
)+"&id="+str(songid
)
282 menuItems
.append(("Grooveshark Favorite", "XBMC.RunPlugin("+fav
+")"))
283 menuItems
.append(("Not Grooveshark Favorite", "XBMC.RunPlugin("+unfav
+")"))
284 songItem
.addContextMenuItems(menuItems
, replaceItems
=False)
285 xbmcplugin
.addDirectoryItem(handle
=int(sys
.argv
[1]),url
=u
,listitem
=songItem
,isFolder
=False)
288 def _addDir(self
, name
, url
, mode
, iconimage
, id):
289 u
=sys
.argv
[0]+"?url="+urllib
.quote_plus(url
)+"&mode="+str(mode
)+"&name="+urllib
.quote_plus(name
)+"&id="+str(id)
290 dir=xbmcgui
.ListItem(name
, iconImage
=iconimage
, thumbnailImage
=iconimage
)
291 dir.setInfo( type="Music", infoLabels
={ "title": name
} )
292 # Codes from http://xbmc-scripting.googlecode.com/svn/trunk/Script%20Templates/common/gui/codes.py
294 menuItems
.append(("Select", "XBMC.executebuiltin(Action(7))"))
295 dir.addContextMenuItems(menuItems
, replaceItems
=True)
296 return xbmcplugin
.addDirectoryItem(handle
=int(sys
.argv
[1]),url
=u
,listitem
=dir,isFolder
=True)
299 def _getThumb(self
, url
, id):
300 # Get the channel icon
301 localThumb
= os
.path
.join(xbmc
.translatePath(os
.path
.join(thumbDir
, str(id)))) + '.tbn'
303 if os
.path
.isfile(localThumb
) == False:
304 loc
= urllib
.URLopener()
305 loc
.retrieve(url
, localThumb
)
307 xbmc
.log('URL download failed of ' + url
+ ' to ' + localThumb
)
310 return os
.path
.join(os
.path
.join(thumbDir
, str(id))) + '.tbn'
316 paramstring
=sys
.argv
[2]
317 if len(paramstring
)>=2:
319 cleanedparams
=params
.replace('?','')
320 if (params
[len(params
)-1]=='/'):
321 params
=params
[0:len(params
)-2]
322 pairsofparams
=cleanedparams
.split('&')
324 for i
in range(len(pairsofparams
)):
326 splitparams
=pairsofparams
[i
].split('=')
327 if (len(splitparams
))==2:
328 param
[splitparams
[0]]=splitparams
[1]
332 grooveshark
= Groveshark();
340 try: url
=urllib
.unquote_plus(params
["url"])
342 try: name
=urllib
.unquote_plus(params
["name"])
344 try: mode
=int(params
["mode"])
346 try: id=int(params
["id"])
353 grooveshark
.categories()
355 elif mode
==MODE_SEARCH_SONGS
:
356 grooveshark
.searchSongs()
358 elif mode
==MODE_SEARCH_ALBUMS
:
359 grooveshark
.searchAlbums()
361 elif mode
==MODE_SEARCH_ARTISTS
:
362 grooveshark
.searchArtists()
364 elif mode
==MODE_POPULAR
:
365 grooveshark
.popular()
367 elif mode
==MODE_PLAYLISTS
:
368 grooveshark
.playlists()
370 elif mode
==MODE_FAVORITES
:
371 grooveshark
.favorites()
373 elif mode
==MODE_SONG
:
374 try: name
=urllib
.unquote_plus(params
["name"])
376 try: album
=urllib
.unquote_plus(params
["album"])
378 try: artist
=urllib
.unquote_plus(params
["artist"])
380 try: duration
=int(params
["duration"])
382 try: thumb
=urllib
.unquote_plus(params
["thumb"])
384 try: image
=urllib
.unquote_plus(params
["image"])
386 grooveshark
.playSong(url
, name
, album
, artist
, duration
, thumb
, image
)
388 elif mode
==MODE_ARTIST
:
389 grooveshark
.artist(lastID
)
391 elif mode
==MODE_ALBUM
:
392 grooveshark
.album(lastID
)
394 elif mode
==MODE_PLAYLIST
:
395 grooveshark
.playlist(lastID
)
397 elif mode
==MODE_FAVORITE
:
398 grooveshark
.favorite(lastID
)
400 elif mode
==MODE_UNFAVORITE
:
401 grooveshark
.unfavorite(lastID
)
403 if (mode
< MODE_SONG
):
404 xbmcplugin
.endOfDirectory(int(sys
.argv
[1]))