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
27 artistsearchlimit
= 15
33 resDir
= xbmc
.translatePath(os
.path
.join(rootDir
, 'resources'))
34 libDir
= xbmc
.translatePath(os
.path
.join(resDir
, 'lib'))
35 imgDir
= xbmc
.translatePath(os
.path
.join(resDir
, 'img'))
37 sys
.path
.append (libDir
)
38 from GrooveAPI
import *
39 groovesharkApi
= GrooveAPI()
42 def __init__( self
, *args
, **kwargs
):
43 self
.__dict
__.update( kwargs
)
47 albumImg
= xbmc
.translatePath(os
.path
.join(imgDir
, 'album.png'))
48 artistImg
= xbmc
.translatePath(os
.path
.join(imgDir
, 'artist.png'))
49 favoritesImg
= xbmc
.translatePath(os
.path
.join(imgDir
, 'favorites.png'))
50 playlistImg
= xbmc
.translatePath(os
.path
.join(imgDir
, 'playlist.png'))
51 popularImg
= xbmc
.translatePath(os
.path
.join(imgDir
, 'popular.png'))
52 songImg
= xbmc
.translatePath(os
.path
.join(imgDir
, 'song.png'))
54 songsearchlimit
= xbmcplugin
.getSetting('songsearchlimit')
55 albumsearchlimit
= xbmcplugin
.getSetting('albumsearchlimit')
56 artistsearchlimit
= xbmcplugin
.getSetting('artistsearchlimit')
59 self
._handle
= int(sys
.argv
[1])
62 userid
= self
._get
_login
()
63 self
._addDir
('Search songs', '', MODE_SEARCH_SONGS
, self
.songImg
, 0)
64 self
._addDir
('Search albums', '', MODE_SEARCH_ALBUMS
, self
.albumImg
, 0)
65 self
._addDir
('Search artists', '', MODE_SEARCH_ARTISTS
, self
.artistImg
, 0)
66 self
._addDir
('Popular', '', MODE_POPULAR
, self
.popularImg
, 0)
68 self
._addDir
('Favorites', '', MODE_FAVORITES
, self
.favoritesImg
, 0)
69 self
._addDir
('Playlists', '', MODE_PLAYLISTS
, self
.playlistImg
, 0)
71 def searchSongs(self
):
72 query
= self
._get
_keyboard
(default
="", heading
="Search songs")
74 songs
= groovesharkApi
.searchSongs(query
, limit
= songsearchlimit
)
76 self
._get
_songs
(songs
)
78 dialog
= xbmcgui
.Dialog()
79 dialog
.ok('Grooveshark', 'No matching songs.')
82 def searchAlbums(self
):
83 query
= self
._get
_keyboard
(default
="", heading
="Search albums")
85 albums
= groovesharkApi
.searchAlbums(query
, limit
= albumsearchlimit
)
87 self
._get
_albums
(albums
)
89 dialog
= xbmcgui
.Dialog()
90 dialog
.ok('Grooveshark', 'No matching albums.')
93 def searchArtists(self
):
94 query
= self
._get
_keyboard
(default
="", heading
="Search artists")
96 artists
= groovesharkApi
.searchArtists(query
, limit
= artistsearchlimit
)
97 if (len(artists
) > 0):
98 self
._get
_artists
(artists
)
100 dialog
= xbmcgui
.Dialog()
101 dialog
.ok('Grooveshark', 'No matching artists.')
105 userid
= self
._get
_login
()
107 favorites
= groovesharkApi
.userGetFavoriteSongs(userid
)
108 if (len(favorites
) > 0):
109 self
._get
_songs
(favorites
)
111 dialog
= xbmcgui
.Dialog()
112 dialog
.ok('Grooveshark', 'You have no favorites.')
116 popular
= groovesharkApi
.popularGetSongs(limit
= songsearchlimit
)
117 if (len(popular
) > 0):
118 self
._get
_songs
(popular
)
120 dialog
= xbmcgui
.Dialog()
121 dialog
.ok('Grooveshark', 'No popular songs.')
125 userid
= self
._get
_login
()
127 playlists
= groovesharkApi
.userGetPlaylists()
128 if (len(playlists
) > 0):
129 self
._get
_playlists
(playlists
)
131 dialog
= xbmcgui
.Dialog()
132 dialog
.ok('Grooveshark', 'You have no playlists.')
135 def favorite(self
, songid
):
136 userid
= self
._get
_login
()
138 xbmc
.log("Favorite song: " + str(songid
))
139 groovesharkApi
.favoriteSong(songID
= songid
)
141 dialog
= xbmcgui
.Dialog()
142 dialog
.ok('Grooveshark', 'You must be logged in', 'to add favorites.')
144 def unfavorite(self
, songid
):
145 userid
= self
._get
_login
()
147 xbmc
.log("Unfavorite song: " + str(songid
))
148 groovesharkApi
.unfavoriteSong(songID
= songid
)
150 dialog
= xbmcgui
.Dialog()
151 dialog
.ok('Grooveshark', 'You must be logged in', 'to remove favorites.')
153 def album(self
,albumid
):
154 album
= groovesharkApi
.albumGetSongs(albumId
= albumid
, limit
= songsearchlimit
)
155 self
._get
_songs
(album
)
157 def artist(self
, artistid
):
158 albums
= groovesharkApi
.artistGetAlbums(artistId
= artistid
, limit
= albumsearchlimit
)
159 self
._get
_albums
(albums
)
161 def playlist(self
, playlistid
):
162 userid
= self
._get
_login
()
164 songs
= groovesharkApi
.playlistGetSongs(playlistId
= playlistid
, limit
= songsearchlimit
)
165 self
._get
_songs
(songs
)
167 dialog
= xbmcgui
.Dialog()
168 dialog
.ok('Grooveshark', 'You must be logged in', 'to get playlists.')
170 def song(self
, url
, name
, album
, artist
, duration
):
171 xbmc
.log("Playing: " + url
)
172 songItem
= xbmcgui
.ListItem(name
+ " - " + artist
, path
=url
)
173 songItem
.setInfo( type="Music", infoLabels
={ "Title": name
, "Duration": duration
, "Album": album
, "Artist": artist
} )
175 xbmc
.Player(xbmc
.PLAYER_CORE_PAPLAYER
).play(url
, songItem
, False)
177 def _get_keyboard(self
, default
="", heading
="", hidden
=False):
178 kb
= xbmc
.Keyboard(default
, heading
, hidden
)
180 if (kb
.isConfirmed()):
181 return unicode(kb
.getText(), "utf-8")
184 def _get_login(self
):
185 username
= xbmcplugin
.getSetting('username')
186 password
= xbmcplugin
.getSetting('password')
187 if (username
== "" or password
== ""):
188 dialog
= xbmcgui
.Dialog()
189 dialog
.ok('Grooveshark', 'Unable to login.', 'Check username and password in settings.')
192 if groovesharkApi
.loggedInStatus() == 1:
193 groovesharkApi
.logout()
195 userid
= groovesharkApi
.loginExt(username
, password
)
196 except (LoginUnknownError
):
199 xbmc
.log("Logged in")
202 dialog
= xbmcgui
.Dialog()
203 dialog
.ok('Grooveshark', 'Unable to login.', 'Check username and password in settings.')
206 def _get_songs(self
, songs
):
207 xbmc
.log("Found " + str(len(songs
)) + " songs...")
209 while i
< len(songs
):
213 songDuration
= song
[2]
218 self
._addSong
(songID
, songName
, groovesharkApi
.getStreamURL(songID
), songDuration
, songAlbum
, songArtist
, songImage
)
220 xbmcplugin
.setContent(self
._handle
, 'songs')
221 xbmcplugin
.addSortMethod(self
._handle
, xbmcplugin
.SORT_METHOD_TITLE_IGNORE_THE
)
223 def _get_albums(self
, albums
):
224 xbmc
.log("Found " + str(len(albums
)) + " albums...")
226 while i
< len(albums
):
228 albumArtistName
= album
[0]
231 albumImage
= album
[4]
233 self
._addDir
(albumName
+ " - " + albumArtistName
, '', MODE_ALBUM
, albumImage
, albumID
)
235 xbmcplugin
.setContent(self
._handle
, 'albums')
236 xbmcplugin
.addSortMethod(self
._handle
, xbmcplugin
.SORT_METHOD_ALBUM_IGNORE_THE
)
238 def _get_artists(self
, artists
):
239 xbmc
.log("Found " + str(len(artists
)) + " artists...")
241 while i
< len(artists
):
243 artistName
= artist
[0]
246 self
._addDir
(artistName
, '', MODE_ARTIST
, self
.artistImg
, artistID
)
248 xbmcplugin
.setContent(self
._handle
, 'artists')
249 xbmcplugin
.addSortMethod(self
._handle
, xbmcplugin
.SORT_METHOD_ARTIST_IGNORE_THE
)
251 def _get_playlists(self
, playlists
):
252 xbmc
.log("Found " + str(len(playlists
)) + " playlists...")
254 while i
< len(playlists
):
255 playlist
= playlists
[i
]
256 playlistName
= playlist
[0]
257 playlistID
= playlist
[1]
258 xbmc
.log(playlistName
)
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
, songimage
):
265 u
=sys
.argv
[0]+"?url="+urllib
.quote_plus(songurl
)+"&mode="+str(MODE_SONG
)+"&name="+urllib
.quote_plus(songname
)+"&id="+str(songid
) \
266 +"&album="+urllib
.quote_plus(songalbum
) \
267 +"&artist="+urllib
.quote_plus(songartist
) \
268 +"&duration="+str(songduration
)
269 songItem
= xbmcgui
.ListItem(songname
+ " - " + songartist
, iconImage
=songimage
, thumbnailImage
=songimage
, path
=songurl
)
270 songItem
.setInfo( type="Music", infoLabels
={ "Title": songname
, "Duration": songduration
, "Album": songalbum
, "Artist": songartist
} )
271 fav
=sys
.argv
[0]+"?url="+urllib
.quote_plus(songurl
)+"&mode="+str(MODE_FAVORITE
)+"&name="+urllib
.quote_plus(songname
)+"&id="+str(songid
)
272 unfav
=sys
.argv
[0]+"?url="+urllib
.quote_plus(songurl
)+"&mode="+str(MODE_UNFAVORITE
)+"&name="+urllib
.quote_plus(songname
)+"&id="+str(songid
)
274 menuItems
.append(("Grooveshark Favorite", "XBMC.RunPlugin("+fav
+")"))
275 menuItems
.append(("Not Grooveshark Favorite", "XBMC.RunPlugin("+unfav
+")"))
276 songItem
.addContextMenuItems(menuItems
, replaceItems
=False)
277 return xbmcplugin
.addDirectoryItem(handle
=int(sys
.argv
[1]),url
=u
,listitem
=songItem
,isFolder
=False)
279 def _addDir(self
, name
, url
, mode
, iconimage
, id):
280 u
=sys
.argv
[0]+"?url="+urllib
.quote_plus(url
)+"&mode="+str(mode
)+"&name="+urllib
.quote_plus(name
)+"&id="+str(id)
281 dir=xbmcgui
.ListItem(name
, iconImage
=iconimage
, thumbnailImage
=iconimage
)
282 dir.setInfo( type="Music", infoLabels
={ "Title": name
} )
283 # Codes from http://xbmc-scripting.googlecode.com/svn/trunk/Script%20Templates/common/gui/codes.py
285 menuItems
.append(("Select", "XBMC.executebuiltin(Action(7))"))
286 dir.addContextMenuItems(menuItems
, replaceItems
=True)
287 return xbmcplugin
.addDirectoryItem(handle
=int(sys
.argv
[1]),url
=u
,listitem
=dir,isFolder
=True)
291 paramstring
=sys
.argv
[2]
292 if len(paramstring
)>=2:
294 cleanedparams
=params
.replace('?','')
295 if (params
[len(params
)-1]=='/'):
296 params
=params
[0:len(params
)-2]
297 pairsofparams
=cleanedparams
.split('&')
299 for i
in range(len(pairsofparams
)):
301 splitparams
=pairsofparams
[i
].split('=')
302 if (len(splitparams
))==2:
303 param
[splitparams
[0]]=splitparams
[1]
307 grooveshark
= Groveshark();
315 try: url
=urllib
.unquote_plus(params
["url"])
317 try: name
=urllib
.unquote_plus(params
["name"])
319 try: mode
=int(params
["mode"])
321 try: id=int(params
["id"])
328 grooveshark
.categories()
330 elif mode
==MODE_SEARCH_SONGS
:
331 grooveshark
.searchSongs()
333 elif mode
==MODE_SEARCH_ALBUMS
:
334 grooveshark
.searchAlbums()
336 elif mode
==MODE_SEARCH_ARTISTS
:
337 grooveshark
.searchArtists()
339 elif mode
==MODE_POPULAR
:
340 grooveshark
.popular()
342 elif mode
==MODE_PLAYLISTS
:
343 grooveshark
.playlists()
345 elif mode
==MODE_FAVORITES
:
346 grooveshark
.favorites()
348 elif mode
==MODE_SONG
:
349 try: name
=urllib
.unquote_plus(params
["name"])
351 try: album
=urllib
.unquote_plus(params
["album"])
353 try: artist
=urllib
.unquote_plus(params
["artist"])
355 try: duration
=int(params
["duration"])
357 grooveshark
.song(url
, name
, album
, artist
, duration
)
359 elif mode
==MODE_ARTIST
:
360 grooveshark
.artist(lastID
)
362 elif mode
==MODE_ALBUM
:
363 grooveshark
.album(lastID
)
365 elif mode
==MODE_PLAYLIST
:
366 grooveshark
.playlist(lastID
)
368 elif mode
==MODE_FAVORITE
:
369 grooveshark
.favorite(lastID
)
371 elif mode
==MODE_UNFAVORITE
:
372 grooveshark
.unfavorite(lastID
)
374 if (mode
< MODE_SONG
):
375 xbmcplugin
.endOfDirectory(int(sys
.argv
[1]))