summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorOmar Roth <omarroth@hotmail.com>2018-08-04 17:12:58 -0500
committerOmar Roth <omarroth@hotmail.com>2018-08-04 17:19:55 -0500
commit3ada6a92348ea2133f2eb0b2387ce7fb490e2e67 (patch)
treee2b3d7fe6b568651c4874eea7d62029f7eefbdb0 /src
parent3f0c823798b8750a96294ea69ef7a96f7be11237 (diff)
downloadinvidious-3ada6a92348ea2133f2eb0b2387ce7fb490e2e67.tar.gz
invidious-3ada6a92348ea2133f2eb0b2387ce7fb490e2e67.tar.bz2
invidious-3ada6a92348ea2133f2eb0b2387ce7fb490e2e67.zip
Add filters to '/api/v1/search' endpoint
Diffstat (limited to 'src')
-rw-r--r--src/invidious.cr34
-rw-r--r--src/invidious/search.cr98
2 files changed, 128 insertions, 4 deletions
diff --git a/src/invidious.cr b/src/invidious.cr
index e82f0b9f..0a023345 100644
--- a/src/invidious.cr
+++ b/src/invidious.cr
@@ -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
diff --git a/src/invidious/search.cr b/src/invidious/search.cr
index 034db789..7714de22 100644
--- a/src/invidious/search.cr
+++ b/src/invidious/search.cr
@@ -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