def add_playlist(id, type=''): if type == '' or type == 'tv': api_url = 'http://youtubelibrary.nl/api/v1/playlists/tv/' + id + '?api_token=' + vars.__settings__.getSetting( 'api_token') if type == 'musicvideo': api_url = 'http://youtubelibrary.nl/api/v1/playlists/musicvideos/' + id + '?api_token=' + vars.__settings__.getSetting( 'api_token') if type == 'movies': api_url = 'http://youtubelibrary.nl/api/v1/playlists/movies/' + id + '?api_token=' + vars.__settings__.getSetting( 'api_token') dev.log('Adding the Api playlist to the config: ' + api_url) data = json.load(urllib2.urlopen(api_url)) if 'data' not in data: url = dev.build_url({'mode': 'ApiIndex'}) dev.adddir( 'Something went wrong', url, description= 'There was an error getting the playlist from the youtubelibrary.nl API.' ) return False playlist = data['data'] return playlist url = dev.build_url({'mode': 'ApiAddPlaylist', 'type': type}) dev.adddir(playlist['title'], url, description=playlist['description'])
def show_playlists_by_channel(Channelid, type=''): search_response = ytube.yt_get_channel_info(Channelid) #Grab the playlists from the response playlists = search_response['items'][0]['contentDetails']['relatedPlaylists'] # Go through each playlist and display the playlist for key, value in playlists.iteritems(): #Grab the number of videos to pl = ytube.yt_get_playlist_info(value) number_vids = str(pl['items'][0]['contentDetails']['itemCount']) #videos.append(search_result) url = dev.build_url({'mode': 'addPlaylist', 'id': value, 'type': type}) dev.adddir(key.capitalize()+' ('+number_vids+')', url, search_response['items'][0]['snippet']['thumbnails']['high']['url'], fanart=search_response['items'][0]['snippet']['thumbnails']['high']['url'], description=dev.lang(31010)+' '+dev.typeName(type)+' \n--------\nPlaylist Description:\n'+search_response['items'][0]['snippet']['description']) # Grab other playlists this user has created to response = ytube.yt_get_playlists_by_channel(Channelid) if isinstance(response, list): # Go through each playlist and display the playlist for playlist in response: #videos.append(search_result) title = playlist['snippet']['title']+' ('+str(playlist['contentDetails']['itemCount'])+')' url = dev.build_url({'mode': 'addPlaylist', 'id': playlist['id'], 'type': type}) dev.adddir(title, url, playlist['snippet']['thumbnails']['high']['url'], fanart=playlist['snippet']['thumbnails']['high']['url'], description=dev.lang(31010)+' '+dev.typeName(type)+' \n--------\nPlaylist Description:\n'+playlist['snippet']['description']) xbmcplugin.endOfDirectory(vars.addon_handle)#Adds a playlist & loads the view to edit it
def manage_playlists(type=''): dev.log('manage_playlists(' + type + ')') #pl = m_xml.xml_get_elem('playlists', 'playlists') #Grab <playlists> m_xml.xml_get(type) pl = m_xml.document.findall('playlists/playlist') if pl is not None: for child in pl: #Loop through each playlist url = dev.build_url({ 'mode': 'editPlaylist', 'id': child.attrib['id'], 'type': type }) #Build the contextmenu item to force the updating of one playlist context_url = dev.build_url({ 'mode': 'updateplaylist', 'id': child.attrib['id'], 'type': type }) context_url2 = dev.build_url({ 'mode': 'deletePlaylist', 'id': child.attrib['id'], 'type': type }) context_url3 = dev.build_url({ 'mode': 'refreshPlaylist', 'id': child.attrib['id'], 'type': type }) context_url4 = dev.build_url({ 'mode': 'refreshArtwork', 'id': child.attrib['id'], 'type': type }) commands = [] commands.append(( dev.lang(31006), 'XBMC.RunPlugin(' + context_url + ')', )) commands.append(( dev.lang(31007), 'XBMC.RunPlugin(' + context_url2 + ')', )) commands.append(( dev.lang(31029), 'XBMC.RunPlugin(' + context_url3 + ')', )) commands.append(( dev.lang(31030), 'XBMC.RunPlugin(' + context_url4 + ')', )) dev.adddir(child.find('title').text, url, child.find('thumb').text, child.find('fanart').text, child.find('description').text, context=commands) xbmcplugin.endOfDirectory(vars.addon_handle)
def searched_playlist(result, type='', pagetoken=''): response = ytube.search_playlist(result, type, pagetoken) if isinstance(response['items'], list): # Go through each playlist and display the playlist for playlist in response['items']: #videos.append(search_result) title = playlist['snippet']['title'] url = dev.build_url({ 'mode': 'addPlaylist', 'id': playlist['id']['playlistId'], 'type': type }) dev.adddir(title, url, dev.playlist_highest_thumbnail(playlist), fanart=dev.playlist_highest_thumbnail(playlist), description=dev.lang(31010) + ' ' + dev.typeName(type) + ' \n--------\nPlaylist Description:\n' + playlist['snippet']['description']) if 'prevPageToken' in response: if response['prevPageToken'] is not None: url = dev.build_url({ 'mode': 'searchedplaylist', 'search': result, 'type': type, 'pagetoken': response['prevPageToken'] }) dev.adddir( '<< Prev Page', url, description='Go to the previous page of available playlists') if 'nextPageToken' in response: if response['nextPageToken'] is not None: url = dev.build_url({ 'mode': 'searchedplaylist', 'search': result, 'type': type, 'pagetoken': response['nextPageToken'] }) dev.adddir( 'Next Page >>', url, description='Go to the next page of available playlists') xbmcplugin.endOfDirectory( vars.addon_handle) #Adds a playlist & loads the view to edit it
def disp_setting(setting, title, description, level=0): #Is the mode in the addon settings high enough to display this setting? if level > vars.mode: return False #no #build url val = None if elem.find(setting) != None: val = elem.find(setting).text if setting == 'published': d = ytube.convert_published(val) val = d['day']+'-'+d['month']+'-'+d['year'] elif setting == 'search_imdb': #Search_IMDB (movies setting) options = ['Yes, fallback on addon settings', 'Yes, dont add if imdb fails', 'No, just use addon settings'] val = options[int(val)] elif setting == 'use_ytimage': options = ['Only if no image found on IMDB', 'Always', 'Dont add if no image is found on IMDB', 'Never'] val = options[int(val)] if val == None or val == 'None': val = '' url = dev.build_url({'mode': 'editPlaylist', 'id': plid, 'set': setting, 'type': pltype}) if 'hardcoded' in title.lower() and 'genre hardcoded' not in title.lower() or 'fallback' in title.lower() and 'song fallback' not in title.lower(): dev.adddir('[COLOR blue] --'+title+':[/COLOR] '+val, url, gear, fanart, description) else: dev.adddir('[COLOR blue]'+title+':[/COLOR] '+val, url, gear, fanart, description)
def manage_playlists(type=''): dev.log('manage_playlists('+type+')') #pl = m_xml.xml_get_elem('playlists', 'playlists') #Grab <playlists> m_xml.xml_get(type) pl = m_xml.document.findall('playlists/playlist') if pl is not None: for child in pl: #Loop through each playlist url = dev.build_url({'mode': 'editPlaylist', 'id': child.attrib['id'], 'type': type}) #Build the contextmenu item to force the updating of one playlist context_url = dev.build_url({'mode': 'updateplaylist', 'id': child.attrib['id'], 'type': type}) context_url2 = dev.build_url({'mode': 'deletePlaylist', 'id': child.attrib['id'], 'type': type}) commands = [] commands.append(( dev.lang(31006), 'XBMC.RunPlugin('+context_url+')', )) commands.append(( dev.lang(31007), 'XBMC.RunPlugin('+context_url2+')', )) dev.adddir(child.find('title').text, url, child.find('thumb').text, child.find('fanart').text, child.find('description').text, context=commands) xbmcplugin.endOfDirectory(vars.addon_handle)
def api_home(): if vars.__settings__.getSetting('enable_donor') == 'false': xbmcgui.Dialog().ok(dev.lang(31991), dev.lang(31992)) elif len(vars.__settings__.getSetting('api_token')) < 60: xbmcgui.Dialog().ok(dev.lang(31993), dev.lang(31994)) else: import xbmcaddon #Browse All Playlists url = dev.build_url({ 'mode': 'ApiIndex2', 'api_url': 'default', 'type': 'tv' }) dev.adddir( 'TV', url, description= 'Easily add pre-configured TV playlists from Youtubelibrary.nl. Available for Donors only at the moment. But you can still visit Youtubelibrary.nl to manually add them!' ) #Browse All Genres url = dev.build_url({ 'mode': 'ApiIndex2', 'api_url': 'default', 'type': 'musicvideo' }) dev.adddir( 'Musicvideos', url, description= 'Easily add pre-configured Musicvideo playlists by Genre from Youtubelibrary.nl. Available for Donors only at the moment. But you can still visit Youtubelibrary.nl to manually add them!' ) #Browse By Tag url = dev.build_url({ 'mode': 'ApiIndex2', 'api_url': 'default', 'type': 'movies' }) dev.adddir( 'Movies', url, description= 'Easily add pre-configured Movies playlists by Tag from Youtubelibrary.nl. Available for Donors only at the moment. But you can still visit Youtubelibrary.nl to manually add them!' ) xbmcplugin.endOfDirectory(vars.addon_handle)
def api_home(): if vars.__settings__.getSetting('enable_donor') == 'false': xbmcgui.Dialog().ok(dev.lang(31991), dev.lang(31992)) elif len(vars.__settings__.getSetting('api_token')) < 60: xbmcgui.Dialog().ok(dev.lang(31993), dev.lang(31994)) else: import xbmcaddon #Browse All Playlists url = dev.build_url({'mode': 'ApiIndex2', 'api_url': 'default', 'type' : 'tv'}) dev.adddir('TV', url, description='Easily add pre-configured TV playlists from Youtubelibrary.nl. Available for Donors only at the moment. But you can still visit Youtubelibrary.nl to manually add them!') #Browse All Genres url = dev.build_url({'mode': 'ApiIndex2', 'api_url': 'default', 'type' : 'musicvideo'}) dev.adddir('Musicvideos', url, description='Easily add pre-configured Musicvideo playlists by Genre from Youtubelibrary.nl. Available for Donors only at the moment. But you can still visit Youtubelibrary.nl to manually add them!') #Browse By Tag url = dev.build_url({'mode': 'ApiIndex2', 'api_url': 'default', 'type' : 'movies'}) dev.adddir('Movies', url, description='Easily add pre-configured Movies playlists by Tag from Youtubelibrary.nl. Available for Donors only at the moment. But you can still visit Youtubelibrary.nl to manually add them!') xbmcplugin.endOfDirectory(vars.addon_handle)
def show_playlists_by_channel(Channelid, type='', pagetoken='default'): if pagetoken == 'default' or pagetoken == '': search_response = ytube.yt_get_channel_info(Channelid) #Grab the playlists from the response playlists = search_response['items'][0]['contentDetails']['relatedPlaylists'] # Go through each playlist and display the playlist for key, value in playlists.iteritems(): if value == 'WL' or value == 'HL': continue #The watch later and watch history playlists are not giving their normal id's, so skip them #Grab the number of videos to pl = ytube.yt_get_playlist_info(value) number_vids = str(pl['items'][0]['contentDetails']['itemCount']) #videos.append(search_result) url = dev.build_url({'mode': 'addPlaylist', 'id': value, 'type': type}) dev.adddir(key.capitalize()+' ('+number_vids+')', url, dev.playlist_highest_thumbnail(search_response['items'][0]), fanart=dev.playlist_highest_thumbnail(search_response['items'][0]), description=dev.lang(31010)+' '+dev.typeName(type)+' \n--------\nPlaylist Description:\n'+search_response['items'][0]['snippet']['description']) # Grab other playlists this user has created to response = ytube.yt_get_playlists_by_channel(Channelid, pagetoken) if isinstance(response['items'], list): # Go through each playlist and display the playlist for playlist in response['items']: #videos.append(search_result) title = playlist['snippet']['title']+' ('+str(playlist['contentDetails']['itemCount'])+')' url = dev.build_url({'mode': 'addPlaylist', 'id': playlist['id'], 'type': type}) dev.adddir(title, url, dev.playlist_highest_thumbnail(playlist), fanart= dev.playlist_highest_thumbnail(playlist), description=dev.lang(31010)+' '+dev.typeName(type)+' \n--------\nPlaylist Description:\n'+playlist['snippet']['description']) if 'prevPageToken' in response: if response['prevPageToken'] is not None: url = dev.build_url({'mode': 'pickedChannel', 'id': Channelid, 'type': type, 'pagetoken': response['prevPageToken']}) dev.adddir('<< Prev Page', url, description='Go to the previous page of available playlists') if 'nextPageToken' in response: if response['nextPageToken'] is not None: url = dev.build_url({'mode': 'pickedChannel', 'id': Channelid, 'type': type, 'pagetoken': response['nextPageToken']}) dev.adddir('Next Page >>', url, description='Go to the next page of available playlists') xbmcplugin.endOfDirectory(vars.addon_handle)#Adds a playlist & loads the view to edit it
def add_playlist(id, type=''): if type=='' or type=='tv': api_url = 'http://youtubelibrary.nl/api/v1/playlists/tv/'+id+'?api_token='+vars.__settings__.getSetting('api_token') if type=='musicvideo': api_url = 'http://youtubelibrary.nl/api/v1/playlists/musicvideos/'+id+'?api_token='+vars.__settings__.getSetting('api_token') if type=='movies': api_url = 'http://youtubelibrary.nl/api/v1/playlists/movies/'+id+'?api_token='+vars.__settings__.getSetting('api_token') dev.log('Adding the Api playlist to the config: '+api_url) data = json.load(urllib2.urlopen(api_url)) if 'data' not in data: url = dev.build_url({'mode': 'ApiIndex'}) dev.adddir('Something went wrong', url, description='There was an error getting the playlist from the youtubelibrary.nl API.') return False; playlist = data['data'] return playlist url = dev.build_url({'mode': 'ApiAddPlaylist', 'type': type}) dev.adddir(playlist['title'], url, description=playlist['description'])
def browse(api_url = 'default', params = False, type=''): if api_url == 'default': if type == '' or type == 'tv': api_url = 'http://youtubelibrary.nl/api/v1/playlists/tv'+build_url()+'&limit=20' if type == 'musicvideo': api_url = 'http://youtubelibrary.nl/api/v1/playlists/musicvideos'+build_url()+'&limit=20' if type == 'movies': api_url = 'http://youtubelibrary.nl/api/v1/playlists/movies'+build_url()+'&limit=20' #Check if we should add params if isinstance(params,dict): for key, val in params.iteritems(): api_url += '&'+key+'='+val dev.log('Browse the API with url: '+api_url) data = json.load(urllib2.urlopen(api_url)) if 'data' not in data: url = dev.build_url({'mode': 'ApiIndex'}) dev.adddir('Something went wrong', url, description='There was an error connecting to the Ytlibrary API.') return False; for playlist in data['data']: #videos.append(search_result) url = dev.build_url({'mode': 'ApiAddPlaylist', 'id': playlist['id'], 'type': type}) dev.adddir(playlist['title'], url, playlist['thumb'], fanart=playlist['fanart'], description=playlist['description']) if 'paginator' in data: if 'prev_page' in data['paginator']: if data['paginator']['prev_page'] is not None: url = dev.build_url({'mode': 'ApiBrowse', 'api_url': data['paginator']['prev_page'], 'type': type}) dev.adddir('<< Page '+str(data['paginator']['current_page']-1), url, description='Go to the previous page') if 'paginator' in data: if 'next_page' in data['paginator']: if data['paginator']['next_page'] is not None: url = dev.build_url({'mode': 'ApiBrowse', 'api_url': data['paginator']['next_page'], 'type': type}) dev.adddir('>> Page '+str(data['paginator']['current_page']+1), url, description='Go to the next page to see more pre-configured playlists.')
def browse_genres(api_url = 'default', type=''): if api_url == 'default': if type=='' or type == 'tv': api_url = 'http://youtubelibrary.nl/api/v1/genres/tv'+build_url() base_url = 'http://youtubelibrary.nl/api/v1/playlists/tv' if type=='musicvideo': api_url = 'http://youtubelibrary.nl/api/v1/genres/musicvideos'+build_url() base_url = 'http://youtubelibrary.nl/api/v1/playlists/musicvideos' if type=='movies': api_url = 'http://youtubelibrary.nl/api/v1/genres/movies'+build_url() base_url = 'http://youtubelibrary.nl/api/v1/playlists/movies' dev.log('Browse genres at the API with url: '+api_url) data = json.load(urllib2.urlopen(api_url)) if 'data' not in data: url = dev.build_url({'mode': 'ApiIndex'}) dev.adddir('Something went wrong', url, description='There was an error connecting to the Ytlibrary API.') return False; for genre in data['data']: #videos.append(search_result) url = dev.build_url({'mode': 'ApiBrowse', 'api_url': base_url+build_url()+'&limit=10&genre='+str(genre['id']), 'type': type}) dev.adddir(genre['title'], url, description='View all playlists from the genre '+genre['title']) if 'paginator' in data: if 'prev_page' in data['paginator']: if data['paginator']['prev_page'] is not None: url = dev.build_url({'mode': 'ApiGenres', 'api_url': data['paginator']['prev_page'], 'type': type}) dev.adddir('<< Page '+str(data['paginator']['current_page']-1), url, description='Go to the previous page') if 'paginator' in data: if 'next_page' in data['paginator']: if data['paginator']['next_page'] is not None: url = dev.build_url({'mode': 'ApiGenres', 'api_url': data['paginator']['next_page'], 'type': type}) dev.adddir('>> Page '+str(data['paginator']['current_page']+1), url, description='Go to the next page to see more genres of pre-configured playlists.')
def api_index(type=''): if vars.__settings__.getSetting('enable_donor') == 'false': xbmcgui.Dialog().ok(dev.lang(31991), dev.lang(31992)) elif len(vars.__settings__.getSetting('api_token')) < 60: xbmcgui.Dialog().ok(dev.lang(31993), dev.lang(31994)) else: import xbmcaddon #Browse All Playlists url = dev.build_url({'mode': 'ApiBrowse', 'api_url': 'default', 'type' : type}) dev.adddir('Browse All Playlists', url, description='Easily add pre-configured playlists from Youtubelibrary.nl. Available for Donors only at the moment. But you can still visit Youtubelibrary.nl to manually add them!') #Browse All Genres url = dev.build_url({'mode': 'ApiGenres', 'api_url': 'default', 'type' : type}) dev.adddir('Browse By Genre', url, description='Easily add pre-configured playlists by Genre from Youtubelibrary.nl. Available for Donors only at the moment. But you can still visit Youtubelibrary.nl to manually add them!') #Browse By Tag url = dev.build_url({'mode': 'ApiTags', 'api_url': 'default', 'type' : type}) dev.adddir('Browse By Tag', url, description='Easily add pre-configured playlists by Tag from Youtubelibrary.nl. Available for Donors only at the moment. But you can still visit Youtubelibrary.nl to manually add them!') #Search by Title / Description url = dev.build_url({'mode': 'ApiSearch', 'type' : type}) dev.adddir('Search by Title / Description', url, description='Search by title / description to add a pre-configured playlist from Youtubelibrary.nl. Available for Donors only at the moment. But you can still visit Youtubelibrary.nl to manually add them!') #Search by Channel url = dev.build_url({'mode': 'ApiSearchChannel', 'type' : type}) dev.adddir('Search by Channel', url, description='Search by channel name to add a pre-configured playlist from Youtubelibrary.nl. Available for Donors only at the moment. But you can still visit Youtubelibrary.nl to manually add them!') xbmcplugin.endOfDirectory(vars.addon_handle)
def searched_playlist(result, type='', pagetoken=''): response = ytube.search_playlist(result, type, pagetoken) if isinstance(response['items'], list): # Go through each playlist and display the playlist for playlist in response['items']: #videos.append(search_result) title = playlist['snippet']['title'] url = dev.build_url({'mode': 'addPlaylist', 'id': playlist['id']['playlistId'], 'type': type}) dev.adddir(title, url, dev.playlist_highest_thumbnail(playlist), fanart=dev.playlist_highest_thumbnail(playlist), description=dev.lang(31010)+' '+dev.typeName(type)+' \n--------\nPlaylist Description:\n'+playlist['snippet']['description']) if 'prevPageToken' in response: if response['prevPageToken'] is not None: url = dev.build_url({'mode': 'searchedplaylist', 'search': result, 'type': type, 'pagetoken': response['prevPageToken']}) dev.adddir('<< Prev Page', url, description='Go to the previous page of available playlists') if 'nextPageToken' in response: if response['nextPageToken'] is not None: url = dev.build_url({'mode': 'searchedplaylist', 'search': result, 'type': type, 'pagetoken': response['nextPageToken']}) dev.adddir('Next Page >>', url, description='Go to the next page of available playlists') xbmcplugin.endOfDirectory(vars.addon_handle)#Adds a playlist & loads the view to edit it
def disp_bool_setting(setting, title, description, level=0): #Is the mode in the addon settings high enough to display this setting? if level > vars.mode: return False #no #build url val = None if elem.find(setting) != None: val = elem.find(setting).text if val == 'true' or val == '1': val = '[COLOR green]ON[/COLOR]' else: val = '[COLOR red]OFF[/COLOR]' url = dev.build_url({'mode': 'editPlaylist', 'id': plid, 'set': setting, 'type': pltype}) dev.adddir('[COLOR blue]'+title+':[/COLOR] '+val, url, gear, fanart, description)
def search_channel(keyword, type=''): youtube = build_youtube() search_response = youtube.search().list( q=keyword, part="id,snippet", maxResults=50, type = "channel" ).execute() videos = [] for search_result in search_response.get("items", []): #videos.append(search_result) url = dev.build_url({'mode': 'pickedChannel', 'id': search_result['id']['channelId'], 'type': type, 'pagetoken': 'default'}) dev.adddir(search_result['snippet']['title'], url, search_result['snippet']['thumbnails']['high']['url'], fanart=search_result['snippet']['thumbnails']['high']['url'], description=search_result['snippet']['description'])
def disp_setting(setting, title, description, level=0): #Is the mode in the addon settings high enough to display this setting? if level > vars.mode: return False #no #build url val = None if elem.find(setting) != None: val = elem.find(setting).text if setting == 'published': d = ytube.convert_published(val) val = d['day']+'-'+d['month']+'-'+d['year'] if val == None or val == 'None': val = '' url = dev.build_url({'mode': 'editPlaylist', 'id': plid, 'set': setting, 'type': pltype}) if 'hardcoded' in title.lower() and 'genre hardcoded' not in title.lower() or 'fallback' in title.lower() and 'song fallback' not in title.lower(): dev.adddir('[COLOR blue] --'+title+':[/COLOR] '+val, url, gear, fanart, description) else: dev.adddir('[COLOR blue]'+title+':[/COLOR] '+val, url, gear, fanart, description)
def search_channel(keyword, type=''): youtube = build( vars.YOUTUBE_API_SERVICE_NAME, vars.YOUTUBE_API_VERSION, developerKey=vars.API_KEY ) search_response = youtube.search().list( q=keyword, part="id,snippet", maxResults=50, type = "channel" ).execute() videos = [] for search_result in search_response.get("items", []): #videos.append(search_result) url = dev.build_url({'mode': 'pickedChannel', 'id': search_result['id']['channelId'], 'type': type}) dev.adddir(search_result['snippet']['title'], url, search_result['snippet']['thumbnails']['high']['url'], fanart=search_result['snippet']['thumbnails']['high']['url'], description=search_result['snippet']['description'])
def search_channel(keyword, type=''): youtube = build_youtube() search_response = youtube.search().list(q=keyword, part="id,snippet", maxResults=50, type="channel").execute() videos = [] for search_result in search_response.get("items", []): #videos.append(search_result) url = dev.build_url({ 'mode': 'pickedChannel', 'id': search_result['id']['channelId'], 'type': type, 'pagetoken': 'default' }) dev.adddir( search_result['snippet']['title'], url, search_result['snippet']['thumbnails']['high']['url'], fanart=search_result['snippet']['thumbnails']['high']['url'], description=search_result['snippet']['description'])
def index_dir(): import xbmcaddon #Manage TV Playlists url = dev.build_url({'mode': 'folder', 'foldername': 'managePlaylists'}) context_url = dev.build_url({'mode': 'updateplaylists'}) commands = [] commands.append(( dev.lang(31003), 'XBMC.RunPlugin('+context_url+')', )) dev.adddir(dev.lang(31001), url, description=dev.lang(31002), context=commands) #Manage Music Video Playlists url = dev.build_url({'mode': 'folder', 'foldername': 'managePlaylists', 'type':'musicvideo'}) context_url = dev.build_url({'mode': 'updateplaylists', 'type':'musicvideo'}) commands = [] commands.append(( dev.lang(31003), 'XBMC.RunPlugin('+context_url+')', )) dev.adddir(dev.lang(31011), url, description=dev.lang(31012), context=commands) #Search TV Channel url = dev.build_url({'mode': 'folder', 'foldername': 'searchchannel'}) dev.adddir(dev.lang(31004), url, description=dev.lang(31005)) #Search Music Video Channel url = dev.build_url({'mode': 'folder', 'foldername': 'searchchannel', 'type': 'musicvideo'}) dev.adddir(dev.lang(31008), url, description=dev.lang(31009))
def editPlaylist(id, type=''): global plid #Make the plid global so disp_setting can reach it without calling it global elem #Make the elem global so disp_setting can reach it without calling it global fanart #Make fanart global so disp_setting can reach it without calling it global gear #Make gear global so disp_setting can reach it without calling it global pltype #make type global so disp_setting can reach it without calling it plid = id pltype = type dev.log('editPlaylist('+id+', '+type+')') #Loads the correct information from the settings.xml elem = m_xml.xml_get_elem('playlists/playlist', 'playlist', {'id': id}, type=type) if elem is None: #We could not find this playlist to edit! dev.log('Could not find playlist '+id+' ('+type+') to edit!') return False else: ''' Build the edit Playlist form ''' #Grab all art to be used with this playlist edit thumb = elem.find('thumb').text fanart = elem.find('fanart').text gear = dev.media('gear') #Return to home button url = dev.build_url({'home': 'home'}) dev.adddir('[COLOR white]Return to Main Menu[/COLOR]', url, dev.media('home'), fanart) #Edit playlist info url = dev.build_url({'mode': 'editPlaylist', 'id': id, 'type': type}) dev.adddir('[COLOR white]Editing Settings for playlist '+id+'[/COLOR]', url, thumb, fanart, 'This is the edit page for the playlist settings. Set this to your taste to have more control over things as which videos will be included or excluded') #Delete playlist url = dev.build_url({'mode': 'deletePlaylist', 'id': id, 'type': type}) dev.adddir('[COLOR red]Delete playlist[/COLOR]', url, dev.media('delete'), fanart, '<!> Careful! <!> This will delete all the settings from this playlist & this playlist will not be scanned into your library anymore') #Refresh playlist url = dev.build_url({'mode': 'refreshPlaylist', 'id': id, 'type': type}) dev.adddir('[COLOR red]Refresh playlist[/COLOR]', url, dev.media('delete'), fanart, '<!> Careful! <!> This will refresh all the episodes from this playlist. Only use this if previous episodes are not scanned properly due to wrong playlist settings.') #Build the Playlist enable/disable button depending on current state if elem.attrib['enabled'] == 'yes': url = dev.build_url({'mode': 'editPlaylist', 'id': id, 'set': 'enable', 'type': type}) dev.adddir('[COLOR green]Playlist is enabled[/COLOR]', url, thumb, fanart, 'The playlist is enabled. Disable it to stop the videos to be scanned into the Kodi Library. \n It is also a good idea to disable it if it only contains videos that wont be updated. That way you spare some precious computer resources.') else: url = dev.build_url({'mode': 'editPlaylist', 'id': id, 'set': 'enable', 'type': type}) dev.adddir('[COLOR red]Playlist is disabled![/COLOR]', url, thumb, fanart, 'The playlist is disabled, so you can change your settings before scanning into your Kodi Library. When you are done setting up this playlist, enable it so it gets scanned into the Kodi Library.') #Title extra_desc = '' if type == '' or type == 'tv': extra_desc = 'Kodi and' disp_setting('title', 'Title', 'The title as it will be displayed in '+extra_desc+' this Addon') #Description disp_setting('description', 'Description', 'The description as it will be displayed in '+extra_desc+' this Addon') #Tags disp_setting('tags', 'Tags', 'Tags for Kodi. For multiple tags use tag1 / tag2 / tag3 (note the space between each / )') disp_setting('download_videos', 'Download Videos', 'If enabled, YTlibrary will download the videos instead of saving stream files (.strm)') #Genres & Stuff if type == 'musicvideo': #Genres #disp_setting('genre', 'Genre', 'Genre Recognizition', 1) genre = elem.find('genre').text if genre != 'hardcoded' and genre != 'video title' and genre != 'playlist channelname' and genre != 'published year' and genre != 'video channelname' and genre != 'artist + published year' and genre != 'video description': disp_setting('genre_fallback', 'Genre Fallback', dev.lang(31900), 1) disp_setting('genre_hardcoded', 'Genre Hardcoded', dev.lang(31901)+' \n For multiple genres use genre1 / genre2 / genre3 (note the space between each / )') #Skip disp_bool_setting('skip_audio', 'Skip Audio Only', 'If enabled, tries to skip videos that are audio only') disp_bool_setting('skip_lyrics', 'Skip Lyrics', 'If enabled, tries to skip Lyric videos') disp_bool_setting('skip_live', 'Skip Live', 'If enabled, tries to skip Live videos') disp_bool_setting('skip_albums', 'Skip Albums', 'If enabled, tries to skip Album videos') #Song Fallback disp_setting('song_fallback', 'Song Fallback', 'Song Fallback', 1) #artists disp_setting('artist', 'artist', 'Artist Recognizition', 1) artist = elem.find('artist').text if artist != 'hardcoded' and artist != 'video title' and artist != 'playlist channelname' and artist != 'published year' and artist != 'video channelname' and artist != 'artist + published year' and artist != 'video description': disp_setting('artist_fallback', 'Artist Fallback', dev.lang(31900), 1) if elem.find('artist').text == 'hardcoded' or elem.find('artist_fallback').text == 'hardcoded': disp_setting('artist_hardcoded', 'Artist Hardcoded', dev.lang(31901)) #albums disp_setting('album', 'album', 'Album Recognizition', 1) album = elem.find('album').text if album != 'hardcoded' and album != 'video title' and album != 'playlist channelname' and album != 'published year' and album != 'video channelname' and album != 'artist + published year' and album != 'video description': disp_setting('album_fallback', 'album Fallback', dev.lang(31900), 1) if elem.find('album').text == 'hardcoded' or elem.find('album_fallback').text == 'hardcoded': disp_setting('album_hardcoded', 'album Hardcoded', dev.lang(31901)) #plots disp_setting('plot', 'plot', 'plot Recognizition', 1) plot = elem.find('plot').text if plot != 'hardcoded' and plot != 'video title' and plot != 'playlist channelname' and plot != 'published year' and plot != 'video channelname' and plot != 'artist + published year' and plot != 'video description': disp_setting('plot_fallback', 'plot Fallback', dev.lang(31900), 1) if elem.find('plot').text == 'hardcoded' or elem.find('plot_fallback').text == 'hardcoded': disp_setting('plot_hardcoded', 'plot Hardcoded', dev.lang(31901)) #years disp_setting('year', 'year', 'year Recognizition', 1) year = elem.find('year').text if year != 'hardcoded' and year != 'video title' and year != 'playlist channelname' and year != 'published year' and year != 'video channelname' and year != 'artist + published year' and year != 'video description': disp_setting('year_fallback', 'year Fallback', dev.lang(31900), 1) if elem.find('year').text == 'hardcoded' or elem.find('year_fallback').text == 'hardcoded': disp_setting('year_hardcoded', 'year Hardcoded', dev.lang(31901)) else: #Genre disp_setting('genre', 'Genre', 'Settings as displayed in Kodi. For multiple genres use genre1 / genre2 / genre3 (note the space between each / )') ###MOVIES if type == 'movies': disp_setting('set', dev.lang(30519), 'The set the movies will belong to in the Kodi library') if vars.mode > 1: #Expert mode disp_bool_setting('smart_search', dev.lang(30521), 'Use some smart filters to strip out must unwanted stuff from titles. Also try to guess info like Director and year in the process.') disp_setting('search_imdb', dev.lang(30504), 'Do you want to try to find a match on imdb? And if so, what to do if no match is found?') if vars.mode > 1: disp_setting('imdb_match_cutoff', dev.lang(30505), 'How much of a percentage does the title need to match the IMDB result?') disp_setting('use_ytimage', dev.lang(30520), 'In case of an IMDB match, would you still like to use the Youtube Image as the Poster image?') #Published if type == '' or type == 'tv': disp_setting('published', 'Published', 'The date the show first aired', 1) #WriteNFO if vars.mode > 0: disp_bool_setting('reverse', dev.lang(30522), 'Reverse this playlist? \n\r (Only use this if the playlist is sorted oldest->newest and you cant find a playlist sorted newest->oldest)') #Only get last X videos disp_setting('onlygrab', 'Grab last X videos', 'Instead of adding all old episodes, only add the last X episodes') disp_setting('updateevery', 'Update every', 'Update this playlist at a specific time interval or day') disp_setting('updateat', 'Update at', 'Update this playlist at a specific time if updateevery is set to a specific day. (This setting is ignored when "update every" is set to every X hours)') disp_setting('update_gmt', 'Timezone', 'Set the timezone for this playlist. YTlibrary will calculate the time to update according to the difference to your current timezone. (This setting is ignored when "update every" is set to every X hours)') url = dev.build_url({'mode': 'editPlaylist', 'id': id, 'set': 'writenfo', 'type': type}) dev.adddir('[COLOR blue]Write NFO:[/COLOR] '+elem.find('writenfo').text, url, gear, fanart, 'NFO Files are needed for Kodi to recognise the youtube episodes as episodes, so it can scan it in its library. If you only want strm files, set this to No') #Filters #Only include disp_setting('onlyinclude', 'Only Include', 'Only include videos containing the following text in the title. Placing words in between | will create an or. So review|trailer will only pick up videos with either review or trailer in its title') #Exclude words disp_setting('excludewords', 'Exclude', 'Excludes videos containing the following text in the title. Placing words in between | will create an or. So review|trailer will refuse videos with either review or trailer in its title') #Min Length disp_setting('minlength', 'Min length', 'Only include videos with this minimum length') #Max Length disp_setting('maxlength', 'Max length', 'Only include videos under this maximum length') #NFO Options if type == '' or type == 'tv': #Season recognisition setting description = """Set to [COLOR blue]year[/COLOR] to have the episode year upload date as its season. ------- [COLOR blue]s02e12[/COLOR] to grab the season/episode numbering as s02e12 from the title. ------- [COLOR blue]02x12[/COLOR] to grab the season/episode numbering as 02x12 from the title. ------- Set to a [COLOR blue]number[/COLOR] to have a hardcoded season for every season. ------- To find a season from the video title using a [COLOR blue]regex[/COLOR]. Please use regex(yourregexhere). If your regex fails to recognise a season it will fallback on calling it 0. """ disp_setting('season', 'Season recognisition', description) #Episode recognisition setting description = """'[COLOR blue]Default[/COLOR] will only number the episodes scanned in the library starting with 1 each season. ------ [COLOR blue]s02e12[/COLOR] to grab the season/episode numbering as s02e12 from the title. ------ [COLOR blue]02x12[/COLOR] to grab the season/episode numbering as 02x12 from the title. ------ [COLOR blue]monthday[/COLOR] to have the month & day upload date as its episode number. ------ [COLOR blue]pos[/COLOR] to have it use its playlist position as its episode number (Know that when videos are removed from the playlist, episode numbering may not be correct for episodes already scanned into the library). ------ Set to a [COLOR blue]number[/COLOR] to have a hardcoded episode for every episode. ------ Use [COLOR blue]regex[/COLOR] to type in a regular expression. Please use regex(yourregexhere). If your regex fails to recognise a episode it will fallback on calling it 0.' """ disp_setting('episode', 'Episode recognisition', description) if vars.mode > 0: #Normal mode or higher #Stripdescription disp_setting('stripdescription', 'Strip Description', 'Deletes every text in the description from and including the text filled in here. For instance, if a channel always has a long text in its description thats always the same, like: Check out our website (..). You fill that line in here, and only the part before that line will be included in the description of episodes. For multiple lines to scan for put them between |') #removedescription disp_setting('removedescription', 'Remove Description', 'Removes this line from the description of episodes.') #Striptitle disp_setting('striptitle', 'Strip Title', 'Same as stripdescription but for the title') #Removetitle disp_setting('removetitle', 'Remove Title', 'Same as removedescription but for the title') if vars.mode > 1: #Expert mode or higher #Overwritefolder disp_setting('overwritefolder', 'Folder', 'Use this directory to write the strm & nfo files to. If this is not filled in it will use the title as it will be displayed in the Addon and the Kodi Library')
def browse_tags(api_url='default', type=''): if api_url == 'default': if type == '' or type == 'tv': api_url = 'http://youtubelibrary.nl/api/v1/tags/tv' + build_url() base_url = 'http://youtubelibrary.nl/api/v1/playlists/tv' if type == 'musicvideo': api_url = 'http://youtubelibrary.nl/api/v1/tags/musicvideos' + build_url( ) base_url = 'http://youtubelibrary.nl/api/v1/playlists/musicvideos' if type == 'movies': api_url = 'http://youtubelibrary.nl/api/v1/tags/movies' + build_url( ) base_url = 'http://youtubelibrary.nl/api/v1/playlists/movies' dev.log('Browse tags at the API with url: ' + api_url) data = json.load(urllib2.urlopen(api_url)) if 'data' not in data: url = dev.build_url({'mode': 'ApiIndex'}) dev.adddir( 'Something went wrong', url, description='There was an error connecting to the Ytlibrary API.') return False for tag in data['data']: #videos.append(search_result) url = dev.build_url({ 'mode': 'ApiBrowse', 'api_url': base_url + build_url() + '&limit=10&tag=' + str(tag['id']), 'type': type }) dev.adddir(tag['title'], url, description='View all playlists from the tag ' + tag['title']) if 'paginator' in data: if 'prev_page' in data['paginator']: if data['paginator']['prev_page'] is not None: url = dev.build_url({ 'mode': 'ApiTags', 'api_url': data['paginator']['prev_page'], 'type': type }) dev.adddir('<< Page ' + str(data['paginator']['current_page'] - 1), url, description='Go to the previous page') if 'paginator' in data: if 'next_page' in data['paginator']: if data['paginator']['next_page'] is not None: url = dev.build_url({ 'mode': 'ApiTags', 'api_url': data['paginator']['next_page'], 'type': type }) dev.adddir( '>> Page ' + str(data['paginator']['current_page'] + 1), url, description= 'Go to the next page to see more tags of pre-configured playlists.' )
def browse(api_url='default', params=False, type=''): if api_url == 'default': if type == '' or type == 'tv': api_url = 'http://youtubelibrary.nl/api/v1/playlists/tv' + build_url( ) + '&limit=20' if type == 'musicvideo': api_url = 'http://youtubelibrary.nl/api/v1/playlists/musicvideos' + build_url( ) + '&limit=20' if type == 'movies': api_url = 'http://youtubelibrary.nl/api/v1/playlists/movies' + build_url( ) + '&limit=20' #Check if we should add params if isinstance(params, dict): for key, val in params.iteritems(): api_url += '&' + key + '=' + val dev.log('Browse the API with url: ' + api_url) data = json.load(urllib2.urlopen(api_url)) if 'data' not in data: url = dev.build_url({'mode': 'ApiIndex'}) dev.adddir( 'Something went wrong', url, description='There was an error connecting to the Ytlibrary API.') return False for playlist in data['data']: #videos.append(search_result) url = dev.build_url({ 'mode': 'ApiAddPlaylist', 'id': playlist['id'], 'type': type }) dev.adddir(playlist['title'], url, playlist['thumb'], fanart=playlist['fanart'], description=playlist['description']) if 'paginator' in data: if 'prev_page' in data['paginator']: if data['paginator']['prev_page'] is not None: url = dev.build_url({ 'mode': 'ApiBrowse', 'api_url': data['paginator']['prev_page'], 'type': type }) dev.adddir('<< Page ' + str(data['paginator']['current_page'] - 1), url, description='Go to the previous page') if 'paginator' in data: if 'next_page' in data['paginator']: if data['paginator']['next_page'] is not None: url = dev.build_url({ 'mode': 'ApiBrowse', 'api_url': data['paginator']['next_page'], 'type': type }) dev.adddir( '>> Page ' + str(data['paginator']['current_page'] + 1), url, description= 'Go to the next page to see more pre-configured playlists.' )
def index_dir(): import xbmcaddon #Manage TV Playlists #Separator url = dev.build_url({'mode': 'folder', 'foldername': 'index'}) dev.adddir( '[COLOR blue]-------------------' + dev.lang(31024) + '-------------------[/COLOR]', url, '') url = dev.build_url({'mode': 'folder', 'foldername': 'managePlaylists'}) context_url = dev.build_url({'mode': 'updateplaylists'}) commands = [] commands.append(( dev.lang(31003), 'XBMC.RunPlugin(' + context_url + ')', )) dev.adddir(dev.lang(31001), url, description=dev.lang(31002), context=commands) #Manage Music Video Playlists url = dev.build_url({ 'mode': 'folder', 'foldername': 'managePlaylists', 'type': 'musicvideo' }) context_url = dev.build_url({ 'mode': 'updateplaylists', 'type': 'musicvideo' }) commands = [] commands.append(( dev.lang(31003), 'XBMC.RunPlugin(' + context_url + ')', )) dev.adddir(dev.lang(31011), url, description=dev.lang(31012), context=commands) #Manage Movies Playlists url = dev.build_url({ 'mode': 'folder', 'foldername': 'managePlaylists', 'type': 'movies' }) context_url = dev.build_url({'mode': 'updateplaylists', 'type': 'movies'}) commands = [] commands.append(( dev.lang(31003), 'XBMC.RunPlugin(' + context_url + ')', )) dev.adddir(dev.lang(31022), url, description=dev.lang(31023), context=commands) #Separator url = dev.build_url({'mode': 'folder', 'foldername': 'index'}) dev.adddir( '[COLOR blue]-------------------' + dev.lang(31025) + '-------------------[/COLOR]', url, '') #Search TV Channel url = dev.build_url({'mode': 'folder', 'foldername': 'searchchannel'}) dev.adddir(dev.lang(31004), url, description=dev.lang(31005)) #Search TV Playlist url = dev.build_url({'mode': 'folder', 'foldername': 'searchplaylist'}) dev.adddir(dev.lang(31016), url, description=dev.lang(31017)) #Search Music Video Channel url = dev.build_url({ 'mode': 'folder', 'foldername': 'searchchannel', 'type': 'musicvideo' }) dev.adddir(dev.lang(31008), url, description=dev.lang(31009)) #Search Music Video Playlist url = dev.build_url({ 'mode': 'folder', 'foldername': 'searchplaylist', 'type': 'musicvideo' }) dev.adddir(dev.lang(31014), url, description=dev.lang(31015)) #Search Movie Channel url = dev.build_url({ 'mode': 'folder', 'foldername': 'searchchannel', 'type': 'movies' }) dev.adddir(dev.lang(31018), url, description=dev.lang(31019)) #Search Movie Playlist url = dev.build_url({ 'mode': 'folder', 'foldername': 'searchplaylist', 'type': 'movies' }) dev.adddir(dev.lang(31020), url, description=dev.lang(31021)) #Separator url = dev.build_url({'mode': 'folder', 'foldername': 'index'}) dev.adddir( '[COLOR blue]-------------------' + dev.lang(31026) + '-------------------[/COLOR]', url, '') #DONOR FUCNTION - Browse Playlists url = dev.build_url({'mode': 'ApiIndex', 'api_url': 'default'}) dev.adddir(dev.lang(31027), url, description=dev.lang(31028))
def api_index(type=''): if vars.__settings__.getSetting('enable_donor') == 'false': xbmcgui.Dialog().ok(dev.lang(31991), dev.lang(31992)) elif len(vars.__settings__.getSetting('api_token')) < 60: xbmcgui.Dialog().ok(dev.lang(31993), dev.lang(31994)) else: import xbmcaddon #Browse All Playlists url = dev.build_url({ 'mode': 'ApiBrowse', 'api_url': 'default', 'type': type }) dev.adddir( 'Browse All Playlists', url, description= 'Easily add pre-configured playlists from Youtubelibrary.nl. Available for Donors only at the moment. But you can still visit Youtubelibrary.nl to manually add them!' ) #Browse All Genres url = dev.build_url({ 'mode': 'ApiGenres', 'api_url': 'default', 'type': type }) dev.adddir( 'Browse By Genre', url, description= 'Easily add pre-configured playlists by Genre from Youtubelibrary.nl. Available for Donors only at the moment. But you can still visit Youtubelibrary.nl to manually add them!' ) #Browse By Tag url = dev.build_url({ 'mode': 'ApiTags', 'api_url': 'default', 'type': type }) dev.adddir( 'Browse By Tag', url, description= 'Easily add pre-configured playlists by Tag from Youtubelibrary.nl. Available for Donors only at the moment. But you can still visit Youtubelibrary.nl to manually add them!' ) #Search by Title / Description url = dev.build_url({'mode': 'ApiSearch', 'type': type}) dev.adddir( 'Search by Title / Description', url, description= 'Search by title / description to add a pre-configured playlist from Youtubelibrary.nl. Available for Donors only at the moment. But you can still visit Youtubelibrary.nl to manually add them!' ) #Search by Channel url = dev.build_url({'mode': 'ApiSearchChannel', 'type': type}) dev.adddir( 'Search by Channel', url, description= 'Search by channel name to add a pre-configured playlist from Youtubelibrary.nl. Available for Donors only at the moment. But you can still visit Youtubelibrary.nl to manually add them!' ) xbmcplugin.endOfDirectory(vars.addon_handle)
def index_dir(): import xbmcaddon #Manage TV Playlists #Separator url = dev.build_url({'mode': 'folder', 'foldername': 'index'}) dev.adddir('[COLOR blue]-------------------'+dev.lang(31024)+'-------------------[/COLOR]', url, '') url = dev.build_url({'mode': 'folder', 'foldername': 'managePlaylists'}) context_url = dev.build_url({'mode': 'updateplaylists'}) commands = [] commands.append(( dev.lang(31003), 'XBMC.RunPlugin('+context_url+')', )) dev.adddir(dev.lang(31001), url, description=dev.lang(31002), context=commands) #Manage Music Video Playlists url = dev.build_url({'mode': 'folder', 'foldername': 'managePlaylists', 'type':'musicvideo'}) context_url = dev.build_url({'mode': 'updateplaylists', 'type':'musicvideo'}) commands = [] commands.append(( dev.lang(31003), 'XBMC.RunPlugin('+context_url+')', )) dev.adddir(dev.lang(31011), url, description=dev.lang(31012), context=commands) #Manage Movies Playlists url = dev.build_url({'mode': 'folder', 'foldername': 'managePlaylists', 'type':'movies'}) context_url = dev.build_url({'mode': 'updateplaylists', 'type':'movies'}) commands = [] commands.append(( dev.lang(31003), 'XBMC.RunPlugin('+context_url+')', )) dev.adddir(dev.lang(31022), url, description=dev.lang(31023), context=commands) #Separator url = dev.build_url({'mode': 'folder', 'foldername': 'index'}) dev.adddir('[COLOR blue]-------------------'+dev.lang(31025)+'-------------------[/COLOR]', url, '') #Search TV Channel url = dev.build_url({'mode': 'folder', 'foldername': 'searchchannel'}) dev.adddir(dev.lang(31004), url, description=dev.lang(31005)) #Search TV Playlist url = dev.build_url({'mode': 'folder', 'foldername': 'searchplaylist'}) dev.adddir(dev.lang(31016), url, description=dev.lang(31017)) #Search Music Video Channel url = dev.build_url({'mode': 'folder', 'foldername': 'searchchannel', 'type': 'musicvideo'}) dev.adddir(dev.lang(31008), url, description=dev.lang(31009)) #Search Music Video Playlist url = dev.build_url({'mode': 'folder', 'foldername': 'searchplaylist', 'type': 'musicvideo'}) dev.adddir(dev.lang(31014), url, description=dev.lang(31015)) #Search Movie Channel url = dev.build_url({'mode': 'folder', 'foldername': 'searchchannel', 'type': 'movies'}) dev.adddir(dev.lang(31018), url, description=dev.lang(31019)) #Search Movie Playlist url = dev.build_url({'mode': 'folder', 'foldername': 'searchplaylist', 'type': 'movies'}) dev.adddir(dev.lang(31020), url, description=dev.lang(31021)) #Separator url = dev.build_url({'mode': 'folder', 'foldername': 'index'}) dev.adddir('[COLOR blue]-------------------'+dev.lang(31026)+'-------------------[/COLOR]', url, '') #DONOR FUCNTION - Browse Playlists url = dev.build_url({'mode': 'ApiIndex', 'api_url': 'default'}) dev.adddir(dev.lang(31027), url, description=dev.lang(31028))
def show_playlists_by_channel(Channelid, type='', pagetoken='default'): if pagetoken == 'default' or pagetoken == '': search_response = ytube.yt_get_channel_info(Channelid) #Grab the playlists from the response playlists = search_response['items'][0]['contentDetails'][ 'relatedPlaylists'] # Go through each playlist and display the playlist for key, value in playlists.iteritems(): if value == 'WL' or value == 'HL': continue #The watch later and watch history playlists are not giving their normal id's, so skip them #Grab the number of videos to pl = ytube.yt_get_playlist_info(value) number_vids = str(pl['items'][0]['contentDetails']['itemCount']) #videos.append(search_result) url = dev.build_url({ 'mode': 'addPlaylist', 'id': value, 'type': type }) dev.adddir(key.capitalize() + ' (' + number_vids + ')', url, dev.playlist_highest_thumbnail( search_response['items'][0]), fanart=dev.playlist_highest_thumbnail( search_response['items'][0]), description=dev.lang(31010) + ' ' + dev.typeName(type) + ' \n--------\nPlaylist Description:\n' + search_response['items'][0]['snippet']['description']) # Grab other playlists this user has created to response = ytube.yt_get_playlists_by_channel(Channelid, pagetoken) if isinstance(response['items'], list): # Go through each playlist and display the playlist for playlist in response['items']: #videos.append(search_result) title = playlist['snippet']['title'] + ' (' + str( playlist['contentDetails']['itemCount']) + ')' url = dev.build_url({ 'mode': 'addPlaylist', 'id': playlist['id'], 'type': type }) dev.adddir(title, url, dev.playlist_highest_thumbnail(playlist), fanart=dev.playlist_highest_thumbnail(playlist), description=dev.lang(31010) + ' ' + dev.typeName(type) + ' \n--------\nPlaylist Description:\n' + playlist['snippet']['description']) if 'prevPageToken' in response: if response['prevPageToken'] is not None: url = dev.build_url({ 'mode': 'pickedChannel', 'id': Channelid, 'type': type, 'pagetoken': response['prevPageToken'] }) dev.adddir( '<< Prev Page', url, description='Go to the previous page of available playlists') if 'nextPageToken' in response: if response['nextPageToken'] is not None: url = dev.build_url({ 'mode': 'pickedChannel', 'id': Channelid, 'type': type, 'pagetoken': response['nextPageToken'] }) dev.adddir( 'Next Page >>', url, description='Go to the next page of available playlists') xbmcplugin.endOfDirectory( vars.addon_handle) #Adds a playlist & loads the view to edit it
def editPlaylist(id, type=''): global plid #Make the plid global so disp_setting can reach it without calling it global elem #Make the elem global so disp_setting can reach it without calling it global fanart #Make fanart global so disp_setting can reach it without calling it global gear #Make gear global so disp_setting can reach it without calling it global pltype #make type global so disp_setting can reach it without calling it plid = id pltype = type dev.log('editPlaylist('+id+', '+type+')') #Loads the correct information from the settings.xml elem = m_xml.xml_get_elem('playlists/playlist', 'playlist', {'id': id}, type=type) if elem is None: #We could not find this playlist to edit! dev.log('Could not find playlist '+id+' ('+type+') to edit!') return False else: ''' Build the edit Playlist form ''' #Grab all art to be used with this playlist edit thumb = elem.find('thumb').text fanart = elem.find('fanart').text gear = dev.media('gear') #Return to home button url = dev.build_url({'home': 'home'}) dev.adddir('[COLOR white]Return to Main Menu[/COLOR]', url, dev.media('home'), fanart) #Edit playlist info url = dev.build_url({'mode': 'editPlaylist', 'id': id, 'type': type}) dev.adddir('[COLOR white]Editing Settings for playlist '+id+'[/COLOR]', url, thumb, fanart, 'This is the edit page for the playlist settings. Set this to your taste to have more control over things as which videos will be included or excluded') #Delete playlist url = dev.build_url({'mode': 'deletePlaylist', 'id': id, 'type': type}) dev.adddir('[COLOR red]Delete playlist[/COLOR]', url, dev.media('delete'), fanart, '<!> Careful! <!> This will delete all the settings from this playlist & this playlist will not be scanned into your library anymore') #Refresh playlist url = dev.build_url({'mode': 'refreshPlaylist', 'id': id, 'type': type}) dev.adddir('[COLOR red]Refresh playlist[/COLOR]', url, dev.media('delete'), fanart, '<!> Careful! <!> This will refresh all the episodes from this playlist. Only use this if previous episodes are not scanned properly due to wrong playlist settings.') #Build the Playlist enable/disable button depending on current state if elem.attrib['enabled'] == 'yes': url = dev.build_url({'mode': 'editPlaylist', 'id': id, 'set': 'enable', 'type': type}) dev.adddir('[COLOR green]Playlist is enabled[/COLOR]', url, thumb, fanart, 'The playlist is enabled. Disable it to stop the videos to be scanned into the Kodi Library. \n It is also a good idea to disable it if it only contains videos that wont be updated. That way you spare some precious computer resources.') else: url = dev.build_url({'mode': 'editPlaylist', 'id': id, 'set': 'enable', 'type': type}) dev.adddir('[COLOR red]Playlist is disabled![/COLOR]', url, thumb, fanart, 'The playlist is disabled, so you can change your settings before scanning into your Kodi Library. When you are done setting up this playlist, enable it so it gets scanned into the Kodi Library.') #Title extra_desc = '' if type == '' or type == 'tv': extra_desc = 'Kodi and' disp_setting('title', 'Title', 'The title as it will be displayed in '+extra_desc+' this Addon') #Description disp_setting('description', 'Description', 'The description as it will be displayed in '+extra_desc+' this Addon') #Tags disp_setting('tags', 'Tags', 'Tags for Kodi. For multiple tags use tag1 / tag2 / tag3 (note the space between each / )') #Genres & Stuff if type == 'musicvideo': #Genres #disp_setting('genre', 'Genre', 'Genre Recognizition', 1) genre = elem.find('genre').text if genre != 'hardcoded' and genre != 'video title' and genre != 'playlist channelname' and genre != 'published year' and genre != 'video channelname' and genre != 'artist + published year' and genre != 'video description': disp_setting('genre_fallback', 'Genre Fallback', dev.lang(31900), 1) disp_setting('genre_hardcoded', 'Genre Hardcoded', dev.lang(31901)+' \n For multiple genres use genre1 / genre2 / genre3 (note the space between each / )') #Skip disp_bool_setting('skip_audio', 'Skip Audio Only', 'If enabled, tries to skip videos that are audio only') disp_bool_setting('skip_lyrics', 'Skip Lyrics', 'If enabled, tries to skip Lyric videos') disp_bool_setting('skip_live', 'Skip Live', 'If enabled, tries to skip Live videos') disp_bool_setting('skip_albums', 'Skip Albums', 'If enabled, tries to skip Album videos') #Song Fallback disp_setting('song_fallback', 'Song Fallback', 'Song Fallback', 1) #artists disp_setting('artist', 'artist', 'Artist Recognizition', 1) artist = elem.find('artist').text if artist != 'hardcoded' and artist != 'video title' and artist != 'playlist channelname' and artist != 'published year' and artist != 'video channelname' and artist != 'artist + published year' and artist != 'video description': disp_setting('artist_fallback', 'Artist Fallback', dev.lang(31900), 1) if elem.find('artist').text == 'hardcoded' or elem.find('artist_fallback').text == 'hardcoded': disp_setting('artist_hardcoded', 'Artist Hardcoded', dev.lang(31901)) #albums disp_setting('album', 'album', 'Album Recognizition', 1) album = elem.find('album').text if album != 'hardcoded' and album != 'video title' and album != 'playlist channelname' and album != 'published year' and album != 'video channelname' and album != 'artist + published year' and album != 'video description': disp_setting('album_fallback', 'album Fallback', dev.lang(31900), 1) if elem.find('album').text == 'hardcoded' or elem.find('album_fallback').text == 'hardcoded': disp_setting('album_hardcoded', 'album Hardcoded', dev.lang(31901)) #plots disp_setting('plot', 'plot', 'plot Recognizition', 1) plot = elem.find('plot').text if plot != 'hardcoded' and plot != 'video title' and plot != 'playlist channelname' and plot != 'published year' and plot != 'video channelname' and plot != 'artist + published year' and plot != 'video description': disp_setting('plot_fallback', 'plot Fallback', dev.lang(31900), 1) if elem.find('plot').text == 'hardcoded' or elem.find('plot_fallback').text == 'hardcoded': disp_setting('plot_hardcoded', 'plot Hardcoded', dev.lang(31901)) #years disp_setting('year', 'year', 'year Recognizition', 1) year = elem.find('year').text if year != 'hardcoded' and year != 'video title' and year != 'playlist channelname' and year != 'published year' and year != 'video channelname' and year != 'artist + published year' and year != 'video description': disp_setting('year_fallback', 'year Fallback', dev.lang(31900), 1) if elem.find('year').text == 'hardcoded' or elem.find('year_fallback').text == 'hardcoded': disp_setting('year_hardcoded', 'year Hardcoded', dev.lang(31901)) else: #Genre disp_setting('genre', 'Genre', 'Settings as displayed in Kodi. For multiple genres use genre1 / genre2 / genre3 (note the space between each / )') ###MOVIES if type == 'movies': disp_setting('set', dev.lang(30519), 'The set the movies will belong to in the Kodi library') if vars.mode > 1: #Expert mode disp_bool_setting('smart_search', dev.lang(30521), 'Use some smart filters to strip out must unwanted stuff from titles. Also try to guess info like Director and year in the process.') disp_setting('search_imdb', dev.lang(30504), 'Do you want to try to find a match on imdb? And if so, what to do if no match is found?') if vars.mode > 1: disp_setting('imdb_match_cutoff', dev.lang(30505), 'How much of a percentage does the title need to match the IMDB result?') disp_setting('use_ytimage', dev.lang(30520), 'In case of an IMDB match, would you still like to use the Youtube Image as the Poster image?') #Published if type == '' or type == 'tv': disp_setting('published', 'Published', 'The date the show first aired', 1) #WriteNFO if vars.mode > 0: disp_bool_setting('reverse', dev.lang(30522), 'Reverse this playlist? \n\r (Only use this if the playlist is sorted oldest->newest and you cant find a playlist sorted newest->oldest)') #Only get last X videos disp_setting('onlygrab', 'Grab last X videos', 'Instead of adding all old episodes, only add the last X episodes') disp_setting('updateevery', 'Update every', 'Update this playlist at a specific time interval or day') disp_setting('updateat', 'Update at', 'Update this playlist at a specific time if updateevery is set to a specific day. (This setting is ignored when "update every" is set to every X hours)') disp_setting('update_gmt', 'Timezone', 'Set the timezone for this playlist. YTlibrary will calculate the time to update according to the difference to your current timezone. (This setting is ignored when "update every" is set to every X hours)') url = dev.build_url({'mode': 'editPlaylist', 'id': id, 'set': 'writenfo', 'type': type}) dev.adddir('[COLOR blue]Write NFO:[/COLOR] '+elem.find('writenfo').text, url, gear, fanart, 'NFO Files are needed for Kodi to recognise the youtube episodes as episodes, so it can scan it in its library. If you only want strm files, set this to No') #Filters #Only include disp_setting('onlyinclude', 'Only Include', 'Only include videos containing the following text in the title. Placing words in between | will create an or. So review|trailer will only pick up videos with either review or trailer in its title') #Exclude words disp_setting('excludewords', 'Exclude', 'Excludes videos containing the following text in the title. Placing words in between | will create an or. So review|trailer will refuse videos with either review or trailer in its title') #Min Length disp_setting('minlength', 'Min length', 'Only include videos with this minimum length') #Max Length disp_setting('maxlength', 'Max length', 'Only include videos under this maximum length') #NFO Options if type == '' or type == 'tv': #Season recognisition setting description = """Set to [COLOR blue]year[/COLOR] to have the episode year upload date as its season. ------- [COLOR blue]s02e12[/COLOR] to grab the season/episode numbering as s02e12 from the title. ------- [COLOR blue]02x12[/COLOR] to grab the season/episode numbering as 02x12 from the title. ------- Set to a [COLOR blue]number[/COLOR] to have a hardcoded season for every season. ------- To find a season from the video title using a [COLOR blue]regex[/COLOR]. Please use regex(yourregexhere). If your regex fails to recognise a season it will fallback on calling it 0. """ disp_setting('season', 'Season recognisition', description) #Episode recognisition setting description = """'[COLOR blue]Default[/COLOR] will only number the episodes scanned in the library starting with 1 each season. ------ [COLOR blue]s02e12[/COLOR] to grab the season/episode numbering as s02e12 from the title. ------ [COLOR blue]02x12[/COLOR] to grab the season/episode numbering as 02x12 from the title. ------ [COLOR blue]monthday[/COLOR] to have the month & day upload date as its episode number. ------ [COLOR blue]pos[/COLOR] to have it use its playlist position as its episode number (Know that when videos are removed from the playlist, episode numbering may not be correct for episodes already scanned into the library). ------ Set to a [COLOR blue]number[/COLOR] to have a hardcoded episode for every episode. ------ Use [COLOR blue]regex[/COLOR] to type in a regular expression. Please use regex(yourregexhere). If your regex fails to recognise a episode it will fallback on calling it 0.' """ disp_setting('episode', 'Episode recognisition', description) if vars.mode > 0: #Normal mode or higher #Stripdescription disp_setting('stripdescription', 'Strip Description', 'Deletes every text in the description from and including the text filled in here. For instance, if a channel always has a long text in its description thats always the same, like: Check out our website (..). You fill that line in here, and only the part before that line will be included in the description of episodes. For multiple lines to scan for put them between |') #removedescription disp_setting('removedescription', 'Remove Description', 'Removes this line from the description of episodes.') #Striptitle disp_setting('striptitle', 'Strip Title', 'Same as stripdescription but for the title') #Removetitle disp_setting('removetitle', 'Remove Title', 'Same as removedescription but for the title') if vars.mode > 1: #Expert mode or higher #Overwritefolder disp_setting('overwritefolder', 'Folder', 'Use this directory to write the strm & nfo files to. If this is not filled in it will use the title as it will be displayed in the Addon and the Kodi Library')
# ############################################################################## # ######################################### TESTS ################################## # ############################################################################## # ## REMUX TEST elif mode[0] == "remuxtest": dev.log('Mode is remuxtest'); id = "Ivp6hfbQnts" from resources.lib import pafy pafy.set_api_key(vars.API_KEY) #Resolve the youtube video url for ourselves v = pafy.new(id) url = dev.build_url({'mode': 'play', 'id': id}) dev.adddir(str(v.getbest()), url, description=v.getbest().url) url = dev.build_url({'mode': 'playtest', 'foldername': 'remux'}) dev.adddir(str(v.getbestvideo()), url, description=v.getbestvideo().url) dev.log('Remuxtest, best Video&Audio: '+str(v.getbest())); dev.log('Remuxtest, best Video: '+str(v.getbestvideo())); dev.log('Remuxtest, best Audio: '+str(v.getbestaudio())); xbmcplugin.endOfDirectory(vars.addon_handle) ##Playvidtest elif mode[0] == "striptest": dev.log('mode is striptest')