summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/invidious.cr93
-rw-r--r--src/invidious/comments.cr10
-rw-r--r--src/invidious/helpers/errors.cr32
-rw-r--r--src/invidious/helpers/helpers.cr57
-rw-r--r--src/invidious/helpers/logger.cr2
-rw-r--r--src/invidious/helpers/proxy.cr6
-rw-r--r--src/invidious/helpers/utils.cr14
-rw-r--r--src/invidious/jobs/bypass_captcha_job.cr31
-rw-r--r--src/invidious/jobs/refresh_channels_job.cr7
-rw-r--r--src/invidious/jobs/refresh_feeds_job.cr5
-rw-r--r--src/invidious/jobs/statistics_refresh_job.cr5
-rw-r--r--src/invidious/jobs/subscribe_to_feeds_job.cr9
-rw-r--r--src/invidious/routes/base_route.cr4
-rw-r--r--src/invidious/routes/embed.cr (renamed from src/invidious/routes/embed/show.cr)32
-rw-r--r--src/invidious/routes/embed/index.cr25
-rw-r--r--src/invidious/routes/licenses.cr6
-rw-r--r--src/invidious/routes/login.cr26
-rw-r--r--src/invidious/routes/misc.cr (renamed from src/invidious/routes/home.cr)14
-rw-r--r--src/invidious/routes/preferences.cr (renamed from src/invidious/routes/user_preferences.cr)33
-rw-r--r--src/invidious/routes/privacy.cr6
-rw-r--r--src/invidious/routes/watch.cr4
-rw-r--r--src/invidious/routing.cr4
-rw-r--r--src/invidious/views/channel.ecr4
-rw-r--r--src/invidious/views/community.ecr4
-rw-r--r--src/invidious/views/components/item.ecr6
-rw-r--r--src/invidious/views/components/player.ecr2
-rw-r--r--src/invidious/views/components/player_sources.ecr1
-rw-r--r--src/invidious/views/playlists.ecr4
-rw-r--r--src/invidious/views/preferences.ecr14
-rw-r--r--src/invidious/views/template.ecr2
-rw-r--r--src/invidious/views/watch.ecr3
31 files changed, 252 insertions, 213 deletions
diff --git a/src/invidious.cr b/src/invidious.cr
index 10c23dac..ec6df302 100644
--- a/src/invidious.cr
+++ b/src/invidious.cr
@@ -30,11 +30,8 @@ require "./invidious/*"
require "./invidious/routes/**"
require "./invidious/jobs/**"
-ENV_CONFIG_NAME = "INVIDIOUS_CONFIG"
-
-CONFIG_STR = ENV.has_key?(ENV_CONFIG_NAME) ? ENV.fetch(ENV_CONFIG_NAME) : File.read("config/config.yml")
-CONFIG = Config.from_yaml(CONFIG_STR)
-HMAC_KEY = CONFIG.hmac_key || Random::Secure.hex(32)
+CONFIG = Config.load
+HMAC_KEY = CONFIG.hmac_key || Random::Secure.hex(32)
PG_URL = URI.new(
scheme: "postgres",
@@ -52,7 +49,7 @@ PUBSUB_URL = URI.parse("https://pubsubhubbub.appspot.com")
REDDIT_URL = URI.parse("https://www.reddit.com")
TEXTCAPTCHA_URL = URI.parse("https://textcaptcha.com")
YT_URL = URI.parse("https://www.youtube.com")
-HOST_URL = make_host_url(CONFIG, Kemal.config)
+HOST_URL = make_host_url(Kemal.config)
CHARS_SAFE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_"
TEST_IDS = {"AgbeGFYluEA", "BaW_jenozKc", "a9LDPn-MO4I", "ddFvjfvPnqk", "iqKdEhx-dD4"}
@@ -85,6 +82,7 @@ LOCALES = {
"eo" => load_locale("eo"),
"es" => load_locale("es"),
"fa" => load_locale("fa"),
+ "fi" => load_locale("fi"),
"fr" => load_locale("fr"),
"hr" => load_locale("hr"),
"is" => load_locale("is"),
@@ -145,8 +143,6 @@ 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, "privacy", PlaylistPrivacy)
@@ -167,28 +163,33 @@ end
# Start jobs
-Invidious::Jobs.register Invidious::Jobs::RefreshChannelsJob.new(PG_DB, config)
-Invidious::Jobs.register Invidious::Jobs::RefreshFeedsJob.new(PG_DB, config)
+if CONFIG.channel_threads > 0
+ Invidious::Jobs.register Invidious::Jobs::RefreshChannelsJob.new(PG_DB)
+end
+
+if CONFIG.feed_threads > 0
+ Invidious::Jobs.register Invidious::Jobs::RefreshFeedsJob.new(PG_DB)
+end
DECRYPT_FUNCTION = DecryptFunction.new(CONFIG.decrypt_polling)
-if 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)
+if CONFIG.statistics_enabled
+ Invidious::Jobs.register Invidious::Jobs::StatisticsRefreshJob.new(PG_DB, 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)
+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, HMAC_KEY)
end
-if config.popular_enabled
+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(config)
+if CONFIG.captcha_key
+ Invidious::Jobs.register Invidious::Jobs::BypassCaptchaJob.new
end
connection_channel = Channel({Bool, Channel(PQ::Notification)}).new(32)
@@ -216,10 +217,10 @@ before_all do |env|
extra_media_csp += " https://*.youtube.com:443"
end
# TODO: Remove style-src's 'unsafe-inline', requires to remove all inline styles (<style> [..] </style>, style=" [..] ")
- env.response.headers["Content-Security-Policy"] = "default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; connect-src 'self'; manifest-src 'self'; media-src 'self' blob:#{extra_media_csp}"
+ env.response.headers["Content-Security-Policy"] = "default-src 'none'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self' data:; connect-src 'self'; manifest-src 'self'; media-src 'self' blob:#{extra_media_csp}; child-src blob:"
env.response.headers["Referrer-Policy"] = "same-origin"
- if (Kemal.config.ssl || config.https_only) && config.hsts
+ if (Kemal.config.ssl || CONFIG.https_only) && CONFIG.hsts
env.response.headers["Strict-Transport-Security"] = "max-age=31536000; includeSubDomains; preload"
end
@@ -310,12 +311,12 @@ before_all do |env|
env.set "current_page", URI.encode_www_form(current_page)
end
-Invidious::Routing.get "/", Invidious::Routes::Home
-Invidious::Routing.get "/privacy", Invidious::Routes::Privacy
-Invidious::Routing.get "/licenses", Invidious::Routes::Licenses
+Invidious::Routing.get "/", Invidious::Routes::Misc, :home
+Invidious::Routing.get "/privacy", Invidious::Routes::Misc, :privacy
+Invidious::Routing.get "/licenses", Invidious::Routes::Misc, :licenses
Invidious::Routing.get "/watch", Invidious::Routes::Watch
-Invidious::Routing.get "/embed/", Invidious::Routes::Embed::Index
-Invidious::Routing.get "/embed/:id", Invidious::Routes::Embed::Show
+Invidious::Routing.get "/embed/", Invidious::Routes::Embed, :redirect
+Invidious::Routing.get "/embed/:id", Invidious::Routes::Embed, :show
Invidious::Routing.get "/view_all_playlists", Invidious::Routes::Playlists, :index
Invidious::Routing.get "/create_playlist", Invidious::Routes::Playlists, :new
Invidious::Routing.post "/create_playlist", Invidious::Routes::Playlists, :create
@@ -334,9 +335,9 @@ Invidious::Routing.get "/search", Invidious::Routes::Search, :search
Invidious::Routing.get "/login", Invidious::Routes::Login, :login_page
Invidious::Routing.post "/login", Invidious::Routes::Login, :login
Invidious::Routing.post "/signout", Invidious::Routes::Login, :signout
-Invidious::Routing.get "/preferences", Invidious::Routes::UserPreferences, :show
-Invidious::Routing.post "/preferences", Invidious::Routes::UserPreferences, :update
-Invidious::Routing.get "/toggle_theme", Invidious::Routes::UserPreferences, :toggle_theme
+Invidious::Routing.get "/preferences", Invidious::Routes::PreferencesRoute, :show
+Invidious::Routing.post "/preferences", Invidious::Routes::PreferencesRoute, :update
+Invidious::Routing.get "/toggle_theme", Invidious::Routes::PreferencesRoute, :toggle_theme
# Users
@@ -1164,7 +1165,7 @@ end
get "/feed/popular" do |env|
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
- if config.popular_enabled
+ if CONFIG.popular_enabled
templated "popular"
else
message = translate(locale, "The Popular feed has been disabled by the administrator.")
@@ -1427,9 +1428,9 @@ get "/feed/playlist/:plid" do |env|
node.attributes.each do |attribute|
case attribute.name
when "url", "href"
- full_path = URI.parse(node[attribute.name]).full_path
- query_string_opt = full_path.starts_with?("/watch?v=") ? "&#{params}" : ""
- node[attribute.name] = "#{HOST_URL}#{full_path}#{query_string_opt}"
+ request_target = URI.parse(node[attribute.name]).request_target
+ query_string_opt = request_target.starts_with?("/watch?v=") ? "&#{params}" : ""
+ node[attribute.name] = "#{HOST_URL}#{request_target}#{query_string_opt}"
else nil # Skip
end
end
@@ -1438,7 +1439,7 @@ get "/feed/playlist/:plid" do |env|
document = document.to_xml(options: XML::SaveOptions::NO_DECL)
document.scan(/<uri>(?<url>[^<]+)<\/uri>/).each do |match|
- content = "#{HOST_URL}#{URI.parse(match["url"]).full_path}"
+ content = "#{HOST_URL}#{URI.parse(match["url"]).request_target}"
document = document.gsub(match[0], "<uri>#{content}</uri>")
end
@@ -1633,7 +1634,7 @@ end
get "/attribution_link" do |env|
if query = env.params.query["u"]?
- url = URI.parse(query).full_path
+ url = URI.parse(query).request_target
else
url = "/"
end
@@ -1822,7 +1823,7 @@ get "/api/v1/stats" do |env|
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
env.response.content_type = "application/json"
- if !config.statistics_enabled
+ if !CONFIG.statistics_enabled
next error_json(400, "Statistics are not enabled.")
end
@@ -1977,7 +1978,7 @@ get "/api/v1/captions/:id" do |env|
caption = caption[0]
end
- url = URI.parse("#{caption.baseUrl}&tlang=#{tlang}").full_path
+ url = URI.parse("#{caption.baseUrl}&tlang=#{tlang}").request_target
# Auto-generated captions often have cues that aren't aligned properly with the video,
# as well as some other markup that makes it cumbersome, so we try to fix that here
@@ -2232,7 +2233,7 @@ get "/api/v1/popular" do |env|
env.response.content_type = "application/json"
- if !config.popular_enabled
+ if !CONFIG.popular_enabled
error_message = {"error" => "Administrator has disabled this endpoint."}.to_json
env.response.status_code = 400
next error_message
@@ -3183,7 +3184,7 @@ get "/api/manifest/dash/id/:id" do |env|
end
if dashmpd = video.dash_manifest_url
- manifest = YT_POOL.client &.get(URI.parse(dashmpd).full_path).body
+ manifest = YT_POOL.client &.get(URI.parse(dashmpd).request_target).body
manifest = manifest.gsub(/<BaseURL>[^<]+<\/BaseURL>/) do |baseurl|
url = baseurl.lchop("<BaseURL>")
@@ -3191,7 +3192,7 @@ get "/api/manifest/dash/id/:id" do |env|
if local
uri = URI.parse(url)
- url = "#{uri.full_path}host/#{uri.host}/"
+ url = "#{uri.request_target}host/#{uri.host}/"
end
"<BaseURL>#{url}</BaseURL>"
@@ -3204,7 +3205,7 @@ get "/api/manifest/dash/id/:id" do |env|
if local
adaptive_fmts.each do |fmt|
- fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).full_path)
+ fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).request_target)
end
end
@@ -3402,7 +3403,7 @@ get "/latest_version" do |env|
next
end
- url = URI.parse(url).full_path.not_nil! if local
+ url = URI.parse(url).request_target.not_nil! if local
url = "#{url}&title=#{title}" if title
env.redirect url
@@ -3514,7 +3515,7 @@ get "/videoplayback" do |env|
client = make_client(URI.parse(new_host), region)
end
- url = "#{location.full_path}&host=#{location.host}#{region ? "&region=#{region}" : ""}"
+ url = "#{location.request_target}&host=#{location.host}#{region ? "&region=#{region}" : ""}"
else
break
end
@@ -3554,7 +3555,7 @@ get "/videoplayback" do |env|
if location = response.headers["Location"]?
location = URI.parse(location)
- location = "#{location.full_path}&host=#{location.host}"
+ location = "#{location.request_target}&host=#{location.host}"
if region
location += "&region=#{region}"
@@ -3618,7 +3619,7 @@ get "/videoplayback" do |env|
if location = response.headers["Location"]?
location = URI.parse(location)
- location = "#{location.full_path}&host=#{location.host}#{region ? "&region=#{region}" : ""}"
+ location = "#{location.request_target}&host=#{location.host}#{region ? "&region=#{region}" : ""}"
env.redirect location
break
@@ -3858,7 +3859,7 @@ end
get "/watch_videos" do |env|
response = YT_POOL.client &.get(env.request.resource)
if url = response.headers["Location"]?
- url = URI.parse(url).full_path
+ url = URI.parse(url).request_target
next env.redirect url
end
@@ -3873,7 +3874,7 @@ error 404 do |env|
response = YT_POOL.client &.get("/#{item}")
if response.status_code == 301
- response = YT_POOL.client &.get(URI.parse(response.headers["Location"]).full_path)
+ response = YT_POOL.client &.get(URI.parse(response.headers["Location"]).request_target)
end
if response.body.empty?
diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr
index 0ac99ba5..a8bbf74b 100644
--- a/src/invidious/comments.cr
+++ b/src/invidious/comments.cr
@@ -294,7 +294,7 @@ def template_youtube_comments(comments, locale, thin_mode)
end
if !thin_mode
- author_thumbnail = "/ggpht#{URI.parse(child["authorThumbnails"][-1]["url"].as_s).full_path}"
+ author_thumbnail = "/ggpht#{URI.parse(child["authorThumbnails"][-1]["url"].as_s).request_target}"
else
author_thumbnail = ""
end
@@ -322,7 +322,7 @@ def template_youtube_comments(comments, locale, thin_mode)
html << <<-END_HTML
<div class="pure-g">
<div class="pure-u-1 pure-u-md-1-2">
- <img style="width:100%" src="/ggpht#{URI.parse(attachment["url"].as_s).full_path}">
+ <img style="width:100%" src="/ggpht#{URI.parse(attachment["url"].as_s).request_target}">
</div>
</div>
END_HTML
@@ -375,7 +375,7 @@ def template_youtube_comments(comments, locale, thin_mode)
if child["creatorHeart"]?
if !thin_mode
- creator_thumbnail = "/ggpht#{URI.parse(child["creatorHeart"]["creatorThumbnail"].as_s).full_path}"
+ creator_thumbnail = "/ggpht#{URI.parse(child["creatorHeart"]["creatorThumbnail"].as_s).request_target}"
else
creator_thumbnail = ""
end
@@ -473,7 +473,7 @@ def replace_links(html)
params = HTTP::Params.parse(url.query.not_nil!)
anchor["href"] = params["q"]?
else
- anchor["href"] = url.full_path
+ anchor["href"] = url.request_target
end
elsif url.to_s == "#"
begin
@@ -544,7 +544,7 @@ def content_to_comment_html(content)
if url.path == "/redirect"
url = HTTP::Params.parse(url.query.not_nil!)["q"]
else
- url = url.full_path
+ url = url.request_target
end
end
diff --git a/src/invidious/helpers/errors.cr b/src/invidious/helpers/errors.cr
index 2c62d44b..68ced430 100644
--- a/src/invidious/helpers/errors.cr
+++ b/src/invidious/helpers/errors.cr
@@ -7,7 +7,7 @@ class InfoException < Exception
end
macro error_template(*args)
- error_template_helper(env, config, locale, {{*args}})
+ error_template_helper(env, locale, {{*args}})
end
def github_details(summary : String, content : String)
@@ -22,9 +22,9 @@ def github_details(summary : String, content : String)
return HTML.escape(details)
end
-def error_template_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception)
+def error_template_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception)
if exception.is_a?(InfoException)
- return error_template_helper(env, config, locale, status_code, exception.message || "")
+ return error_template_helper(env, locale, status_code, exception.message || "")
end
env.response.content_type = "text/html"
env.response.status_code = status_code
@@ -43,7 +43,7 @@ def error_template_helper(env : HTTP::Server::Context, config : Config, locale :
return templated "error"
end
-def error_template_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String)
+def error_template_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String)
env.response.content_type = "text/html"
env.response.status_code = status_code
error_message = translate(locale, message)
@@ -51,31 +51,31 @@ def error_template_helper(env : HTTP::Server::Context, config : Config, locale :
end
macro error_atom(*args)
- error_atom_helper(env, config, locale, {{*args}})
+ error_atom_helper(env, locale, {{*args}})
end
-def error_atom_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception)
+def error_atom_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception)
if exception.is_a?(InfoException)
- return error_atom_helper(env, config, locale, status_code, exception.message || "")
+ return error_atom_helper(env, locale, status_code, exception.message || "")
end
env.response.content_type = "application/atom+xml"
env.response.status_code = status_code
return "<error>#{exception.inspect_with_backtrace}</error>"
end
-def error_atom_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String)
+def error_atom_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String)
env.response.content_type = "application/atom+xml"
env.response.status_code = status_code
return "<error>#{message}</error>"
end
macro error_json(*args)
- error_json_helper(env, config, locale, {{*args}})
+ error_json_helper(env, locale, {{*args}})
end
-def error_json_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception, additional_fields : Hash(String, Object) | Nil)
+def error_json_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception, additional_fields : Hash(String, Object) | Nil)
if exception.is_a?(InfoException)
- return error_json_helper(env, config, locale, status_code, exception.message || "", additional_fields)
+ return error_json_helper(env, locale, status_code, exception.message || "", additional_fields)
end
env.response.content_type = "application/json"
env.response.status_code = status_code
@@ -86,11 +86,11 @@ def error_json_helper(env : HTTP::Server::Context, config : Config, locale : Has
return error_message.to_json
end
-def error_json_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception)
- return error_json_helper(env, config, locale, status_code, exception, nil)
+def error_json_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, exception : Exception)
+ return error_json_helper(env, locale, status_code, exception, nil)
end
-def error_json_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String, additional_fields : Hash(String, Object) | Nil)
+def error_json_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String, additional_fields : Hash(String, Object) | Nil)
env.response.content_type = "application/json"
env.response.status_code = status_code
error_message = {"error" => message}
@@ -100,6 +100,6 @@ def error_json_helper(env : HTTP::Server::Context, config : Config, locale : Has
return error_message.to_json
end
-def error_json_helper(env : HTTP::Server::Context, config : Config, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String)
- error_json_helper(env, config, locale, status_code, message, nil)
+def error_json_helper(env : HTTP::Server::Context, locale : Hash(String, JSON::Any) | Nil, status_code : Int32, message : String)
+ error_json_helper(env, locale, status_code, message, nil)
end
diff --git a/src/invidious/helpers/helpers.cr b/src/invidious/helpers/helpers.cr
index 6bbb18cb..00087143 100644
--- a/src/invidious/helpers/helpers.cr
+++ b/src/invidious/helpers/helpers.cr
@@ -115,6 +115,63 @@ class Config
return false
end
end
+
+ def self.load
+ # Load config from file or YAML string env var
+ env_config_file = "INVIDIOUS_CONFIG_FILE"
+ env_config_yaml = "INVIDIOUS_CONFIG"
+
+ config_file = ENV.has_key?(env_config_file) ? ENV.fetch(env_config_file) : "config/config.yml"
+ config_yaml = ENV.has_key?(env_config_yaml) ? ENV.fetch(env_config_yaml) : File.read(config_file)
+
+ config = Config.from_yaml(config_yaml)
+
+ # Update config from env vars (upcased and prefixed with "INVIDIOUS_")
+ {% for ivar in Config.instance_vars %}
+ {% env_id = "INVIDIOUS_#{ivar.id.upcase}" %}
+
+ if ENV.has_key?({{env_id}})
+ # puts %(Config.{{ivar.id}} : Loading from env var {{env_id}})
+ env_value = ENV.fetch({{env_id}})
+ success = false
+
+ # Use YAML converter if specified
+ {% ann = ivar.annotation(::YAML::Field) %}
+ {% if ann && ann[:converter] %}
+ puts %(Config.{{ivar.id}} : Parsing "#{env_value}" as {{ivar.type}} with {{ann[:converter]}} converter)
+ config.{{ivar.id}} = {{ann[:converter]}}.from_yaml(YAML::ParseContext.new, YAML::Nodes.parse(ENV.fetch({{env_id}})).nodes[0])
+ puts %(Config.{{ivar.id}} : Set to #{config.{{ivar.id}}})
+ success = true
+
+ # Use regular YAML parser otherwise
+ {% else %}
+ {% ivar_types = ivar.type.union? ? ivar.type.union_types : [ivar.type] %}
+ # Sort types to avoid parsing nulls and numbers as strings
+ {% ivar_types = ivar_types.sort_by { |ivar_type| ivar_type == Nil ? 0 : ivar_type == Int32 ? 1 : 2 } %}
+ {{ivar_types}}.each do |ivar_type|
+ if !success
+ begin
+ # puts %(Config.{{ivar.id}} : Trying to parse "#{env_value}" as #{ivar_type})
+ config.{{ivar.id}} = ivar_type.from_yaml(env_value)
+ puts %(Config.{{ivar.id}} : Set to #{config.{{ivar.id}}} (#{ivar_type}))
+ success = true
+ rescue
+ # nop
+ end
+ end
+ end
+ {% end %}
+
+ # Exit on fail
+ if !success
+ puts %(Config.{{ivar.id}} failed to parse #{env_value} as {{ivar.type}})
+ exit(1)
+ end
+ end
+ {% end %}
+
+ return config
+ end
end
struct DBConfig
diff --git a/src/invidious/helpers/logger.cr b/src/invidious/helpers/logger.cr
index 7c5b0247..5d91a258 100644
--- a/src/invidious/helpers/logger.cr
+++ b/src/invidious/helpers/logger.cr
@@ -1,5 +1,3 @@
-require "logger"
-
enum LogLevel
All = 0
Trace = 1
diff --git a/src/invidious/helpers/proxy.cr b/src/invidious/helpers/proxy.cr
index 7a42ef41..3418d887 100644
--- a/src/invidious/helpers/proxy.cr
+++ b/src/invidious/helpers/proxy.cr
@@ -71,14 +71,14 @@ end
class HTTPClient < HTTP::Client
def set_proxy(proxy : HTTPProxy)
begin
- @socket = proxy.open(host: @host, port: @port, tls: @tls, connection_options: proxy_connection_options)
+ @io = proxy.open(host: @host, port: @port, tls: @tls, connection_options: proxy_connection_options)
rescue IO::Error
- @socket = nil
+ @io = nil
end
end
def unset_proxy
- @socket = nil
+ @io = nil
end
def proxy_connection_options
diff --git a/src/invidious/helpers/utils.cr b/src/invidious/helpers/utils.cr
index f068b5f2..2c95a373 100644
--- a/src/invidious/helpers/utils.cr
+++ b/src/invidious/helpers/utils.cr
@@ -280,9 +280,9 @@ def arg_array(array, start = 1)
return args
end
-def make_host_url(config, kemal_config)
- ssl = config.https_only || kemal_config.ssl
- port = config.external_port || kemal_config.port
+def make_host_url(kemal_config)
+ ssl = CONFIG.https_only || kemal_config.ssl
+ port = CONFIG.external_port || kemal_config.port
if ssl
scheme = "https://"
@@ -297,11 +297,11 @@ def make_host_url(config, kemal_config)
port = ""
end
- if !config.domain
+ if !CONFIG.domain
return ""
end
- host = config.domain.not_nil!.lchop(".")
+ host = CONFIG.domain.not_nil!.lchop(".")
return "#{scheme}#{host}#{port}"
end
@@ -329,7 +329,7 @@ def get_referer(env, fallback = "/", unroll = true)
end
end
- referer = referer.full_path
+ referer = referer.request_target
referer = "/" + referer.gsub(/[^\/?@&%=\-_.0-9a-zA-Z]/, "").lstrip("/\\")
if referer == env.request.path
@@ -345,7 +345,7 @@ def sha256(text)
return digest.final.hexstring
end
-def subscribe_pubsub(topic, key, config)
+def subscribe_pubsub(topic, key)
case topic
when .match(/^UC[A-Za-z0-9_-]{22}$/)
topic = "channel_id=#{topic}"
diff --git a/src/invidious/jobs/bypass_captcha_job.cr b/src/invidious/jobs/bypass_captcha_job.cr
index 22c54036..4269e123 100644
--- a/src/invidious/jobs/bypass_captcha_job.cr
+++ b/src/invidious/jobs/bypass_captcha_job.cr
@@ -1,9 +1,4 @@
class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob
- private getter config : Config
-
- def initialize(@config)
- end
-
def begin
loop do
begin
@@ -22,9 +17,9 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob
headers = response.cookies.add_request_headers(HTTP::Headers.new)
- response = JSON.parse(HTTP::Client.post(config.captcha_api_url + "/createTask",
+ response = JSON.parse(HTTP::Client.post(CONFIG.captcha_api_url + "/createTask",
headers: HTTP::Headers{"Content-Type" => "application/json"}, body: {
- "clientKey" => config.captcha_key,
+ "clientKey" => CONFIG.captcha_key,
"task" => {
"type" => "NoCaptchaTaskProxyless",
"websiteURL" => "https://www.youtube.com#{path}",
@@ -39,9 +34,9 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob
loop do
sleep 10.seconds
- response = JSON.parse(HTTP::Client.post(config.captcha_api_url + "/getTaskResult",
+ response = JSON.parse(HTTP::Client.post(CONFIG.captcha_api_url + "/getTaskResult",
headers: HTTP::Headers{"Content-Type" => "application/json"}, body: {
- "clientKey" => config.captcha_key,
+ "clientKey" => CONFIG.captcha_key,
"taskId" => task_id,
}.to_json).body)
@@ -58,14 +53,14 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob
response.cookies
.select { |cookie| cookie.name != "PREF" }
- .each { |cookie| config.cookies << cookie }
+ .each { |cookie| CONFIG.cookies << cookie }
# Persist cookies between runs
- File.write("config/config.yml", config.to_yaml)
+ File.write("config/config.yml", CONFIG.to_yaml)
elsif response.headers["Location"]?.try &.includes?("/sorry/index")
location = response.headers["Location"].try { |u| URI.parse(u) }
headers = HTTP::Headers{":authority" => location.host.not_nil!}
- response = YT_POOL.client &.get(location.full_path, headers)
+ response = YT_POOL.client &.get(location.request_target, headers)
html = XML.parse_html(response.body)
form = html.xpath_node(%(//form[@action="index"])).not_nil!
@@ -77,11 +72,11 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob
inputs[node["name"]] = node["value"]
end
- captcha_client = HTTPClient.new(URI.parse(config.captcha_api_url))
- captcha_client.family = config.force_resolve || Socket::Family::INET
+ captcha_client = HTTPClient.new(URI.parse(CONFIG.captcha_api_url))
+ captcha_client.family = CONFIG.force_resolve || Socket::Family::INET
response = JSON.parse(captcha_client.post("/createTask",
headers: HTTP::Headers{"Content-Type" => "application/json"}, body: {
- "clientKey" => config.captcha_key,
+ "clientKey" => CONFIG.captcha_key,
"task" => {
"type" => "NoCaptchaTaskProxyless",
"websiteURL" => location.to_s,
@@ -100,7 +95,7 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob
response = JSON.parse(captcha_client.post("/getTaskResult",
headers: HTTP::Headers{"Content-Type" => "application/json"}, body: {
- "clientKey" => config.captcha_key,
+ "clientKey" => CONFIG.captcha_key,
"taskId" => task_id,
}.to_json).body)
@@ -119,10 +114,10 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob
}
cookies = HTTP::Cookies.from_headers(headers)
- cookies.each { |cookie| config.cookies << cookie }
+ cookies.each { |cookie| CONFIG.cookies << cookie }
# Persist cookies between runs
- File.write("config/config.yml", config.to_yaml)
+ File.write("config/config.yml", CONFIG.to_yaml)
end
end
rescue ex
diff --git a/src/invidious/jobs/refresh_channels_job.cr b/src/invidious/jobs/refresh_channels_job.cr
index 3e94a56e..fbe6d381 100644
--- a/src/invidious/jobs/refresh_channels_job.cr
+++ b/src/invidious/jobs/refresh_channels_job.cr
@@ -1,12 +1,11 @@
class Invidious::Jobs::RefreshChannelsJob < Invidious::Jobs::BaseJob
private getter db : DB::Database
- private getter config : Config
- def initialize(@db, @config)
+ def initialize(@db)
end
def begin
- max_fibers = config.channel_threads
+ max_fibers = CONFIG.channel_threads
lim_fibers = max_fibers
active_fibers = 0
active_channel = Channel(Bool).new
@@ -31,7 +30,7 @@ class Invidious::Jobs::RefreshChannelsJob < Invidious::Jobs::BaseJob
spawn do
begin
LOGGER.trace("RefreshChannelsJob: #{id} fiber : Fetching channel")
- channel = fetch_channel(id, db, config.full_refresh)
+ channel = fetch_channel(id, db, CONFIG.full_refresh)
lim_fibers = max_fibers
diff --git a/src/invidious/jobs/refresh_feeds_job.cr b/src/invidious/jobs/refresh_feeds_job.cr
index 7b4ccdea..926c27fa 100644
--- a/src/invidious/jobs/refresh_feeds_job.cr
+++ b/src/invidious/jobs/refresh_feeds_job.cr
@@ -1,12 +1,11 @@
class Invidious::Jobs::RefreshFeedsJob < Invidious::Jobs::BaseJob
private getter db : DB::Database
- private getter config : Config
- def initialize(@db, @config)
+ def initialize(@db)
end
def begin
- max_fibers = config.feed_threads
+ max_fibers = CONFIG.feed_threads
active_fibers = 0
active_channel = Channel(Bool).new
diff --git a/src/invidious/jobs/statistics_refresh_job.cr b/src/invidious/jobs/statistics_refresh_job.cr
index 021671be..aa46fb0e 100644
--- a/src/invidious/jobs/statistics_refresh_job.cr
+++ b/src/invidious/jobs/statistics_refresh_job.cr
@@ -21,9 +21,8 @@ class Invidious::Jobs::StatisticsRefreshJob < Invidious::Jobs::BaseJob
}
private getter db : DB::Database
- private getter config : Config
- def initialize(@db, @config, @software_config : Hash(String, String))
+ def initialize(@db, @software_config : Hash(String, String))
end
def begin
@@ -43,7 +42,7 @@ class Invidious::Jobs::StatisticsRefreshJob < Invidious::Jobs::BaseJob
"version" => @software_config["version"],
"branch" => @software_config["branch"],
}
- STATISTICS["openRegistration"] = config.registration_enabled
+ STATISTICS["openRegistration"] = CONFIG.registration_enabled
end
private def refresh_stats
diff --git a/src/invidious/jobs/subscribe_to_feeds_job.cr b/src/invidious/jobs/subscribe_to_feeds_job.cr
index 750aceb8..a431a48a 100644
--- a/src/invidious/jobs/subscribe_to_feeds_job.cr
+++ b/src/invidious/jobs/subscribe_to_feeds_job.cr
@@ -1,15 +1,14 @@
class Invidious::Jobs::SubscribeToFeedsJob < Invidious::Jobs::BaseJob
private getter db : DB::Database
private getter hmac_key : String
- private getter config : Config
- def initialize(@db, @config, @hmac_key)
+ def initialize(@db, @hmac_key)
end
def begin
max_fibers = 1
- if config.use_pubsub_feeds.is_a?(Int32)
- max_fibers = config.use_pubsub_feeds.as(Int32)
+ if CONFIG.use_pubsub_feeds.is_a?(Int32)
+ max_fibers = CONFIG.use_pubsub_feeds.as(Int32)
end
active_fibers = 0
@@ -30,7 +29,7 @@ class Invidious::Jobs::SubscribeToFeedsJob < Invidious::Jobs::BaseJob
spawn do
begin
- response = subscribe_pubsub(ucid, hmac_key, config)
+ response = subscribe_pubsub(ucid, hmac_key)
if response.status_code >= 400
LOGGER.error("SubscribeToFeedsJob: #{ucid} : #{response.body}")
diff --git a/src/invidious/routes/base_route.cr b/src/invidious/routes/base_route.cr
index 37624267..07c6f15b 100644
--- a/src/invidious/routes/base_route.cr
+++ b/src/invidious/routes/base_route.cr
@@ -1,6 +1,2 @@
abstract class Invidious::Routes::BaseRoute
- private getter config : Config
-
- def initialize(@config)
- end
end
diff --git a/src/invidious/routes/embed/show.cr b/src/invidious/routes/embed.cr
index 8a655556..5db32788 100644
--- a/src/invidious/routes/embed/show.cr
+++ b/src/invidious/routes/embed.cr
@@ -1,5 +1,29 @@
-class Invidious::Routes::Embed::Show < Invidious::Routes::BaseRoute
- def handle(env)
+class Invidious::Routes::Embed < Invidious::Routes::BaseRoute
+ def redirect(env)
+ locale = LOCALES[env.get("preferences").as(Preferences).locale]?
+
+ if plid = env.params.query["list"]?.try &.gsub(/[^a-zA-Z0-9_-]/, "")
+ begin
+ playlist = get_playlist(PG_DB, plid, locale: locale)
+ offset = env.params.query["index"]?.try &.to_i? || 0
+ videos = get_playlist_videos(PG_DB, playlist, offset: offset, locale: locale)
+ rescue ex
+ return error_template(500, ex)
+ end
+
+ url = "/embed/#{videos[0].id}?#{env.params.query}"
+
+ if env.params.query.size > 0
+ url += "?#{env.params.query}"
+ end
+ else
+ url = "/"
+ end
+
+ env.redirect url
+ end
+
+ def show(env)
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
id = env.params.url["id"]
@@ -120,8 +144,8 @@ class Invidious::Routes::Embed::Show < Invidious::Routes::BaseRoute
adaptive_fmts = video.adaptive_fmts
if params.local
- fmt_stream.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).full_path) }
- adaptive_fmts.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).full_path) }
+ fmt_stream.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).request_target) }
+ adaptive_fmts.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).request_target) }
end
video_streams = video.video_streams
diff --git a/src/invidious/routes/embed/index.cr b/src/invidious/routes/embed/index.cr
deleted file mode 100644
index 32a4966b..00000000
--- a/src/invidious/routes/embed/index.cr
+++ /dev/null
@@ -1,25 +0,0 @@
-class Invidious::Routes::Embed::Index < Invidious::Routes::BaseRoute
- def handle(env)
- locale = LOCALES[env.get("preferences").as(Preferences).locale]?
-
- if plid = env.params.query["list"]?.try &.gsub(/[^a-zA-Z0-9_-]/, "")
- begin
- playlist = get_playlist(PG_DB, plid, locale: locale)
- offset = env.params.query["index"]?.try &.to_i? || 0
- videos = get_playlist_videos(PG_DB, playlist, offset: offset, locale: locale)
- rescue ex
- return error_template(500, ex)
- end
-
- url = "/embed/#{videos[0].id}?#{env.params.query}"
-
- if env.params.query.size > 0
- url += "?#{env.params.query}"
- end
- else
- url = "/"
- end
-
- env.redirect url
- end
-end
diff --git a/src/invidious/routes/licenses.cr b/src/invidious/routes/licenses.cr
deleted file mode 100644
index 38fde7bb..00000000
--- a/src/invidious/routes/licenses.cr
+++ /dev/null
@@ -1,6 +0,0 @@
-class Invidious::Routes::Licenses < Invidious::Routes::BaseRoute
- def handle(env)
- locale = LOCALES[env.get("preferences").as(Preferences).locale]?
- rendered "licenses"
- end
-end
diff --git a/src/invidious/routes/login.cr b/src/invidious/routes/login.cr
index 45a6d4d8..ffe5f568 100644
--- a/src/invidious/routes/login.cr
+++ b/src/invidious/routes/login.cr
@@ -6,7 +6,7 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute
return env.redirect "/feed/subscriptions" if user
- if !config.login_enabled
+ if !CONFIG.login_enabled
return error_template(400, "Login has been disabled by administrator.")
end
@@ -33,7 +33,7 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute
referer = get_referer(env, "/feed/subscriptions")
- if !config.login_enabled
+ if !CONFIG.login_enabled
return error_template(403, "Login has been disabled by administrator.")
end
@@ -255,7 +255,7 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute
traceback << "Unhandled dialog /b/0/SmsAuthInterstitial."
end
- login = client.get(location.full_path, headers)
+ login = client.get(location.request_target, headers)
headers = login.cookies.add_request_headers(headers)
location = login.headers["Location"]?.try { |u| URI.parse(u) }
@@ -274,14 +274,14 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute
host = URI.parse(env.request.headers["Host"]).host
- if Kemal.config.ssl || config.https_only
+ if Kemal.config.ssl || CONFIG.https_only
secure = true
else
secure = false
end
cookies.each do |cookie|
- if Kemal.config.ssl || config.https_only
+ if Kemal.config.ssl || CONFIG.https_only
cookie.secure = secure
else
cookie.secure = secure
@@ -330,14 +330,14 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute
sid = Base64.urlsafe_encode(Random::Secure.random_bytes(32))
PG_DB.exec("INSERT INTO session_ids VALUES ($1, $2, $3)", sid, email, Time.utc)
- if Kemal.config.ssl || config.https_only
+ if Kemal.config.ssl || CONFIG.https_only
secure = true
else
secure = false
end
- if config.domain
- env.response.cookies["SID"] = HTTP::Cookie.new(name: "SID", domain: "#{config.domain}", value: sid, expires: Time.utc + 2.years,
+ if CONFIG.domain
+ env.response.cookies["SID"] = HTTP::Cookie.new(name: "SID", domain: "#{CONFIG.domain}", value: sid, expires: Time.utc + 2.years,
secure: secure, http_only: true)
else
env.response.cookies["SID"] = HTTP::Cookie.new(name: "SID", value: sid, expires: Time.utc + 2.years,
@@ -354,7 +354,7 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute
env.response.cookies << cookie
end
else
- if !config.registration_enabled
+ if !CONFIG.registration_enabled
return error_template(400, "Registration has been disabled by administrator.")
end
@@ -369,7 +369,7 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute
password = password.byte_slice(0, 55)
- if config.captcha_enabled
+ if CONFIG.captcha_enabled
captcha_type = env.params.body["captcha_type"]?
answer = env.params.body["answer"]?
change_type = env.params.body["change_type"]?
@@ -445,14 +445,14 @@ class Invidious::Routes::Login < Invidious::Routes::BaseRoute
view_name = "subscriptions_#{sha256(user.email)}"
PG_DB.exec("CREATE MATERIALIZED VIEW #{view_name} AS #{MATERIALIZED_VIEW_SQL.call(user.email)}")
- if Kemal.config.ssl || config.https_only
+ if Kemal.config.ssl || CONFIG.https_only
secure = true
else
secure = false
end
- if config.domain
- env.response.cookies["SID"] = HTTP::Cookie.new(name: "SID", domain: "#{config.domain}", value: sid, expires: Time.utc + 2.years,
+ if CONFIG.domain
+ env.response.cookies["SID"] = HTTP::Cookie.new(name: "SID", domain: "#{CONFIG.domain}", value: sid, expires: Time.utc + 2.years,
secure: secure, http_only: true)
else
env.response.cookies["SID"] = HTTP::Cookie.new(name: "SID", value: sid, expires: Time.utc + 2.years,
diff --git a/src/invidious/routes/home.cr b/src/invidious/routes/misc.cr
index 486a7344..bc009633 100644
--- a/src/invidious/routes/home.cr
+++ b/src/invidious/routes/misc.cr
@@ -1,5 +1,5 @@
-class Invidious::Routes::Home < Invidious::Routes::BaseRoute
- def handle(env)
+class Invidious::Routes::Misc < Invidious::Routes::BaseRoute
+ def home(env)
preferences = env.get("preferences").as(Preferences)
locale = LOCALES[preferences.locale]?
user = env.get? "user"
@@ -25,4 +25,14 @@ class Invidious::Routes::Home < Invidious::Routes::BaseRoute
templated "empty"
end
end
+
+ def privacy(env)
+ locale = LOCALES[env.get("preferences").as(Preferences).locale]?
+ templated "privacy"
+ end
+
+ def licenses(env)
+ locale = LOCALES[env.get("preferences").as(Preferences).locale]?
+ rendered "licenses"
+ end
end
diff --git a/src/invidious/routes/user_preferences.cr b/src/invidious/routes/preferences.cr
index 7f334115..4901d22b 100644
--- a/src/invidious/routes/user_preferences.cr
+++ b/src/invidious/routes/preferences.cr
@@ -1,4 +1,4 @@
-class Invidious::Routes::UserPreferences < Invidious::Routes::BaseRoute
+class Invidious::Routes::PreferencesRoute < Invidious::Routes::BaseRoute
def show(env)
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
@@ -146,8 +146,8 @@ class Invidious::Routes::UserPreferences < Invidious::Routes::BaseRoute
user = user.as(User)
PG_DB.exec("UPDATE users SET preferences = $1 WHERE email = $2", preferences, user.email)
- if config.admins.includes? user.email
- config.default_user_preferences.default_home = env.params.body["admin_default_home"]?.try &.as(String) || config.default_user_preferences.default_home
+ if CONFIG.admins.includes? user.email
+ CONFIG.default_user_preferences.default_home = env.params.body["admin_default_home"]?.try &.as(String) || CONFIG.default_user_preferences.default_home
admin_feed_menu = [] of String
4.times do |index|
@@ -156,40 +156,39 @@ class Invidious::Routes::UserPreferences < Invidious::Routes::BaseRoute
admin_feed_menu << option
end
end
- config.default_user_preferences.feed_menu = admin_feed_menu
+ CONFIG.default_user_preferences.feed_menu = admin_feed_menu
popular_enabled = env.params.body["popular_enabled"]?.try &.as(String)
popular_enabled ||= "off"
- config.popular_enabled = popular_enabled == "on"
+ CONFIG.popular_enabled = popular_enabled == "on"
captcha_enabled = env.params.body["captcha_enabled"]?.try &.as(String)
captcha_enabled ||= "off"
- config.captcha_enabled = captcha_enabled == "on"
+ CONFIG.captcha_enabled = captcha_enabled == "on"
login_enabled = env.params.body["login_enabled"]?.try &.as(String)
login_enabled ||= "off"
- config.login_enabled = login_enabled == "on"
+ CONFIG.login_enabled = login_enabled == "on"
registration_enabled = env.params.body["registration_enabled"]?.try &.as(String)
registration_enabled ||= "off"
- config.registration_enabled = registration_enabled == "on"
+ CONFIG.registration_enabled = registration_enabled == "on"
statistics_enabled = env.params.body["statistics_enabled"]?.try &.as(String)
statistics_enabled ||= "off"
- config.statistics_enabled = statistics_enabled == "on"
+ CONFIG.statistics_enabled = statistics_enabled == "on"
- CONFIG.default_user_preferences = config.default_user_preferences
- File.write("config/config.yml", config.to_yaml)
+ File.write("config/config.yml", CONFIG.to_yaml)
end
else
- if Kemal.config.ssl || config.https_only
+ if Kemal.config.ssl || CONFIG.https_only
secure = true
else
secure = false
end
- if config.domain
- env.response.cookies["PREFS"] = HTTP::Cookie.new(name: "PREFS", domain: "#{config.domain}", value: preferences, expires: Time.utc + 2.years,
+ if CONFIG.domain
+ env.response.cookies["PREFS"] = HTTP::Cookie.new(name: "PREFS", domain: "#{CONFIG.domain}", value: preferences, expires: Time.utc + 2.years,
secure: secure, http_only: true)
else
env.response.cookies["PREFS"] = HTTP::Cookie.new(name: "PREFS", value: preferences, expires: Time.utc + 2.years,
@@ -234,14 +233,14 @@ class Invidious::Routes::UserPreferences < Invidious::Routes::BaseRoute
preferences = preferences.to_json
- if Kemal.config.ssl || config.https_only
+ if Kemal.config.ssl || CONFIG.https_only
secure = true
else
secure = false
end
- if config.domain
- env.response.cookies["PREFS"] = HTTP::Cookie.new(name: "PREFS", domain: "#{config.domain}", value: preferences, expires: Time.utc + 2.years,
+ if CONFIG.domain
+ env.response.cookies["PREFS"] = HTTP::Cookie.new(name: "PREFS", domain: "#{CONFIG.domain}", value: preferences, expires: Time.utc + 2.years,
secure: secure, http_only: true)
else
env.response.cookies["PREFS"] = HTTP::Cookie.new(name: "PREFS", value: preferences, expires: Time.utc + 2.years,
diff --git a/src/invidious/routes/privacy.cr b/src/invidious/routes/privacy.cr
deleted file mode 100644
index 4565c94c..00000000
--- a/src/invidious/routes/privacy.cr
+++ /dev/null
@@ -1,6 +0,0 @@
-class Invidious::Routes::Privacy < Invidious::Routes::BaseRoute
- def handle(env)
- locale = LOCALES[env.get("preferences").as(Preferences).locale]?
- templated "privacy"
- end
-end
diff --git a/src/invidious/routes/watch.cr b/src/invidious/routes/watch.cr
index 65604a88..8169e1ed 100644
--- a/src/invidious/routes/watch.cr
+++ b/src/invidious/routes/watch.cr
@@ -126,8 +126,8 @@ class Invidious::Routes::Watch < Invidious::Routes::BaseRoute
adaptive_fmts = video.adaptive_fmts
if params.local
- fmt_stream.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).full_path) }
- adaptive_fmts.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).full_path) }
+ fmt_stream.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).request_target) }
+ adaptive_fmts.each { |fmt| fmt["url"] = JSON::Any.new(URI.parse(fmt["url"].as_s).request_target) }
end
video_streams = video.video_streams
diff --git a/src/invidious/routing.cr b/src/invidious/routing.cr
index 593c7372..82d0028b 100644
--- a/src/invidious/routing.cr
+++ b/src/invidious/routing.cr
@@ -1,14 +1,14 @@
module Invidious::Routing
macro get(path, controller, method = :handle)
get {{ path }} do |env|
- controller_instance = {{ controller }}.new(config)
+ controller_instance = {{ controller }}.new
controller_instance.{{ method.id }}(env)
end
end
macro post(path, controller, method = :handle)
post {{ path }} do |env|
- controller_instance = {{ controller }}.new(config)
+ controller_instance = {{ controller }}.new
controller_instance.{{ method.id }}(env)
end
end
diff --git a/src/invidious/views/channel.ecr b/src/invidious/views/channel.ecr
index caa0ad0e..061d7eec 100644
--- a/src/invidious/views/channel.ecr
+++ b/src/invidious/views/channel.ecr
@@ -5,7 +5,7 @@
<% if channel.banner %>
<div class="h-box">
- <img style="width:100%" src="/ggpht<%= URI.parse(channel.banner.not_nil!.gsub("=w1060-", "=w1280-")).full_path %>">
+ <img style="width:100%" src="/ggpht<%= URI.parse(channel.banner.not_nil!.gsub("=w1060-", "=w1280-")).request_target %>">
</div>
<div class="h-box">
@@ -16,7 +16,7 @@
<div class="pure-g h-box">
<div class="pure-u-2-3">
<div class="channel-profile">
- <img src="/ggpht<%= URI.parse(channel.author_thumbnail).full_path %>">
+ <img src="/ggpht<%= URI.parse(channel.author_thumbnail).request_target %>">
<span><%= channel.author %></span>
</div>
</div>
diff --git a/src/invidious/views/community.ecr b/src/invidious/views/community.ecr
index 69724390..3c4eaabb 100644
--- a/src/invidious/views/community.ecr
+++ b/src/invidious/views/community.ecr
@@ -4,7 +4,7 @@
<% if channel.banner %>
<div class="h-box">
- <img style="width:100%" src="/ggpht<%= URI.parse(channel.banner.not_nil!.gsub("=w1060-", "=w1280-")).full_path %>">
+ <img style="width:100%" src="/ggpht<%= URI.parse(channel.banner.not_nil!.gsub("=w1060-", "=w1280-")).request_target %>">
</div>
<div class="h-box">
@@ -15,7 +15,7 @@
<div class="pure-g h-box">
<div class="pure-u-2-3">
<div class="channel-profile">
- <img src="/ggpht<%= URI.parse(channel.author_thumbnail).full_path %>">
+ <img src="/ggpht<%= URI.parse(channel.author_thumbnail).request_target %>">
<span><%= channel.author %></span>
</div>
</div>
diff --git a/src/invidious/views/components/item.ecr b/src/invidious/views/components/item.ecr
index e4a60697..ea7d356c 100644
--- a/src/invidious/views/components/item.ecr
+++ b/src/invidious/views/components/item.ecr
@@ -5,7 +5,7 @@
<a style="width:100%" href="/channel/<%= item.ucid %>">
<% if !env.get("preferences").as(Preferences).thin_mode %>
<center>
- <img style="width:56.25%" src="/ggpht<%= URI.parse(item.author_thumbnail).full_path %>"/>
+ <img style="width:56.25%" src="/ggpht<%= URI.parse(item.author_thumbnail).request_target.gsub(/=s\d+/, "=s176") %>"/>
</center>
<% end %>
<p><%= item.author %></p>
@@ -15,7 +15,7 @@
<h5><%= item.description_html %></h5>
<% when SearchPlaylist, InvidiousPlaylist %>
<% if item.id.starts_with? "RD" %>
- <% url = "/mix?list=#{item.id}&continuation=#{URI.parse(item.thumbnail || "/vi/-----------").full_path.split("/")[2]}" %>
+ <% url = "/mix?list=#{item.id}&continuation=#{URI.parse(item.thumbnail || "/vi/-----------").request_target.split("/")[2]}" %>
<% else %>
<% url = "/playlist?list=#{item.id}" %>
<% end %>
@@ -23,7 +23,7 @@
<a style="width:100%" href="<%= url %>">
<% if !env.get("preferences").as(Preferences).thin_mode %>
<div class="thumbnail">
- <img class="thumbnail" src="<%= URI.parse(item.thumbnail || "/").full_path %>"/>
+ <img class="thumbnail" src="<%= URI.parse(item.thumbnail || "/").request_target %>"/>
<p class="length"><%= number_with_separator(item.video_count) %> videos</p>
</div>
<% end %>
diff --git a/src/invidious/views/components/player.ecr b/src/invidious/views/components/player.ecr
index 625c6fee..a898a41f 100644
--- a/src/invidious/views/components/player.ecr
+++ b/src/invidious/views/components/player.ecr
@@ -4,7 +4,7 @@
<% if params.video_loop %>loop<% end %>
<% if params.controls %>controls<% end %>>
<% if (hlsvp = video.hls_manifest_url) && !CONFIG.disabled?("livestreams") %>
- <source src="<%= URI.parse(hlsvp).full_path %><% if params.local %>?local=true<% end %>" type="application/x-mpegURL" label="livestream">
+ <source src="<%= URI.parse(hlsvp).request_target %><% if params.local %>?local=true<% end %>" type="application/x-mpegURL" label="livestream">
<% else %>
<% if params.listen %>
<% audio_streams.each_with_index do |fmt, i| %>
diff --git a/src/invidious/views/components/player_sources.ecr b/src/invidious/views/components/player_sources.ecr
index 8162546e..d950e0da 100644
--- a/src/invidious/views/components/player_sources.ecr
+++ b/src/invidious/views/components/player_sources.ecr
@@ -3,7 +3,6 @@
<link rel="stylesheet" href="/css/videojs.markers.min.css?v=<%= ASSET_COMMIT %>">
<link rel="stylesheet" href="/css/videojs-share.css?v=<%= ASSET_COMMIT %>">
<link rel="stylesheet" href="/css/videojs-vtt-thumbnails.css?v=<%= ASSET_COMMIT %>">
-<script src="/js/global.js?v=<%= ASSET_COMMIT %>"></script>
<script src="/js/video.min.js?v=<%= ASSET_COMMIT %>"></script>
<script src="/js/videojs-contrib-quality-levels.min.js?v=<%= ASSET_COMMIT %>"></script>
<script src="/js/videojs-http-source-selector.min.js?v=<%= ASSET_COMMIT %>"></script>
diff --git a/src/invidious/views/playlists.ecr b/src/invidious/views/playlists.ecr
index a77d106d..44bdb94d 100644
--- a/src/invidious/views/playlists.ecr
+++ b/src/invidious/views/playlists.ecr
@@ -4,7 +4,7 @@
<% if channel.banner %>
<div class="h-box">
- <img style="width:100%" src="/ggpht<%= URI.parse(channel.banner.not_nil!.gsub("=w1060-", "=w1280-")).full_path %>">
+ <img style="width:100%" src="/ggpht<%= URI.parse(channel.banner.not_nil!.gsub("=w1060-", "=w1280-")).request_target %>">
</div>
<div class="h-box">
@@ -15,7 +15,7 @@
<div class="pure-g h-box">
<div class="pure-u-2-3">
<div class="channel-profile">
- <img src="/ggpht<%= URI.parse(channel.author_thumbnail).full_path %>">
+ <img src="/ggpht<%= URI.parse(channel.author_thumbnail).request_target %>">
<span><%= channel.author %></span>
</div>
</div>
diff --git a/src/invidious/views/preferences.ecr b/src/invidious/views/preferences.ecr
index 1ef080be..14d63536 100644
--- a/src/invidious/views/preferences.ecr
+++ b/src/invidious/views/preferences.ecr
@@ -208,14 +208,14 @@
</div>
<% # Web notifications are only supported over HTTPS %>
- <% if Kemal.config.ssl || config.https_only %>
+ <% if Kemal.config.ssl || CONFIG.https_only %>
<div class="pure-control-group">
<a href="#" data-onclick="notification_requestPermission"><%= translate(locale, "Enable web notifications") %></a>
</div>
<% end %>
<% end %>
- <% if env.get?("user") && config.admins.includes? env.get?("user").as(User).email %>
+ <% if env.get?("user") && CONFIG.admins.includes? env.get?("user").as(User).email %>
<legend><%= translate(locale, "Administrator preferences") %></legend>
<div class="pure-control-group">
@@ -240,28 +240,28 @@
<div class="pure-control-group">
<label for="popular_enabled"><%= translate(locale, "Popular enabled: ") %></label>
- <input name="popular_enabled" id="popular_enabled" type="checkbox" <% if config.popular_enabled %>checked<% end %>>
+ <input name="popular_enabled" id="popular_enabled" type="checkbox" <% if CONFIG.popular_enabled %>checked<% end %>>
</div>
<div class="pure-control-group">
<label for="captcha_enabled"><%= translate(locale, "CAPTCHA enabled: ") %></label>
- <input name="captcha_enabled" id="captcha_enabled" type="checkbox" <% if config.captcha_enabled %>checked<% end %>>
+ <input name="captcha_enabled" id="captcha_enabled" type="checkbox" <% if CONFIG.captcha_enabled %>checked<% end %>>
</div>
<div class="pure-control-group">
<label for="login_enabled"><%= translate(locale, "Login enabled: ") %></label>
- <input name="login_enabled" id="login_enabled" type="checkbox" <% if config.login_enabled %>checked<% end %>>
+ <input name="login_enabled" id="login_enabled" type="checkbox" <% if CONFIG.login_enabled %>checked<% end %>>
</div>
<div class="pure-control-group">
<label for="registration_enabled"><%= translate(locale, "Registration enabled: ") %></label>
- <input name="registration_enabled" id="registration_enabled" type="checkbox" <% if config.registration_enabled %>checked<% end %>>
+ <input name="registration_enabled" id="registration_enabled" type="checkbox" <% if CONFIG.registration_enabled %>checked<% end %>>
</div>
<div class="pure-control-group">
<label for="statistics_enabled"><%= translate(locale, "Report statistics: ") %></label>
- <input name="statistics_enabled" id="statistics_enabled" type="checkbox" <% if config.statistics_enabled %>checked<% end %>>
+ <input name="statistics_enabled" id="statistics_enabled" type="checkbox" <% if CONFIG.statistics_enabled %>checked<% end %>>
</div>
<% end %>
diff --git a/src/invidious/views/template.ecr b/src/invidious/views/template.ecr
index f6e5262d..61b900e3 100644
--- a/src/invidious/views/template.ecr
+++ b/src/invidious/views/template.ecr
@@ -87,7 +87,7 @@
<i class="icon ion-ios-cog"></i>
</a>
</div>
- <% if config.login_enabled %>
+ <% if CONFIG.login_enabled %>
<div class="pure-u-1-3">
<a href="/login?referer=<%= env.get?("current_page") %>" class="pure-menu-heading">
<%= translate(locale, "Log in") %>
diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr
index 786a88b6..924914a5 100644
--- a/src/invidious/views/watch.ecr
+++ b/src/invidious/views/watch.ecr
@@ -22,6 +22,7 @@
<meta name="twitter:player" content="<%= HOST_URL %>/embed/<%= video.id %>">
<meta name="twitter:player:width" content="1280">
<meta name="twitter:player:height" content="720">
+<link rel="alternate" href="https://www.youtube.com/watch?v=<%= video.id %>">
<%= rendered "components/player_sources" %>
<title><%= HTML.escape(video.title) %> - Invidious</title>
<% end %>
@@ -203,7 +204,7 @@
<a href="/channel/<%= video.ucid %>" style="display:block;width:fit-content;width:-moz-fit-content">
<div class="channel-profile">
<% if !video.author_thumbnail.empty? %>
- <img src="/ggpht<%= URI.parse(video.author_thumbnail).full_path %>">
+ <img src="/ggpht<%= URI.parse(video.author_thumbnail).request_target %>">
<% end %>
<span id="channel-name"><%= video.author %></span>
</div>