From e549b5f67c4beff421a2b2b36f3b5031bfe8ed88 Mon Sep 17 00:00:00 2001 From: James Taylor Date: Fri, 5 Mar 2021 23:27:31 -0800 Subject: Channel: Allow going to next pages of playlists page MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Uses previous and next buttons. Now can view more than just first page of playlists page Signed-off-by: Jesús --- youtube/channel.py | 6 +++++- youtube/templates/channel.html | 7 ++++++- youtube/yt_data_extract/common.py | 8 ++++++++ youtube/yt_data_extract/everything_else.py | 2 +- 4 files changed, 20 insertions(+), 3 deletions(-) diff --git a/youtube/channel.py b/youtube/channel.py index 00e1cf9..69092d3 100644 --- a/youtube/channel.py +++ b/youtube/channel.py @@ -280,8 +280,11 @@ def get_channel_page_general_url(base_url, tab, request, channel_id=None): number_of_videos, polymer_json = tasks[0].value, tasks[1].value elif tab == 'about': polymer_json = util.fetch_url(base_url + '/about?pbj=1', headers_desktop, debug_name='gen_channel_about') - elif tab == 'playlists': + elif tab == 'playlists' and page_number == 1: polymer_json = util.fetch_url(base_url+ '/playlists?pbj=1&view=1&sort=' + playlist_sort_codes[sort], headers_desktop, debug_name='gen_channel_playlists') + elif tab == 'playlists': + polymer_json = get_channel_tab(channel_id, page_number, sort, + 'playlists', view) elif tab == 'search' and channel_id: polymer_json = get_channel_search_json(channel_id, query, page_number) elif tab == 'search': @@ -304,6 +307,7 @@ def get_channel_page_general_url(base_url, tab, request, channel_id=None): elif tab == 'search': info['search_box_value'] = query info['header_playlist_names'] = local_playlist.get_playlist_names() + if tab in ('search', 'playlists'): info['page_number'] = page_number info['subscribed'] = subscriptions.is_subscribed(info['channel_id']) diff --git a/youtube/templates/channel.html b/youtube/templates/channel.html index 252d017..294f1df 100644 --- a/youtube/templates/channel.html +++ b/youtube/templates/channel.html @@ -78,6 +78,11 @@
{{ number_of_videos }} videos
{% elif current_tab == 'playlists' %} {% set sorts = [('2', 'oldest'), ('3', 'newest'), ('4', 'last video added')] %} + {% if items %} +

Page {{ page_number }}

+ {% else %} +

No items

+ {% endif %} {% elif current_tab == 'search' %} {% if items %}

Page {{ page_number }}

@@ -113,7 +118,7 @@ - {% elif current_tab == 'search' %} + {% elif current_tab == 'playlists' or current_tab == 'search' %} diff --git a/youtube/yt_data_extract/common.py b/youtube/yt_data_extract/common.py index 57a84ed..2b394e6 100644 --- a/youtube/yt_data_extract/common.py +++ b/youtube/yt_data_extract/common.py @@ -450,6 +450,14 @@ def extract_items_from_renderer(renderer, item_types=_item_types): if key in item_types: items.append(renderer) + # ctoken sometimes placed in these renderers, e.g. channel playlists + elif key == 'continuationItemRenderer': + cont = deep_get( + value, 'continuationEndpoint', 'continuationCommand', 'token' + ) + if cont: + ctoken = cont + # has a list in it, add it to the iter stack elif get_nested_renderer_list_function(key): renderer_list, cont = get_nested_renderer_list_function(key)(value) diff --git a/youtube/yt_data_extract/everything_else.py b/youtube/yt_data_extract/everything_else.py index 197cf88..f9c47cb 100644 --- a/youtube/yt_data_extract/everything_else.py +++ b/youtube/yt_data_extract/everything_else.py @@ -77,7 +77,7 @@ def extract_channel_info(polymer_json, tab): additional_info = {'author': info['channel_name'], 'author_url': info['channel_url']} info['items'] = [extract_item_info(renderer, additional_info) for renderer in items] info['ctoken'] = ctoken - if tab == 'search': + if tab in ('search', 'playlists'): info['is_last_page'] = (ctoken is None) elif tab == 'about': items, _ = extract_items(response, item_types={'channelAboutFullMetadataRenderer'}) -- cgit v1.2.3