mirror of
https://github.com/iv-org/invidious.git
synced 2025-06-28 01:28:30 +00:00
Merge 7b8bc8f68a
into df8839d1f0
This commit is contained in:
commit
5d9e7c1c0f
@ -3,8 +3,8 @@ private IMAGE_QUALITIES = {320, 560, 640, 1280, 2000}
|
|||||||
# TODO: Add "sort_by"
|
# TODO: Add "sort_by"
|
||||||
def fetch_channel_community(ucid, cursor, locale, format, thin_mode)
|
def fetch_channel_community(ucid, cursor, locale, format, thin_mode)
|
||||||
if cursor.nil?
|
if cursor.nil?
|
||||||
# Egljb21tdW5pdHk%3D is the protobuf object to load "community"
|
# EgVwb3N0c_IGBAoCSgA%3D is the protobuf object to load "posts"
|
||||||
initial_data = YoutubeAPI.browse(ucid, params: "Egljb21tdW5pdHk%3D")
|
initial_data = YoutubeAPI.browse(ucid, params: "EgVwb3N0c_IGBAoCSgA%3D")
|
||||||
|
|
||||||
items = [] of JSON::Any
|
items = [] of JSON::Any
|
||||||
extract_items(initial_data) do |item|
|
extract_items(initial_data) do |item|
|
||||||
@ -24,15 +24,21 @@ def fetch_channel_community(ucid, cursor, locale, format, thin_mode)
|
|||||||
return extract_channel_community(items, ucid: ucid, locale: locale, format: format, thin_mode: thin_mode)
|
return extract_channel_community(items, ucid: ucid, locale: locale, format: format, thin_mode: thin_mode)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def decode_ucid_from_post_protobuf(params)
|
||||||
|
decoded_protobuf = params.try { |i| URI.decode_www_form(i) }
|
||||||
|
.try { |i| Base64.decode(i) }
|
||||||
|
.try { |i| IO::Memory.new(i) }
|
||||||
|
.try { |i| Protodec::Any.parse(i) }
|
||||||
|
|
||||||
|
return decoded_protobuf.try(&.["56:0:embedded"]["2:0:string"].as_s)
|
||||||
|
end
|
||||||
|
|
||||||
def fetch_channel_community_post(ucid, post_id, locale, format, thin_mode)
|
def fetch_channel_community_post(ucid, post_id, locale, format, thin_mode)
|
||||||
object = {
|
object = {
|
||||||
"2:string" => "community",
|
"56:embedded" => {
|
||||||
"25:embedded" => {
|
"2:string" => ucid,
|
||||||
"22:string" => post_id.to_s,
|
"3:string" => post_id.to_s,
|
||||||
},
|
"11:string" => ucid,
|
||||||
"45:embedded" => {
|
|
||||||
"2:varint" => 1_i64,
|
|
||||||
"3:varint" => 1_i64,
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
params = object.try { |i| Protodec::Any.cast_json(i) }
|
params = object.try { |i| Protodec::Any.cast_json(i) }
|
||||||
@ -40,7 +46,7 @@ def fetch_channel_community_post(ucid, post_id, locale, format, thin_mode)
|
|||||||
.try { |i| Base64.urlsafe_encode(i) }
|
.try { |i| Base64.urlsafe_encode(i) }
|
||||||
.try { |i| URI.encode_www_form(i) }
|
.try { |i| URI.encode_www_form(i) }
|
||||||
|
|
||||||
initial_data = YoutubeAPI.browse(ucid, params: params)
|
initial_data = YoutubeAPI.browse("FEpost_detail", params: params)
|
||||||
|
|
||||||
items = [] of JSON::Any
|
items = [] of JSON::Any
|
||||||
extract_items(initial_data) do |item|
|
extract_items(initial_data) do |item|
|
||||||
|
@ -16,34 +16,40 @@ module Invidious::Comments
|
|||||||
return parse_youtube(id, response, format, locale, thin_mode, sort_by)
|
return parse_youtube(id, response, format, locale, thin_mode, sort_by)
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch_community_post_comments(ucid, post_id)
|
def fetch_community_post_comments(ucid, post_id, sort_by = "top")
|
||||||
object = {
|
object = {
|
||||||
"2:string" => "community",
|
"2:string" => "posts",
|
||||||
"25:embedded" => {
|
|
||||||
"22:string" => post_id,
|
|
||||||
},
|
|
||||||
"45:embedded" => {
|
|
||||||
"2:varint" => 1_i64,
|
|
||||||
"3:varint" => 1_i64,
|
|
||||||
},
|
|
||||||
"53:embedded" => {
|
"53:embedded" => {
|
||||||
"4:embedded" => {
|
"4:embedded" => {
|
||||||
"6:varint" => 0_i64,
|
"6:varint" => 0_i64,
|
||||||
"27:varint" => 1_i64,
|
"15:varint" => 2_i64,
|
||||||
|
"25:varint" => 0_i64,
|
||||||
"29:string" => post_id,
|
"29:string" => post_id,
|
||||||
"30:string" => ucid,
|
"30:string" => ucid,
|
||||||
},
|
},
|
||||||
|
"7:varint" => 0_i64,
|
||||||
"8:string" => "comments-section",
|
"8:string" => "comments-section",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case sort_by
|
||||||
|
when "top"
|
||||||
|
sort_by_val = 0_i64
|
||||||
|
when "new", "newest"
|
||||||
|
sort_by_val = 1_i64
|
||||||
|
else # top
|
||||||
|
sort_by_val = 0_i64
|
||||||
|
end
|
||||||
|
|
||||||
|
object["53:embedded"].as(Hash)["4:embedded"].as(Hash)["6:varint"] = sort_by_val
|
||||||
|
|
||||||
object_parsed = object.try { |i| Protodec::Any.cast_json(i) }
|
object_parsed = object.try { |i| Protodec::Any.cast_json(i) }
|
||||||
.try { |i| Protodec::Any.from_json(i) }
|
.try { |i| Protodec::Any.from_json(i) }
|
||||||
.try { |i| Base64.urlsafe_encode(i) }
|
.try { |i| Base64.urlsafe_encode(i) }
|
||||||
|
|
||||||
object2 = {
|
object2 = {
|
||||||
"80226972:embedded" => {
|
"80226972:embedded" => {
|
||||||
"2:string" => ucid,
|
"2:string" => "FEcomment_post_detail_page_web_top_level",
|
||||||
"3:string" => object_parsed,
|
"3:string" => object_parsed,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -436,7 +436,7 @@ module Invidious::Routes::API::V1::Channels
|
|||||||
if ucid.nil?
|
if ucid.nil?
|
||||||
response = YoutubeAPI.resolve_url("https://www.youtube.com/post/#{id}")
|
response = YoutubeAPI.resolve_url("https://www.youtube.com/post/#{id}")
|
||||||
return error_json(400, "Invalid post ID") if response["error"]?
|
return error_json(400, "Invalid post ID") if response["error"]?
|
||||||
ucid = response.dig("endpoint", "browseEndpoint", "browseId").as_s
|
ucid = decode_ucid_from_post_protobuf(response.dig("endpoint", "browseEndpoint", "params").as_s)
|
||||||
else
|
else
|
||||||
ucid = ucid.to_s
|
ucid = ucid.to_s
|
||||||
end
|
end
|
||||||
@ -460,13 +460,15 @@ module Invidious::Routes::API::V1::Channels
|
|||||||
|
|
||||||
format = env.params.query["format"]?
|
format = env.params.query["format"]?
|
||||||
format ||= "json"
|
format ||= "json"
|
||||||
|
sort_by = env.params.query["sort_by"]?.try &.downcase
|
||||||
|
sort_by ||= "top"
|
||||||
|
|
||||||
continuation = env.params.query["continuation"]?
|
continuation = env.params.query["continuation"]?
|
||||||
|
|
||||||
case continuation
|
case continuation
|
||||||
when nil, ""
|
when nil, ""
|
||||||
ucid = env.params.query["ucid"]
|
ucid = env.params.query["ucid"]
|
||||||
comments = Comments.fetch_community_post_comments(ucid, id)
|
comments = Comments.fetch_community_post_comments(ucid, id, sort_by: sort_by)
|
||||||
else
|
else
|
||||||
comments = YoutubeAPI.browse(continuation: continuation)
|
comments = YoutubeAPI.browse(continuation: continuation)
|
||||||
end
|
end
|
||||||
|
@ -190,15 +190,30 @@ module Invidious::Routes::API::V1::Misc
|
|||||||
|
|
||||||
sub_endpoint = endpoint["watchEndpoint"]? || endpoint["browseEndpoint"]? || endpoint
|
sub_endpoint = endpoint["watchEndpoint"]? || endpoint["browseEndpoint"]? || endpoint
|
||||||
params = sub_endpoint.try &.dig?("params")
|
params = sub_endpoint.try &.dig?("params")
|
||||||
|
|
||||||
|
if sub_endpoint["browseId"]?.try &.as_s == "FEpost_detail"
|
||||||
|
decoded_protobuf = params.try &.as_s.try { |i| URI.decode_www_form(i) }
|
||||||
|
.try { |i| Base64.decode(i) }
|
||||||
|
.try { |i| IO::Memory.new(i) }
|
||||||
|
.try { |i| Protodec::Any.parse(i) }
|
||||||
|
|
||||||
|
ucid = decoded_protobuf.try(&.["56:0:embedded"]["2:0:string"].as_s)
|
||||||
|
post_id = decoded_protobuf.try(&.["56:0:embedded"]["3:1:string"].as_s)
|
||||||
|
else
|
||||||
|
ucid = sub_endpoint["browseId"]? if sub_endpoint["browseId"]? && sub_endpoint["browseId"]?.try &.as_s.starts_with? "UC"
|
||||||
|
post_id = nil
|
||||||
|
end
|
||||||
rescue ex
|
rescue ex
|
||||||
return error_json(500, ex)
|
return error_json(500, ex)
|
||||||
end
|
end
|
||||||
JSON.build do |json|
|
JSON.build do |json|
|
||||||
json.object do
|
json.object do
|
||||||
json.field "ucid", sub_endpoint["browseId"].as_s if sub_endpoint["browseId"]?
|
json.field "browseId", sub_endpoint["browseId"].as_s if sub_endpoint["browseId"]?
|
||||||
|
json.field "ucid", ucid if ucid != nil
|
||||||
json.field "videoId", sub_endpoint["videoId"].as_s if sub_endpoint["videoId"]?
|
json.field "videoId", sub_endpoint["videoId"].as_s if sub_endpoint["videoId"]?
|
||||||
json.field "playlistId", sub_endpoint["playlistId"].as_s if sub_endpoint["playlistId"]?
|
json.field "playlistId", sub_endpoint["playlistId"].as_s if sub_endpoint["playlistId"]?
|
||||||
json.field "startTimeSeconds", sub_endpoint["startTimeSeconds"].as_i if sub_endpoint["startTimeSeconds"]?
|
json.field "startTimeSeconds", sub_endpoint["startTimeSeconds"].as_i if sub_endpoint["startTimeSeconds"]?
|
||||||
|
json.field "postId", post_id if post_id != nil
|
||||||
json.field "params", params.try &.as_s
|
json.field "params", params.try &.as_s
|
||||||
json.field "pageType", page_type
|
json.field "pageType", page_type
|
||||||
end
|
end
|
||||||
|
@ -284,7 +284,7 @@ module Invidious::Routes::Channels
|
|||||||
response = YoutubeAPI.resolve_url("https://www.youtube.com/post/#{id}")
|
response = YoutubeAPI.resolve_url("https://www.youtube.com/post/#{id}")
|
||||||
return error_template(400, "Invalid post ID") if response["error"]?
|
return error_template(400, "Invalid post ID") if response["error"]?
|
||||||
|
|
||||||
ucid = response.dig("endpoint", "browseEndpoint", "browseId").as_s
|
ucid = decode_ucid_from_post_protobuf(response.dig("endpoint", "browseEndpoint", "params").as_s)
|
||||||
post_response = fetch_channel_community_post(ucid, id, locale, "json", thin_mode)
|
post_response = fetch_channel_community_post(ucid, id, locale, "json", thin_mode)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user