1
0
mirror of https://github.com/iv-org/invidious.git synced 2025-03-21 19:24:33 +05:30

Add endpoint to check if instance is blocked by YT

This commit is contained in:
syeopite 2023-08-29 12:47:30 -07:00
parent ac0c0609bb
commit 51e4fbc5c2
No known key found for this signature in database
GPG Key ID: A73C186DA3955A1A
6 changed files with 73 additions and 0 deletions

@ -345,6 +345,16 @@ feed_threads: 1
##
#decrypt_polling: false
#
# Time interval between two executions of the job that checks
# whether or not Invidious has been blocked by YouTube
#
# Accepted values: a valid time interval (like 1h30m or 90m)
# Default: 30m
#
#blockage_check_interval: 30m
jobs:

@ -185,6 +185,8 @@ Invidious::Jobs.register Invidious::Jobs::NotificationJob.new(CONNECTION_CHANNEL
Invidious::Jobs.register Invidious::Jobs::ClearExpiredItemsJob.new
Invidious::Jobs.register Invidious::Jobs::CheckBlockageStatusJob.new(PG_DB)
Invidious::Jobs.start_all
def popular_videos

@ -138,6 +138,9 @@ class Config
# Playlist length limit
property playlist_length_limit : Int32 = 500
@[YAML::Field(converter: Preferences::TimeSpanConverter)]
property blockage_check_interval : Time::Span = 30.minutes
def disabled?(option)
case disabled = CONFIG.disable_proxy
when Bool

@ -0,0 +1,51 @@
class Invidious::Jobs::CheckBlockageStatusJob < Invidious::Jobs::BaseJob
private getter db : DB::Database
BLOCKAGE_STATUS = {
"version" => "1.0",
"blocked" => false,
}
def initialize(@db)
end
def begin
# Logic mostly taken from bypass_captcha_job.cr
loop do
begin
# TODO find performant way of fetching a random video from the videos table.
video = fetch_video("zj82_v2R6ts", nil)
if !video.nil?
# Assume unblocked
BLOCKAGE_STATUS["blocked"] = false
if video.reason.try &.includes?("YouTube is currently trying to block Invidious instances")
BLOCKAGE_STATUS["blocked"] = true
else
# Fetch a random fetch stream. If it returns a 403 then the instance has been blocked.
random_stream = video.video_streams.sample(1)
if !random_stream.empty?
url = URI.parse(random_stream[0]["url"].as_s)
client = make_client(URI.parse("https://#{url.host.not_nil!}"))
client.get(url.request_target) do |resp|
if resp.status_code == 403
BLOCKAGE_STATUS["blocked"] = true
end
break
end
end
end
end
rescue ex
LOGGER.error("CheckBlockageStatusJob: #{ex.message}")
ensure
LOGGER.debug("CheckBlockageStatusJob: Done, sleeping for #{CONFIG.blockage_check_interval}")
sleep CONFIG.blockage_check_interval
Fiber.yield
end
end
end
end

@ -10,6 +10,12 @@ module Invidious::Routes::API::V1::Misc
end
end
# Endpoint for checking whether or not a specific instance has been blocked
def self.blockage(env)
env.response.content_type = "application/json"
return Invidious::Jobs::CheckBlockageStatusJob::BLOCKAGE_STATUS.to_json
end
# APIv1 currently uses the same logic for both
# user playlists and Invidious playlists. This means that we can't
# reasonably split them yet. This should be addressed in APIv2

@ -291,6 +291,7 @@ module Invidious::Routing
# Misc
get "/api/v1/stats", {{namespace}}::Misc, :stats
get "/api/v1/information/status/blocked", {{namespace}}::Misc, :blockage
get "/api/v1/playlists/:plid", {{namespace}}::Misc, :get_playlist
get "/api/v1/auth/playlists/:plid", {{namespace}}::Misc, :get_playlist
get "/api/v1/mixes/:rdid", {{namespace}}::Misc, :mixes