summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/invidious.cr43
-rw-r--r--src/invidious/channels.cr5
-rw-r--r--src/invidious/comments.cr2
-rw-r--r--src/invidious/helpers/helpers.cr3
-rw-r--r--src/invidious/helpers/proxy.cr6
-rw-r--r--src/invidious/helpers/utils.cr11
-rw-r--r--src/invidious/jobs/bypass_captcha_job.cr2
-rw-r--r--src/invidious/routes/home.cr12
-rw-r--r--src/invidious/routes/user_preferences.cr4
-rw-r--r--src/invidious/routes/watch.cr2
-rw-r--r--src/invidious/users.cr2
-rw-r--r--src/invidious/views/message.ecr12
-rw-r--r--src/invidious/views/preferences.ecr6
13 files changed, 82 insertions, 28 deletions
diff --git a/src/invidious.cr b/src/invidious.cr
index 7184145a..8d4c2e58 100644
--- a/src/invidious.cr
+++ b/src/invidious.cr
@@ -168,13 +168,16 @@ end
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::PullPopularVideosJob.new(PG_DB)
Invidious::Jobs.register Invidious::Jobs::UpdateDecryptFunctionJob.new
if config.statistics_enabled
Invidious::Jobs.register Invidious::Jobs::StatisticsRefreshJob.new(PG_DB, config, SOFTWARE)
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)
end
@@ -1146,13 +1149,20 @@ end
get "/feed/top" do |env|
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
- env.redirect "/"
+
+ message = translate(locale, "The Top feed has been removed from Invidious.")
+ templated "message"
end
get "/feed/popular" do |env|
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
- templated "popular"
+ if config.popular_enabled
+ templated "popular"
+ else
+ message = translate(locale, "The Popular feed has been disabled by the administrator.")
+ templated "message"
+ end
end
get "/feed/trending" do |env|
@@ -2123,14 +2133,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
@@ -2216,6 +2225,12 @@ get "/api/v1/popular" do |env|
env.response.content_type = "application/json"
+ if !config.popular_enabled
+ error_message = {"error" => "Administrator has disabled this endpoint."}.to_json
+ env.response.status_code = 400
+ next error_message
+ end
+
JSON.build do |json|
json.array do
popular_videos.each do |video|
@@ -2229,7 +2244,8 @@ get "/api/v1/top" do |env|
locale = LOCALES[env.get("preferences").as(Preferences).locale]?
env.response.content_type = "application/json"
- "[]"
+ env.response.status_code = 400
+ {"error" => "The Top feed has been removed from Invidious."}.to_json
end
get "/api/v1/channels/:ucid" do |env|
@@ -3481,8 +3497,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 ? "&region=#{region}" : ""}"
else
@@ -3513,7 +3533,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)
@@ -3554,8 +3573,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
@@ -3619,6 +3636,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
@@ -3628,6 +3646,7 @@ get "/videoplayback" do |env|
first_chunk = false
end
end
+ client.close
end
get "/ggpht/*" do |env|
diff --git a/src/invidious/channels.cr b/src/invidious/channels.cr
index 659dc599..6907ff3d 100644
--- a/src/invidious/channels.cr
+++ b/src/invidious/channels.cr
@@ -651,7 +651,8 @@ def fetch_channel_community(ucid, continuation, locale, format, thin_mode)
else
video_id = attachment["videoId"].as_s
- json.field "title", attachment["title"]["simpleText"].as_s
+ video_title = attachment["title"]["simpleText"]? || attachment["title"]["runs"]?.try &.[0]?.try &.["text"]?
+ json.field "title", video_title
json.field "videoId", video_id
json.field "videoThumbnails" do
generate_thumbnails(json, video_id)
@@ -673,7 +674,7 @@ def fetch_channel_community(ucid, continuation, locale, format, thin_mode)
json.field "published", published.to_unix
json.field "publishedText", translate(locale, "`x` ago", recode_date(published, locale))
- view_count = attachment["viewCountText"]["simpleText"].as_s.gsub(/\D/, "").to_i64? || 0_i64
+ view_count = attachment["viewCountText"]?.try &.["simpleText"].as_s.gsub(/\D/, "").to_i64? || 0_i64
json.field "viewCount", view_count
json.field "viewCountText", translate(locale, "`x` views", number_to_short_text(view_count))
diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr
index 9f9edca0..8849c87f 100644
--- a/src/invidious/comments.cr
+++ b/src/invidious/comments.cr
@@ -269,6 +269,8 @@ def fetch_reddit_comments(id, sort_by = "confidence")
raise InfoException.new("Could not fetch comments")
end
+ client.close
+
comments = result[1].data.as(RedditListing).children
return comments, thread
end
diff --git a/src/invidious/helpers/helpers.cr b/src/invidious/helpers/helpers.cr
index efd4d255..2da49abb 100644
--- a/src/invidious/helpers/helpers.cr
+++ b/src/invidious/helpers/helpers.cr
@@ -61,7 +61,7 @@ struct ConfigPreferences
end
end
-struct Config
+class Config
include YAML::Serializable
property channel_threads : Int32 # Number of threads to use for crawling videos from channels (for updating subscriptions)
@@ -72,6 +72,7 @@ struct Config
property hmac_key : String? # HMAC signing key for CSRF tokens and verifying pubsub subscriptions
property domain : String? # Domain to be used for links to resources on the site where an absolute URL is required
property use_pubsub_feeds : Bool | Int32 = false # Subscribe to channels using PubSubHubbub (requires domain, hmac_key)
+ property popular_enabled : Bool = true
property captcha_enabled : Bool = true
property login_enabled : Bool = true
property registration_enabled : Bool = true
diff --git a/src/invidious/helpers/proxy.cr b/src/invidious/helpers/proxy.cr
index 4f415ba0..7a42ef41 100644
--- a/src/invidious/helpers/proxy.cr
+++ b/src/invidious/helpers/proxy.cr
@@ -108,7 +108,9 @@ def filter_proxies(proxies)
proxy = HTTPProxy.new(proxy_host: proxy[:ip], proxy_port: proxy[:port])
client.set_proxy(proxy)
- client.head("/").status_code == 200
+ status_ok = client.head("/").status_code == 200
+ client.close
+ status_ok
rescue ex
false
end
@@ -132,6 +134,7 @@ def get_nova_proxies(country_code = "US")
headers["Referer"] = "https://www.proxynova.com/proxy-server-list/country-#{country_code}/"
response = client.get("/proxy-server-list/country-#{country_code}/", headers)
+ client.close
document = XML.parse_html(response.body)
proxies = [] of {ip: String, port: Int32, score: Float64}
@@ -177,6 +180,7 @@ def get_spys_proxies(country_code = "US")
}
response = client.post("/free-proxy-list/#{country_code}/", headers, form: body)
+ client.close
20.times do
if response.status_code == 200
break
diff --git a/src/invidious/helpers/utils.cr b/src/invidious/helpers/utils.cr
index bb9a35ea..f068b5f2 100644
--- a/src/invidious/helpers/utils.cr
+++ b/src/invidious/helpers/utils.cr
@@ -101,6 +101,15 @@ def make_client(url : URI, region = nil)
return client
end
+def make_client(url : URI, region = nil, &block)
+ client = make_client(url, region)
+ begin
+ yield client
+ ensure
+ client.close
+ end
+end
+
def decode_length_seconds(string)
length_seconds = string.gsub(/[^0-9:]/, "").split(":").map &.to_i
length_seconds = [0] * (3 - length_seconds.size) + length_seconds
@@ -361,7 +370,7 @@ def subscribe_pubsub(topic, key, config)
"hub.secret" => key.to_s,
}
- return make_client(PUBSUB_URL).post("/subscribe", form: body)
+ return make_client(PUBSUB_URL, &.post("/subscribe", form: body))
end
def parse_range(range)
diff --git a/src/invidious/jobs/bypass_captcha_job.cr b/src/invidious/jobs/bypass_captcha_job.cr
index daba64d5..61f8eaf3 100644
--- a/src/invidious/jobs/bypass_captcha_job.cr
+++ b/src/invidious/jobs/bypass_captcha_job.cr
@@ -91,6 +91,8 @@ class Invidious::Jobs::BypassCaptchaJob < Invidious::Jobs::BaseJob
},
}.to_json).body)
+ captcha_client.close
+
raise response["error"].as_s if response["error"]?
task_id = response["taskId"].as_i
diff --git a/src/invidious/routes/home.cr b/src/invidious/routes/home.cr
index 9b1bf61b..486a7344 100644
--- a/src/invidious/routes/home.cr
+++ b/src/invidious/routes/home.cr
@@ -5,30 +5,24 @@ class Invidious::Routes::Home < Invidious::Routes::BaseRoute
user = env.get? "user"
case preferences.default_home
- when ""
- templated "empty"
when "Popular"
- templated "popular"
+ env.redirect "/feed/popular"
when "Trending"
env.redirect "/feed/trending"
when "Subscriptions"
if user
env.redirect "/feed/subscriptions"
else
- templated "popular"
+ env.redirect "/feed/popular"
end
when "Playlists"
if user
env.redirect "/view_all_playlists"
else
- templated "popular"
+ env.redirect "/feed/popular"
end
else
templated "empty"
end
end
-
- private def popular_videos
- Jobs::PullPopularVideosJob::POPULAR_VIDEOS.get
- end
end
diff --git a/src/invidious/routes/user_preferences.cr b/src/invidious/routes/user_preferences.cr
index 3ca8ed1b..7f334115 100644
--- a/src/invidious/routes/user_preferences.cr
+++ b/src/invidious/routes/user_preferences.cr
@@ -158,6 +158,10 @@ class Invidious::Routes::UserPreferences < Invidious::Routes::BaseRoute
end
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"
+
captcha_enabled = env.params.body["captcha_enabled"]?.try &.as(String)
captcha_enabled ||= "off"
config.captcha_enabled = captcha_enabled == "on"
diff --git a/src/invidious/routes/watch.cr b/src/invidious/routes/watch.cr
index 7225c17f..a5c05c00 100644
--- a/src/invidious/routes/watch.cr
+++ b/src/invidious/routes/watch.cr
@@ -30,7 +30,7 @@ class Invidious::Routes::Watch < Invidious::Routes::BaseRoute
embed_link = "/embed/#{id}"
if env.params.query.size > 1
- embed_params = env.params.query.dup
+ embed_params = HTTP::Params.parse(env.params.query.to_s)
embed_params.delete_all("v")
embed_link += "?"
embed_link += embed_params.to_s
diff --git a/src/invidious/users.cr b/src/invidious/users.cr
index 38767a23..5dc16edd 100644
--- a/src/invidious/users.cr
+++ b/src/invidious/users.cr
@@ -427,7 +427,7 @@ def generate_captcha(key, db)
end
def generate_text_captcha(key, db)
- response = make_client(TEXTCAPTCHA_URL).get("/omarroth@protonmail.com.json").body
+ response = make_client(TEXTCAPTCHA_URL, &.get("/omarroth@protonmail.com.json").body)
response = JSON.parse(response)
tokens = response["a"].as_a.map do |answer|
diff --git a/src/invidious/views/message.ecr b/src/invidious/views/message.ecr
new file mode 100644
index 00000000..8c7bf611
--- /dev/null
+++ b/src/invidious/views/message.ecr
@@ -0,0 +1,12 @@
+<% content_for "header" do %>
+<meta name="description" content="<%= translate(locale, "An alternative front-end to YouTube") %>">
+<title>
+ Invidious
+</title>
+<% end %>
+
+<%= rendered "components/feed_menu" %>
+
+<p>
+ <%= message %>
+</p>
diff --git a/src/invidious/views/preferences.ecr b/src/invidious/views/preferences.ecr
index 6f674e86..1ef080be 100644
--- a/src/invidious/views/preferences.ecr
+++ b/src/invidious/views/preferences.ecr
@@ -239,6 +239,12 @@
</div>
<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 %>>
+ </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 %>>
</div>