diff options
author | James Taylor <user234683@users.noreply.github.com> | 2021-02-25 15:55:23 -0800 |
---|---|---|
committer | Jesús <heckyel@hyperbola.info> | 2021-02-26 11:39:23 -0500 |
commit | 00ef1c862744ec00886bc3fa4b95fdfc6c151866 (patch) | |
tree | bac6025f0e09df7d1fc65665eaef429407bf1391 /youtube/comments.py | |
parent | f26c9be85e1ac78d30954b3aa38c119bef415579 (diff) | |
download | yt-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.py | 69 |
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: |