Create a search processors module
This commit is contained in:
parent
f4e19ac05c
commit
f9b8bc006f
4 changed files with 60 additions and 44 deletions
|
@ -35,6 +35,7 @@ require "./invidious/frontend/*"
|
||||||
require "./invidious/*"
|
require "./invidious/*"
|
||||||
require "./invidious/channels/*"
|
require "./invidious/channels/*"
|
||||||
require "./invidious/user/*"
|
require "./invidious/user/*"
|
||||||
|
require "./invidious/search/*"
|
||||||
require "./invidious/routes/**"
|
require "./invidious/routes/**"
|
||||||
require "./invidious/jobs/**"
|
require "./invidious/jobs/**"
|
||||||
|
|
||||||
|
|
|
@ -262,7 +262,7 @@ module Invidious::Routes::API::V1::Channels
|
||||||
page = env.params.query["page"]?.try &.to_i?
|
page = env.params.query["page"]?.try &.to_i?
|
||||||
page ||= 1
|
page ||= 1
|
||||||
|
|
||||||
search_results = channel_search(query, page, ucid)
|
search_results = Invidious::Search::Processors.channel(query, page, ucid)
|
||||||
JSON.build do |json|
|
JSON.build do |json|
|
||||||
json.array do
|
json.array do
|
||||||
search_results.each do |item|
|
search_results.each do |item|
|
||||||
|
|
|
@ -5,35 +5,6 @@ class ChannelSearchException < InfoException
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def channel_search(query, page, channel) : Array(SearchItem)
|
|
||||||
response = YT_POOL.client &.get("/channel/#{channel}")
|
|
||||||
|
|
||||||
if response.status_code == 404
|
|
||||||
response = YT_POOL.client &.get("/user/#{channel}")
|
|
||||||
response = YT_POOL.client &.get("/c/#{channel}") if response.status_code == 404
|
|
||||||
initial_data = extract_initial_data(response.body)
|
|
||||||
ucid = initial_data.dig?("header", "c4TabbedHeaderRenderer", "channelId").try(&.as_s?)
|
|
||||||
raise ChannelSearchException.new(channel) if !ucid
|
|
||||||
else
|
|
||||||
ucid = channel
|
|
||||||
end
|
|
||||||
|
|
||||||
continuation = produce_channel_search_continuation(ucid, query, page)
|
|
||||||
response_json = YoutubeAPI.browse(continuation)
|
|
||||||
|
|
||||||
continuation_items = response_json["onResponseReceivedActions"]?
|
|
||||||
.try &.[0]["appendContinuationItemsAction"]["continuationItems"]
|
|
||||||
|
|
||||||
return [] of SearchItem if !continuation_items
|
|
||||||
|
|
||||||
items = [] of SearchItem
|
|
||||||
continuation_items.as_a.select(&.as_h.has_key?("itemSectionRenderer")).each do |item|
|
|
||||||
extract_item(item["itemSectionRenderer"]["contents"].as_a[0]).try { |t| items << t }
|
|
||||||
end
|
|
||||||
|
|
||||||
return items
|
|
||||||
end
|
|
||||||
|
|
||||||
def search(query, search_params = produce_search_params(content_type: "all"), region = nil) : Array(SearchItem)
|
def search(query, search_params = produce_search_params(content_type: "all"), region = nil) : Array(SearchItem)
|
||||||
return [] of SearchItem if query.empty?
|
return [] of SearchItem if query.empty?
|
||||||
|
|
||||||
|
@ -175,11 +146,6 @@ def produce_channel_search_continuation(ucid, query, page)
|
||||||
end
|
end
|
||||||
|
|
||||||
def process_search_query(query, page, user, region)
|
def process_search_query(query, page, user, region)
|
||||||
if user
|
|
||||||
user = user.as(Invidious::User)
|
|
||||||
view_name = "subscriptions_#{sha256(user.email)}"
|
|
||||||
end
|
|
||||||
|
|
||||||
channel = nil
|
channel = nil
|
||||||
content_type = "all"
|
content_type = "all"
|
||||||
date = ""
|
date = ""
|
||||||
|
@ -215,16 +181,11 @@ def process_search_query(query, page, user, region)
|
||||||
search_query = (query.split(" ") - operators).join(" ")
|
search_query = (query.split(" ") - operators).join(" ")
|
||||||
|
|
||||||
if channel
|
if channel
|
||||||
items = channel_search(search_query, page, channel)
|
items = Invidious::Search::Processors.channel(search_query, page, channel)
|
||||||
elsif subscriptions
|
elsif subscriptions
|
||||||
if view_name
|
if user
|
||||||
items = PG_DB.query_all("SELECT id,title,published,updated,ucid,author,length_seconds FROM (
|
user = user.as(Invidious::User)
|
||||||
SELECT *,
|
items = Invidious::Search::Processors.subscriptions(query, page, user)
|
||||||
to_tsvector(#{view_name}.title) ||
|
|
||||||
to_tsvector(#{view_name}.author)
|
|
||||||
as document
|
|
||||||
FROM #{view_name}
|
|
||||||
) v_search WHERE v_search.document @@ plainto_tsquery($1) LIMIT 20 OFFSET $2;", search_query, (page - 1) * 20, as: ChannelVideo)
|
|
||||||
else
|
else
|
||||||
items = [] of ChannelVideo
|
items = [] of ChannelVideo
|
||||||
end
|
end
|
||||||
|
|
54
src/invidious/search/processors.cr
Normal file
54
src/invidious/search/processors.cr
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
module Invidious::Search
|
||||||
|
module Processors
|
||||||
|
extend self
|
||||||
|
|
||||||
|
# Search a youtube channel
|
||||||
|
# TODO: clean code, and rely more on YoutubeAPI
|
||||||
|
def channel(query, page, channel) : Array(SearchItem)
|
||||||
|
response = YT_POOL.client &.get("/channel/#{channel}")
|
||||||
|
|
||||||
|
if response.status_code == 404
|
||||||
|
response = YT_POOL.client &.get("/user/#{channel}")
|
||||||
|
response = YT_POOL.client &.get("/c/#{channel}") if response.status_code == 404
|
||||||
|
initial_data = extract_initial_data(response.body)
|
||||||
|
ucid = initial_data.dig?("header", "c4TabbedHeaderRenderer", "channelId").try(&.as_s?)
|
||||||
|
raise ChannelSearchException.new(channel) if !ucid
|
||||||
|
else
|
||||||
|
ucid = channel
|
||||||
|
end
|
||||||
|
|
||||||
|
continuation = produce_channel_search_continuation(ucid, query, page)
|
||||||
|
response_json = YoutubeAPI.browse(continuation)
|
||||||
|
|
||||||
|
continuation_items = response_json["onResponseReceivedActions"]?
|
||||||
|
.try &.[0]["appendContinuationItemsAction"]["continuationItems"]
|
||||||
|
|
||||||
|
return [] of SearchItem if !continuation_items
|
||||||
|
|
||||||
|
items = [] of SearchItem
|
||||||
|
continuation_items.as_a.select(&.as_h.has_key?("itemSectionRenderer")).each do |item|
|
||||||
|
extract_item(item["itemSectionRenderer"]["contents"].as_a[0]).try { |t| items << t }
|
||||||
|
end
|
||||||
|
|
||||||
|
return items
|
||||||
|
end
|
||||||
|
|
||||||
|
# Search inside of user subscriptions
|
||||||
|
def subscriptions(query, page, user : Invidious::User) : Array(ChannelVideo)
|
||||||
|
view_name = "subscriptions_#{sha256(user.email)}"
|
||||||
|
|
||||||
|
return PG_DB.query_all("
|
||||||
|
SELECT id,title,published,updated,ucid,author,length_seconds
|
||||||
|
FROM (
|
||||||
|
SELECT *,
|
||||||
|
to_tsvector(#{view_name}.title) ||
|
||||||
|
to_tsvector(#{view_name}.author)
|
||||||
|
as document
|
||||||
|
FROM #{view_name}
|
||||||
|
) v_search WHERE v_search.document @@ plainto_tsquery($1) LIMIT 20 OFFSET $2;",
|
||||||
|
query, (page - 1) * 20,
|
||||||
|
as: ChannelVideo
|
||||||
|
)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in a new issue