diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/invidious.cr | 5 | ||||
| -rw-r--r-- | src/invidious/comments.cr | 121 | ||||
| -rw-r--r-- | src/invidious/videos.cr | 8 |
3 files changed, 118 insertions, 16 deletions
diff --git a/src/invidious.cr b/src/invidious.cr index e97198d8..8494f9d9 100644 --- a/src/invidious.cr +++ b/src/invidious.cr @@ -2691,11 +2691,14 @@ get "/api/v1/comments/:id" do |env| format = env.params.query["format"]? format ||= "json" + sort_by = env.params.query["sort_by"]?.try &.downcase + sort_by ||= "top" + continuation = env.params.query["continuation"]? if source == "youtube" begin - comments = fetch_youtube_comments(id, PG_DB, continuation, proxies, format, locale, thin_mode, region) + comments = fetch_youtube_comments(id, PG_DB, continuation, proxies, format, locale, thin_mode, region, sort_by: sort_by) rescue ex error_message = {"error" => ex.message}.to_json env.response.status_code = 500 diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr index b5133cf2..aa3233d4 100644 --- a/src/invidious/comments.cr +++ b/src/invidious/comments.cr @@ -56,15 +56,14 @@ class RedditListing }) end -def fetch_youtube_comments(id, db, continuation, proxies, format, locale, thin_mode, region) +def fetch_youtube_comments(id, db, continuation, proxies, format, locale, thin_mode, region, sort_by = "top") video = get_video(id, db, proxies, region: region) - session_token = video.info["session_token"]? - itct = video.info["itct"]? - ctoken = video.info["ctoken"]? + + ctoken = produce_comment_continuation(id, cursor: "", sort_by: sort_by) continuation ||= ctoken - if !continuation || !itct || !session_token + if !continuation || !session_token if format == "json" return {"comments" => [] of String}.to_json else @@ -73,7 +72,7 @@ def fetch_youtube_comments(id, db, continuation, proxies, format, locale, thin_m end post_req = { - "session_token" => session_token.not_nil!, + "session_token" => session_token, } post_req = HTTP::Params.encode(post_req) @@ -90,7 +89,7 @@ def fetch_youtube_comments(id, db, continuation, proxies, format, locale, thin_m headers["x-youtube-client-name"] = "1" headers["x-youtube-client-version"] = "2.20180719" - response = client.post("/comment_service_ajax?action_get_comments=1&pbj=1&ctoken=#{continuation}&continuation=#{continuation}&itct=#{itct}&hl=en&gl=US", headers, post_req) + response = client.post("/comment_service_ajax?action_get_comments=1&ctoken=#{continuation}&continuation=#{continuation}&hl=en&gl=US", headers, post_req) response = JSON.parse(response.body) if !response["response"]["continuationContents"]? @@ -516,3 +515,111 @@ def content_to_comment_html(content) return comment_html end + +def produce_comment_continuation(video_id, cursor = "", sort_by = "top") + continuation = IO::Memory.new + + continuation.write(Bytes[0x12, 0x26]) + + continuation.write(Bytes[0x12, video_id.size]) + continuation.print(video_id) + + continuation.write(Bytes[0xc0, 0x01, 0x01]) + continuation.write(Bytes[0xc8, 0x01, 0x01]) + continuation.write(Bytes[0xe0, 0x01, 0x01]) + + continuation.write(Bytes[0xa2, 0x02, 0x0d]) + continuation.write(Bytes[0x28, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01]) + + continuation.write(Bytes[0x40, 0x00]) + continuation.write(Bytes[0x18, 0x06]) + + if cursor.empty? + continuation.write(Bytes[0x32]) + continuation.write(write_var_int(video_id.size + 8)) + + continuation.write(Bytes[0x22, video_id.size + 4]) + continuation.write(Bytes[0x22, video_id.size]) + continuation.print(video_id) + + case sort_by + when "top" + continuation.write(Bytes[0x30, 0x00]) + when "new", "newest" + continuation.write(Bytes[0x30, 0x01]) + end + + continuation.write(Bytes[0x78, 0x02]) + else + continuation.write(Bytes[0x32]) + continuation.write(write_var_int(cursor.size + video_id.size + 11)) + + continuation.write(Bytes[0x0a]) + continuation.write(write_var_int(cursor.size)) + continuation.print(cursor) + + continuation.write(Bytes[0x22, video_id.size + 4]) + continuation.write(Bytes[0x22, video_id.size]) + continuation.print(video_id) + + case sort_by + when "top" + continuation.write(Bytes[0x30, 0x00]) + when "new", "newest" + continuation.write(Bytes[0x30, 0x01]) + end + + continuation.write(Bytes[0x28, 0x14]) + end + + continuation.rewind + continuation = continuation.gets_to_end + + continuation = Base64.urlsafe_encode(continuation.to_slice) + continuation = URI.escape(continuation) + + return continuation +end + +def produce_comment_reply_continuation(video_id, ucid, comment_id) + continuation = IO::Memory.new + + continuation.write(Bytes[0x12, 0x26]) + + continuation.write(Bytes[0x12, video_id.size]) + continuation.print(video_id) + + continuation.write(Bytes[0xc0, 0x01, 0x01]) + continuation.write(Bytes[0xc8, 0x01, 0x01]) + continuation.write(Bytes[0xe0, 0x01, 0x01]) + + continuation.write(Bytes[0xa2, 0x02, 0x0d]) + continuation.write(Bytes[0x28, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01]) + + continuation.write(Bytes[0x40, 0x00]) + continuation.write(Bytes[0x18, 0x06]) + + continuation.write(Bytes[0x32, ucid.size + video_id.size + comment_id.size + 16]) + continuation.write(Bytes[0x1a, ucid.size + video_id.size + comment_id.size + 14]) + + continuation.write(Bytes[0x12, comment_id.size]) + continuation.print(comment_id) + + continuation.write(Bytes[0x22, 0x02, 0x08, 0x00]) # ?? + + continuation.write(Bytes[ucid.size + video_id.size + 7]) + continuation.write(Bytes[ucid.size]) + continuation.print(ucid) + continuation.write(Bytes[0x32, video_id.size]) + continuation.print(video_id) + continuation.write(Bytes[0x40, 0x01]) + continuation.write(Bytes[0x48, 0x0a]) + + continuation.rewind + continuation = continuation.gets_to_end + + continuation = Base64.urlsafe_encode(continuation.to_slice) + continuation = URI.escape(continuation) + + return continuation +end diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr index 856b6447..3887277a 100644 --- a/src/invidious/videos.cr +++ b/src/invidious/videos.cr @@ -608,14 +608,6 @@ def extract_player_config(body, html) params["session_token"] = md["session_token"] end - if md = body.match(/itct=(?<itct>[^"]+)"/) - params["itct"] = md["itct"] - end - - if md = body.match(/'COMMENTS_TOKEN': "(?<ctoken>[^"]+)"/) - params["ctoken"] = md["ctoken"] - end - if md = body.match(/'RELATED_PLAYER_ARGS': (?<rvs>{"rvs":"[^"]+"})/) params["rvs"] = JSON.parse(md["rvs"])["rvs"].as_s end |
