2faa23b5cff9a9de7511f04b6d4c18d1acb03b54
[clinton/xbmc-groove.git] / default.py
1 import urllib, urllib2, re, xbmcplugin, xbmcgui, xbmc, sys, os
2
3 # plugin constants
4 __plugin__ = "Grooveshark"
5 __author__ = "Stephen Denham"
6 __url__ = ""
7 __svn_url__ = ""
8 __version__ = "0.0.1"
9 __svn_revision__ = ""
10 __XBMC_Revision__ = ""
11
12 MODE_SEARCH_SONGS = 1
13 MODE_SEARCH_ALBUMS = 2
14 MODE_SEARCH_ARTISTS = 3
15 MODE_POPULAR = 4
16 MODE_FAVORITES = 5
17 MODE_PLAYLISTS = 6
18 MODE_ALBUM = 7
19 MODE_ARTIST = 8
20 MODE_PLAYLIST = 9
21 MODE_SONG = 10
22 MODE_FAVORITE = 11
23 MODE_UNFAVORITE = 12
24
25 songsearchlimit = 0
26 albumsearchlimit = 0
27 artistsearchlimit = 0
28
29 lastID = 0
30
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()))
35
36 sys.path.append (libDir)
37 from GrooveAPI import *
38 groovesharkApi = GrooveAPI()
39
40 class _Info:
41 def __init__( self, *args, **kwargs ):
42 self.__dict__.update( kwargs )
43
44 class Groveshark:
45
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'))
52
53 songsearchlimit = xbmcplugin.getSetting('songsearchlimit')
54 albumsearchlimit = xbmcplugin.getSetting('albumsearchlimit')
55 artistsearchlimit = xbmcplugin.getSetting('artistsearchlimit')
56
57
58 def __init__( self ):
59 self._handle = int(sys.argv[1])
60
61 def categories(self):
62
63 userid = self._get_login()
64
65 # Setup
66 groovesharkApi.setRemoveDuplicates(True)
67
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)
72 if (userid != 0):
73 self._addDir('Favorites', '', MODE_FAVORITES, self.favoritesImg, 0)
74 self._addDir('Playlists', '', MODE_PLAYLISTS, self.playlistImg, 0)
75
76 def searchSongs(self):
77 query = self._get_keyboard(default="", heading="Search songs")
78 if (query):
79 songs = groovesharkApi.searchSongs(query, limit = xbmcplugin.getSetting('songsearchlimit'))
80 if (len(songs) > 0):
81 self._get_songs(songs)
82 else:
83 dialog = xbmcgui.Dialog()
84 dialog.ok('Grooveshark', 'No matching songs.')
85 self.categories()
86
87 def searchAlbums(self):
88 query = self._get_keyboard(default="", heading="Search albums")
89 if (query):
90 albums = groovesharkApi.searchAlbums(query, limit = xbmcplugin.getSetting('albumsearchlimit'))
91 if (len(albums) > 0):
92 self._get_albums(albums)
93 else:
94 dialog = xbmcgui.Dialog()
95 dialog.ok('Grooveshark', 'No matching albums.')
96 self.categories()
97
98 def searchArtists(self):
99 query = self._get_keyboard(default="", heading="Search artists")
100 if (query):
101 artists = groovesharkApi.searchArtists(query, limit = xbmcplugin.getSetting('artistsearchlimit'))
102 if (len(artists) > 0):
103 self._get_artists(artists)
104 else:
105 dialog = xbmcgui.Dialog()
106 dialog.ok('Grooveshark', 'No matching artists.')
107 self.categories()
108
109 def favorites(self):
110 userid = self._get_login()
111 if (userid != 0):
112 favorites = groovesharkApi.userGetFavoriteSongs(userid)
113 if (len(favorites) > 0):
114 self._get_songs(favorites)
115 else:
116 dialog = xbmcgui.Dialog()
117 dialog.ok('Grooveshark', 'You have no favorites.')
118 self.categories()
119
120 def popular(self):
121 popular = groovesharkApi.popularGetSongs(limit = xbmcplugin.getSetting('songsearchlimit'))
122 if (len(popular) > 0):
123 self._get_songs(popular)
124 else:
125 dialog = xbmcgui.Dialog()
126 dialog.ok('Grooveshark', 'No popular songs.')
127 self.categories()
128
129 def playlists(self):
130 userid = self._get_login()
131 if (userid != 0):
132 playlists = groovesharkApi.userGetPlaylists()
133 if (len(playlists) > 0):
134 self._get_playlists(playlists)
135 else:
136 dialog = xbmcgui.Dialog()
137 dialog.ok('Grooveshark', 'You have no playlists.')
138 self.categories()
139
140 def favorite(self, songid):
141 userid = self._get_login()
142 if (userid != 0):
143 xbmc.log("Favorite playSong: " + str(songid))
144 groovesharkApi.favoriteSong(songID = songid)
145 else:
146 dialog = xbmcgui.Dialog()
147 dialog.ok('Grooveshark', 'You must be logged in', 'to add favorites.')
148
149 def unfavorite(self, songid):
150 userid = self._get_login()
151 if (userid != 0):
152 xbmc.log("Unfavorite playSong: " + str(songid))
153 groovesharkApi.unfavoriteSong(songID = songid)
154 else:
155 dialog = xbmcgui.Dialog()
156 dialog.ok('Grooveshark', 'You must be logged in', 'to remove favorites.')
157
158 def album(self,albumid):
159 album = groovesharkApi.albumGetSongs(albumId = albumid, limit = xbmcplugin.getSetting('songsearchlimit'))
160 self._get_songs(album)
161
162 def artist(self, artistid):
163 albums = groovesharkApi.artistGetAlbums(artistId = artistid, limit = xbmcplugin.getSetting('albumsearchlimit'))
164 self._get_albums(albums)
165
166 def playlist(self, playlistid):
167 userid = self._get_login()
168 if (userid != 0):
169 songs = groovesharkApi.playlistGetSongs(playlistId = playlistid, limit = xbmcplugin.getSetting('songsearchlimit'))
170 self._get_songs(songs)
171 else:
172 dialog = xbmcgui.Dialog()
173 dialog.ok('Grooveshark', 'You must be logged in', 'to get playlists.')
174
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')
180 xbmc.Player().stop()
181 xbmc.Player(xbmc.PLAYER_CORE_PAPLAYER).play(url, songItem, False)
182
183 def _get_keyboard(self, default="", heading="", hidden=False):
184 kb = xbmc.Keyboard(default, heading, hidden)
185 kb.doModal()
186 if (kb.isConfirmed()):
187 return unicode(kb.getText(), "utf-8")
188 return ''
189
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.')
196 return 0
197 else:
198 if groovesharkApi.loggedInStatus() == 1:
199 groovesharkApi.logout()
200 userid = groovesharkApi.loginExt(username, password)
201 if (userid != 0):
202 xbmc.log("Logged in")
203 return userid
204 else:
205 dialog = xbmcgui.Dialog()
206 dialog.ok('Grooveshark', 'Unable to login.', 'Check username and password in settings.')
207 return 0
208
209 def _get_songs(self, songs):
210 xbmc.log("Found " + str(len(songs)) + " songs...")
211 i = 0
212 while i < len(songs):
213 song = songs[i]
214 songName = song[0]
215 songID = song[1]
216 songDuration = song[2]
217 songAlbum = song[3]
218 songArtist = song[6]
219 songThumb = song[8]
220 songImage = song[9]
221 songUrl = groovesharkApi.getStreamURL(songID)
222 self._addSong(songID, songName, songUrl, songDuration, songAlbum, songArtist, songThumb, songImage)
223 i = i + 1
224 xbmcplugin.setContent(self._handle, 'songs')
225
226 def _get_albums(self, albums):
227 xbmc.log("Found " + str(len(albums)) + " albums...")
228 i = 0
229 while i < len(albums):
230 album = albums[i]
231 albumArtistName = album[0]
232 albumName = album[2]
233 albumID = album[3]
234 albumImage = album[4]
235 self._addDir(albumName + " - " + albumArtistName, '', MODE_ALBUM, albumImage, albumID)
236 i = i + 1
237 xbmcplugin.setContent(self._handle, 'albums')
238 xbmcplugin.addSortMethod(self._handle, xbmcplugin.SORT_METHOD_ALBUM_IGNORE_THE)
239
240 def _get_artists(self, artists):
241 xbmc.log("Found " + str(len(artists)) + " artists...")
242 i = 0
243 while i < len(artists):
244 artist = artists[i]
245 artistName = artist[0]
246 artistID = artist[1]
247 self._addDir(artistName, '', MODE_ARTIST, self.artistImg, artistID)
248 i = i + 1
249 xbmcplugin.setContent(self._handle, 'artists')
250 xbmcplugin.addSortMethod(self._handle, xbmcplugin.SORT_METHOD_ARTIST_IGNORE_THE)
251
252 def _get_playlists(self, playlists):
253 xbmc.log("Found " + str(len(playlists)) + " playlists...")
254 i = 0
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, )
260 i = i + 1
261 xbmcplugin.setContent(self._handle, 'files')
262 xbmcplugin.addSortMethod(self._handle, xbmcplugin.SORT_METHOD_PLAYLIST_ORDER)
263
264 def _addSong(self, songid, songname, songurl, songduration, songalbum, songartist, songthumb, songimage):
265 songImg = self._getThumb(songimage, str(songid) + "-image")
266 if songImg == "":
267 songImg = songimage
268 songThm = self._getThumb(songthumb, str(songid) + "-thumb")
269 if songThm == "":
270 songThm = songthumb
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)
281 menuItems = []
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)
286 return songItem
287
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
293 menuItems = []
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)
297
298 # File download
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'
302 try:
303 if os.path.isfile(localThumb) == False:
304 loc = urllib.URLopener()
305 loc.retrieve(url, localThumb)
306 except:
307 xbmc.log('URL download failed of ' + url + ' to ' + localThumb)
308 return ""
309
310 return os.path.join(os.path.join(thumbDir, str(id))) + '.tbn'
311
312
313
314 def get_params():
315 param=[]
316 paramstring=sys.argv[2]
317 if len(paramstring)>=2:
318 params=sys.argv[2]
319 cleanedparams=params.replace('?','')
320 if (params[len(params)-1]=='/'):
321 params=params[0:len(params)-2]
322 pairsofparams=cleanedparams.split('&')
323 param={}
324 for i in range(len(pairsofparams)):
325 splitparams={}
326 splitparams=pairsofparams[i].split('=')
327 if (len(splitparams))==2:
328 param[splitparams[0]]=splitparams[1]
329 print param
330 return param
331
332 grooveshark = Groveshark();
333
334 params=get_params()
335 url=None
336 name=None
337 mode=None
338 id=None
339
340 try: url=urllib.unquote_plus(params["url"])
341 except: pass
342 try: name=urllib.unquote_plus(params["name"])
343 except: pass
344 try: mode=int(params["mode"])
345 except: pass
346 try: id=int(params["id"])
347 except: pass
348
349 if (id > 0):
350 lastID = id
351
352 if mode==None:
353 grooveshark.categories()
354
355 elif mode==MODE_SEARCH_SONGS:
356 grooveshark.searchSongs()
357
358 elif mode==MODE_SEARCH_ALBUMS:
359 grooveshark.searchAlbums()
360
361 elif mode==MODE_SEARCH_ARTISTS:
362 grooveshark.searchArtists()
363
364 elif mode==MODE_POPULAR:
365 grooveshark.popular()
366
367 elif mode==MODE_PLAYLISTS:
368 grooveshark.playlists()
369
370 elif mode==MODE_FAVORITES:
371 grooveshark.favorites()
372
373 elif mode==MODE_SONG:
374 try: name=urllib.unquote_plus(params["name"])
375 except: pass
376 try: album=urllib.unquote_plus(params["album"])
377 except: pass
378 try: artist=urllib.unquote_plus(params["artist"])
379 except: pass
380 try: duration=int(params["duration"])
381 except: pass
382 try: thumb=urllib.unquote_plus(params["thumb"])
383 except: pass
384 try: image=urllib.unquote_plus(params["image"])
385 except: pass
386 grooveshark.playSong(url, name, album, artist, duration, thumb, image)
387
388 elif mode==MODE_ARTIST:
389 grooveshark.artist(lastID)
390
391 elif mode==MODE_ALBUM:
392 grooveshark.album(lastID)
393
394 elif mode==MODE_PLAYLIST:
395 grooveshark.playlist(lastID)
396
397 elif mode==MODE_FAVORITE:
398 grooveshark.favorite(lastID)
399
400 elif mode==MODE_UNFAVORITE:
401 grooveshark.unfavorite(lastID)
402
403 if (mode < MODE_SONG):
404 xbmcplugin.endOfDirectory(int(sys.argv[1]))