X-Git-Url: https://git.hcoop.net/clinton/xbmc-groove.git/blobdiff_plain/4be4235772b9654af30be73b730cb816ae6af3ce..aa0c1263c8a5bc58cfb233356e2338bf2649fd9c:/default.py diff --git a/default.py b/default.py index 06d8133..695ce9c 100644 --- a/default.py +++ b/default.py @@ -1,4 +1,4 @@ -import urllib, urllib2, re, xbmcplugin, xbmcgui, xbmc, sys, os, time, pprint, shutil, xbmcaddon +import urllib, urllib2, re, xbmcplugin, xbmcgui, xbmc, sys, os, time, shutil, xbmcaddon MODE_SEARCH_SONGS = 1 MODE_SEARCH_ALBUMS = 2 @@ -17,6 +17,15 @@ MODE_MAKE_PLAYLIST = 14 MODE_REMOVE_PLAYLIST = 15 MODE_RENAME_PLAYLIST = 16 MODE_REMOVE_PLAYLIST_SONG = 17 +MODE_ADD_PLAYLIST_SONG = 18 + +ACTION_MOVE_LEFT = 1 +ACTION_MOVE_UP = 3 +ACTION_MOVE_DOWN = 4 +ACTION_PAGE_UP = 5 +ACTION_PAGE_DOWN = 6 +ACTION_SELECT_ITEM = 7 +ACTION_PREVIOUS_MENU = 10 baseDir = os.getcwd() resDir = xbmc.translatePath(os.path.join(baseDir, 'resources')) @@ -30,6 +39,7 @@ playlistsUrl = baseModeUrl + '?mode=' + str(MODE_PLAYLISTS) favoritesUrl = baseModeUrl + '?mode=' + str(MODE_FAVORITES) thumbDef = os.path.join(os.path.basename(os.getcwd()), 'default.tbn') +listBackground = os.path.join(imgDir, 'listbackground.png') sys.path.append (libDir) from GrooveAPI import * @@ -39,15 +49,75 @@ class _Info: def __init__( self, *args, **kwargs ): self.__dict__.update( kwargs ) +class GroovesharkPlaylistSelect(xbmcgui.WindowDialog): + + def __init__(self, items=[]): + gap = int(self.getHeight()/100) + w = int(self.getWidth()*0.5) + h = self.getHeight()-30*gap + rw = self.getWidth() + rh = self.getHeight() + x = rw/2 - w/2 + y = rh/2 -h/2 + + self.imgBg = xbmcgui.ControlImage(x+gap, 5*gap+y, w-2*gap, h-5*gap, listBackground) + self.addControl(self.imgBg) + + self.playlistControl = xbmcgui.ControlList(2*gap+x, y+3*gap+30, w-4*gap, h-10*gap, textColor='0xFFFFFFFF', selectedColor='0xFFFF4242', itemTextYOffset=0, itemHeight=30, alignmentY = 0) + self.addControl(self.playlistControl) + + self.lastPos = 0 + self.isSelecting = False + self.selected = -1 + listitems = [] + for playlist in items: + listitems.append(xbmcgui.ListItem(playlist[0])) + listitems.append(xbmcgui.ListItem('New...')) + self.playlistControl.addItems(listitems) + self.setFocus(self.playlistControl) + self.playlistControl.selectItem(0) + item = self.playlistControl.getListItem(self.lastPos) + item.select(True) + + # Highlight selected item + def setHighlight(self): + if self.isSelecting: + return + else: + self.isSelecting = True + + pos = self.playlistControl.getSelectedPosition() + if pos >= 0: + item = self.playlistControl.getListItem(self.lastPos) + item.select(False) + item = self.playlistControl.getListItem(pos) + item.select(True) + self.lastPos = pos + self.isSelecting = False + + # Control + def onControl(self, control): + if control == self.playlistControl: + self.selected = self.playlistControl.getSelectedPosition() + self.close() + + def onAction(self, action): + if action == ACTION_PREVIOUS_MENU: + self.selected = -1 + self.close() + elif action == ACTION_MOVE_UP or action == ACTION_MOVE_DOWN or action == ACTION_PAGE_UP or action == ACTION_PAGE_DOWN == 6: + self.setFocus(self.playlistControl) + self.setHighlight() + class Groveshark: - albumImg = xbmc.translatePath(os.path.join(imgDir, 'album.png')) - artistImg = xbmc.translatePath(os.path.join(imgDir, 'artist.png')) - favoritesImg = xbmc.translatePath(os.path.join(imgDir, 'favorites.png')) - playlistImg = xbmc.translatePath(os.path.join(imgDir, 'playlist.png')) - popularSongsImg = xbmc.translatePath(os.path.join(imgDir, 'popularSongs.png')) - songImg = xbmc.translatePath(os.path.join(imgDir, 'song.png')) - defImg = xbmc.translatePath(os.path.join(imgDir, 'default.tbn')) + albumImg = xbmc.translatePath(os.path.join(imgDir, 'album.png')) + artistImg = xbmc.translatePath(os.path.join(imgDir, 'artist.png')) + favoritesImg = xbmc.translatePath(os.path.join(imgDir, 'favorites.png')) + playlistImg = xbmc.translatePath(os.path.join(imgDir, 'playlist.png')) + popularSongsImg = xbmc.translatePath(os.path.join(imgDir, 'popularSongs.png')) + songImg = xbmc.translatePath(os.path.join(imgDir, 'song.png')) + defImg = xbmc.translatePath(os.path.join(imgDir, 'default.tbn')) fanImg = xbmc.translatePath(os.path.join(baseDir, 'fanart.png')) settings = xbmcaddon.Addon(id='plugin.audio.groove') @@ -56,6 +126,7 @@ class Groveshark: artistsearchlimit = settings.getSetting('artistsearchlimit') username = settings.getSetting('username') password = settings.getSetting('password') + userid = 0 def __init__( self ): self._handle = int(sys.argv[1]) @@ -64,7 +135,7 @@ class Groveshark: xbmc.log(self.username + ", limits: " + str(self.songsearchlimit) + ", " + str(self.albumsearchlimit) + ", " + str(self.artistsearchlimit)) - userid = self._get_login() + self.userid = self._get_login() # Setup xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg) @@ -75,43 +146,49 @@ class Groveshark: self._add_dir('Search albums', '', MODE_SEARCH_ALBUMS, self.albumImg, 0) self._add_dir('Search artists', '', MODE_SEARCH_ARTISTS, self.artistImg, 0) self._add_dir('Popular songs', '', MODE_POPULAR_SONGS, self.popularSongsImg, 0) - if (userid != 0): + if (self.userid != 0): self._add_dir('Favorites', '', MODE_FAVORITES, self.favoritesImg, 0) self._add_dir('Playlists', '', MODE_PLAYLISTS, self.playlistImg, 0) def searchSongs(self): query = self._get_keyboard(default="", heading="Search songs") - if (query): + if (query != ''): groovesharkApi.setRemoveDuplicates(True) songs = groovesharkApi.searchSongs(query, limit = self.songsearchlimit) if (len(songs) > 0): self._add_songs_directory(songs) else: dialog = xbmcgui.Dialog() - dialog.ok('Grooveshark', 'No matching songs.') + dialog.ok('Grooveshark XBMC', 'No matching songs.') self.categories() + else: + self.categories() def searchAlbums(self): query = self._get_keyboard(default="", heading="Search albums") - if (query): + if (query != ''): albums = groovesharkApi.searchAlbums(query, limit = self.albumsearchlimit) if (len(albums) > 0): self._add_albums_directory(albums) else: dialog = xbmcgui.Dialog() - dialog.ok('Grooveshark', 'No matching albums.') + dialog.ok('Grooveshark XBMC', 'No matching albums.') self.categories() + else: + self.categories() def searchArtists(self): query = self._get_keyboard(default="", heading="Search artists") - if (query): + if (query != ''): artists = groovesharkApi.searchArtists(query, limit = self.artistsearchlimit) if (len(artists) > 0): self._add_artists_directory(artists) else: dialog = xbmcgui.Dialog() - dialog.ok('Grooveshark', 'No matching artists.') + dialog.ok('Grooveshark XBMC', 'No matching artists.') self.categories() + else: + self.categories() def favorites(self): userid = self._get_login() @@ -121,7 +198,7 @@ class Groveshark: self._add_songs_directory(favorites, isFavorites=True) else: dialog = xbmcgui.Dialog() - dialog.ok('Grooveshark', 'You have no favorites.') + dialog.ok('Grooveshark XBMC', 'You have no favorites.') self.categories() def popularSongs(self): @@ -130,7 +207,7 @@ class Groveshark: self._add_songs_directory(popular) else: dialog = xbmcgui.Dialog() - dialog.ok('Grooveshark', 'No popular songs.') + dialog.ok('Grooveshark XBMC', 'No popular songs.') self.categories() def popularAlbums(self): @@ -139,7 +216,7 @@ class Groveshark: self._add_albums_directory(popular) else: dialog = xbmcgui.Dialog() - dialog.ok('Grooveshark', 'No popular albums.') + dialog.ok('Grooveshark XBMC', 'No popular albums.') self.categories() def popularArtists(self): @@ -148,7 +225,7 @@ class Groveshark: self._add_artists_directory(popular) else: dialog = xbmcgui.Dialog() - dialog.ok('Grooveshark', 'No popular artists.') + dialog.ok('Grooveshark XBMC', 'No popular artists.') self.categories() def playlists(self): @@ -159,30 +236,34 @@ class Groveshark: self._add_playlists_directory(playlists) else: dialog = xbmcgui.Dialog() - dialog.ok('Grooveshark', 'You have no playlists.') + dialog.ok('Grooveshark XBMC', 'You have no Grooveshark playlists.') self.categories() + else: + dialog = xbmcgui.Dialog() + dialog.ok('Grooveshark XBMC', 'You must be logged in ', ' to see your Grooveshark playlists.') + def favorite(self, songid): userid = self._get_login() if (userid != 0): xbmc.log("Favorite song: " + str(songid)) groovesharkApi.favoriteSong(songID = songid) - xbmc.executebuiltin('XBMC.Notification(Grooveshark, Added to favorites, 1000, ' + thumbDef + ')') + xbmc.executebuiltin('XBMC.Notification(Grooveshark XBMC, Added to favorites, 1000, ' + thumbDef + ')') else: dialog = xbmcgui.Dialog() - dialog.ok('Grooveshark', 'You must be logged in', 'to add favorites.') + dialog.ok('Grooveshark XBMC', 'You must be logged in', 'to add favorites.') def unfavorite(self, songid, prevMode): userid = self._get_login() if (userid != 0): xbmc.log("Unfavorite song: " + str(songid) + ', previous mode was ' + str(prevMode)) groovesharkApi.unfavoriteSong(songID = songid) - xbmc.executebuiltin('XBMC.Notification(Grooveshark, Removed from favorites, 1000, ' + thumbDef + ')') + xbmc.executebuiltin('XBMC.Notification(Grooveshark XBMC, Removed from Grooveshark favorites, 1000, ' + thumbDef + ')') if (int(prevMode) == MODE_FAVORITES): - xbmc.executebuiltin("Container.Update(" + favoritesUrl + ",replace)") + xbmc.executebuiltin("Container.Update(" + favoritesUrl + ")") else: dialog = xbmcgui.Dialog() - dialog.ok('Grooveshark', 'You must be logged in', 'to remove favorites.') + dialog.ok('Grooveshark XBMC', 'You must be logged in', 'to remove Grooveshark favorites.') def frown(self, songid): userid = self._get_login() @@ -191,10 +272,10 @@ class Groveshark: if groovesharkApi.radioFrown(songId = songid) != True: xbmc.log("Unable to frown song " + str(songid)) else: - xbmc.executebuiltin('XBMC.Notification(Grooveshark, Frowned, 1000, ' + thumbDef + ')') + xbmc.executebuiltin('XBMC.Notification(Grooveshark XBMC, Frowned, 1000, ' + thumbDef + ')') else: dialog = xbmcgui.Dialog() - dialog.ok('Grooveshark', 'You must be logged in', 'to frown a song.') + dialog.ok('Grooveshark XBMC', 'You must be logged in', 'to frown a Grooveshark song.') def similarArtists(self, artistId): similar = groovesharkApi.artistGetSimilar(artistId, limit = self.artistsearchlimit) @@ -202,7 +283,7 @@ class Groveshark: self._add_artists_directory(similar) else: dialog = xbmcgui.Dialog() - dialog.ok('Grooveshark', 'No similar artists.') + dialog.ok('Grooveshark XBMC', 'No similar artists.') self.categories() def makePlaylist(self, albumid, name): @@ -210,62 +291,103 @@ class Groveshark: if (userid != 0): re.split(' - ',name,1) nameTokens = re.split(' - ',name,1) - name = self._get_keyboard(default=nameTokens[0], heading="Playlist name") + name = self._get_keyboard(default=nameTokens[0], heading="Grooveshark playlist name") if name != '': groovesharkApi.setRemoveDuplicates(True) album = groovesharkApi.albumGetSongs(albumid, self.songsearchlimit) songids = [] for song in album: songids.append(song[1]) - id = groovesharkApi.playlistCreateUnique(name, songids) - if id == 0: + if groovesharkApi.playlistCreateUnique(name, songids) == 0: dialog = xbmcgui.Dialog() - dialog.ok('Grooveshark', 'Cannot create playlist ', name) + dialog.ok('Grooveshark XBMC', 'Cannot create Grooveshark playlist ', name) else: - xbmc.executebuiltin('XBMC.Notification(Grooveshark, Playlist created, 1000, ' + thumbDef + ')') + xbmc.executebuiltin('XBMC.Notification(Grooveshark XBMC, Grooveshark playlist created, 1000, ' + thumbDef + ')') else: dialog = xbmcgui.Dialog() - dialog.ok('Grooveshark', 'You must be logged in ', ' to create a playlist.') + dialog.ok('Grooveshark XBMC', 'You must be logged in ', ' to create a Grooveshark playlist.') def removePlaylist(self, playlistid, name): dialog = xbmcgui.Dialog() - if dialog.yesno('Grooveshark', name, 'Delete this playlist?') == True: + if dialog.yesno('Grooveshark XBMC', name, 'Delete this Grooveshark playlist?') == True: userid = self._get_login() if (userid != 0): groovesharkApi.playlistDelete(playlistid) - xbmc.executebuiltin("Container.Update(" + playlistsUrl + ",replace)") + xbmc.executebuiltin("Container.Refresh(" + playlistsUrl + ")") else: dialog = xbmcgui.Dialog() - dialog.ok('Grooveshark', 'You must be logged in ', ' to delete a playlist.') + dialog.ok('Grooveshark XBMC', 'You must be logged in ', ' to delete a Grooveshark playlist.') def removePlaylistSong(self, playlistid, playlistname, songpos): dialog = xbmcgui.Dialog() - if dialog.yesno('Grooveshark', 'Delete this song from the playlist?') == True: + if dialog.yesno('Grooveshark XBMC', 'Delete this song from the Grooveshark playlist?') == True: userid = self._get_login() if (userid != 0): if groovesharkApi.playlistDeleteSong(playlistid, songpos) == 0: dialog = xbmcgui.Dialog() - dialog.ok('Grooveshark', 'Failed to remove ', ' song from playlist.') + dialog.ok('Grooveshark XBMC', 'Failed to remove ', ' song from Grooveshark playlist.') else: - xbmc.executebuiltin("Container.Update(" + playlistUrl + "&id="+str(playlistid) + "&name=" + playlistname + ",replace)") + xbmc.executebuiltin("Container.Refresh(" + playlistUrl + "&id="+str(playlistid) + "&name=" + playlistname + ",replace)") + else: + dialog = xbmcgui.Dialog() + dialog.ok('Grooveshark XBMC', 'You must be logged in ', ' to delete a song from a Grooveshark playlist.') + + def addPlaylistSong(self, songid): + userid = self._get_login() + if (userid != 0): + playlists = groovesharkApi.userGetPlaylists() + if (len(playlists) > 0): + ret = 0 + playlistSelect = GroovesharkPlaylistSelect(items=playlists) + playlistSelect.setFocus(playlistSelect.playlistControl) + playlistSelect.doModal() + i = playlistSelect.selected + del playlistSelect + if i > -1: + # New playlist + if i >= len(playlists): + name = self._get_keyboard(default='', heading="Grooveshark playlist name") + if name != '': + songIds = [] + songIds.append(songid) + if groovesharkApi.playlistCreateUnique(name, songIds) == 0: + dialog = xbmcgui.Dialog() + dialog.ok('Grooveshark XBMC', 'Cannot create Grooveshark playlist ', name) + else: + xbmc.executebuiltin('XBMC.Notification(Grooveshark XBMC, Grooveshark playlist created, 1000, ' + thumbDef + ')') + # Existing playlist + else: + playlist = playlists[i] + playlistid = playlist[1] + xbmc.log("Add song " + str(songid) + " to playlist " + str(playlistid)) + ret = groovesharkApi.playlistAddSong(playlistid, songid, 0) + if ret == 0: + dialog = xbmcgui.Dialog() + dialog.ok('Grooveshark XBMC', 'Cannot add to playlist ') + else: + xbmc.executebuiltin('XBMC.Notification(Grooveshark XBMC, Added song to Grooveshark playlist, 1000, ' + thumbDef + ')') else: dialog = xbmcgui.Dialog() - dialog.ok('Grooveshark', 'You must be logged in ', ' to delete a song from a playlist.') + dialog.ok('Grooveshark XBMC', 'You have no Grooveshark playlists.') + self.categories() + else: + dialog = xbmcgui.Dialog() + dialog.ok('Grooveshark XBMC', 'You must be logged in ', ' to add a song to a Grooveshark playlist.') def renamePlaylist(self, playlistid, name): userid = self._get_login() if (userid != 0): - newname = self._get_keyboard(default=name, heading="Playlist name") + newname = self._get_keyboard(default=name, heading="Grooveshark playlist name") if newname == '': return elif groovesharkApi.playlistRename(playlistid, newname) == 0: dialog = xbmcgui.Dialog() - dialog.ok('Grooveshark', 'Cannot rename playlist ', name) + dialog.ok('Grooveshark XBMC', 'Cannot rename Grooveshark playlist ', name) else: xbmc.executebuiltin("Container.Refresh") else: dialog = xbmcgui.Dialog() - dialog.ok('Grooveshark', 'You must be logged in ', ' to rename a playlist.') + dialog.ok('Grooveshark XBMC', 'You must be logged in ', ' to rename a Grooveshark playlist.') def album(self, albumid): groovesharkApi.setRemoveDuplicates(True) @@ -283,7 +405,7 @@ class Groveshark: self._add_songs_directory(songs, playlistid, playlistname) else: dialog = xbmcgui.Dialog() - dialog.ok('Grooveshark', 'You must be logged in', 'to get playlists.') + dialog.ok('Grooveshark XBMC', 'You must be logged in', 'to get Grooveshark playlists.') def playSong(self, item): url = item.getProperty('url') @@ -319,18 +441,17 @@ class Groveshark: def _get_login(self): if (self.username == "" or self.password == ""): dialog = xbmcgui.Dialog() - dialog.ok('Grooveshark', 'Unable to login.', 'Check username and password in settings.') + dialog.ok('Grooveshark XBMC', 'Unable to login.', 'Check username and password in settings.') return 0 else: - if groovesharkApi.loggedInStatus() == 1: - groovesharkApi.logout() - userid = groovesharkApi.loginExt(self.username, self.password) - if (userid != 0): + if self.userid == 0: + uid = groovesharkApi.loginExt(self.username, self.password) + if (uid != 0): xbmc.log("Logged in") - return userid + return uid else: dialog = xbmcgui.Dialog() - dialog.ok('Grooveshark', 'Unable to login.', 'Check username and password in settings.') + dialog.ok('Grooveshark XBMC', 'Unable to login.', 'Check username and password in settings.') return 0 def _get_song_item(self, song): @@ -360,6 +481,7 @@ class Groveshark: def _add_songs_directory(self, songs, playlistid=0, playlistname='', isFavorites=False): n = len(songs) xbmc.log("Found " + str(n) + " songs...") + dirItems = [] i = 0 while i < n: song = songs[i] @@ -386,14 +508,23 @@ class Groveshark: if isFavorites == True: unfav = unfav +str(MODE_FAVORITES) else: - menuItems.append(("Grooveshark Favorite", "XBMC.RunPlugin("+fav+")")) - menuItems.append(("Not Grooveshark Favorite", "XBMC.RunPlugin("+unfav+")")) + menuItems.append(("Grooveshark favorite", "XBMC.RunPlugin("+fav+")")) + menuItems.append(("Not Grooveshark favorite", "XBMC.RunPlugin("+unfav+")")) if playlistid > 0: rmplaylstsong=sys.argv[0]+"?playlistid="+str(playlistid)+"&id="+str(i+1)+"&mode="+str(MODE_REMOVE_PLAYLIST_SONG)+"&name="+playlistname - menuItems.append(("Remove from playlist", "XBMC.RunPlugin("+rmplaylstsong+")")) + menuItems.append(("Remove from Grooveshark playlist", "XBMC.RunPlugin("+rmplaylstsong+")")) + else: + addplaylstsong=sys.argv[0]+"?id="+str(songid)+"&mode="+str(MODE_ADD_PLAYLIST_SONG) + menuItems.append(("Add to Grooveshark playlist", "XBMC.RunPlugin("+addplaylstsong+")")) item.addContextMenuItems(menuItems, replaceItems=False) - xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=item,isFolder=False,totalItems=n) + dirItem = (u, item, False) + dirItems.append(dirItem) + if i % 5 == 0: + xbmcplugin.addDirectoryItems(int(sys.argv[1]), dirItems ,n) + dirItems = [] i = i + 1 + + xbmcplugin.addDirectoryItems(int(sys.argv[1]), dirItems ,n) xbmcplugin.setContent(self._handle, 'songs') xbmcplugin.setPluginFanart(int(sys.argv[1]), self.fanImg) @@ -447,18 +578,16 @@ class Groveshark: u=sys.argv[0]+"?url="+urllib.quote_plus(url)+"&mode="+str(mode)+"&name="+urllib.quote_plus(name)+"&id="+str(id) dir=xbmcgui.ListItem(name, iconImage=iconimage, thumbnailImage=iconimage) dir.setInfo( type="Music", infoLabels={ "title": name } ) - # Codes from http://xbmc-scripting.googlecode.com/svn/trunk/Script%20Templates/common/gui/codes.py menuItems = [] - menuItems.append(("Select", "XBMC.executebuiltin(Action(7))")) if mode == MODE_ALBUM: mkplaylst=sys.argv[0]+"?mode="+str(MODE_MAKE_PLAYLIST)+"&name="+name+"&id="+str(id) menuItems.append(("Make Grooveshark playlist", "XBMC.RunPlugin("+mkplaylst+")")) if mode == MODE_PLAYLIST: rmplaylst=sys.argv[0]+"?mode="+str(MODE_REMOVE_PLAYLIST)+"&name="+urllib.quote_plus(name)+"&id="+str(id) - menuItems.append(("Delete playlist", "XBMC.RunPlugin("+rmplaylst+")")) + menuItems.append(("Delete Grooveshark playlist", "XBMC.RunPlugin("+rmplaylst+")")) mvplaylst=sys.argv[0]+"?mode="+str(MODE_RENAME_PLAYLIST)+"&name="+urllib.quote_plus(name)+"&id="+str(id) - menuItems.append(("Rename playlist", "XBMC.RunPlugin("+mvplaylst+")")) - dir.addContextMenuItems(menuItems, replaceItems=True) + menuItems.append(("Rename Grooveshark playlist", "XBMC.RunPlugin("+mvplaylst+")")) + dir.addContextMenuItems(menuItems, replaceItems=False) return xbmcplugin.addDirectoryItem(handle=int(sys.argv[1]),url=u,listitem=dir,isFolder=True, totalItems=items) @@ -566,5 +695,8 @@ elif mode==MODE_REMOVE_PLAYLIST_SONG: except: pass grooveshark.removePlaylistSong(playlistID, name, id) +elif mode==MODE_ADD_PLAYLIST_SONG: + grooveshark.addPlaylistSong(id) + if (mode < MODE_SONG): xbmcplugin.endOfDirectory(int(sys.argv[1]))