summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/invidious/routes/api/manifest.cr15
-rw-r--r--src/invidious/routes/api/v1/authenticated.cr5
-rw-r--r--src/invidious/routes/api/v1/channels.cr15
-rw-r--r--src/invidious/routes/api/v1/feeds.cr5
-rw-r--r--src/invidious/routes/api/v1/misc.cr2
-rw-r--r--src/invidious/routes/api/v1/routes.cr67
-rw-r--r--src/invidious/routes/api/v1/search.cr2
-rw-r--r--src/invidious/routes/api/v1/videos.cr31
-rw-r--r--src/invidious/routes/video_playback.cr10
-rw-r--r--src/invidious/routing.cr89
10 files changed, 122 insertions, 119 deletions
diff --git a/src/invidious/routes/api/manifest.cr b/src/invidious/routes/api/manifest.cr
index 31e1a123..93bee55c 100644
--- a/src/invidious/routes/api/manifest.cr
+++ b/src/invidious/routes/api/manifest.cr
@@ -1,4 +1,4 @@
-module Invidious::Routes::APIManifest
+module Invidious::Routes::API::Manifest
# /api/manifest/dash/id/:id
def self.get_dash_video_id(env)
env.response.headers.add("Access-Control-Allow-Origin", "*")
@@ -222,16 +222,3 @@ module Invidious::Routes::APIManifest
manifest
end
end
-
-macro define_api_manifest_routes
- Invidious::Routing.get "/api/manifest/dash/id/:id", Invidious::Routes::APIManifest, :get_dash_video_id
-
- Invidious::Routing.get "/api/manifest/dash/id/videoplayback", Invidious::Routes::APIManifest, :get_dash_video_playback
- Invidious::Routing.get "/api/manifest/dash/id/videoplayback/*", Invidious::Routes::APIManifest, :get_dash_video_playback_greedy
-
- Invidious::Routing.options "/api/manifest/dash/id/videoplayback", Invidious::Routes::APIManifest, :options_dash_video_playback
- Invidious::Routing.options "/api/manifest/dash/id/videoplayback/*", Invidious::Routes::APIManifest, :options_dash_video_playback
-
- Invidious::Routing.get "/api/manifest/hls_playlist/*", Invidious::Routes::APIManifest, :get_hls_playlist
- Invidious::Routing.get "/api/manifest/hls_variant/*", Invidious::Routes::APIManifest, :get_hls_variant
-end
diff --git a/src/invidious/routes/api/v1/authenticated.cr b/src/invidious/routes/api/v1/authenticated.cr
index 4201f26d..b4e9e9c8 100644
--- a/src/invidious/routes/api/v1/authenticated.cr
+++ b/src/invidious/routes/api/v1/authenticated.cr
@@ -1,4 +1,7 @@
-module Invidious::Routes::APIv1::Authenticated
+module Invidious::Routes::API::V1::Authenticated
+ # The notification APIs cannot be extracted yet!
+ # They require the *local* notifications constant defined in invidious.cr
+ #
# def self.notifications(env)
# env.response.content_type = "text/event-stream"
diff --git a/src/invidious/routes/api/v1/channels.cr b/src/invidious/routes/api/v1/channels.cr
index 3401232b..5caa656d 100644
--- a/src/invidious/routes/api/v1/channels.cr
+++ b/src/invidious/routes/api/v1/channels.cr
@@ -1,4 +1,4 @@
-module Invidious::Routes::APIv1::Channels
+module Invidious::Routes::API::V1::Channels
def self.home(env)
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
@@ -241,7 +241,7 @@ module Invidious::Routes::APIv1::Channels
end
end
- def self.channel_search(env)
+ def self.search(env)
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
env.response.content_type = "application/json"
@@ -263,4 +263,15 @@ module Invidious::Routes::APIv1::Channels
end
end
end
+
+ # 301 redirect from /api/v1/channels/comments/:ucid
+ # and /api/v1/channels/:ucid/comments to new /api/v1/channels/:ucid/community and
+ # corresponding equivalent URL structure of the other one.
+ def self.channel_comments_redirect(env)
+ env.response.content_type = "application/json"
+ ucid = env.params.url["ucid"]
+
+ env.response.headers["Location"] = "/api/v1/channels/#{ucid}/community?#{env.params.query}"
+ haltf env, status_code: 301
+ end
end
diff --git a/src/invidious/routes/api/v1/feeds.cr b/src/invidious/routes/api/v1/feeds.cr
index 0107b71d..bb8f661b 100644
--- a/src/invidious/routes/api/v1/feeds.cr
+++ b/src/invidious/routes/api/v1/feeds.cr
@@ -1,4 +1,4 @@
-module Invidious::Routes::APIv1::Feeds
+module Invidious::Routes::API::V1::Feeds
def self.trending(env)
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
@@ -31,8 +31,7 @@ module Invidious::Routes::APIv1::Feeds
if !CONFIG.popular_enabled
error_message = {"error" => "Administrator has disabled this endpoint."}.to_json
- env.response.status_code = 400
- return error_message
+ haltf env, 400, error_message
end
JSON.build do |json|
diff --git a/src/invidious/routes/api/v1/misc.cr b/src/invidious/routes/api/v1/misc.cr
index afb61fc1..cf95bd9b 100644
--- a/src/invidious/routes/api/v1/misc.cr
+++ b/src/invidious/routes/api/v1/misc.cr
@@ -1,4 +1,4 @@
-module Invidious::Routes::APIv1::Misc
+module Invidious::Routes::API::V1::Misc
# Stats API endpoint for Invidious
def self.stats(env)
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
diff --git a/src/invidious/routes/api/v1/routes.cr b/src/invidious/routes/api/v1/routes.cr
deleted file mode 100644
index 9e3c03be..00000000
--- a/src/invidious/routes/api/v1/routes.cr
+++ /dev/null
@@ -1,67 +0,0 @@
-# There is far too many API routes to define in invidious.cr
-# so we'll just do it here instead with a macro.
-macro define_v1_api_routes(base_url = "/api/v1")
- # Videos
- Invidious::Routing.get "#{{{base_url}}}/videos/:id", Invidious::Routes::APIv1::Videos, :videos
- Invidious::Routing.get "#{{{base_url}}}/storyboards/:id", Invidious::Routes::APIv1::Videos, :storyboards
- Invidious::Routing.get "#{{{base_url}}}/captions/:id", Invidious::Routes::APIv1::Videos, :captions
- Invidious::Routing.get "#{{{base_url}}}/annotations/:id", Invidious::Routes::APIv1::Videos, :annotations
- Invidious::Routing.get "#{{{base_url}}}/comments/:id", Invidious::Routes::APIv1::Videos, :comments
-
- # Feeds
- Invidious::Routing.get "#{{{base_url}}}/trending", Invidious::Routes::APIv1::Feeds, :trending
- Invidious::Routing.get "#{{{base_url}}}/popular", Invidious::Routes::APIv1::Feeds, :popular
-
- # Channels
- Invidious::Routing.get "#{{{base_url}}}/channels/:ucid", Invidious::Routes::APIv1::Channels, :home
- {% for route in {
- {"home", "home"},
- {"videos", "videos"},
- {"latest", "latest"},
- {"playlists", "playlists"},
- {"comments", "community"}, # Why is the route for the community API `comments`?,
- {"search", "channel_search"},
- } %}
-
- Invidious::Routing.get "#{{{base_url}}}/channels/#{{{route[0]}}}/:ucid", Invidious::Routes::APIv1::Channels, :{{route[1]}}
- Invidious::Routing.get "#{{{base_url}}}/channels/:ucid/#{{{route[0]}}}", Invidious::Routes::APIv1::Channels, :{{route[1]}}
- {% end %}
-
- # Search
- Invidious::Routing.get "#{{{base_url}}}/search", Invidious::Routes::APIv1::Search, :search
- Invidious::Routing.get "#{{{base_url}}}/search/suggestions/:id", Invidious::Routes::APIv1::Search, :search_suggestions
-
- # Authenticated
- # Invidious::Routing.get "#{{{base_url}}}/auth/notifications", Invidious::Routes::APIv1::Authenticated, :notifications
- # Invidious::Routing.post "#{{{base_url}}}/auth/notifications", Invidious::Routes::APIv1::Authenticated, :notifications
-
- Invidious::Routing.get "#{{{base_url}}}/auth/preferences", Invidious::Routes::APIv1::Authenticated, :get_preferences
- Invidious::Routing.post "#{{{base_url}}}/auth/preferences", Invidious::Routes::APIv1::Authenticated, :set_preferences
-
- Invidious::Routing.get "#{{{base_url}}}/auth/feed", Invidious::Routes::APIv1::Authenticated, :feed
-
- Invidious::Routing.get "#{{{base_url}}}/auth/subscriptions", Invidious::Routes::APIv1::Authenticated, :get_subscriptions
- Invidious::Routing.post "#{{{base_url}}}/auth/subscriptions/:ucid", Invidious::Routes::APIv1::Authenticated, :subscribe_channel
- Invidious::Routing.delete "#{{{base_url}}}/auth/subscriptions/:ucid", Invidious::Routes::APIv1::Authenticated, :unsubscribe_channel
-
-
- Invidious::Routing.get "#{{{base_url}}}/auth/playlists", Invidious::Routes::APIv1::Authenticated, :list_playlists
- Invidious::Routing.post "#{{{base_url}}}/auth/playlists", Invidious::Routes::APIv1::Authenticated, :create_playlist
- Invidious::Routing.patch "#{{{base_url}}}/auth/playlists/:ucid", Invidious::Routes::APIv1::Authenticated, :update_playlist_attribute
- Invidious::Routing.delete "#{{{base_url}}}/auth/playlists/:ucid", Invidious::Routes::APIv1::Authenticated, :delete_playlist
-
-
- Invidious::Routing.post "#{{{base_url}}}/auth/playlists/:ucid/videos", Invidious::Routes::APIv1::Authenticated, :insert_video_into_playlist
- Invidious::Routing.delete "#{{{base_url}}}/auth/playlists/:ucid/videos/:index", Invidious::Routes::APIv1::Authenticated, :delete_video_in_playlist
-
- Invidious::Routing.get "#{{{base_url}}}/auth/tokens", Invidious::Routes::APIv1::Authenticated, :get_tokens
- Invidious::Routing.post "#{{{base_url}}}/auth/tokens/register", Invidious::Routes::APIv1::Authenticated, :register_token
- Invidious::Routing.post "#{{{base_url}}}/auth/tokens/unregister", Invidious::Routes::APIv1::Authenticated, :unregister_token
-
- # Misc
- Invidious::Routing.get "#{{{base_url}}}/stats", Invidious::Routes::APIv1::Misc, :stats
- Invidious::Routing.get "#{{{base_url}}}/playlists/:plid", Invidious::Routes::APIv1::Misc, :get_playlist
- Invidious::Routing.get "#{{{base_url}}}/auth/playlists/:plid", Invidious::Routes::APIv1::Misc, :get_playlist
- Invidious::Routing.get "#{{{base_url}}}//mixes/:rdid", Invidious::Routes::APIv1::Misc, :mixes
-
-end
diff --git a/src/invidious/routes/api/v1/search.cr b/src/invidious/routes/api/v1/search.cr
index e4d5809f..f3a6fa06 100644
--- a/src/invidious/routes/api/v1/search.cr
+++ b/src/invidious/routes/api/v1/search.cr
@@ -1,4 +1,4 @@
-module Invidious::Routes::APIv1::Search
+module Invidious::Routes::API::V1::Search
def self.search(env)
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
region = env.params.query["region"]?
diff --git a/src/invidious/routes/api/v1/videos.cr b/src/invidious/routes/api/v1/videos.cr
index 0eb2fca3..575e6fdf 100644
--- a/src/invidious/routes/api/v1/videos.cr
+++ b/src/invidious/routes/api/v1/videos.cr
@@ -1,4 +1,4 @@
-module Invidious::Routes::APIv1::Videos
+module Invidious::Routes::API::V1::Videos
def self.videos(env)
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
@@ -41,8 +41,7 @@ module Invidious::Routes::APIv1::Videos
env.response.headers["Location"] = env.request.resource.gsub(id, ex.video_id)
return error_json(302, "Video is unavailable", {"videoId" => ex.video_id})
rescue ex
- env.response.status_code = 500
- return
+ haltf env, 500
end
captions = video.captions
@@ -80,8 +79,7 @@ module Invidious::Routes::APIv1::Videos
end
if caption.empty?
- env.response.status_code = 404
- return
+ haltf env, 404
else
caption = caption[0]
end
@@ -164,8 +162,7 @@ module Invidious::Routes::APIv1::Videos
env.response.headers["Location"] = env.request.resource.gsub(id, ex.video_id)
return error_json(302, "Video is unavailable", {"videoId" => ex.video_id})
rescue ex
- env.response.status_code = 500
- return
+ haltf env, 500
end
storyboards = video.storyboards
@@ -189,8 +186,7 @@ module Invidious::Routes::APIv1::Videos
storyboard = storyboards.select { |storyboard| width == "#{storyboard[:width]}" || height == "#{storyboard[:height]}" }
if storyboard.empty?
- env.response.status_code = 404
- return
+ haltf env, 404
else
storyboard = storyboard[0]
end
@@ -236,8 +232,7 @@ module Invidious::Routes::APIv1::Videos
source ||= "archive"
if !id.match(/[a-zA-Z0-9_-]{11}/)
- env.response.status_code = 400
- return
+ haltf env, 400
end
annotations = ""
@@ -267,13 +262,11 @@ module Invidious::Routes::APIv1::Videos
response = make_client(URI.parse(location.headers["Location"]), &.get(location.headers["Location"]))
if response.body.empty?
- env.response.status_code = 404
- return
+ haltf env, 404
end
if response.status_code != 200
- env.response.status_code = response.status_code
- return
+ haltf env, response.status_code
end
annotations = response.body
@@ -284,8 +277,7 @@ module Invidious::Routes::APIv1::Videos
response = YT_POOL.client &.get("/annotations_invideo?video_id=#{id}")
if response.status_code != 200
- env.response.status_code = response.status_code
- return
+ haltf env, response.status_code
end
annotations = response.body
@@ -293,7 +285,7 @@ module Invidious::Routes::APIv1::Videos
etag = sha256(annotations)[0, 16]
if env.request.headers["If-None-Match"]?.try &.== etag
- env.response.status_code = 304
+ haltf env, 304
else
env.response.headers["ETag"] = etag
annotations
@@ -349,8 +341,7 @@ module Invidious::Routes::APIv1::Videos
end
if !reddit_thread || !comments
- env.response.status_code = 404
- return
+ haltf env, 404
end
if format == "json"
diff --git a/src/invidious/routes/video_playback.cr b/src/invidious/routes/video_playback.cr
index 0fe2853d..acbf62b4 100644
--- a/src/invidious/routes/video_playback.cr
+++ b/src/invidious/routes/video_playback.cr
@@ -278,13 +278,3 @@ module Invidious::Routes::VideoPlayback
return env.redirect url
end
end
-
-macro define_video_playback_routes
- Invidious::Routing.get "/videoplayback", Invidious::Routes::VideoPlayback, :get_video_playback
- Invidious::Routing.get "/videoplayback/*", Invidious::Routes::VideoPlayback, :get_video_playback_greedy
-
- Invidious::Routing.options "/videoplayback", Invidious::Routes::VideoPlayback, :options_video_playback
- Invidious::Routing.options "/videoplayback/*", Invidious::Routes::VideoPlayback, :options_video_playback
-
- Invidious::Routing.get "/latest_version", Invidious::Routes::VideoPlayback, :latest_version
-end
diff --git a/src/invidious/routing.cr b/src/invidious/routing.cr
index 1fd3477d..62a51399 100644
--- a/src/invidious/routing.cr
+++ b/src/invidious/routing.cr
@@ -9,3 +9,92 @@ module Invidious::Routing
{% end %}
end
+
+macro define_v1_api_routes
+ {{namespace = Invidious::Routes::API::V1}}
+ # Videos
+ Invidious::Routing.get "/api/v1/videos/:id", {{namespace}}::Videos, :videos
+ Invidious::Routing.get "/api/v1/storyboards/:id", {{namespace}}::Videos, :storyboards
+ Invidious::Routing.get "/api/v1/captions/:id", {{namespace}}::Videos, :captions
+ Invidious::Routing.get "/api/v1/annotations/:id", {{namespace}}::Videos, :annotations
+ Invidious::Routing.get "/api/v1/comments/:id", {{namespace}}::Videos, :comments
+
+ # Feeds
+ Invidious::Routing.get "/api/v1/trending", {{namespace}}::Feeds, :trending
+ Invidious::Routing.get "/api/v1/popular", {{namespace}}::Feeds, :popular
+
+ # Channels
+ Invidious::Routing.get "/api/v1/channels/:ucid", {{namespace}}::Channels, :home
+ {% for route in {"videos", "latest", "playlists", "community", "search"} %}
+ Invidious::Routing.get "/api/v1/channels/#{{{route}}}/:ucid", {{namespace}}::Channels, :{{route}}
+ Invidious::Routing.get "/api/v1/channels/:ucid/#{{{route}}}", {{namespace}}::Channels, :{{route}}
+ {% end %}
+
+ # 301 redirects to new /api/v1/channels/community/:ucid and /:ucid/community
+ Invidious::Routing.get "/api/v1/channels/comments/:ucid", {{namespace}}::Channels, :channel_comments_redirect
+ Invidious::Routing.get "/api/v1/channels/:ucid/comments", {{namespace}}::Channels, :channel_comments_redirect
+
+
+ # Search
+ Invidious::Routing.get "/api/v1/search", {{namespace}}::Search, :search
+ Invidious::Routing.get "/api/v1/search/suggestions/:id", {{namespace}}::Search, :search_suggestions
+
+ # Authenticated
+
+ # The notification APIs cannot be extracted yet! They require the *local* notifications constant defined in invidious.cr
+ #
+ # Invidious::Routing.get "/api/v1/auth/notifications", {{namespace}}::Authenticated, :notifications
+ # Invidious::Routing.post "/api/v1/auth/notifications", {{namespace}}::Authenticated, :notifications
+
+ Invidious::Routing.get "/api/v1/auth/preferences", {{namespace}}::Authenticated, :get_preferences
+ Invidious::Routing.post "/api/v1/auth/preferences", {{namespace}}::Authenticated, :set_preferences
+
+ Invidious::Routing.get "/api/v1/auth/feed", {{namespace}}::Authenticated, :feed
+
+ Invidious::Routing.get "/api/v1/auth/subscriptions", {{namespace}}::Authenticated, :get_subscriptions
+ Invidious::Routing.post "/api/v1/auth/subscriptions/:ucid", {{namespace}}::Authenticated, :subscribe_channel
+ Invidious::Routing.delete "/api/v1/auth/subscriptions/:ucid", {{namespace}}::Authenticated, :unsubscribe_channel
+
+
+ Invidious::Routing.get "/api/v1/auth/playlists", {{namespace}}::Authenticated, :list_playlists
+ Invidious::Routing.post "/api/v1/auth/playlists", {{namespace}}::Authenticated, :create_playlist
+ Invidious::Routing.patch "/api/v1/auth/playlists/:plid",{{namespace}}:: Authenticated, :update_playlist_attribute
+ Invidious::Routing.delete "/api/v1/auth/playlists/:plid", {{namespace}}::Authenticated, :delete_playlist
+
+
+ Invidious::Routing.post "/api/v1/auth/playlists/:plid/videos", {{namespace}}::Authenticated, :insert_video_into_playlist
+ Invidious::Routing.delete "/api/v1/auth/playlists/:plid/videos/:index", {{namespace}}::Authenticated, :delete_video_in_playlist
+
+ Invidious::Routing.get "/api/v1/auth/tokens", {{namespace}}::Authenticated, :get_tokens
+ Invidious::Routing.post "/api/v1/auth/tokens/register", {{namespace}}::Authenticated, :register_token
+ Invidious::Routing.post "/api/v1/auth/tokens/unregister", {{namespace}}::Authenticated, :unregister_token
+
+ # Misc
+ Invidious::Routing.get "/api/v1/stats", {{namespace}}::Misc, :stats
+ Invidious::Routing.get "/api/v1/playlists/:plid", {{namespace}}::Misc, :get_playlist
+ Invidious::Routing.get "/api/v1/auth/playlists/:plid", {{namespace}}::Misc, :get_playlist
+ Invidious::Routing.get "/api/v1//mixes/:rdid", {{namespace}}::Misc, :mixes
+end
+
+macro define_api_manifest_routes
+ Invidious::Routing.get "/api/manifest/dash/id/:id", Invidious::Routes::API::Manifest, :get_dash_video_id
+
+ Invidious::Routing.get "/api/manifest/dash/id/videoplayback", Invidious::Routes::API::Manifest, :get_dash_video_playback
+ Invidious::Routing.get "/api/manifest/dash/id/videoplayback/*", Invidious::Routes::API::Manifest, :get_dash_video_playback_greedy
+
+ Invidious::Routing.options "/api/manifest/dash/id/videoplayback", Invidious::Routes::API::Manifest, :options_dash_video_playback
+ Invidious::Routing.options "/api/manifest/dash/id/videoplayback/*", Invidious::Routes::API::Manifest, :options_dash_video_playback
+
+ Invidious::Routing.get "/api/manifest/hls_playlist/*", Invidious::Routes::API::Manifest, :get_hls_playlist
+ Invidious::Routing.get "/api/manifest/hls_variant/*", Invidious::Routes::API::Manifest, :get_hls_variant
+end
+
+macro define_video_playback_routes
+ Invidious::Routing.get "/videoplayback", Invidious::Routes::VideoPlayback, :get_video_playback
+ Invidious::Routing.get "/videoplayback/*", Invidious::Routes::VideoPlayback, :get_video_playback_greedy
+
+ Invidious::Routing.options "/videoplayback", Invidious::Routes::VideoPlayback, :options_video_playback
+ Invidious::Routing.options "/videoplayback/*", Invidious::Routes::VideoPlayback, :options_video_playback
+
+ Invidious::Routing.get "/latest_version", Invidious::Routes::VideoPlayback, :latest_version
+end