diff --git a/GoogleMusicActions.py b/GoogleMusicActions.py
index f28ea3c..19f4893 100644
--- a/GoogleMusicActions.py
+++ b/GoogleMusicActions.py
@@ -1,4 +1,4 @@
-import os, xbmc, utils
+import os, xbmc, xbmcgui, utils
import GoogleMusicApi
class GoogleMusicActions():
@@ -11,6 +11,9 @@ def __init__(self):
def executeAction(self, action, params):
if (action == "play_all"):
self.playAll(params)
+ elif (action == "play_all_yt"):
+ titles = [song[23] for song in self._getSongs(params)]
+ self.playYoutube(titles)
elif (action == "update_playlist"):
self.api.getPlaylistSongs(params["playlist_id"], True)
elif (action == "update_playlists"):
@@ -32,12 +35,11 @@ def executeAction(self, action, params):
elif (action == "del_from_playlist"):
self.api.delFromPlaylist(params["playlist_id"], params["song_id"])
elif (action == "update_library"):
- try:
- self.api.clearCache()
- xbmc.executebuiltin("XBMC.RunPlugin(%s)" % utils.addon_url)
+ try: self.api.clearCache()
except Exception as e:
utils.log(repr(e))
self.notify(self.lang(30106))
+ xbmc.executebuiltin("XBMC.RunPlugin(%s)" % utils.addon_url)
elif (action == "export_library"):
if utils.addon.getSetting('export_path'):
self.exportLibrary(utils.addon.getSetting('export_path'))
@@ -52,11 +54,12 @@ def executeAction(self, action, params):
self.playAll({'radio_id': self.api.startRadio(keyboard.getText(), params["song_id"])})
xbmc.executebuiltin("ActivateWindow(10500)")
#xbmc.executebuiltin("XBMC.RunPlugin(%s?path=station&id=%s)" % (sys.argv[0],radio_id))
- elif (action == "youtube"):
- try:
- xbmc.executebuiltin("ActivateWindow(10025,plugin://plugin.video.youtube/kodion/search/query/?q=%s)" % params['title'])
- except:
- self.notify(self.lang(30109))
+ elif (action == "search_yt"):
+ xbmc.executebuiltin("ActivateWindow(10025,plugin://plugin.video.youtube/kodion/search/query/?q=%s)" % params['title'])
+ elif (action == "play_yt"):
+ self.playYoutube([params.get('title')])
+ elif (action == "search"):
+ xbmc.executebuiltin("ActivateWindow(10501,%s/?path=search_result&query=%s)" % (utils.addon_url, params.get('filter_criteria')))
else:
utils.log("Invalid action: " + action)
@@ -64,26 +67,7 @@ def notify(self, text):
xbmc.executebuiltin("XBMC.Notification(%s,%s,5000,%s)" % (utils.plugin, text, self.icon))
def playAll(self, params={}):
- get = params.get
-
- if get('playlist_id'):
- utils.log("Loading playlist: " + get('playlist_id'))
- songs = self.api.getPlaylistSongs(get('playlist_id'))
- elif get('album_id'):
- utils.log("Loading album: " + get('album_id'))
- songs = self.api.getAlbum(get('album_id'))
- elif get('share_token'):
- import urllib
- utils.log("Loading shared playlist: " + get('share_token'))
- songs = self.api.getSharedPlaylist(urllib.unquote_plus(get('share_token')))
- elif get('artist_id'):
- utils.log("Loading artist top tracks: " + get('artist_id'))
- songs = self.api.getArtist(get('artist_id'))
- elif get('radio_id'):
- utils.log("Loading radio: " + get('radio_id'))
- songs = self.api.getStationTracks(get('radio_id'))
- else:
- songs = self.api.getFilterSongs(get('filter_type'), get('filter_criteria'), albums='')
+ songs = self._getSongs(params)
player = xbmc.Player()
if (player.isPlaying()):
@@ -100,8 +84,28 @@ def playAll(self, params={}):
xbmc.executebuiltin('playlist.playoffset(music , 0)')
+ def playYoutube(self, titles):
+ #print repr(titles)
+
+ player = xbmc.Player()
+ if (player.isPlaying()):
+ player.stop()
+
+ playlist = xbmc.PlayList(xbmc.PLAYLIST_VIDEO)
+ playlist.clear()
+
+ dp = None
+ if len(titles) > 1:
+ dp = xbmcgui.DialogProgress();
+ dp.create('Fetching video IDs', str(len(titles))+' '+self.lang(30213).lower(), self.lang(30404))
+
+ ytaddonurl = "plugin://plugin.video.youtube/play/?video_id=%s"
+ for videoid, title in self._getVideoIDs(titles, dp):
+ playlist.add(ytaddonurl % videoid, xbmcgui.ListItem(title))
+
+ xbmc.executebuiltin('playlist.playoffset(video , 0)')
+
def addToPlaylist (self, song_id):
- import xbmcgui
playlists = self.api.getPlaylistsByType('user')
plist = [pl_name for pl_id, pl_name in playlists]
selected = xbmcgui.Dialog().select(self.lang(30401) , plist)
@@ -125,7 +129,6 @@ def addFavourite(self, name, params):
print line,
def exportLibrary(self, path):
- import xbmcgui
songs = self.api.getPlaylistSongs('all_songs')
dp = xbmcgui.DialogProgress();
dp.create(self.lang(30403), str(len(songs))+' '+self.lang(30213).lower(), self.lang(30404))
@@ -155,5 +158,53 @@ def exportLibrary(self, path):
def _sanitizePath(self, name):
name = "".join(i for i in name if i not in "\/:*?<>|,;$%\"\'.`")
if len(name) > 50: name = name[:50]
- return unicode(name.decode('utf8')).strip()
- #return ("".join([i if i.isalnum() else " " for i in name.strip()])).strip()
\ No newline at end of file
+ return utils.tryEncode(name).strip()
+
+ def _getSongs(self, params):
+ get = params.get
+
+ if get('playlist_id'):
+ utils.log("Loading playlist: " + get('playlist_id'))
+ songs = self.api.getPlaylistSongs(get('playlist_id'))
+ elif get('album_id'):
+ utils.log("Loading album: " + get('album_id'))
+ songs = self.api.getAlbum(get('album_id'))
+ elif get('share_token'):
+ import urllib
+ utils.log("Loading shared playlist: " + get('share_token'))
+ songs = self.api.getSharedPlaylist(urllib.unquote_plus(get('share_token')))
+ elif get('artist_id'):
+ utils.log("Loading artist top tracks: " + get('artist_id'))
+ songs = self.api.getArtist(get('artist_id'))
+ elif get('radio_id'):
+ utils.log("Loading radio: " + get('radio_id'))
+ songs = self.api.getStationTracks(get('radio_id'))
+ else:
+ songs = self.api.getFilterSongs(get('filter_type'), get('filter_criteria'), albums='')
+
+ return songs
+
+ def _getVideoIDs(self, titles, progress_dialog=None):
+ import urllib, urllib2, re
+
+ videoids = []
+ opener = urllib2.build_opener()
+ userAgent = "Mozilla/5.0 (Windows NT 6.1; rv:30.0) Gecko/20100101 Firefox/30.0"
+ opener.addheaders = [('User-Agent', userAgent)]
+ url = "http://gdata.youtube.com/feeds/api/videos?q=%s+-interview+-cover+-remix+-album&category=Music&max-results=1&start-index=1&orderby=relevance&time=all_time&v=2"
+
+ count = 0
+ for title in titles:
+ if progress_dialog:
+ if progress_dialog.iscanceled():
+ progress_dialog.close()
+ return videoids
+ count = count +1
+ progress_dialog.update(int(count * 100 / len(titles)))
+ content = opener.open(url % urllib.quote_plus(utils.tryEncode(title.lower()))).read()
+ match=re.compile('(.+?)', re.DOTALL).findall(content)
+ if match:
+ #print match[0]+' '+repr(title)
+ videoids.append([match[0], title])
+
+ return videoids
diff --git a/GoogleMusicNavigation.py b/GoogleMusicNavigation.py
index a440e34..dff5eca 100644
--- a/GoogleMusicNavigation.py
+++ b/GoogleMusicNavigation.py
@@ -106,7 +106,7 @@ def getMenuItems(self, items):
elif 'playlist_type' in params:
cm = self.getPlaylistsContextMenuItems(menu_item['title'], params['playlist_type'])
elif params['path'] == 'library':
- cm.append(('Export', "XBMC.RunPlugin(%s?action=export_library)" % utils.addon_url))
+ cm.append((self.lang(30314), "XBMC.RunPlugin(%s?action=export_library)" % utils.addon_url))
cm.append((self.lang(30305), "XBMC.RunPlugin(%s?action=update_library)" % utils.addon_url))
cm.append((self.lang(30306), "XBMC.RunPlugin(%s?action=add_favourite&path=library&title=%s)" % (utils.addon_url,menu_item['title'])))
elif 'criteria' in params:
@@ -145,7 +145,8 @@ def getPlaylists(self, playlist_type):
if playlist_type == 'radio':
icon = utils.addon.getAddonInfo('icon')
for rs in self.api.getStations():
- append(addFolder(rs['name'], {'path':"station",'id':rs['id']}, album_art_url=rs.get('imageUrl', icon)))
+ cm = self.getRadioContextMenuItems(rs['name'], rs['id'])
+ append(addFolder(rs['name'], {'path':"station",'id':rs['id']}, cm, album_art_url=rs.get('imageUrl', icon)))
else:
for pl_id, pl_name in self.api.getPlaylistsByType(playlist_type):
cm = self.getPlayAllContextMenuItems(pl_name, pl_id)
@@ -204,29 +205,41 @@ def createItem(self, song, song_type):
def getSongContextMenu(self, song_id, title, song_type):
cm = []
+ if song_id.startswith('T'):
+ cm.append((self.lang(30309), "XBMC.RunPlugin(%s?action=add_library&song_id=%s)" % (utils.addon_url,song_id)))
if song_type == 'library':
cm.append((self.lang(30307),"XBMC.RunPlugin(%s?action=add_playlist&song_id=%s)" % (utils.addon_url,song_id)))
elif song_type.startswith('playlist'):
cm.append((self.lang(30308), "XBMC.RunPlugin(%s?action=del_from_playlist&song_id=%s&playlist_id=%s)" % (utils.addon_url, song_id, song_type[8:])))
- if song_id.startswith('T'):
- cm.append((self.lang(30309), "XBMC.RunPlugin(%s?action=add_library&song_id=%s)" % (utils.addon_url,song_id)))
+ cm.append((self.lang(30313), "XBMC.RunPlugin(%s?action=play_yt&title=%s)" % (utils.addon_url,title)))
+ cm.append((self.lang(30311), "XBMC.RunPlugin(%s?action=search_yt&title=%s)" % (utils.addon_url,title)))
cm.append((self.lang(30310), "XBMC.RunPlugin(%s?action=start_radio&song_id=%s)" % (utils.addon_url,song_id)))
- cm.append((self.lang(30311), "XBMC.RunPlugin(%s?action=youtube&title=%s)" % (utils.addon_url,title)))
+ return cm
+
+ def getRadioContextMenuItems(self, name, radio_id):
+ cm = []
+ cm.append((self.lang(30301), "XBMC.RunPlugin(%s?action=play_all&radio_id=%s)" % (utils.addon_url, radio_id)))
+ cm.append((self.lang(30302), "XBMC.RunPlugin(%s?action=play_all&radio_id=%s&shuffle=true)" % (utils.addon_url, radio_id)))
+ cm.append((self.lang(30312), "XBMC.RunPlugin(%s?action=play_all_yt&radio_id=%s)" % (utils.addon_url, radio_id)))
+ cm.append((self.lang(30306), "XBMC.RunPlugin(%s?action=add_favourite&path=playlist&radio_id=%s&title=%s)" % (utils.addon_url, radio_id, name)))
return cm
def getPlayAllContextMenuItems(self, name, playlist):
cm = []
cm.append((self.lang(30301), "XBMC.RunPlugin(%s?action=play_all&playlist_id=%s)" % (utils.addon_url, playlist)))
cm.append((self.lang(30302), "XBMC.RunPlugin(%s?action=play_all&playlist_id=%s&shuffle=true)" % (utils.addon_url, playlist)))
+ cm.append((self.lang(30312), "XBMC.RunPlugin(%s?action=play_all_yt&playlist_id=%s)" % (utils.addon_url, playlist)))
cm.append((self.lang(30303), "XBMC.RunPlugin(%s?action=update_playlist&playlist_id=%s)" % (utils.addon_url, playlist)))
cm.append((self.lang(30306), "XBMC.RunPlugin(%s?action=add_favourite&path=playlist&playlist_id=%s&title=%s)" % (utils.addon_url, playlist, name)))
return cm
def getFilterContextMenuItems(self, filter_type, filter_criteria):
cm = []
+ cm.append((self.lang(30306), "XBMC.RunPlugin(%s?action=add_favourite&path=%s&name=%s&title=%s)" % (utils.addon_url, filter_type, filter_criteria, filter_criteria)))
cm.append((self.lang(30301), "XBMC.RunPlugin(%s?action=play_all&filter_type=%s&filter_criteria=%s)" % (utils.addon_url, filter_type, filter_criteria)))
cm.append((self.lang(30302), "XBMC.RunPlugin(%s?action=play_all&filter_type=%s&filter_criteria=%s&shuffle=true)" % (utils.addon_url, filter_type, filter_criteria)))
- cm.append((self.lang(30306), "XBMC.RunPlugin(%s?action=add_favourite&path=%s&name=%s&title=%s)" % (utils.addon_url, filter_type, filter_criteria, filter_criteria)))
+ cm.append((self.lang(30312), "XBMC.RunPlugin(%s?action=play_all_yt&filter_type=%s&filter_criteria=%s)" % (utils.addon_url, filter_type, filter_criteria)))
+ cm.append((self.lang(30208), "XBMC.RunPlugin(%s?action=search&filter_type=%s&filter_criteria=%s)" % (utils.addon_url, filter_type, filter_criteria)))
return cm
def getPlaylistsContextMenuItems(self, name, playlist_type):
@@ -242,7 +255,7 @@ def listAlbumsResults():
listItems.append(self.createFolder('[COLOR orange]*** '+self.lang(30206)+' ***[/COLOR]',{'path':'none'}))
cm = []
for album in result['albums']:
- params = {'path':"search_result",'query':self.tryEncode(album[0])}
+ params = {'path':"search_result",'query':utils.tryEncode(album[0])}
if len(album) > 3:
cm = [(self.lang(30301), "XBMC.RunPlugin(%s?action=play_all&album_id=%s)" % (utils.addon_url, album[3]))]
params['albumid'] = album[3]
@@ -255,7 +268,7 @@ def listAlbumsResults():
listItems.append(self.createFolder('[COLOR orange]*** '+self.lang(30205)+' ***[/COLOR]',{'path':'none'}))
cm = []
for artist in result['artists']:
- params = {'path':"search_result",'query':self.tryEncode(artist[0])}
+ params = {'path':"search_result",'query':utils.tryEncode(artist[0])}
if len(artist) > 2:
cm = [(self.lang(30301), "XBMC.RunPlugin(%s?action=play_all&artist_id=%s)" % (utils.addon_url, artist[2]))]
params['artistid'] = artist[2]
@@ -275,10 +288,5 @@ def listAlbumsResults():
listItems.extend(self.getSearch(unquote_plus(query['query'])))
return listItems
- def tryEncode(self, text, encoding='utf8'):
- try:
- return text.encode(encoding)
- except:
- utils.log(" ENCODING FAIL!!!@ "+encoding)
- return repr(text)
+
diff --git a/addon.xml b/addon.xml
index 4f33ed8..1041e8f 100644
--- a/addon.xml
+++ b/addon.xml
@@ -6,6 +6,7 @@
+
diff --git a/utils.py b/utils.py
index 48145dd..a332e64 100644
--- a/utils.py
+++ b/utils.py
@@ -22,8 +22,9 @@ def paramsToDict(parameters):
paramPairs = parameters[1:].split('&')
for paramsPair in paramPairs:
paramSplits = paramsPair.split('=')
- if len(paramSplits) == 2:
+ try:
paramDict[paramSplits[0]] = paramSplits[1]
+ except: pass
return paramDict
def createItem(title, thumb):
@@ -40,11 +41,23 @@ def setResolvedUrl(listItem):
xbmcplugin.setResolvedUrl(handle=handle, succeeded=True, listitem=listItem)
def setDirectory(listItems, content, sortMethods):
- if handle < 0: return
+ #if handle < 0: return
xbmcplugin.addDirectoryItems(handle, listItems)
- xbmcplugin.setContent(handle, content)
+ if handle > 0:
+ xbmcplugin.setContent(handle, content)
for sorts in sortMethods:
xbmcplugin.addSortMethod(int(sys.argv[1]), sorts)
- xbmcplugin.endOfDirectory(handle, succeeded=True)
\ No newline at end of file
+ xbmcplugin.endOfDirectory(handle, succeeded=True)
+
+def tryEncode(text, encoding='utf8'):
+ try:
+ text = text.decode(encoding)
+ return unicode(text)
+ except: pass
+ try:
+ return text.encode(encoding)
+ except:
+ log(" ENCODING FAIL!!! "+encoding+" "+repr(text))
+ return repr(text)
\ No newline at end of file