diff options
Diffstat (limited to 'src/invidious.cr')
| -rw-r--r-- | src/invidious.cr | 98 |
1 files changed, 55 insertions, 43 deletions
diff --git a/src/invidious.cr b/src/invidious.cr index 1b8be67e..deb24ac3 100644 --- a/src/invidious.cr +++ b/src/invidious.cr @@ -106,34 +106,30 @@ LOCALES = { YT_POOL = QUICPool.new(YT_URL, capacity: CONFIG.pool_size, timeout: 2.0) -config = CONFIG -output = STDOUT -loglvl = LogLevel::Debug - +# CLI Kemal.config.extra_options do |parser| parser.banner = "Usage: invidious [arguments]" - parser.on("-c THREADS", "--channel-threads=THREADS", "Number of threads for refreshing channels (default: #{config.channel_threads})") do |number| + parser.on("-c THREADS", "--channel-threads=THREADS", "Number of threads for refreshing channels (default: #{CONFIG.channel_threads})") do |number| begin - config.channel_threads = number.to_i + CONFIG.channel_threads = number.to_i rescue ex puts "THREADS must be integer" exit end end - parser.on("-f THREADS", "--feed-threads=THREADS", "Number of threads for refreshing feeds (default: #{config.feed_threads})") do |number| + parser.on("-f THREADS", "--feed-threads=THREADS", "Number of threads for refreshing feeds (default: #{CONFIG.feed_threads})") do |number| begin - config.feed_threads = number.to_i + CONFIG.feed_threads = number.to_i rescue ex puts "THREADS must be integer" exit end end - parser.on("-o OUTPUT", "--output=OUTPUT", "Redirect output (default: STDOUT)") do |output_arg| - FileUtils.mkdir_p(File.dirname(output_arg)) - output = File.open(output_arg, mode: "a") + parser.on("-o OUTPUT", "--output=OUTPUT", "Redirect output (default: #{CONFIG.output})") do |output| + CONFIG.output = output end - parser.on("-l LEVEL", "--log-level=LEVEL", "Log level, one of #{LogLevel.values} (default: #{loglvl})") do |loglvl_arg| - loglvl = LogLevel.parse(loglvl_arg) + parser.on("-l LEVEL", "--log-level=LEVEL", "Log level, one of #{LogLevel.values} (default: #{CONFIG.log_level})") do |log_level| + CONFIG.log_level = LogLevel.parse(log_level) end parser.on("-v", "--version", "Print version") do puts SOFTWARE.to_pretty_json @@ -143,43 +139,56 @@ end Kemal::CLI.new ARGV -logger = Invidious::LogHandler.new(output, loglvl) +if CONFIG.output.upcase != "STDOUT" + FileUtils.mkdir_p(File.dirname(CONFIG.output)) +end +OUTPUT = CONFIG.output.upcase == "STDOUT" ? STDOUT : File.open(CONFIG.output, mode: "a") +LOGGER = Invidious::LogHandler.new(OUTPUT, CONFIG.log_level) + +config = CONFIG # Check table integrity if CONFIG.check_tables - check_enum(PG_DB, logger, "privacy", PlaylistPrivacy) + check_enum(PG_DB, "privacy", PlaylistPrivacy) - check_table(PG_DB, logger, "channels", InvidiousChannel) - check_table(PG_DB, logger, "channel_videos", ChannelVideo) - check_table(PG_DB, logger, "playlists", InvidiousPlaylist) - check_table(PG_DB, logger, "playlist_videos", PlaylistVideo) - check_table(PG_DB, logger, "nonces", Nonce) - check_table(PG_DB, logger, "session_ids", SessionId) - check_table(PG_DB, logger, "users", User) - check_table(PG_DB, logger, "videos", Video) + check_table(PG_DB, "channels", InvidiousChannel) + check_table(PG_DB, "channel_videos", ChannelVideo) + check_table(PG_DB, "playlists", InvidiousPlaylist) + check_table(PG_DB, "playlist_videos", PlaylistVideo) + check_table(PG_DB, "nonces", Nonce) + check_table(PG_DB, "session_ids", SessionId) + check_table(PG_DB, "users", User) + check_table(PG_DB, "videos", Video) if CONFIG.cache_annotations - check_table(PG_DB, logger, "annotations", Annotation) + check_table(PG_DB, "annotations", Annotation) end end # Start jobs -Invidious::Jobs.register Invidious::Jobs::RefreshChannelsJob.new(PG_DB, logger, config) -Invidious::Jobs.register Invidious::Jobs::RefreshFeedsJob.new(PG_DB, logger, config) -Invidious::Jobs.register Invidious::Jobs::SubscribeToFeedsJob.new(PG_DB, logger, config, HMAC_KEY) -Invidious::Jobs.register Invidious::Jobs::UpdateDecryptFunctionJob.new +Invidious::Jobs.register Invidious::Jobs::RefreshChannelsJob.new(PG_DB, config) +Invidious::Jobs.register Invidious::Jobs::RefreshFeedsJob.new(PG_DB, config) + +DECRYPT_FUNCTION = DecryptFunction.new(CONFIG.decrypt_polling) +if config.decrypt_polling + Invidious::Jobs.register Invidious::Jobs::UpdateDecryptFunctionJob.new +end if config.statistics_enabled Invidious::Jobs.register Invidious::Jobs::StatisticsRefreshJob.new(PG_DB, config, SOFTWARE) end +if (config.use_pubsub_feeds.is_a?(Bool) && config.use_pubsub_feeds.as(Bool)) || (config.use_pubsub_feeds.is_a?(Int32) && config.use_pubsub_feeds.as(Int32) > 0) + Invidious::Jobs.register Invidious::Jobs::SubscribeToFeedsJob.new(PG_DB, config, HMAC_KEY) +end + if config.popular_enabled Invidious::Jobs.register Invidious::Jobs::PullPopularVideosJob.new(PG_DB) end if config.captcha_key - Invidious::Jobs.register Invidious::Jobs::BypassCaptchaJob.new(logger, config) + Invidious::Jobs.register Invidious::Jobs::BypassCaptchaJob.new(config) end connection_channel = Channel({Bool, Channel(PQ::Notification)}).new(32) @@ -191,8 +200,6 @@ def popular_videos Invidious::Jobs::PullPopularVideosJob::POPULAR_VIDEOS.get end -DECRYPT_FUNCTION = Invidious::Jobs::UpdateDecryptFunctionJob::DECRYPT_FUNCTION - before_all do |env| preferences = begin Preferences.from_json(env.request.cookies["PREFS"]?.try &.value || "{}") @@ -1511,7 +1518,7 @@ post "/feed/webhook/:token" do |env| signature = env.request.headers["X-Hub-Signature"].lchop("sha1=") if signature != OpenSSL::HMAC.hexdigest(:sha1, HMAC_KEY, body) - logger.error("/feed/webhook/#{token} : Invalid signature") + LOGGER.error("/feed/webhook/#{token} : Invalid signature") env.response.status_code = 200 next end @@ -2133,14 +2140,13 @@ get "/api/v1/annotations/:id" do |env| file = URI.encode_www_form("#{id[0, 3]}/#{id}.xml") - client = make_client(ARCHIVE_URL) - location = client.get("/download/youtubeannotations_#{index}/#{id[0, 2]}.tar/#{file}") + location = make_client(ARCHIVE_URL, &.get("/download/youtubeannotations_#{index}/#{id[0, 2]}.tar/#{file}")) if !location.headers["Location"]? env.response.status_code = location.status_code end - response = make_client(URI.parse(location.headers["Location"])).get(location.headers["Location"]) + response = make_client(URI.parse(location.headers["Location"]), &.get(location.headers["Location"])) if response.body.empty? env.response.status_code = 404 @@ -2622,6 +2628,8 @@ end begin playlist = get_playlist(PG_DB, plid, locale) + rescue ex : InfoException + next error_json(404, ex) rescue ex next error_json(404, "Playlist does not exist.") end @@ -3182,7 +3190,8 @@ get "/api/manifest/dash/id/:id" do |env| url = url.rchop("</BaseURL>") if local - url = URI.parse(url).full_path + uri = URI.parse(url) + url = "#{uri.full_path}host/#{uri.host}/" end "<BaseURL>#{url}</BaseURL>" @@ -3364,7 +3373,7 @@ get "/latest_version" do |env| env.redirect "/api/v1/captions/#{id}?label=#{label}&title=#{title}" next else - itag = download_widget["itag"].as_s + itag = download_widget["itag"].as_s.to_i local = "true" end end @@ -3498,8 +3507,12 @@ get "/videoplayback" do |env| location = URI.parse(response.headers["Location"]) env.response.headers["Access-Control-Allow-Origin"] = "*" - host = "#{location.scheme}://#{location.host}" - client = make_client(URI.parse(host), region) + new_host = "#{location.scheme}://#{location.host}" + if new_host != host + host = new_host + client.close + client = make_client(URI.parse(new_host), region) + end url = "#{location.full_path}&host=#{location.host}#{region ? "®ion=#{region}" : ""}" else @@ -3530,7 +3543,6 @@ get "/videoplayback" do |env| end begin - client = make_client(URI.parse(host), region) client.get(url, headers) do |response| response.headers.each do |key, value| if !RESPONSE_HEADERS_BLACKLIST.includes?(key.downcase) @@ -3571,8 +3583,6 @@ get "/videoplayback" do |env| chunk_end = chunk_start + HTTP_CHUNK_SIZE - 1 end - client = make_client(URI.parse(host), region) - # TODO: Record bytes written so we can restart after a chunk fails while true if !range_end && content_length @@ -3636,6 +3646,7 @@ get "/videoplayback" do |env| if ex.message != "Error reading socket: Connection reset by peer" break else + client.close client = make_client(URI.parse(host), region) end end @@ -3645,6 +3656,7 @@ get "/videoplayback" do |env| first_chunk = false end end + client.close end get "/ggpht/*" do |env| @@ -3919,7 +3931,7 @@ add_context_storage_type(Array(String)) add_context_storage_type(Preferences) add_context_storage_type(User) -Kemal.config.logger = logger +Kemal.config.logger = LOGGER Kemal.config.host_binding = Kemal.config.host_binding != "0.0.0.0" ? Kemal.config.host_binding : CONFIG.host_binding Kemal.config.port = Kemal.config.port != 3000 ? Kemal.config.port : CONFIG.port Kemal.run |
