forked from midou/invidious
Extract embed routes into separate classes
This commit is contained in:
parent
cda322e311
commit
dda02f783f
201
src/invidious.cr
201
src/invidious.cr
@ -297,205 +297,8 @@ Invidious::Routing.get "/", Invidious::Routes::Home
|
||||
Invidious::Routing.get "/privacy", Invidious::Routes::Privacy
|
||||
Invidious::Routing.get "/licenses", Invidious::Routes::Licenses
|
||||
Invidious::Routing.get "/watch", Invidious::Routes::Watch
|
||||
|
||||
get "/embed/" do |env|
|
||||
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
||||
|
||||
if plid = env.params.query["list"]?.try &.gsub(/[^a-zA-Z0-9_-]/, "")
|
||||
begin
|
||||
playlist = get_playlist(PG_DB, plid, locale: locale)
|
||||
offset = env.params.query["index"]?.try &.to_i? || 0
|
||||
videos = get_playlist_videos(PG_DB, playlist, offset: offset, locale: locale)
|
||||
rescue ex
|
||||
error_message = ex.message
|
||||
env.response.status_code = 500
|
||||
next templated "error"
|
||||
end
|
||||
|
||||
url = "/embed/#{videos[0].id}?#{env.params.query}"
|
||||
|
||||
if env.params.query.size > 0
|
||||
url += "?#{env.params.query}"
|
||||
end
|
||||
else
|
||||
url = "/"
|
||||
end
|
||||
|
||||
env.redirect url
|
||||
end
|
||||
|
||||
get "/embed/:id" do |env|
|
||||
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
||||
id = env.params.url["id"]
|
||||
|
||||
plid = env.params.query["list"]?.try &.gsub(/[^a-zA-Z0-9_-]/, "")
|
||||
continuation = process_continuation(PG_DB, env.params.query, plid, id)
|
||||
|
||||
if md = env.params.query["playlist"]?
|
||||
.try &.match(/[a-zA-Z0-9_-]{11}(,[a-zA-Z0-9_-]{11})*/)
|
||||
video_series = md[0].split(",")
|
||||
env.params.query.delete("playlist")
|
||||
end
|
||||
|
||||
preferences = env.get("preferences").as(Preferences)
|
||||
|
||||
if id.includes?("%20") || id.includes?("+") || env.params.query.to_s.includes?("%20") || env.params.query.to_s.includes?("+")
|
||||
id = env.params.url["id"].gsub("%20", "").delete("+")
|
||||
|
||||
url = "/embed/#{id}"
|
||||
|
||||
if env.params.query.size > 0
|
||||
url += "?#{env.params.query.to_s.gsub("%20", "").delete("+")}"
|
||||
end
|
||||
|
||||
next env.redirect url
|
||||
end
|
||||
|
||||
# YouTube embed supports `videoseries` with either `list=PLID`
|
||||
# or `playlist=VIDEO_ID,VIDEO_ID`
|
||||
case id
|
||||
when "videoseries"
|
||||
url = ""
|
||||
|
||||
if plid
|
||||
begin
|
||||
playlist = get_playlist(PG_DB, plid, locale: locale)
|
||||
offset = env.params.query["index"]?.try &.to_i? || 0
|
||||
videos = get_playlist_videos(PG_DB, playlist, offset: offset, locale: locale)
|
||||
rescue ex
|
||||
error_message = ex.message
|
||||
env.response.status_code = 500
|
||||
next templated "error"
|
||||
end
|
||||
|
||||
url = "/embed/#{videos[0].id}"
|
||||
elsif video_series
|
||||
url = "/embed/#{video_series.shift}"
|
||||
env.params.query["playlist"] = video_series.join(",")
|
||||
else
|
||||
next env.redirect "/"
|
||||
end
|
||||
|
||||
if env.params.query.size > 0
|
||||
url += "?#{env.params.query}"
|
||||
end
|
||||
|
||||
next env.redirect url
|
||||
when "live_stream"
|
||||
response = YT_POOL.client &.get("/embed/live_stream?channel=#{env.params.query["channel"]? || ""}")
|
||||
video_id = response.body.match(/"video_id":"(?<video_id>[a-zA-Z0-9_-]{11})"/).try &.["video_id"]
|
||||
|
||||
env.params.query.delete_all("channel")
|
||||
|
||||
if !video_id || video_id == "live_stream"
|
||||
error_message = "Video is unavailable."
|
||||
next templated "error"
|
||||
end
|
||||
|
||||
url = "/embed/#{video_id}"
|
||||
|
||||
if env.params.query.size > 0
|
||||
url += "?#{env.params.query}"
|
||||
end
|
||||
|
||||
next env.redirect url
|
||||
when id.size > 11
|
||||
url = "/embed/#{id[0, 11]}"
|
||||
|
||||
if env.params.query.size > 0
|
||||
url += "?#{env.params.query}"
|
||||
end
|
||||
|
||||
next env.redirect url
|
||||
else nil # Continue
|
||||
end
|
||||
|
||||
params = process_video_params(env.params.query, preferences)
|
||||
|
||||
user = env.get?("user").try &.as(User)
|
||||
if user
|
||||
subscriptions = user.subscriptions
|
||||
watched = user.watched
|
||||
notifications = user.notifications
|
||||
end
|
||||
subscriptions ||= [] of String
|
||||
|
||||
begin
|
||||
video = get_video(id, PG_DB, region: params.region)
|
||||
rescue ex : VideoRedirect
|
||||
next env.redirect env.request.resource.gsub(id, ex.video_id)
|
||||
rescue ex
|
||||
error_message = ex.message
|
||||
env.response.status_code = 500
|
||||
next templated "error"
|
||||
end
|
||||
|
||||
if preferences.annotations_subscribed &&
|
||||
subscriptions.includes?(video.ucid) &&
|
||||
(env.params.query["iv_load_policy"]? || "1") == "1"
|
||||
params.annotations = true
|
||||
end
|
||||
|
||||
# if watched && !watched.includes? id
|
||||
# PG_DB.exec("UPDATE users SET watched = array_append(watched, $1) WHERE email = $2", id, user.as(User).email)
|
||||
# end
|
||||
|
||||
if notifications && notifications.includes? id
|
||||
PG_DB.exec("UPDATE users SET notifications = array_remove(notifications, $1) WHERE email = $2", id, user.as(User).email)
|
||||
env.get("user").as(User).notifications.delete(id)
|
||||
notifications.delete(id)
|
||||
end
|
||||
|
||||
fmt_stream = video.fmt_stream
|
||||
adaptive_fmts = video.adaptive_fmts
|
||||
|
||||
if params.local
|
||||
fmt_stream.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).full_path) }
|
||||
adaptive_fmts.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).full_path) }
|
||||
end
|
||||
|
||||
video_streams = video.video_streams
|
||||
audio_streams = video.audio_streams
|
||||
|
||||
if audio_streams.empty? && !video.live_now
|
||||
if params.quality == "dash"
|
||||
env.params.query.delete_all("quality")
|
||||
next env.redirect "/embed/#{id}?#{env.params.query}"
|
||||
elsif params.listen
|
||||
env.params.query.delete_all("listen")
|
||||
env.params.query["listen"] = "0"
|
||||
next env.redirect "/embed/#{id}?#{env.params.query}"
|
||||
end
|
||||
end
|
||||
|
||||
captions = video.captions
|
||||
|
||||
preferred_captions = captions.select { |caption|
|
||||
params.preferred_captions.includes?(caption.name.simpleText) ||
|
||||
params.preferred_captions.includes?(caption.languageCode.split("-")[0])
|
||||
}
|
||||
preferred_captions.sort_by! { |caption|
|
||||
(params.preferred_captions.index(caption.name.simpleText) ||
|
||||
params.preferred_captions.index(caption.languageCode.split("-")[0])).not_nil!
|
||||
}
|
||||
captions = captions - preferred_captions
|
||||
|
||||
aspect_ratio = nil
|
||||
|
||||
thumbnail = "/vi/#{video.id}/maxres.jpg"
|
||||
|
||||
if params.raw
|
||||
url = fmt_stream[0]["url"].as_s
|
||||
|
||||
fmt_stream.each do |fmt|
|
||||
url = fmt["url"].as_s if fmt["quality"].as_s == params.quality
|
||||
end
|
||||
|
||||
next env.redirect url
|
||||
end
|
||||
|
||||
rendered "embed"
|
||||
end
|
||||
Invidious::Routing.get "/embed/", Invidious::Routes::Embed::Index
|
||||
Invidious::Routing.get "/embed/:id", Invidious::Routes::Embed::Show
|
||||
|
||||
# Playlists
|
||||
|
||||
|
27
src/invidious/routes/embed/index.cr
Normal file
27
src/invidious/routes/embed/index.cr
Normal file
@ -0,0 +1,27 @@
|
||||
class Invidious::Routes::Embed::Index < Invidious::Routes::BaseRoute
|
||||
def handle(env)
|
||||
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
||||
|
||||
if plid = env.params.query["list"]?.try &.gsub(/[^a-zA-Z0-9_-]/, "")
|
||||
begin
|
||||
playlist = get_playlist(PG_DB, plid, locale: locale)
|
||||
offset = env.params.query["index"]?.try &.to_i? || 0
|
||||
videos = get_playlist_videos(PG_DB, playlist, offset: offset, locale: locale)
|
||||
rescue ex
|
||||
error_message = ex.message
|
||||
env.response.status_code = 500
|
||||
return templated "error"
|
||||
end
|
||||
|
||||
url = "/embed/#{videos[0].id}?#{env.params.query}"
|
||||
|
||||
if env.params.query.size > 0
|
||||
url += "?#{env.params.query}"
|
||||
end
|
||||
else
|
||||
url = "/"
|
||||
end
|
||||
|
||||
env.redirect url
|
||||
end
|
||||
end
|
174
src/invidious/routes/embed/show.cr
Normal file
174
src/invidious/routes/embed/show.cr
Normal file
@ -0,0 +1,174 @@
|
||||
class Invidious::Routes::Embed::Show < Invidious::Routes::BaseRoute
|
||||
def handle(env)
|
||||
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
||||
id = env.params.url["id"]
|
||||
|
||||
plid = env.params.query["list"]?.try &.gsub(/[^a-zA-Z0-9_-]/, "")
|
||||
continuation = process_continuation(PG_DB, env.params.query, plid, id)
|
||||
|
||||
if md = env.params.query["playlist"]?
|
||||
.try &.match(/[a-zA-Z0-9_-]{11}(,[a-zA-Z0-9_-]{11})*/)
|
||||
video_series = md[0].split(",")
|
||||
env.params.query.delete("playlist")
|
||||
end
|
||||
|
||||
preferences = env.get("preferences").as(Preferences)
|
||||
|
||||
if id.includes?("%20") || id.includes?("+") || env.params.query.to_s.includes?("%20") || env.params.query.to_s.includes?("+")
|
||||
id = env.params.url["id"].gsub("%20", "").delete("+")
|
||||
|
||||
url = "/embed/#{id}"
|
||||
|
||||
if env.params.query.size > 0
|
||||
url += "?#{env.params.query.to_s.gsub("%20", "").delete("+")}"
|
||||
end
|
||||
|
||||
return env.redirect url
|
||||
end
|
||||
|
||||
# YouTube embed supports `videoseries` with either `list=PLID`
|
||||
# or `playlist=VIDEO_ID,VIDEO_ID`
|
||||
case id
|
||||
when "videoseries"
|
||||
url = ""
|
||||
|
||||
if plid
|
||||
begin
|
||||
playlist = get_playlist(PG_DB, plid, locale: locale)
|
||||
offset = env.params.query["index"]?.try &.to_i? || 0
|
||||
videos = get_playlist_videos(PG_DB, playlist, offset: offset, locale: locale)
|
||||
rescue ex
|
||||
error_message = ex.message
|
||||
env.response.status_code = 500
|
||||
return templated "error"
|
||||
end
|
||||
|
||||
url = "/embed/#{videos[0].id}"
|
||||
elsif video_series
|
||||
url = "/embed/#{video_series.shift}"
|
||||
env.params.query["playlist"] = video_series.join(",")
|
||||
else
|
||||
return env.redirect "/"
|
||||
end
|
||||
|
||||
if env.params.query.size > 0
|
||||
url += "?#{env.params.query}"
|
||||
end
|
||||
|
||||
return env.redirect url
|
||||
when "live_stream"
|
||||
response = YT_POOL.client &.get("/embed/live_stream?channel=#{env.params.query["channel"]? || ""}")
|
||||
video_id = response.body.match(/"video_id":"(?<video_id>[a-zA-Z0-9_-]{11})"/).try &.["video_id"]
|
||||
|
||||
env.params.query.delete_all("channel")
|
||||
|
||||
if !video_id || video_id == "live_stream"
|
||||
error_message = "Video is unavailable."
|
||||
return templated "error"
|
||||
end
|
||||
|
||||
url = "/embed/#{video_id}"
|
||||
|
||||
if env.params.query.size > 0
|
||||
url += "?#{env.params.query}"
|
||||
end
|
||||
|
||||
return env.redirect url
|
||||
when id.size > 11
|
||||
url = "/embed/#{id[0, 11]}"
|
||||
|
||||
if env.params.query.size > 0
|
||||
url += "?#{env.params.query}"
|
||||
end
|
||||
|
||||
return env.redirect url
|
||||
else nil # Continue
|
||||
end
|
||||
|
||||
params = process_video_params(env.params.query, preferences)
|
||||
|
||||
user = env.get?("user").try &.as(User)
|
||||
if user
|
||||
subscriptions = user.subscriptions
|
||||
watched = user.watched
|
||||
notifications = user.notifications
|
||||
end
|
||||
subscriptions ||= [] of String
|
||||
|
||||
begin
|
||||
video = get_video(id, PG_DB, region: params.region)
|
||||
rescue ex : VideoRedirect
|
||||
return env.redirect env.request.resource.gsub(id, ex.video_id)
|
||||
rescue ex
|
||||
error_message = ex.message
|
||||
env.response.status_code = 500
|
||||
return templated "error"
|
||||
end
|
||||
|
||||
if preferences.annotations_subscribed &&
|
||||
subscriptions.includes?(video.ucid) &&
|
||||
(env.params.query["iv_load_policy"]? || "1") == "1"
|
||||
params.annotations = true
|
||||
end
|
||||
|
||||
# if watched && !watched.includes? id
|
||||
# PG_DB.exec("UPDATE users SET watched = array_append(watched, $1) WHERE email = $2", id, user.as(User).email)
|
||||
# end
|
||||
|
||||
if notifications && notifications.includes? id
|
||||
PG_DB.exec("UPDATE users SET notifications = array_remove(notifications, $1) WHERE email = $2", id, user.as(User).email)
|
||||
env.get("user").as(User).notifications.delete(id)
|
||||
notifications.delete(id)
|
||||
end
|
||||
|
||||
fmt_stream = video.fmt_stream
|
||||
adaptive_fmts = video.adaptive_fmts
|
||||
|
||||
if params.local
|
||||
fmt_stream.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).full_path) }
|
||||
adaptive_fmts.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).full_path) }
|
||||
end
|
||||
|
||||
video_streams = video.video_streams
|
||||
audio_streams = video.audio_streams
|
||||
|
||||
if audio_streams.empty? && !video.live_now
|
||||
if params.quality == "dash"
|
||||
env.params.query.delete_all("quality")
|
||||
return env.redirect "/embed/#{id}?#{env.params.query}"
|
||||
elsif params.listen
|
||||
env.params.query.delete_all("listen")
|
||||
env.params.query["listen"] = "0"
|
||||
return env.redirect "/embed/#{id}?#{env.params.query}"
|
||||
end
|
||||
end
|
||||
|
||||
captions = video.captions
|
||||
|
||||
preferred_captions = captions.select { |caption|
|
||||
params.preferred_captions.includes?(caption.name.simpleText) ||
|
||||
params.preferred_captions.includes?(caption.languageCode.split("-")[0])
|
||||
}
|
||||
preferred_captions.sort_by! { |caption|
|
||||
(params.preferred_captions.index(caption.name.simpleText) ||
|
||||
params.preferred_captions.index(caption.languageCode.split("-")[0])).not_nil!
|
||||
}
|
||||
captions = captions - preferred_captions
|
||||
|
||||
aspect_ratio = nil
|
||||
|
||||
thumbnail = "/vi/#{video.id}/maxres.jpg"
|
||||
|
||||
if params.raw
|
||||
url = fmt_stream[0]["url"].as_s
|
||||
|
||||
fmt_stream.each do |fmt|
|
||||
url = fmt["url"].as_s if fmt["quality"].as_s == params.quality
|
||||
end
|
||||
|
||||
return env.redirect url
|
||||
end
|
||||
|
||||
rendered "embed"
|
||||
end
|
||||
end
|
Loading…
Reference in New Issue
Block a user