def __parse_music(fullscan, playlist_id, page_token=None, update=False): __logger('Getting info for playlist: ' + playlist_id) url = "https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=50&playlistId=" + playlist_id + "&key=" + addon.getSetting( 'API_key') reply = c_download(url) last_video_id = 'Nevergonnagiveyouup' while True: reply = c_download(url) vid = [] totalResults = int(reply['pageInfo']['totalResults']) if addon.getSetting('toggle_import_limit') == 'true': totalResults = min(int(reply['pageInfo']['totalResults']), int(addon.getSetting('import_limit'))) if (PARSER['total_steps'] == 0): PARSER['total_steps'] = int(totalResults * 4) PARSER['total'] = totalResults if PARSER['steps'] < 1 and LOCAL_CONF['update'] == False: PDIALOG.create(AddonString(30016), AddonString(30025)) try: if 'last_video' in CONFIG['music_videos'][ reply['items'][0]['snippet']['channelId']]: last_video_id = CONFIG['music_videos'][reply['items'][0][ 'snippet']['channelId']]['last_video']['video_id'] except KeyError: pass __logger('no previous scan found') for item in reply['items']: if LOCAL_CONF['update'] == False and PDIALOG.iscanceled(): return season = int( item['snippet']['publishedAt'].split('T')[0].split('-')[0]) VIDEOS.append(item) PARSER['items'] += 1 PARSER['steps'] += 1 if item['snippet']['resourceId']['videoId'] == last_video_id: break vid.append(item['snippet']['resourceId']['videoId']) if LOCAL_CONF['update'] == False: # There seems to be a problem with \n and progress dialog in leia # so let's not use it in leia.... if PY_V >= 3: # "Downloading channel info" dialog_string = AddonString(30016) + str( PARSER['items']) + '/' + str(PARSER['total']) else: dialog_string = AddonString(30016) + str( PARSER['items']) + '/' + str(PARSER['total']) PDIALOG.update( int(100 * PARSER['steps'] / PARSER['total_steps']), dialog_string) __get_video_details(vid) if 'nextPageToken' not in reply or not fullscan or PARSER[ 'items'] >= PARSER['total']: break page_token = reply['nextPageToken'] url = "https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=50&playlistId=" + playlist_id + "&pageToken=" + page_token + "&key=" + addon.getSetting( 'API_key') if len(VIDEOS) > 0: __render('music')
def __search(query,search_type='tv'): del SEARCH_QUERY[:] channel_url = "https://www.googleapis.com/youtube/v3/search?type=channel&part=id,snippet&maxResults=10&q="+query+"&key="+addon.getSetting('API_key') reply = c_download(channel_url) try: if 'error' in reply: e_reason=reply['error']['errors'][0]['reason'] e_message=reply['error']['errors'][0]['message'] if e_reason == 'quotaExceeded': e_message = "The request cannot be completed because you have exceeded your quota.Quota resets in :\n\n"+ convert(__get_token_reset(),'text') __print(e_message) raise SystemExit(" error") except NameError: pass if not 'items' in reply: __print(30015) raise SystemExit(" error") for item in reply['items']: data={} data['title'] = item['snippet']['title'] data['id'] = item['snippet']['channelId'] data['description'] = item['snippet']['description'] data['thumbnail'] = item['snippet']['thumbnails']['high']['url'] SEARCH_QUERY.append(data) __folders('search', search_type)
def __get_video_details(array): x = [array[i:i + 50] for i in range(0, len(array), 50)] for stacks in x: get = ','.join(stacks) url = "https://www.googleapis.com/youtube/v3/videos?part=contentDetails&id=" + get + "&key=" + addon.getSetting( 'API_key') reply = c_download(url) for item in reply['items']: VIDEO_DURATION[item['id']] = __yt_duration( item['contentDetails']['duration']) PARSER['steps'] += 1
def __get_playlists(channel_id): playlist_dict = {} channel_url = 'https://www.googleapis.com/youtube/v3/playlists?part=contentDetails,id,snippet&maxResults=50&channelId=' + channel_id + "&key=" + addon.getSetting( 'API_key') while True: reply = c_download(channel_url) if len(playlist_dict) == 0: playlist_dict = reply else: playlist_dict['items'].extend(reply['items']) if 'nextPageToken' not in reply: break else: page_token = reply['nextPageToken'] channel_url = 'https://www.googleapis.com/youtube/v3/playlists?part=contentDetails,id,snippet&maxResults=50&channelId=' + channel_id + "&pageToken=" + page_token + "&key=" + addon.getSetting( 'API_key') return playlist_dict
def __add_music(channel_id): data = {} channel_url = "https://www.googleapis.com/youtube/v3/channels?part=brandingSettings,contentDetails,contentOwnerDetails,id,localizations,snippet,statistics,status,topicDetails&id=" + channel_id + "&key=" + addon.getSetting( 'API_key') reply = c_download(channel_url) if 'items' not in reply: __print(AddonString(30015)) #No Such channel return "no such channel" data['channel_id'] = channel_id data['title'] = reply['items'][0]['brandingSettings']['channel']['title'] if 'description' in reply['items'][0]['brandingSettings']['channel']: data['plot'] = reply['items'][0]['brandingSettings']['channel'][ 'description'] else: data['plot'] = data['title'] data['aired'] = reply['items'][0]['snippet']['publishedAt'] if 'high' in reply['items'][0]['snippet']['thumbnails']: data['thumb'] = reply['items'][0]['snippet']['thumbnails']['high'][ 'url'] else: data['thumb'] = reply['items'][0]['snippet']['thumbnails']['default'][ 'url'] # data['banner'] = reply['items'][0]['brandingSettings']['image']['bannerImageUrl'] # if 'bannerTvHighImageUrl' in reply['items'][0]['brandingSettings']['image']: # data['fanart'] = reply['items'][0]['brandingSettings']['image']['bannerTvHighImageUrl'] # else: # data['fanart'] = reply['items'][0]['brandingSettings']['image']['bannerImageUrl'] data['banner'] = data['thumb'] data['fanart'] = data['thumb'] uploads = reply['items'][0]['contentDetails']['relatedPlaylists'][ 'uploads'] xbmcvfs.mkdirs(MUSIC_VIDEOS + '\\' + data['channel_id']) if channel_id not in CONFIG['music_videos']: CONFIG['music_videos'][channel_id] = {} CONFIG['music_videos'][channel_id]['channel_name'] = data['title'] CONFIG['music_videos'][channel_id]['branding'] = {} CONFIG['music_videos'][channel_id]['branding']['thumbnail'] = data['thumb'] CONFIG['music_videos'][channel_id]['branding']['fanart'] = data['fanart'] CONFIG['music_videos'][channel_id]['branding']['banner'] = data['banner'] CONFIG['music_videos'][channel_id]['branding']['description'] = data[ 'plot'] CONFIG['music_videos'][channel_id]['playlist_id'] = uploads __save() __parse_music(True, uploads, None)
def __add_channel_playlist(channel_id): if 'playlists' not in CONFIG: CONFIG['playlists'] = {} data = {} custom_uuid = 'PL_' + uuid.uuid4().hex channel_url = "https://www.googleapis.com/youtube/v3/channels?part=brandingSettings,contentDetails,contentOwnerDetails,id,localizations,snippet,statistics,status,topicDetails&id=" + channel_id + "&key=" + addon.getSetting( 'API_key') reply = c_download(channel_url) if 'items' not in reply: __print(AddonString(30015)) #No Such channel return "no such channel" playlists = __get_playlists(channel_id) data_set = __select_playlists(playlists) data['channel_id_original'] = channel_id data['channel_id'] = custom_uuid data['title'] = data_set['title'] if 'description' in reply['items'][0]['brandingSettings']['channel']: data['plot'] = reply['items'][0]['brandingSettings']['channel'][ 'description'] else: data['plot'] = data['title'] data['aired'] = reply['items'][0]['snippet']['publishedAt'] if 'high' in reply['items'][0]['snippet']['thumbnails']: data['thumb'] = reply['items'][0]['snippet']['thumbnails']['high'][ 'url'] else: data['thumb'] = reply['items'][0]['snippet']['thumbnails']['default'][ 'url'] data['banner'] = data['thumb'] # # #reply['items'][0]['brandingSettings']['image']['bannerImageUrl'] #if 'bannerTvHighImageUrl' in reply['items'][0]['brandingSettings']['image']: # data['fanart'] = data['thumb'] # #reply['items'][0]['brandingSettings']['image']['bannerTvHighImageUrl'] #else: # data['fanart'] = data['thumb'] # reply['items'][0]['brandingSettings']['image']['bannerImageUrl'] data['fanart'] = data['thumb'] data['banner'] = data['thumb'] uploads = data_set['items'] data['uploader_stripped'] = re.sub(r'[^\w\s]', '', data['title']).replace(" ", "_") xbmcvfs.mkdirs(CHANNELS + '\\' + data['channel_id']) if custom_uuid not in CONFIG['playlists']: CONFIG['playlists'][custom_uuid] = {} CONFIG['playlists'][custom_uuid]['channel_name'] = data['title'] CONFIG['playlists'][custom_uuid][ 'channel_type'] = 'series' #temporarily until music videos and movies are implemented CONFIG['playlists'][custom_uuid]['branding'] = {} CONFIG['playlists'][custom_uuid]['branding']['thumbnail'] = data['thumb'] CONFIG['playlists'][custom_uuid]['branding']['fanart'] = data['fanart'] CONFIG['playlists'][custom_uuid]['branding']['banner'] = data['banner'] CONFIG['playlists'][custom_uuid]['branding']['description'] = data['plot'] CONFIG['playlists'][custom_uuid]['original_channel_id'] = channel_id CONFIG['playlists'][custom_uuid]['playlist_id'] = uploads output = u""" <?xml version="1.0" encoding="UTF-8" standalone="yes" ?>\n <tvshow> <title>{title}</title> <showtitle>{title}</showtitle> <plot>{plot}</plot> <genre>None</genre> <premiered>{aired}</premiered> <aired>{aired}</aired> <studio>{title}</studio> <thumb>{thumb}</thumb> <thumb aspect="poster">{fanart}</thumb> <thumb aspect="banner">{banner}</thumb> <fanart> <thumb>{fanart}</thumb> </fanart> <tag>Youtube</tag> </tvshow> """.format(**data) tvshow_file = CHANNELS + '\\' + data['channel_id'] + '\\' + 'tvshow.nfo' if PY_V >= 3: with xbmcvfs.File(tvshow_file, 'w') as f: result = f.write(output) else: f = xbmcvfs.File(tvshow_file, 'w') # Python 2 result = f.write(bytearray(output.encode('utf-8'))) # f.close() local_index_file = CHANNELS + '\\' + data['channel_id'] + '\\index.json' if xbmcvfs.exists(index_file) == False: __save(data=[], file=local_index_file) __save() __parse_playlists(True, uploads, custom_uuid, None)
def __parse_uploads(fullscan, playlist_id, page_token=None, update=False): __logger('Getting info for playlist: ' + playlist_id) url = "https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=50&playlistId=" + playlist_id + "&key=" + addon.getSetting( 'API_key') reply = c_download(url) last_video_id = 'Nevergonnagiveyouup' while True: reply = c_download(url) vid = [] totalResults = int(reply['pageInfo']['totalResults']) if addon.getSetting('toggle_import_limit') == 'true': totalResults = min(int(reply['pageInfo']['totalResults']), int(addon.getSetting('import_limit'))) if (PARSER['total_steps'] == 0): PARSER['total_steps'] = int(totalResults * 4) PARSER['total'] = totalResults # needed because of changes to folder structure as it now uses channel id for folder name # instead of stripped down channel name (no need to worry about non ASCII characters.) if not xbmcvfs.exists(CHANNELS + '\\' + reply['items'][0]['snippet']['channelId'] + '\\' + 'tvshow.nfo'): success = __add_channel(reply['items'][0]['snippet']['channelId'], 'just_the_info') __logger('great success') if PARSER['steps'] < 1 and LOCAL_CONF['update'] == False: PDIALOG.create(AddonString(30016), AddonString(30025)) try: if 'last_video' in CONFIG['channels'][reply['items'][0]['snippet'] ['channelId']]: last_video_id = CONFIG['channels'][reply['items'][0][ 'snippet']['channelId']]['last_video']['video_id'] except KeyError: __logger('no previous scan found') for item in reply['items']: if LOCAL_CONF['update'] == False and PDIALOG.iscanceled(): return season = int( item['snippet']['publishedAt'].split('T')[0].split('-')[0]) VIDEOS.append(item) PARSER['items'] += 1 PARSER['steps'] += 1 item_vid = item['snippet']['resourceId']['videoId'] if item_vid == last_video_id: break if item_vid in INDEX: break vid.append(item['snippet']['resourceId']['videoId']) INDEX.append(item['snippet']['resourceId']['videoId']) if LOCAL_CONF['update'] == False: # There seems to be a problem with \n and progress dialog in leia # so let's not use it in leia.... if PY_V >= 3: # "Downloading channel info" dialog_string = AddonString(30016) + str( PARSER['items']) + '/' + str( PARSER['total']) + '\n' + AddonString(30017) + str( season) else: dialog_string = AddonString(30016) + str( PARSER['items']) + '/' + str( PARSER['total']) + ' ' + AddonString( 30017) + str(season) PDIALOG.update( int(100 * PARSER['steps'] / PARSER['total_steps']), dialog_string) __get_video_details(vid) if 'nextPageToken' not in reply or not fullscan or PARSER[ 'items'] >= PARSER['total']: break page_token = reply['nextPageToken'] url = "https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=50&playlistId=" + playlist_id + "&pageToken=" + page_token + "&key=" + addon.getSetting( 'API_key') if len(VIDEOS) > 0: __render('tv')
def __parse_playlists(fullscan, playlists, channel_id, page_token=None, update=False): local_index_file = CHANNELS + '\\' + channel_id + '\\index.json' if xbmcvfs.exists(local_index_file): if PY_V >= 3: with xbmcvfs.File(local_index_file) as f: # PYTHON 3 v19+ LOCAL_INDEX = json.load(f) # else: f = xbmcvfs.File(local_index_file) # PYTHON 2 v18+ LOCAL_INDEX = json.loads(f.read()) f.close() else: LOCAL_INDEX = [] __logger(playlists) for enum, playlist_id in enumerate(playlists): __logger('Getting info for playlist: ' + playlist_id) url = "https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=50&playlistId=" + playlist_id + "&key=" + addon.getSetting( 'API_key') #reply = c_download(url) last_video_id = 'Nevergonnagiveyouup' while True: PARSER['items'] = 0 reply = c_download(url) vid = [] totalResults = int(reply['pageInfo']['totalResults']) if addon.getSetting('toggle_import_limit') == 'true': totalResults = min(int(reply['pageInfo']['totalResults']), int(addon.getSetting('import_limit'))) if (PARSER['total_steps'] == 0): PARSER['total_steps'] = int(totalResults * 4) PARSER['total'] = totalResults if PARSER['steps'] < 1 and LOCAL_CONF['update'] == False: PDIALOG.create(AddonString(30016), AddonString(30025)) for item in reply['items']: if LOCAL_CONF['update'] == False and PDIALOG.iscanceled(): return season = int( item['snippet']['publishedAt'].split('T')[0].split('-')[0]) item['snippet']['channelId'] = channel_id item['snippet']['channelId'] = channel_id PARSER['items'] += 1 PARSER['steps'] += 1 item_vid = item['snippet']['resourceId']['videoId'] if item_vid in INDEX: break VIDEOS.append(item) vid.append(item['snippet']['resourceId']['videoId']) INDEX.append(item['snippet']['resourceId']['videoId']) if LOCAL_CONF['update'] == False: # There seems to be a problem with \n and progress dialog in leia # so let's not use it in leia.... if PY_V >= 3: # "Downloading channel info" dialog_string = AddonString(30051) + str( enum) + '/' + str(len( playlists)) + '\n' + AddonString(30046) + str( PARSER['items']) + '/' + str( PARSER['total']) + '\n' + AddonString( 30017) + str(season) else: dialog_string = AddonString(30051) + str( enum ) + '/' + str( len(playlists) ) + ' ' + AddonString( 30046) + str(PARSER['items']) + '/' + str( PARSER['total']) + ' ' + AddonString( 30017) + str(season) PDIALOG.update( int(100 * PARSER['steps'] / PARSER['total_steps']), dialog_string) __get_video_details(vid) if 'nextPageToken' not in reply or not fullscan or PARSER[ 'items'] >= PARSER['total']: break page_token = reply['nextPageToken'] url = "https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=50&playlistId=" + playlist_id + "&pageToken=" + page_token + "&key=" + addon.getSetting( 'API_key') if len(VIDEOS) > 0: __render('tv_playlist')