From 43679efff5c44c41e7e8c6ca46da145becbe7c03 Mon Sep 17 00:00:00 2001
From: James Taylor <user234683@users.noreply.github.com>
Date: Thu, 17 Dec 2020 13:46:29 -0800
Subject: channel: replace page #s w/ next page button using provided ctoken
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Since yt doesn't accept page #'s when sorting by oldest

Signed-off-by: Jesús <heckyel@hyperbola.info>
---
 youtube/channel.py                         | 28 +++++++++++-----------------
 youtube/templates/channel.html             |  6 +++++-
 youtube/templates/common_elements.html     | 14 ++++++++++++++
 youtube/yt_data_extract/everything_else.py |  2 ++
 4 files changed, 32 insertions(+), 18 deletions(-)

(limited to 'youtube')

diff --git a/youtube/channel.py b/youtube/channel.py
index 97afa6e..eed3253 100644
--- a/youtube/channel.py
+++ b/youtube/channel.py
@@ -113,26 +113,18 @@ def channel_ctoken_v1(channel_id, page, sort, tab, view=1):
     return base64.urlsafe_b64encode(pointless_nest).decode('ascii')
 
 
-def get_channel_tab(channel_id, page="1", sort=3, tab='videos', view=1, print_status=True):
+def get_channel_tab(channel_id, page="1", sort=3, tab='videos', view=1,
+                    ctoken=None, print_status=True):
     message = 'Got channel tab' if print_status else None
 
-    if int(sort) == 2 and int(page) > 1:
-        ctoken = channel_ctoken_v1(channel_id, page, sort, tab, view)
-        ctoken = ctoken.replace('=', '%3D')
-        url = ('https://www.youtube.com/channel/' + channel_id + '/' + tab
-            + '?action_continuation=1&continuation=' + ctoken
-            + '&pbj=1')
-        content = util.fetch_url(
-            url, headers_desktop + real_cookie,
-            debug_name='channel_tab', report_text=message)
-    else:
+    if not ctoken:
         ctoken = channel_ctoken_v3(channel_id, page, sort, tab, view)
         ctoken = ctoken.replace('=', '%3D')
-        url = 'https://www.youtube.com/browse_ajax?ctoken=' + ctoken
-        content = util.fetch_url(
-            url,
-            headers_desktop + generic_cookie,
-            debug_name='channel_tab', report_text=message)
+    url = 'https://www.youtube.com/browse_ajax?ctoken=' + ctoken
+    content = util.fetch_url(
+        url,
+        headers_desktop + generic_cookie,
+        debug_name='channel_tab', report_text=message)
 
     return content
 
@@ -220,11 +212,13 @@ def get_channel_page_general_url(base_url, tab, request, channel_id=None):
     sort = request.args.get('sort', '3')
     view = request.args.get('view', '1')
     query = request.args.get('query', '')
+    ctoken = request.args.get('ctoken', '')
 
     if tab == 'videos' and channel_id:
         tasks = (
             gevent.spawn(get_number_of_videos_channel, channel_id),
-            gevent.spawn(get_channel_tab, channel_id, page_number, sort, 'videos', view)
+            gevent.spawn(get_channel_tab, channel_id, page_number, sort,
+                         'videos', view, ctoken)
         )
         gevent.joinall(tasks)
         util.check_gevent_exceptions(*tasks)
diff --git a/youtube/templates/channel.html b/youtube/templates/channel.html
index 780b651..252d017 100644
--- a/youtube/templates/channel.html
+++ b/youtube/templates/channel.html
@@ -105,7 +105,11 @@
         <hr/>
 
         <footer class="pagination-container">
-            {% if current_tab == 'videos' %}
+            {% if current_tab == 'videos' and current_sort.__str__() == '2' %}
+                <nav class="next-previous-button-row">
+                    {{ common_elements.next_previous_ctoken_buttons(None, ctoken, channel_url + '/' + current_tab, parameters_dictionary) }}
+                </nav>
+            {% elif current_tab == 'videos' %}
                 <nav class="pagination-list">
                     {{ common_elements.page_buttons(number_of_pages, channel_url + '/' + current_tab, parameters_dictionary, include_ends=(current_sort.__str__() == '3')) }}
                 </nav>
diff --git a/youtube/templates/common_elements.html b/youtube/templates/common_elements.html
index 9ccafeb..3c36157 100644
--- a/youtube/templates/common_elements.html
+++ b/youtube/templates/common_elements.html
@@ -112,4 +112,18 @@
             {% set _ = parameters_dictionary.__setitem__('page', current_page + 1) %}
             <a class="page-link next-page" href="{{ url + '?' + parameters_dictionary|urlencode }}">Next page</a>
     {% endif %}
+
+    {% macro next_previous_ctoken_buttons(prev_ctoken, next_ctoken, url, parameters_dictionary) %}
+        {% set parameters_dictionary = parameters_dictionary.to_dict() %}
+
+    {% if prev_ctoken %}
+        {% set _ = parameters_dictionary.__setitem__('ctoken', prev_ctoken) %}
+        <a class="page-link previous-page" href="{{ url + '?' + parameters_dictionary|urlencode }}">Previous page</a>
+    {% endif %}
+
+    {% if next_ctoken %}
+        {% set _ = parameters_dictionary.__setitem__('ctoken', next_ctoken) %}
+        <a class="page-link next-page" href="{{ url + '?' + parameters_dictionary|urlencode }}">Next page</a>
+    {% endif %}
+    {% endmacro %}
 {% endmacro %}
diff --git a/youtube/yt_data_extract/everything_else.py b/youtube/yt_data_extract/everything_else.py
index b4b612d..ae8715f 100644
--- a/youtube/yt_data_extract/everything_else.py
+++ b/youtube/yt_data_extract/everything_else.py
@@ -66,6 +66,7 @@ def extract_channel_info(polymer_json, tab):
 
     # get items
     info['items'] = []
+    info['ctoken'] = None
 
     # empty channel
     if 'contents' not in response and 'continuationContents' not in response:
@@ -75,6 +76,7 @@ def extract_channel_info(polymer_json, tab):
         items, ctoken = extract_items(response)
         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':
             info['is_last_page'] = (ctoken is None)
     elif tab == 'about':
-- 
cgit v1.2.3