From 68cf24d100d55a87d57650716c589a8bdf9a2434 Mon Sep 17 00:00:00 2001 From: Omar Roth Date: Sun, 8 Sep 2019 12:08:59 -0400 Subject: [PATCH] Add support for channel redirects --- src/invidious.cr | 48 +++++++++++++++++++++++++++++++-------- src/invidious/channels.cr | 11 +++++++++ src/invidious/videos.cr | 6 ++++- 3 files changed, 54 insertions(+), 11 deletions(-) diff --git a/src/invidious.cr b/src/invidious.cr index 8f7e1a63..58ba981d 100644 --- a/src/invidious.cr +++ b/src/invidious.cr @@ -391,7 +391,7 @@ get "/watch" do |env| begin video = get_video(id, PG_DB, region: params.region) rescue ex : VideoRedirect - next env.redirect "/watch?v=#{ex.message}" + next env.redirect env.request.resource.gsub(id, ex.video_id) rescue ex error_message = ex.message env.response.status_code = 500 @@ -668,7 +668,7 @@ get "/embed/:id" do |env| begin video = get_video(id, PG_DB, region: params.region) rescue ex : VideoRedirect - next env.redirect "/embed/#{ex.message}" + next env.redirect env.request.resource.gsub(id, ex.video_id) rescue ex error_message = ex.message env.response.status_code = 500 @@ -2632,6 +2632,8 @@ get "/feed/channel/:ucid" do |env| begin channel = get_about_info(ucid, locale) + rescue ex : ChannelRedirect + next env.redirect env.request.resource.gsub(ucid, ex.channel_id) rescue ex error_message = ex.message env.response.status_code = 500 @@ -3035,6 +3037,8 @@ get "/channel/:ucid" do |env| begin channel = get_about_info(ucid, locale) + rescue ex : ChannelRedirect + next env.redirect env.request.resource.gsub(ucid, ex.channel_id) rescue ex error_message = ex.message env.response.status_code = 500 @@ -3102,6 +3106,8 @@ get "/channel/:ucid/playlists" do |env| begin channel = get_about_info(ucid, locale) + rescue ex : ChannelRedirect + next env.redirect env.request.resource.gsub(ucid, ex.channel_id) rescue ex error_message = ex.message env.response.status_code = 500 @@ -3140,6 +3146,8 @@ get "/channel/:ucid/community" do |env| begin channel = get_about_info(ucid, locale) + rescue ex : ChannelRedirect + next env.redirect env.request.resource.gsub(ucid, ex.channel_id) rescue ex error_message = ex.message env.response.status_code = 500 @@ -3195,7 +3203,10 @@ get "/api/v1/storyboards/:id" do |env| begin video = get_video(id, PG_DB, region: region) rescue ex : VideoRedirect - next env.redirect "/api/v1/storyboards/#{ex.message}" + error_message = {"error" => "Video is unavailable", "videoId" => ex.video_id}.to_json + env.response.status_code = 302 + env.response.headers["Location"] = env.request.resource.gsub(id, ex.video_id) + next error_message rescue ex env.response.status_code = 500 next @@ -3280,7 +3291,10 @@ get "/api/v1/captions/:id" do |env| begin video = get_video(id, PG_DB, region: region) rescue ex : VideoRedirect - next env.redirect "/api/v1/captions/#{ex.message}" + error_message = {"error" => "Video is unavailable", "videoId" => ex.video_id}.to_json + env.response.status_code = 302 + env.response.headers["Location"] = env.request.resource.gsub(id, ex.video_id) + next error_message rescue ex env.response.status_code = 500 next @@ -3620,7 +3634,10 @@ get "/api/v1/videos/:id" do |env| begin video = get_video(id, PG_DB, region: region) rescue ex : VideoRedirect - next env.redirect "/api/v1/videos/#{ex.message}" + error_message = {"error" => "Video is unavailable", "videoId" => ex.video_id}.to_json + env.response.status_code = 302 + env.response.headers["Location"] = env.request.resource.gsub(id, ex.video_id) + next error_message rescue ex error_message = {"error" => ex.message}.to_json env.response.status_code = 500 @@ -3723,6 +3740,11 @@ get "/api/v1/channels/:ucid" do |env| begin channel = get_about_info(ucid, locale) + rescue ex : ChannelRedirect + error_message = {"error" => "Channel is unavailable", "authorId" => ex.channel_id}.to_json + env.response.status_code = 302 + env.response.headers["Location"] = env.request.resource.gsub(ucid, ex.channel_id) + next error_message rescue ex error_message = {"error" => ex.message}.to_json env.response.status_code = 500 @@ -3853,6 +3875,11 @@ end begin channel = get_about_info(ucid, locale) + rescue ex : ChannelRedirect + error_message = {"error" => "Channel is unavailable", "authorId" => ex.channel_id}.to_json + env.response.status_code = 302 + env.response.headers["Location"] = env.request.resource.gsub(ucid, ex.channel_id) + next error_message rescue ex error_message = {"error" => ex.message}.to_json env.response.status_code = 500 @@ -3917,6 +3944,11 @@ end begin channel = get_about_info(ucid, locale) + rescue ex : ChannelRedirect + error_message = {"error" => "Channel is unavailable", "authorId" => ex.channel_id}.to_json + env.response.status_code = 302 + env.response.headers["Location"] = env.request.resource.gsub(ucid, ex.channel_id) + next error_message rescue ex error_message = {"error" => ex.message}.to_json env.response.status_code = 500 @@ -4501,11 +4533,7 @@ get "/api/manifest/dash/id/:id" do |env| begin video = get_video(id, PG_DB, region: region) rescue ex : VideoRedirect - url = "/api/manifest/dash/id/#{ex.message}" - if env.params.query - url += "?#{env.params.query}" - end - next env.redirect url + next env.redirect env.request.resource.gsub(id, ex.video_id) rescue ex env.response.status_code = 403 next diff --git a/src/invidious/channels.cr b/src/invidious/channels.cr index 00eac902..3291efbd 100644 --- a/src/invidious/channels.cr +++ b/src/invidious/channels.cr @@ -127,6 +127,13 @@ struct AboutChannel }) end +class ChannelRedirect < Exception + property channel_id : String + + def initialize(@channel_id) + end +end + def get_batch_channels(channels, db, refresh = false, pull_all_videos = true, max_threads = 10) finished_channel = Channel(String | Nil).new @@ -927,6 +934,10 @@ def get_about_info(ucid, locale) about = client.get("/user/#{ucid}/about?disable_polymer=1&gl=US&hl=en") end + if md = about.headers["location"]?.try &.match(/\/channel\/(?UC[a-zA-Z0-9_-]{22})/) + raise ChannelRedirect.new(channel_id: md["ucid"]) + end + about = XML.parse_html(about.body) if about.xpath_node(%q(//div[contains(@class, "channel-empty-message")])) diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr index 7b68656e..3cda835b 100644 --- a/src/invidious/videos.cr +++ b/src/invidious/videos.cr @@ -882,6 +882,10 @@ struct CaptionName end class VideoRedirect < Exception + property video_id : String + + def initialize(@video_id) + end end def get_video(id, db, refresh = true, region = nil, force_refresh = false) @@ -1149,7 +1153,7 @@ def fetch_video(id, region) response = client.get("/watch?v=#{id}&gl=US&hl=en&disable_polymer=1&has_verified=1&bpctr=9999999999") if md = response.headers["location"]?.try &.match(/v=(?[a-zA-Z0-9_-]{11})/) - raise VideoRedirect.new(md["id"]) + raise VideoRedirect.new(video_id: md["id"]) end html = XML.parse_html(response.body)