Fix directory creation bug.
[clinton/xbmc-groove.git] / default.py
CommitLineData
7ce01be6 1import urllib, sys, os, shutil, re, time, xbmcaddon, xbmcplugin, xbmcgui, xbmc
8817bb2e 2MODE_SEARCH_SONGS = 1
3MODE_SEARCH_ALBUMS = 2
4MODE_SEARCH_ARTISTS = 3
36cc00d7 5MODE_POPULAR_SONGS = 4
8817bb2e 6MODE_FAVORITES = 5
7MODE_PLAYLISTS = 6
8MODE_ALBUM = 7
9MODE_ARTIST = 8
10MODE_PLAYLIST = 9
406ab447 11MODE_SONG = 11
12MODE_FAVORITE = 12
7ea6f166 13
38df1fa5 14ACTION_MOVE_LEFT = 1
7ea6f166 15ACTION_MOVE_UP = 3
16ACTION_MOVE_DOWN = 4
17ACTION_PAGE_UP = 5
18ACTION_PAGE_DOWN = 6
19ACTION_SELECT_ITEM = 7
20ACTION_PREVIOUS_MENU = 10
8817bb2e 21
6ae708d0 22baseDir = os.getcwd()
23resDir = xbmc.translatePath(os.path.join(baseDir, 'resources'))
8817bb2e 24libDir = xbmc.translatePath(os.path.join(resDir, 'lib'))
25imgDir = xbmc.translatePath(os.path.join(resDir, 'img'))
7ce01be6 26cacheDir = os.path.join(xbmc.translatePath('special://masterprofile/addon_data/'), os.path.basename(os.getcwd()))
27thumbDirName = 'thumb'
28thumbDir = os.path.join('special://masterprofile/addon_data/', os.path.basename(os.getcwd()), thumbDirName)
4be42357 29
30baseModeUrl = 'plugin://plugin.audio.groove/'
e278f474 31playlistUrl = baseModeUrl + '?mode=' + str(MODE_PLAYLIST)
4be42357 32playlistsUrl = baseModeUrl + '?mode=' + str(MODE_PLAYLISTS)
33favoritesUrl = baseModeUrl + '?mode=' + str(MODE_FAVORITES)
34
7ce01be6 35thumbDef = os.path.join(imgDir, 'default.tbn')
8817bb2e 36
37sys.path.append (libDir)
7ce01be6 38from GroovesharkAPI import GrooveAPI
39
a3ad8f73 40try:
41 groovesharkApi = GrooveAPI()
7ce01be6 42 if groovesharkApi.pingService() != True:
43 raise StandardError('No Grooveshark service')
a3ad8f73 44except:
45 dialog = xbmcgui.Dialog()
46 dialog.ok('Grooveshark XBMC', 'Unable to connect with Grooveshark.', 'Please try again later')
47 sys.exit(-1)
48
8817bb2e 49
50class _Info:
51 def __init__( self, *args, **kwargs ):
52 self.__dict__.update( kwargs )
e278f474 53
7ce01be6 54
8817bb2e 55class Groveshark:
973b4c6c 56
7ea6f166 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'))
2254a6b5 64 fanImg = xbmc.translatePath(os.path.join(baseDir, 'fanart.png'))
8817bb2e 65
2254a6b5 66 settings = xbmcaddon.Addon(id='plugin.audio.groove')
7ce01be6 67 songsearchlimit = int(settings.getSetting('songsearchlimit'))
68 albumsearchlimit = int(settings.getSetting('albumsearchlimit'))
69 artistsearchlimit = int(settings.getSetting('artistsearchlimit'))
2254a6b5 70 username = settings.getSetting('username')
71 password = settings.getSetting('password')
38df1fa5 72 userid = 0
4be42357 73
8817bb2e 74 def __init__( self ):
75 self._handle = int(sys.argv[1])
7ce01be6 76 if os.path.isdir(cacheDir) == False:
77 os.makedirs(cacheDir)
78 xbmc.log("Made " + cacheDir)
79 if os.path.isdir(thumbDir) == False:
fc5562d8 80 os.makedirs(thumbDir)
81 xbmc.log("Made " + thumbDir)
b738088f 82
e278f474 83 # Top-level menu
8817bb2e 84 def categories(self):
2254a6b5 85
38df1fa5 86 self.userid = self._get_login()
b738088f 87
88 # Setup
6ae708d0 89 xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
6ae708d0 90
e278f474 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)
36cc00d7 94 self._add_dir('Popular songs', '', MODE_POPULAR_SONGS, self.popularSongsImg, 0)
38df1fa5 95 if (self.userid != 0):
3fcef5ba 96 self._add_dir('Favorites', '', MODE_FAVORITES, self.favoritesImg, 0)
97 self._add_dir('Playlists', '', MODE_PLAYLISTS, self.playlistImg, 0)
e278f474 98
99 # Search for songs
8817bb2e 100 def searchSongs(self):
101 query = self._get_keyboard(default="", heading="Search songs")
7ea6f166 102 if (query != ''):
7ce01be6 103 songs = groovesharkApi.getSongSearchResults(query, limit = self.songsearchlimit)
8817bb2e 104 if (len(songs) > 0):
6ae708d0 105 self._add_songs_directory(songs)
8817bb2e 106 else:
107 dialog = xbmcgui.Dialog()
38df1fa5 108 dialog.ok('Grooveshark XBMC', 'No matching songs.')
8817bb2e 109 self.categories()
7ea6f166 110 else:
111 self.categories()
8817bb2e 112
e278f474 113 # Search for albums
8817bb2e 114 def searchAlbums(self):
115 query = self._get_keyboard(default="", heading="Search albums")
7ea6f166 116 if (query != ''):
7ce01be6 117 albums = groovesharkApi.getAlbumSearchResults(query, limit = self.albumsearchlimit)
8817bb2e 118 if (len(albums) > 0):
6ae708d0 119 self._add_albums_directory(albums)
8817bb2e 120 else:
121 dialog = xbmcgui.Dialog()
38df1fa5 122 dialog.ok('Grooveshark XBMC', 'No matching albums.')
8817bb2e 123 self.categories()
7ea6f166 124 else:
125 self.categories()
8817bb2e 126
e278f474 127 # Search for artists
8817bb2e 128 def searchArtists(self):
129 query = self._get_keyboard(default="", heading="Search artists")
7ea6f166 130 if (query != ''):
7ce01be6 131 artists = groovesharkApi.getArtistSearchResults(query, limit = self.artistsearchlimit)
8817bb2e 132 if (len(artists) > 0):
6ae708d0 133 self._add_artists_directory(artists)
8817bb2e 134 else:
135 dialog = xbmcgui.Dialog()
38df1fa5 136 dialog.ok('Grooveshark XBMC', 'No matching artists.')
8817bb2e 137 self.categories()
7ea6f166 138 else:
139 self.categories()
8817bb2e 140
e278f474 141 # Get my favorites
8817bb2e 142 def favorites(self):
36cc00d7 143 userid = self._get_login()
144 if (userid != 0):
7ce01be6 145 favorites = groovesharkApi.getUserFavoriteSongs()
36cc00d7 146 if (len(favorites) > 0):
7ce01be6 147 self._add_songs_directory(favorites)
36cc00d7 148 else:
149 dialog = xbmcgui.Dialog()
38df1fa5 150 dialog.ok('Grooveshark XBMC', 'You have no favorites.')
36cc00d7 151 self.categories()
8817bb2e 152
e278f474 153 # Get popular songs
36cc00d7 154 def popularSongs(self):
7ce01be6 155 popular = groovesharkApi.getPopularSongsToday(limit = self.songsearchlimit)
8817bb2e 156 if (len(popular) > 0):
6ae708d0 157 self._add_songs_directory(popular)
8817bb2e 158 else:
159 dialog = xbmcgui.Dialog()
38df1fa5 160 dialog.ok('Grooveshark XBMC', 'No popular songs.')
8817bb2e 161 self.categories()
36cc00d7 162
e278f474 163 # Get my playlists
8817bb2e 164 def playlists(self):
165 userid = self._get_login()
166 if (userid != 0):
7ce01be6 167 playlists = groovesharkApi.getUserPlaylists()
8817bb2e 168 if (len(playlists) > 0):
6ae708d0 169 self._add_playlists_directory(playlists)
8817bb2e 170 else:
171 dialog = xbmcgui.Dialog()
38df1fa5 172 dialog.ok('Grooveshark XBMC', 'You have no Grooveshark playlists.')
8817bb2e 173 self.categories()
7ea6f166 174 else:
175 dialog = xbmcgui.Dialog()
38df1fa5 176 dialog.ok('Grooveshark XBMC', 'You must be logged in ', ' to see your Grooveshark playlists.')
7ea6f166 177
e278f474 178 # Make songs a favorite
8817bb2e 179 def favorite(self, songid):
180 userid = self._get_login()
181 if (userid != 0):
406ab447 182 xbmc.log("Favorite song: " + str(songid))
7ce01be6 183 groovesharkApi.addUserFavoriteSong(songID = songid)
38df1fa5 184 xbmc.executebuiltin('XBMC.Notification(Grooveshark XBMC, Added to favorites, 1000, ' + thumbDef + ')')
8817bb2e 185 else:
186 dialog = xbmcgui.Dialog()
38df1fa5 187 dialog.ok('Grooveshark XBMC', 'You must be logged in', 'to add favorites.')
e278f474 188
189 # Show selected album
36cc00d7 190 def album(self, albumid):
7ce01be6 191 album = groovesharkApi.getAlbumSongs(albumid, limit = self.songsearchlimit)
6ae708d0 192 self._add_songs_directory(album)
e278f474 193
194 # Show selected artist
8817bb2e 195 def artist(self, artistid):
7ce01be6 196 albums = groovesharkApi.getArtistAlbums(artistid, limit = self.albumsearchlimit)
7fda21f0 197 self._add_albums_directory(albums)
8817bb2e 198
e278f474 199 # Show selected playlist
7ce01be6 200 def playlist(self, playlistid):
8817bb2e 201 userid = self._get_login()
202 if (userid != 0):
7ce01be6 203 songs = groovesharkApi.getPlaylistSongs(playlistid)
204 self._add_songs_directory(songs)
8817bb2e 205 else:
206 dialog = xbmcgui.Dialog()
38df1fa5 207 dialog.ok('Grooveshark XBMC', 'You must be logged in', 'to get Grooveshark playlists.')
8817bb2e 208
e278f474 209 # Play a song
6ae708d0 210 def playSong(self, item):
7ce01be6 211 songid = item.getProperty('songid')
212 song = groovesharkApi.getSongURLFromSongID(songid)
cbb0985e 213 if song != '':
7ce01be6 214 item.setPath(song)
215 xbmc.log("Playing: " + song)
216 xbmcplugin.setResolvedUrl(handle=int(sys.argv[1]), succeeded=True, listitem=item)
217 else:
cbb0985e 218 xbmc.executebuiltin('XBMC.Notification(Grooveshark XBMC, Unable to play song, 1000, ' + thumbDef + ')')
3fcef5ba 219
e278f474 220 # Make a song directory item
7ce01be6 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} )
2254a6b5 225 item.setProperty('mimetype', 'audio/mpeg')
226 item.setProperty("IsPlayable", "true")
7ce01be6 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)
232
6ae708d0 233 return item
2254a6b5 234
e278f474 235 # Get keyboard input
8817bb2e 236 def _get_keyboard(self, default="", heading="", hidden=False):
3cfead3c 237 kb = xbmc.Keyboard(default, heading, hidden)
238 kb.doModal()
239 if (kb.isConfirmed()):
240 return unicode(kb.getText(), "utf-8")
241 return ''
8817bb2e 242
e278f474 243 # Login to grooveshark
8817bb2e 244 def _get_login(self):
2254a6b5 245 if (self.username == "" or self.password == ""):
8817bb2e 246 dialog = xbmcgui.Dialog()
38df1fa5 247 dialog.ok('Grooveshark XBMC', 'Unable to login.', 'Check username and password in settings.')
8817bb2e 248 return 0
249 else:
38df1fa5 250 if self.userid == 0:
7ce01be6 251 uid = groovesharkApi.login(self.username, self.password)
38df1fa5 252 if (uid != 0):
38df1fa5 253 return uid
8817bb2e 254 else:
255 dialog = xbmcgui.Dialog()
38df1fa5 256 dialog.ok('Grooveshark XBMC', 'Unable to login.', 'Check username and password in settings.')
8817bb2e 257 return 0
258
e278f474 259 # Get a song directory item
6ae708d0 260 def _get_song_item(self, song):
261 name = song[0]
7ce01be6 262 songid = song[1]
263 album = song[2]
264 artist = song[4]
265 coverart = song[6]
266 return self.songItem(songid, name, album, artist, coverart)
6ae708d0 267
268 # File download
7ce01be6 269 def _get_icon(self, url, songid):
270 if url != 'None':
271 localThumb = os.path.join(xbmc.translatePath(os.path.join(thumbDir, str(songid)))) + '.tbn'
272 try:
273 if os.path.isfile(localThumb) == False:
274 loc = urllib.URLopener()
275 loc.retrieve(url, localThumb)
276 except:
277 shutil.copy2(thumbDef, localThumb)
278 return os.path.join(os.path.join(thumbDir, str(songid))) + '.tbn'
279 else:
280 return thumbDef
e278f474 281
282 # Add songs to directory
7ce01be6 283 def _add_songs_directory(self, songs):
6ae708d0 284 n = len(songs)
285 xbmc.log("Found " + str(n) + " songs...")
8817bb2e 286 i = 0
6ae708d0 287 while i < n:
8817bb2e 288 song = songs[i]
6ae708d0 289 item = self._get_song_item(song)
7ce01be6 290 coverart = item.getProperty('coverart')
6ae708d0 291 songname = song[0]
292 songid = song[1]
7ce01be6 293 songalbum = song[2]
294 songartist = song[4]
e278f474 295 u=sys.argv[0]+"?mode="+str(MODE_SONG)+"&name="+urllib.quote_plus(songname)+"&id="+str(songid) \
6ae708d0 296 +"&album="+urllib.quote_plus(songalbum) \
297 +"&artist="+urllib.quote_plus(songartist) \
7ce01be6 298 +"&coverart="+urllib.quote_plus(coverart)
e278f474 299 fav=sys.argv[0]+"?mode="+str(MODE_FAVORITE)+"&name="+urllib.quote_plus(songname)+"&id="+str(songid)
6ae708d0 300 menuItems = []
7ce01be6 301 menuItems.append(("Grooveshark favorite", "XBMC.RunPlugin("+fav+")"))
6ae708d0 302 item.addContextMenuItems(menuItems, replaceItems=False)
e278f474 303 xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=item,isFolder=False, totalItems=n)
8817bb2e 304 i = i + 1
cb06c186 305
8817bb2e 306 xbmcplugin.setContent(self._handle, 'songs')
31731635 307 xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
e278f474 308
309 # Add albums to directory
7ce01be6 310 def _add_albums_directory(self, albums):
31731635 311 n = len(albums)
312 xbmc.log("Found " + str(n) + " albums...")
8817bb2e 313 i = 0
31731635 314 while i < n:
8817bb2e 315 album = albums[i]
316 albumArtistName = album[0]
317 albumName = album[2]
318 albumID = album[3]
2254a6b5 319 albumImage = self._get_icon(album[4], 'album-' + str(albumID))
31731635 320 self._add_dir(albumName + " - " + albumArtistName, '', MODE_ALBUM, albumImage, albumID, n)
8817bb2e 321 i = i + 1
322 xbmcplugin.setContent(self._handle, 'albums')
323 xbmcplugin.addSortMethod(self._handle, xbmcplugin.SORT_METHOD_ALBUM_IGNORE_THE)
31731635 324 xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
e278f474 325
326 # Add artists to directory
6ae708d0 327 def _add_artists_directory(self, artists):
31731635 328 n = len(artists)
329 xbmc.log("Found " + str(n) + " artists...")
8817bb2e 330 i = 0
31731635 331 while i < n:
8817bb2e 332 artist = artists[i]
333 artistName = artist[0]
334 artistID = artist[1]
31731635 335 self._add_dir(artistName, '', MODE_ARTIST, self.artistImg, artistID, n)
8817bb2e 336 i = i + 1
337 xbmcplugin.setContent(self._handle, 'artists')
338 xbmcplugin.addSortMethod(self._handle, xbmcplugin.SORT_METHOD_ARTIST_IGNORE_THE)
31731635 339 xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
e278f474 340
341 # Add playlists to directory
6ae708d0 342 def _add_playlists_directory(self, playlists):
31731635 343 n = len(playlists)
344 xbmc.log("Found " + str(n) + " playlists...")
8817bb2e 345 i = 0
31731635 346 while i < n:
8817bb2e 347 playlist = playlists[i]
348 playlistName = playlist[0]
349 playlistID = playlist[1]
31731635 350 self._add_dir(playlistName, '', MODE_PLAYLIST, self.playlistImg, playlistID, n)
8817bb2e 351 i = i + 1
352 xbmcplugin.setContent(self._handle, 'files')
353 xbmcplugin.addSortMethod(self._handle, xbmcplugin.SORT_METHOD_PLAYLIST_ORDER)
31731635 354 xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg)
3fcef5ba 355
e278f474 356 # Add whatever directory
31731635 357 def _add_dir(self, name, url, mode, iconimage, id, items=1):
e278f474 358
359 u=sys.argv[0]+"?mode="+str(mode)+"&name="+urllib.quote_plus(name)+"&id="+str(id)
8817bb2e 360 dir=xbmcgui.ListItem(name, iconImage=iconimage, thumbnailImage=iconimage)
b738088f 361 dir.setInfo( type="Music", infoLabels={ "title": name } )
31731635 362 return xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=dir,isFolder=True, totalItems=items)
6ae708d0 363
e278f474 364
365# Parse URL parameters
8817bb2e 366def get_params():
367 param=[]
368 paramstring=sys.argv[2]
e278f474 369 xbmc.log(paramstring)
8817bb2e 370 if len(paramstring)>=2:
371 params=sys.argv[2]
372 cleanedparams=params.replace('?','')
373 if (params[len(params)-1]=='/'):
374 params=params[0:len(params)-2]
375 pairsofparams=cleanedparams.split('&')
376 param={}
377 for i in range(len(pairsofparams)):
378 splitparams={}
379 splitparams=pairsofparams[i].split('=')
380 if (len(splitparams))==2:
381 param[splitparams[0]]=splitparams[1]
8817bb2e 382 return param
383
e278f474 384# Main
8817bb2e 385grooveshark = Groveshark();
e278f474 386
8817bb2e 387params=get_params()
8817bb2e 388mode=None
8817bb2e 389try: mode=int(params["mode"])
390except: pass
7ce01be6 391id=0
392try: id=int(params["id"])
393except: pass
e278f474 394
395# Call function for URL
8817bb2e 396if mode==None:
397 grooveshark.categories()
398
399elif mode==MODE_SEARCH_SONGS:
400 grooveshark.searchSongs()
401
402elif mode==MODE_SEARCH_ALBUMS:
403 grooveshark.searchAlbums()
404
405elif mode==MODE_SEARCH_ARTISTS:
406 grooveshark.searchArtists()
407
36cc00d7 408elif mode==MODE_POPULAR_SONGS:
409 grooveshark.popularSongs()
8817bb2e 410
8817bb2e 411elif mode==MODE_FAVORITES:
412 grooveshark.favorites()
413
e278f474 414elif mode==MODE_PLAYLISTS:
415 grooveshark.playlists()
416
8817bb2e 417elif mode==MODE_SONG:
7ce01be6 418 try: name=urllib.unquote_plus(params["name"])
419 except: pass
8817bb2e 420 try: album=urllib.unquote_plus(params["album"])
421 except: pass
422 try: artist=urllib.unquote_plus(params["artist"])
423 except: pass
7ce01be6 424 try: coverart=urllib.unquote_plus(params["coverart"])
8817bb2e 425 except: pass
7ce01be6 426 song = grooveshark.songItem(id, name, album, artist, coverart)
3fcef5ba 427 grooveshark.playSong(song)
8817bb2e 428
429elif mode==MODE_ARTIST:
4be42357 430 grooveshark.artist(id)
8817bb2e 431
432elif mode==MODE_ALBUM:
4be42357 433 grooveshark.album(id)
8817bb2e 434
435elif mode==MODE_PLAYLIST:
7ce01be6 436 grooveshark.playlist(id)
8817bb2e 437
438elif mode==MODE_FAVORITE:
4be42357 439 grooveshark.favorite(id)
8817bb2e 440
e278f474 441if mode < MODE_SONG:
8817bb2e 442 xbmcplugin.endOfDirectory(int(sys.argv[1]))