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 ||= 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)
|
||||
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)
|
||||
|
||||
results = JSON.build do |json|
|
||||
json.array do
|
||||
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"
|
||||
next
|
||||
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)
|
||||
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)
|
||||
|
||||
videos = [] of ChannelVideo
|
||||
|
@ -28,3 +28,97 @@ def search(query, page = 1)
|
|||
|
||||
return videos
|
||||
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