mirror of
https://gitea.invidious.io/iv-org/invidious.git
synced 2024-08-15 00:53:41 +00:00
Restructure API route organisation
This commit is contained in:
parent
cbf3d75087
commit
66becbf46f
8 changed files with 166 additions and 163 deletions
|
@ -1,116 +0,0 @@
|
||||||
class Invidious::Routes::V1Api < Invidious::Routes::BaseRoute
|
|
||||||
def comments(env)
|
|
||||||
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
|
||||||
region = env.params.query["region"]?
|
|
||||||
|
|
||||||
env.response.content_type = "application/json"
|
|
||||||
|
|
||||||
id = env.params.url["id"]
|
|
||||||
|
|
||||||
source = env.params.query["source"]?
|
|
||||||
source ||= "youtube"
|
|
||||||
|
|
||||||
thin_mode = env.params.query["thin_mode"]?
|
|
||||||
thin_mode = thin_mode == "true"
|
|
||||||
|
|
||||||
format = env.params.query["format"]?
|
|
||||||
format ||= "json"
|
|
||||||
|
|
||||||
action = env.params.query["action"]?
|
|
||||||
action ||= "action_get_comments"
|
|
||||||
|
|
||||||
continuation = env.params.query["continuation"]?
|
|
||||||
sort_by = env.params.query["sort_by"]?.try &.downcase
|
|
||||||
|
|
||||||
if source == "youtube"
|
|
||||||
sort_by ||= "top"
|
|
||||||
|
|
||||||
begin
|
|
||||||
comments = fetch_youtube_comments(id, PG_DB, continuation, format, locale, thin_mode, region, sort_by: sort_by, action: action)
|
|
||||||
rescue ex
|
|
||||||
return error_json(500, ex)
|
|
||||||
end
|
|
||||||
|
|
||||||
return comments
|
|
||||||
elsif source == "reddit"
|
|
||||||
sort_by ||= "confidence"
|
|
||||||
|
|
||||||
begin
|
|
||||||
comments, reddit_thread = fetch_reddit_comments(id, sort_by: sort_by)
|
|
||||||
content_html = template_reddit_comments(comments, locale)
|
|
||||||
|
|
||||||
content_html = fill_links(content_html, "https", "www.reddit.com")
|
|
||||||
content_html = replace_links(content_html)
|
|
||||||
rescue ex
|
|
||||||
comments = nil
|
|
||||||
reddit_thread = nil
|
|
||||||
content_html = ""
|
|
||||||
end
|
|
||||||
|
|
||||||
if !reddit_thread || !comments
|
|
||||||
env.response.status_code = 404
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if format == "json"
|
|
||||||
reddit_thread = JSON.parse(reddit_thread.to_json).as_h
|
|
||||||
reddit_thread["comments"] = JSON.parse(comments.to_json)
|
|
||||||
|
|
||||||
return reddit_thread.to_json
|
|
||||||
else
|
|
||||||
response = {
|
|
||||||
"title" => reddit_thread.title,
|
|
||||||
"permalink" => reddit_thread.permalink,
|
|
||||||
"contentHtml" => content_html,
|
|
||||||
}
|
|
||||||
|
|
||||||
return response.to_json
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def trending(env)
|
|
||||||
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
|
||||||
|
|
||||||
env.response.content_type = "application/json"
|
|
||||||
|
|
||||||
region = env.params.query["region"]?
|
|
||||||
trending_type = env.params.query["type"]?
|
|
||||||
|
|
||||||
begin
|
|
||||||
trending, plid = fetch_trending(trending_type, region, locale)
|
|
||||||
rescue ex
|
|
||||||
return error_json(500, ex)
|
|
||||||
end
|
|
||||||
|
|
||||||
videos = JSON.build do |json|
|
|
||||||
json.array do
|
|
||||||
trending.each do |video|
|
|
||||||
video.to_json(locale, json)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
videos
|
|
||||||
end
|
|
||||||
|
|
||||||
def popular(env)
|
|
||||||
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
|
||||||
|
|
||||||
env.response.content_type = "application/json"
|
|
||||||
|
|
||||||
if !CONFIG.popular_enabled
|
|
||||||
error_message = {"error" => "Administrator has disabled this endpoint."}.to_json
|
|
||||||
env.response.status_code = 400
|
|
||||||
return error_message
|
|
||||||
end
|
|
||||||
|
|
||||||
JSON.build do |json|
|
|
||||||
json.array do
|
|
||||||
popular_videos.each do |video|
|
|
||||||
video.to_json(locale, json)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -1,5 +1,5 @@
|
||||||
class Invidious::Routes::V1Api < Invidious::Routes::BaseRoute
|
module Invidious::Routes::APIv1
|
||||||
def home(env)
|
def self.home(env)
|
||||||
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
||||||
|
|
||||||
env.response.content_type = "application/json"
|
env.response.content_type = "application/json"
|
||||||
|
@ -124,7 +124,7 @@ class Invidious::Routes::V1Api < Invidious::Routes::BaseRoute
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def latest(env)
|
def self.latest(env)
|
||||||
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
||||||
|
|
||||||
env.response.content_type = "application/json"
|
env.response.content_type = "application/json"
|
||||||
|
@ -146,7 +146,7 @@ class Invidious::Routes::V1Api < Invidious::Routes::BaseRoute
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def videos(env)
|
def self.videos(env)
|
||||||
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
||||||
|
|
||||||
env.response.content_type = "application/json"
|
env.response.content_type = "application/json"
|
||||||
|
@ -182,7 +182,7 @@ class Invidious::Routes::V1Api < Invidious::Routes::BaseRoute
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def playlists(env)
|
def self.playlists(env)
|
||||||
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
||||||
|
|
||||||
env.response.content_type = "application/json"
|
env.response.content_type = "application/json"
|
||||||
|
@ -219,7 +219,7 @@ class Invidious::Routes::V1Api < Invidious::Routes::BaseRoute
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def community(env)
|
def self.community(env)
|
||||||
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
||||||
|
|
||||||
env.response.content_type = "application/json"
|
env.response.content_type = "application/json"
|
||||||
|
@ -241,27 +241,4 @@ class Invidious::Routes::V1Api < Invidious::Routes::BaseRoute
|
||||||
return error_json(500, ex)
|
return error_json(500, ex)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def channel_search(env)
|
|
||||||
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
|
||||||
|
|
||||||
env.response.content_type = "application/json"
|
|
||||||
|
|
||||||
ucid = env.params.url["ucid"]
|
|
||||||
|
|
||||||
query = env.params.query["q"]?
|
|
||||||
query ||= ""
|
|
||||||
|
|
||||||
page = env.params.query["page"]?.try &.to_i?
|
|
||||||
page ||= 1
|
|
||||||
|
|
||||||
count, search_results = channel_search(query, page, ucid)
|
|
||||||
JSON.build do |json|
|
|
||||||
json.array do
|
|
||||||
search_results.each do |item|
|
|
||||||
item.to_json(locale, json)
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
46
src/invidious/routes/api_v1/feeds.cr
Normal file
46
src/invidious/routes/api_v1/feeds.cr
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
module Invidious::Routes::APIv1
|
||||||
|
def self.trending(env)
|
||||||
|
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
||||||
|
|
||||||
|
env.response.content_type = "application/json"
|
||||||
|
|
||||||
|
region = env.params.query["region"]?
|
||||||
|
trending_type = env.params.query["type"]?
|
||||||
|
|
||||||
|
begin
|
||||||
|
trending, plid = fetch_trending(trending_type, region, locale)
|
||||||
|
rescue ex
|
||||||
|
return error_json(500, ex)
|
||||||
|
end
|
||||||
|
|
||||||
|
videos = JSON.build do |json|
|
||||||
|
json.array do
|
||||||
|
trending.each do |video|
|
||||||
|
video.to_json(locale, json)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
videos
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.popular(env)
|
||||||
|
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
||||||
|
|
||||||
|
env.response.content_type = "application/json"
|
||||||
|
|
||||||
|
if !CONFIG.popular_enabled
|
||||||
|
error_message = {"error" => "Administrator has disabled this endpoint."}.to_json
|
||||||
|
env.response.status_code = 400
|
||||||
|
return error_message
|
||||||
|
end
|
||||||
|
|
||||||
|
JSON.build do |json|
|
||||||
|
json.array do
|
||||||
|
popular_videos.each do |video|
|
||||||
|
video.to_json(locale, json)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,6 +1,6 @@
|
||||||
class Invidious::Routes::V1Api < Invidious::Routes::BaseRoute
|
module Invidious::Routes::APIv1
|
||||||
# Stats API endpoint for Invidious
|
# Stats API endpoint for Invidious
|
||||||
def stats(env)
|
def self.stats(env)
|
||||||
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
||||||
env.response.content_type = "application/json"
|
env.response.content_type = "application/json"
|
||||||
|
|
|
@ -1,18 +1,18 @@
|
||||||
# There is far too many API routes to define in invidious.cr
|
# There is far too many API routes to define in invidious.cr
|
||||||
# so we'll just do it here instead with a macro.
|
# so we'll just do it here instead with a macro.
|
||||||
macro define_v1_api_routes(base_url = "/api/v1")
|
macro define_v1_api_routes(base_url = "/api/v1")
|
||||||
Invidious::Routing.get "#{{{base_url}}}/stats", Invidious::Routes::V1Api, :stats
|
Invidious::Routing.get "#{{{base_url}}}/stats", Invidious::Routes::APIv1, :stats
|
||||||
|
|
||||||
Invidious::Routing.get "#{{{base_url}}}/storyboards/:id", Invidious::Routes::V1Api, :storyboards
|
Invidious::Routing.get "#{{{base_url}}}/storyboards/:id", Invidious::Routes::APIv1, :storyboards
|
||||||
Invidious::Routing.get "#{{{base_url}}}/captions/:id", Invidious::Routes::V1Api, :captions
|
Invidious::Routing.get "#{{{base_url}}}/captions/:id", Invidious::Routes::APIv1, :captions
|
||||||
Invidious::Routing.get "#{{{base_url}}}/annotations/:id", Invidious::Routes::V1Api, :annotations
|
Invidious::Routing.get "#{{{base_url}}}/annotations/:id", Invidious::Routes::APIv1, :annotations
|
||||||
Invidious::Routing.get "#{{{base_url}}}/search/suggestions/:id", Invidious::Routes::V1Api, :search_suggestions
|
Invidious::Routing.get "#{{{base_url}}}/search/suggestions/:id", Invidious::Routes::APIv1, :search_suggestions
|
||||||
|
|
||||||
Invidious::Routing.get "#{{{base_url}}}/comments/:id", Invidious::Routes::V1Api, :comments
|
Invidious::Routing.get "#{{{base_url}}}/comments/:id", Invidious::Routes::APIv1, :comments
|
||||||
Invidious::Routing.get "#{{{base_url}}}/trending", Invidious::Routes::V1Api, :trending
|
Invidious::Routing.get "#{{{base_url}}}/trending", Invidious::Routes::APIv1, :trending
|
||||||
Invidious::Routing.get "#{{{base_url}}}/popular", Invidious::Routes::V1Api, :popular
|
Invidious::Routing.get "#{{{base_url}}}/popular", Invidious::Routes::APIv1, :popular
|
||||||
|
|
||||||
Invidious::Routing.get "#{{{base_url}}}/channels/:ucid", Invidious::Routes::V1Api, :home
|
Invidious::Routing.get "#{{{base_url}}}/channels/:ucid", Invidious::Routes::APIv1, :home
|
||||||
|
|
||||||
{% for route in {
|
{% for route in {
|
||||||
{"home", "home"},
|
{"home", "home"},
|
||||||
|
@ -23,8 +23,8 @@ macro define_v1_api_routes(base_url = "/api/v1")
|
||||||
{"search", "channel_search"},
|
{"search", "channel_search"},
|
||||||
} %}
|
} %}
|
||||||
|
|
||||||
Invidious::Routing.get "#{{{base_url}}}/channels/#{{{route[0]}}}/:ucid", Invidious::Routes::V1Api, :{{route[1]}}
|
Invidious::Routing.get "#{{{base_url}}}/channels/#{{{route[0]}}}/:ucid", Invidious::Routes::APIv1, :{{route[1]}}
|
||||||
Invidious::Routing.get "#{{{base_url}}}/channels/:ucid/#{{{route[0]}}}", Invidious::Routes::V1Api, :{{route[1]}}
|
Invidious::Routing.get "#{{{base_url}}}/channels/:ucid/#{{{route[0]}}}", Invidious::Routes::APIv1, :{{route[1]}}
|
||||||
|
|
||||||
{% end %}
|
{% end %}
|
||||||
end
|
end
|
24
src/invidious/routes/api_v1/search.cr
Normal file
24
src/invidious/routes/api_v1/search.cr
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
module Invidious::Routes::APIv1
|
||||||
|
def self.channel_search(env)
|
||||||
|
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
||||||
|
|
||||||
|
env.response.content_type = "application/json"
|
||||||
|
|
||||||
|
ucid = env.params.url["ucid"]
|
||||||
|
|
||||||
|
query = env.params.query["q"]?
|
||||||
|
query ||= ""
|
||||||
|
|
||||||
|
page = env.params.query["page"]?.try &.to_i?
|
||||||
|
page ||= 1
|
||||||
|
|
||||||
|
count, search_results = channel_search(query, page, ucid)
|
||||||
|
JSON.build do |json|
|
||||||
|
json.array do
|
||||||
|
search_results.each do |item|
|
||||||
|
item.to_json(locale, json)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
2
src/invidious/routes/api_v1/video_playback.cr
Normal file
2
src/invidious/routes/api_v1/video_playback.cr
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
module Invidious::Routes::APIv1
|
||||||
|
end
|
|
@ -1,10 +1,10 @@
|
||||||
class Invidious::Routes::V1Api < Invidious::Routes::BaseRoute
|
module Invidious::Routes::APIv1
|
||||||
# Fetches YouTube storyboards
|
# Fetches YouTube storyboards
|
||||||
#
|
#
|
||||||
# Which are sprites containing x * y preview
|
# Which are sprites containing x * y preview
|
||||||
# thumbnails for individual scenes in a video.
|
# thumbnails for individual scenes in a video.
|
||||||
# See https://support.jwplayer.com/articles/how-to-add-preview-thumbnails
|
# See https://support.jwplayer.com/articles/how-to-add-preview-thumbnails
|
||||||
def storyboards(env)
|
def self.storyboards(env)
|
||||||
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
||||||
|
|
||||||
env.response.content_type = "application/json"
|
env.response.content_type = "application/json"
|
||||||
|
@ -80,7 +80,7 @@ class Invidious::Routes::V1Api < Invidious::Routes::BaseRoute
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def captions(env)
|
def self.captions(env)
|
||||||
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
||||||
|
|
||||||
env.response.content_type = "application/json"
|
env.response.content_type = "application/json"
|
||||||
|
@ -206,7 +206,7 @@ class Invidious::Routes::V1Api < Invidious::Routes::BaseRoute
|
||||||
webvtt
|
webvtt
|
||||||
end
|
end
|
||||||
|
|
||||||
def annotations(env)
|
def self.annotations(env)
|
||||||
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
||||||
|
|
||||||
env.response.content_type = "text/xml"
|
env.response.content_type = "text/xml"
|
||||||
|
@ -280,7 +280,7 @@ class Invidious::Routes::V1Api < Invidious::Routes::BaseRoute
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def search_suggestions(env)
|
def self.search_suggestions(env)
|
||||||
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
||||||
region = env.params.query["region"]?
|
region = env.params.query["region"]?
|
||||||
|
|
||||||
|
@ -313,4 +313,74 @@ class Invidious::Routes::V1Api < Invidious::Routes::BaseRoute
|
||||||
return error_json(500, ex)
|
return error_json(500, ex)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def self.comments(env)
|
||||||
|
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
|
||||||
|
region = env.params.query["region"]?
|
||||||
|
|
||||||
|
env.response.content_type = "application/json"
|
||||||
|
|
||||||
|
id = env.params.url["id"]
|
||||||
|
|
||||||
|
source = env.params.query["source"]?
|
||||||
|
source ||= "youtube"
|
||||||
|
|
||||||
|
thin_mode = env.params.query["thin_mode"]?
|
||||||
|
thin_mode = thin_mode == "true"
|
||||||
|
|
||||||
|
format = env.params.query["format"]?
|
||||||
|
format ||= "json"
|
||||||
|
|
||||||
|
action = env.params.query["action"]?
|
||||||
|
action ||= "action_get_comments"
|
||||||
|
|
||||||
|
continuation = env.params.query["continuation"]?
|
||||||
|
sort_by = env.params.query["sort_by"]?.try &.downcase
|
||||||
|
|
||||||
|
if source == "youtube"
|
||||||
|
sort_by ||= "top"
|
||||||
|
|
||||||
|
begin
|
||||||
|
comments = fetch_youtube_comments(id, continuation, format, locale, thin_mode, region, sort_by: sort_by)
|
||||||
|
rescue ex
|
||||||
|
return error_json(500, ex)
|
||||||
|
end
|
||||||
|
|
||||||
|
return comments
|
||||||
|
elsif source == "reddit"
|
||||||
|
sort_by ||= "confidence"
|
||||||
|
|
||||||
|
begin
|
||||||
|
comments, reddit_thread = fetch_reddit_comments(id, sort_by: sort_by)
|
||||||
|
content_html = template_reddit_comments(comments, locale)
|
||||||
|
|
||||||
|
content_html = fill_links(content_html, "https", "www.reddit.com")
|
||||||
|
content_html = replace_links(content_html)
|
||||||
|
rescue ex
|
||||||
|
comments = nil
|
||||||
|
reddit_thread = nil
|
||||||
|
content_html = ""
|
||||||
|
end
|
||||||
|
|
||||||
|
if !reddit_thread || !comments
|
||||||
|
env.response.status_code = 404
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
if format == "json"
|
||||||
|
reddit_thread = JSON.parse(reddit_thread.to_json).as_h
|
||||||
|
reddit_thread["comments"] = JSON.parse(comments.to_json)
|
||||||
|
|
||||||
|
return reddit_thread.to_json
|
||||||
|
else
|
||||||
|
response = {
|
||||||
|
"title" => reddit_thread.title,
|
||||||
|
"permalink" => reddit_thread.permalink,
|
||||||
|
"contentHtml" => content_html,
|
||||||
|
}
|
||||||
|
|
||||||
|
return response.to_json
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
Loading…
Reference in a new issue