Skip to content

Commit

Permalink
Youtube support
Browse files Browse the repository at this point in the history
Play songs in Youtube
  • Loading branch information
foreverguest committed Mar 24, 2015
1 parent 85ba3b7 commit 1309b5e
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 51 deletions.
117 changes: 84 additions & 33 deletions GoogleMusicActions.py
@@ -1,4 +1,4 @@
import os, xbmc, utils
import os, xbmc, xbmcgui, utils
import GoogleMusicApi

class GoogleMusicActions():
Expand All @@ -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"):
Expand All @@ -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'))
Expand All @@ -52,38 +54,20 @@ 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)

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()):
Expand All @@ -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)
Expand All @@ -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))
Expand Down Expand Up @@ -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()
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('<yt:videoid>(.+?)</yt:videoid>', re.DOTALL).findall(content)
if match:
#print match[0]+' '+repr(title)
videoids.append([match[0], title])

return videoids
36 changes: 22 additions & 14 deletions GoogleMusicNavigation.py
Expand Up @@ -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:
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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):
Expand All @@ -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]
Expand All @@ -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]
Expand All @@ -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)


1 change: 1 addition & 0 deletions addon.xml
Expand Up @@ -6,6 +6,7 @@
<requires>
<import addon="xbmc.python" version="2.1.0"/>
<import addon="xbmc.addon" version="12.0.0"/>
<import addon="plugin.video.youtube" version="5.0.0" optional="true"/>
<import addon="script.module.decorator" version="3.4.0"/>
<import addon="script.module.requests" version="1.1.0"/>
</requires>
Expand Down
21 changes: 17 additions & 4 deletions utils.py
Expand Up @@ -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):
Expand All @@ -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)
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)

0 comments on commit 1309b5e

Please sign in to comment.