api: Add support for shorts and livestreams

This commit is contained in:
Samantaz Fox 2022-12-04 19:24:51 +01:00
parent 6c9754e663
commit 40c666cab2
No known key found for this signature in database
GPG key ID: F42821059186176E
2 changed files with 92 additions and 29 deletions

View file

@ -1,11 +1,7 @@
module Invidious::Routes::API::V1::Channels module Invidious::Routes::API::V1::Channels
def self.home(env) # Macro to avoid duplicating some code below
locale = env.get("preferences").as(Preferences).locale # This sets the `channel` variable, or handles Exceptions.
private macro get_channel
env.response.content_type = "application/json"
ucid = env.params.url["ucid"]
begin begin
channel = get_about_info(ucid, locale) channel = get_about_info(ucid, locale)
rescue ex : ChannelRedirect rescue ex : ChannelRedirect
@ -16,6 +12,17 @@ module Invidious::Routes::API::V1::Channels
rescue ex rescue ex
return error_json(500, ex) return error_json(500, ex)
end end
end
def self.home(env)
locale = env.get("preferences").as(Preferences).locale
ucid = env.params.url["ucid"]
env.response.content_type = "application/json"
# Use the private macro defined above.
channel = nil # Make the compiler happy
get_channel()
# Retrieve "sort by" setting from URL parameters # Retrieve "sort by" setting from URL parameters
sort_by = env.params.query["sort_by"]?.try &.downcase || "newest" sort_by = env.params.query["sort_by"]?.try &.downcase || "newest"
@ -138,21 +145,13 @@ module Invidious::Routes::API::V1::Channels
def self.videos(env) def self.videos(env)
locale = env.get("preferences").as(Preferences).locale locale = env.get("preferences").as(Preferences).locale
ucid = env.params.url["ucid"]
env.response.content_type = "application/json" env.response.content_type = "application/json"
ucid = env.params.url["ucid"] # Use the private macro defined above.
channel = nil # Make the compiler happy
begin get_channel()
channel = get_about_info(ucid, locale)
rescue ex : ChannelRedirect
env.response.headers["Location"] = env.request.resource.gsub(ucid, ex.channel_id)
return error_json(302, "Channel is unavailable", {"authorId" => ex.channel_id})
rescue ex : NotFoundException
return error_json(404, ex)
rescue ex
return error_json(500, ex)
end
# Retrieve some URL parameters # Retrieve some URL parameters
sort_by = env.params.query["sort_by"]?.try &.downcase || "newest" sort_by = env.params.query["sort_by"]?.try &.downcase || "newest"
@ -179,6 +178,74 @@ module Invidious::Routes::API::V1::Channels
end end
end end
def self.shorts(env)
locale = env.get("preferences").as(Preferences).locale
ucid = env.params.url["ucid"]
env.response.content_type = "application/json"
# Use the private macro defined above.
channel = nil # Make the compiler happy
get_channel()
# Retrieve continuation from URL parameters
continuation = env.params.query["continuation"]?
begin
videos, next_continuation = Channel::Tabs.get_shorts(
channel, continuation: continuation
)
rescue ex
return error_json(500, ex)
end
return JSON.build do |json|
json.object do
json.field "videos" do
json.array do
videos.each &.to_json(locale, json)
end
end
json.field "continuation", next_continuation if next_continuation
end
end
end
def self.streams(env)
locale = env.get("preferences").as(Preferences).locale
ucid = env.params.url["ucid"]
env.response.content_type = "application/json"
# Use the private macro defined above.
channel = nil # Make the compiler happy
get_channel()
# Retrieve continuation from URL parameters
continuation = env.params.query["continuation"]?
begin
videos, next_continuation = Channel::Tabs.get_60_livestreams(
channel, continuation: continuation
)
rescue ex
return error_json(500, ex)
end
return JSON.build do |json|
json.object do
json.field "videos" do
json.array do
videos.each &.to_json(locale, json)
end
end
json.field "continuation", next_continuation if next_continuation
end
end
end
def self.playlists(env) def self.playlists(env)
locale = env.get("preferences").as(Preferences).locale locale = env.get("preferences").as(Preferences).locale
@ -190,16 +257,9 @@ module Invidious::Routes::API::V1::Channels
env.params.query["sort_by"]?.try &.downcase || env.params.query["sort_by"]?.try &.downcase ||
"last" "last"
begin # Use the macro defined above
channel = get_about_info(ucid, locale) channel = nil # Make the compiler happy
rescue ex : ChannelRedirect get_channel()
env.response.headers["Location"] = env.request.resource.gsub(ucid, ex.channel_id)
return error_json(302, "Channel is unavailable", {"authorId" => ex.channel_id})
rescue ex : NotFoundException
return error_json(404, ex)
rescue ex
return error_json(500, ex)
end
items, continuation = fetch_channel_playlists(channel.ucid, channel.author, continuation, sort_by) items, continuation = fetch_channel_playlists(channel.ucid, channel.author, continuation, sort_by)

View file

@ -222,6 +222,9 @@ module Invidious::Routing
# Channels # Channels
get "/api/v1/channels/:ucid", {{namespace}}::Channels, :home get "/api/v1/channels/:ucid", {{namespace}}::Channels, :home
get "/api/v1/channels/:ucid/shorts", {{namespace}}::Channels, :shorts
get "/api/v1/channels/:ucid/streams", {{namespace}}::Channels, :streams
{% for route in {"videos", "latest", "playlists", "community", "search"} %} {% for route in {"videos", "latest", "playlists", "community", "search"} %}
get "/api/v1/channels/#{{{route}}}/:ucid", {{namespace}}::Channels, :{{route}} get "/api/v1/channels/#{{{route}}}/:ucid", {{namespace}}::Channels, :{{route}}
get "/api/v1/channels/:ucid/#{{{route}}}", {{namespace}}::Channels, :{{route}} get "/api/v1/channels/:ucid/#{{{route}}}", {{namespace}}::Channels, :{{route}}