Add filters to '/api/v1/search' endpoint
This commit is contained in:
parent
3f0c823798
commit
3ada6a9234
@ -2569,14 +2569,44 @@ get "/api/v1/search" do |env|
|
|||||||
page = env.params.query["page"]?.try &.to_i?
|
page = env.params.query["page"]?.try &.to_i?
|
||||||
page ||= 1
|
page ||= 1
|
||||||
|
|
||||||
|
sort_by = env.params.query["sort_by"]?.try &.downcase
|
||||||
|
sort_by ||= "relevance"
|
||||||
|
|
||||||
|
date = env.params.query["date"]?.try &.downcase
|
||||||
|
date ||= ""
|
||||||
|
|
||||||
|
duration = env.params.query["date"]?.try &.downcase
|
||||||
|
duration ||= ""
|
||||||
|
|
||||||
|
features = env.params.query["features"]?.try &.split(",").map { |feature| feature.downcase }
|
||||||
|
features ||= [] of String
|
||||||
|
|
||||||
|
# TODO: Support other content types
|
||||||
|
content_type = "video"
|
||||||
|
|
||||||
|
begin
|
||||||
|
search_params = build_search_params(sort_by, date, content_type, duration, features)
|
||||||
|
rescue ex
|
||||||
|
env.response.content_type = "application/json"
|
||||||
|
next JSON.build do |json|
|
||||||
|
json.object do
|
||||||
|
json.field "error", ex.message
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
client = make_client(YT_URL)
|
client = make_client(YT_URL)
|
||||||
html = client.get("/results?q=#{URI.escape(query)}&page=#{page}&sp=EgIQAVAU&disable_polymer=1").body
|
html = client.get("/results?q=#{URI.escape(query)}&page=#{page}&sp=#{search_params}&disable_polymer=1").body
|
||||||
html = XML.parse_html(html)
|
html = XML.parse_html(html)
|
||||||
|
|
||||||
results = JSON.build do |json|
|
results = JSON.build do |json|
|
||||||
json.array do
|
json.array do
|
||||||
html.xpath_nodes(%q(//ol[@class="item-section"]/li)).each do |node|
|
html.xpath_nodes(%q(//ol[@class="item-section"]/li)).each do |node|
|
||||||
anchor = node.xpath_node(%q(.//h3[contains(@class,"yt-lockup-title")]/a)).not_nil!
|
anchor = node.xpath_node(%q(.//h3[contains(@class,"yt-lockup-title")]/a))
|
||||||
|
if !anchor
|
||||||
|
next
|
||||||
|
end
|
||||||
|
|
||||||
if anchor["href"].starts_with? "https://www.googleadservices.com"
|
if anchor["href"].starts_with? "https://www.googleadservices.com"
|
||||||
next
|
next
|
||||||
end
|
end
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
def search(query, page = 1)
|
def search(query, page = 1, search_params = build_search_params(content_type: "video"))
|
||||||
client = make_client(YT_URL)
|
client = make_client(YT_URL)
|
||||||
html = client.get("/results?q=#{URI.escape(query)}&page=#{page}&sp=EgIQAVAU").body
|
html = client.get("/results?q=#{URI.escape(query)}&page=#{page}&sp=#{search_params}").body
|
||||||
html = XML.parse_html(html)
|
html = XML.parse_html(html)
|
||||||
|
|
||||||
videos = [] of ChannelVideo
|
videos = [] of ChannelVideo
|
||||||
@ -28,3 +28,97 @@ def search(query, page = 1)
|
|||||||
|
|
||||||
return videos
|
return videos
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def build_search_params(sort_by = "relevance", date : String = "", content_type : String = "", duration : String = "", features : Array(String) = [] of String)
|
||||||
|
head = "\x08"
|
||||||
|
head += case sort_by
|
||||||
|
when "relevance"
|
||||||
|
"\x00"
|
||||||
|
when "rating"
|
||||||
|
"\x01"
|
||||||
|
when "upload_date"
|
||||||
|
"\x02"
|
||||||
|
when "view_count"
|
||||||
|
"\x03"
|
||||||
|
else
|
||||||
|
raise "No sort #{sort_by}"
|
||||||
|
end
|
||||||
|
|
||||||
|
body = ""
|
||||||
|
body += case date
|
||||||
|
when "hour"
|
||||||
|
"\x08\x01"
|
||||||
|
when "today"
|
||||||
|
"\x08\x02"
|
||||||
|
when "week"
|
||||||
|
"\x08\x03"
|
||||||
|
when "month"
|
||||||
|
"\x08\x04"
|
||||||
|
when "year"
|
||||||
|
"\x08\x05"
|
||||||
|
else
|
||||||
|
""
|
||||||
|
end
|
||||||
|
|
||||||
|
body += case content_type
|
||||||
|
when "video"
|
||||||
|
"\x10\x01"
|
||||||
|
when "channel"
|
||||||
|
"\x10\x02"
|
||||||
|
when "playlist"
|
||||||
|
"\x10\x03"
|
||||||
|
when "movie"
|
||||||
|
"\x10\x04"
|
||||||
|
when "show"
|
||||||
|
"\x10\x05"
|
||||||
|
else
|
||||||
|
""
|
||||||
|
end
|
||||||
|
|
||||||
|
body += case duration
|
||||||
|
when "short"
|
||||||
|
"\x18\x01"
|
||||||
|
when "long"
|
||||||
|
"\x18\x02"
|
||||||
|
else
|
||||||
|
""
|
||||||
|
end
|
||||||
|
|
||||||
|
features.each do |feature|
|
||||||
|
body += case feature
|
||||||
|
when "hd"
|
||||||
|
"\x20\x01"
|
||||||
|
when "subtitles"
|
||||||
|
"\x28\x01"
|
||||||
|
when "creative_commons"
|
||||||
|
"\x30\x01"
|
||||||
|
when "3d"
|
||||||
|
"\x38\x01"
|
||||||
|
when "live"
|
||||||
|
"\x40\x01"
|
||||||
|
when "purchased"
|
||||||
|
"\x48\x01"
|
||||||
|
when "4k"
|
||||||
|
"\x70\x01"
|
||||||
|
when "360"
|
||||||
|
"\x78\x01"
|
||||||
|
when "location"
|
||||||
|
"\xb8\x01\x01"
|
||||||
|
when "hdr"
|
||||||
|
"\xc8\x01\x01"
|
||||||
|
else
|
||||||
|
raise "Unknown feature #{feature}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
if body.size > 0
|
||||||
|
token = head + "\x12" + body.size.to_u8.unsafe_chr + body
|
||||||
|
else
|
||||||
|
token = head
|
||||||
|
end
|
||||||
|
|
||||||
|
token = Base64.urlsafe_encode(token)
|
||||||
|
token = URI.escape(token)
|
||||||
|
|
||||||
|
return token
|
||||||
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user