aboutsummaryrefslogtreecommitdiffstats
path: root/youtube/comments.py
diff options
context:
space:
mode:
authorJames Taylor <user234683@users.noreply.github.com>2021-02-25 15:55:23 -0800
committerJesús <heckyel@hyperbola.info>2021-02-26 11:39:23 -0500
commit00ef1c862744ec00886bc3fa4b95fdfc6c151866 (patch)
treebac6025f0e09df7d1fc65665eaef429407bf1391 /youtube/comments.py
parentf26c9be85e1ac78d30954b3aa38c119bef415579 (diff)
downloadyt-local-00ef1c862744ec00886bc3fa4b95fdfc6c151866.tar.lz
yt-local-00ef1c862744ec00886bc3fa4b95fdfc6c151866.tar.xz
yt-local-00ef1c862744ec00886bc3fa4b95fdfc6c151866.zip
Fix comment replies
Comment reply protobuf now requires the channel id of the uploader of the video. Otherwise the endpoint returns 500. Instead of making the protobuf ourselves and passing this data around through query parameters, just use the ctoken provided to us but modify the max_replies field from 10 to 250. Fixes #53 Signed-off-by: Jesús <heckyel@hyperbola.info>
Diffstat (limited to 'youtube/comments.py')
-rw-r--r--youtube/comments.py69
1 files changed, 30 insertions, 39 deletions
diff --git a/youtube/comments.py b/youtube/comments.py
index 8ab2b2c..66b5353 100644
--- a/youtube/comments.py
+++ b/youtube/comments.py
@@ -33,8 +33,8 @@ def make_comment_ctoken(video_id, sort=0, offset=0, lc='', secret_key=''):
video_id = proto.as_bytes(video_id)
secret_key = proto.as_bytes(secret_key)
- page_info = proto.string(4, video_id) + proto.uint(6, sort)
+ page_info = proto.string(4,video_id) + proto.uint(6, sort)
offset_information = proto.nested(4, page_info) + proto.uint(5, offset)
if secret_key:
offset_information = proto.string(1, secret_key) + offset_information
@@ -47,15 +47,6 @@ def make_comment_ctoken(video_id, sort=0, offset=0, lc='', secret_key=''):
return base64.urlsafe_b64encode(result).decode('ascii')
-def comment_replies_ctoken(video_id, comment_id, max_results=500):
-
- params = proto.string(2, comment_id) + proto.uint(9, max_results)
- params = proto.nested(3, params)
-
- result = proto.nested(2, proto.string(2, video_id)) + proto.uint(3, 6) + proto.nested(6, params)
- return base64.urlsafe_b64encode(result).decode('ascii')
-
-
mobile_headers = {
'User-Agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1',
'Accept': '*/*',
@@ -66,10 +57,11 @@ mobile_headers = {
def request_comments(ctoken, replies=False):
- if replies: # let's make it use different urls for no reason despite all the data being encoded
- base_url = "https://m.youtube.com/watch_comment?action_get_comment_replies=1&ctoken="
+ base_url = 'https://m.youtube.com/watch_comment?'
+ if replies:
+ base_url += 'action_get_comment_replies=1&ctoken='
else:
- base_url = "https://m.youtube.com/watch_comment?action_get_comments=1&ctoken="
+ base_url += 'action_get_comments=1&ctoken='
url = base_url + ctoken.replace("=", "%3D") + "&pbj=1"
content = util.fetch_url(
@@ -99,17 +91,24 @@ def post_process_comments_info(comments_info):
comment['permalink'] = concat_or_none(
util.URL_ORIGIN, '/watch?v=',
- comments_info['video_id'], '&lc=', comment['id'])
+ comments_info['video_id'],
+ '&lc=', comment['id']
+ )
reply_count = comment['reply_count']
-
- if reply_count == 0:
- comment['replies_url'] = None
- else:
- comment['replies_url'] = concat_or_none(
- util.URL_ORIGIN,
- '/comments?parent_id=', comment['id'],
- '&video_id=', comments_info['video_id'])
+ comment['replies_url'] = None
+ if comment['reply_ctoken']:
+ # change max_replies field to 250 in ctoken
+ ctoken = comment['reply_ctoken']
+ ctoken, err = proto.set_protobuf_value(
+ ctoken,
+ 'base64p', 6, 3, 9, value=250)
+ if err:
+ print('Error setting ctoken value:')
+ print(err)
+ comment['replies_url'] = None
+ comment['replies_url'] = concat_or_none(util.URL_ORIGIN,
+ '/comments?replies=1&ctoken=' + ctoken)
if reply_count == 0:
comment['view_replies_text'] = 'Reply'
@@ -118,6 +117,7 @@ def post_process_comments_info(comments_info):
else:
comment['view_replies_text'] = str(reply_count) + ' replies'
+
if comment['like_count'] == 1:
comment['likes_text'] = '1 like'
else:
@@ -125,10 +125,12 @@ def post_process_comments_info(comments_info):
comments_info['include_avatars'] = settings.enable_comment_avatars
if comments_info['ctoken']:
+ replies_param = '&replies=1' if comments_info['is_replies'] else ''
comments_info['more_comments_url'] = concat_or_none(
util.URL_ORIGIN,
'/comments?ctoken=',
- comments_info['ctoken']
+ comments_info['ctoken'],
+ replies_param
)
comments_info['page_number'] = page_number = str(int(comments_info['offset']/20) + 1)
@@ -137,14 +139,11 @@ def post_process_comments_info(comments_info):
comments_info['sort_text'] = 'top' if comments_info['sort'] == 0 else 'newest'
comments_info['video_url'] = concat_or_none(
- util.URL_ORIGIN,
- '/watch?v=',
- comments_info['video_id']
- )
-
+ util.URL_ORIGIN, '/watch?v=', comments_info['video_id'])
comments_info['video_thumbnail'] = concat_or_none(
settings.img_prefix, 'https://i.ytimg.com/vi/',
- comments_info['video_id'], '/mqdefault.jpg')
+ comments_info['video_id'], '/mqdefault.jpg'
+ )
def video_comments(video_id, sort=0, offset=0, lc='', secret_key=''):
@@ -198,17 +197,9 @@ def video_comments(video_id, sort=0, offset=0, lc='', secret_key=''):
@yt_app.route('/comments')
def get_comments_page():
ctoken = request.args.get('ctoken', '')
- replies = False
- if not ctoken:
- video_id = request.args['video_id']
- parent_id = request.args['parent_id']
-
- ctoken = comment_replies_ctoken(video_id, parent_id)
- replies = True
-
- comments_info = yt_data_extract.extract_comments_info(
- request_comments(ctoken, replies))
+ replies = request.args.get('replies', '0') == '1'
+ comments_info = yt_data_extract.extract_comments_info(request_comments(ctoken, replies))
post_process_comments_info(comments_info)
if not replies: