mirror of
https://github.com/iv-org/invidious.git
synced 2024-11-26 16:52:12 +05:30
Merge branch 'iv-org:master' into beautify_404_page
This commit is contained in:
commit
e9e89a58f7
@ -301,7 +301,6 @@ Spectator.describe Invidious::Search::Filters do
|
||||
|
||||
it "Encodes features filter (single)" do
|
||||
Invidious::Search::Filters::Features.each do |value|
|
||||
string = described_class.format_features(value)
|
||||
filters = described_class.new(features: value)
|
||||
|
||||
expect("#{filters.to_iv_params}")
|
||||
|
@ -232,7 +232,7 @@ def fetch_channel(ucid, pull_all_videos : Bool)
|
||||
id: video_id,
|
||||
title: title,
|
||||
published: published,
|
||||
updated: Time.utc,
|
||||
updated: updated,
|
||||
ucid: ucid,
|
||||
author: author,
|
||||
length_seconds: length_seconds,
|
||||
|
@ -149,12 +149,12 @@ module Invidious::Frontend::Comments
|
||||
|
||||
if comments["videoId"]?
|
||||
html << <<-END_HTML
|
||||
<a href="https://www.youtube.com/watch?v=#{comments["videoId"]}&lc=#{child["commentId"]}" title="#{translate(locale, "YouTube comment permalink")}">[YT]</a>
|
||||
<a rel="noreferrer noopener" href="https://www.youtube.com/watch?v=#{comments["videoId"]}&lc=#{child["commentId"]}" title="#{translate(locale, "YouTube comment permalink")}">[YT]</a>
|
||||
|
|
||||
END_HTML
|
||||
elsif comments["authorId"]?
|
||||
html << <<-END_HTML
|
||||
<a href="https://www.youtube.com/channel/#{comments["authorId"]}/community?lb=#{child["commentId"]}" title="#{translate(locale, "YouTube comment permalink")}">[YT]</a>
|
||||
<a rel="noreferrer noopener" href="https://www.youtube.com/channel/#{comments["authorId"]}/community?lb=#{child["commentId"]}" title="#{translate(locale, "YouTube comment permalink")}">[YT]</a>
|
||||
|
|
||||
END_HTML
|
||||
end
|
||||
|
@ -6,9 +6,9 @@ module Invidious::Frontend::Misc
|
||||
|
||||
if prefs.automatic_instance_redirect
|
||||
current_page = env.get?("current_page").as(String)
|
||||
redirect_url = "/redirect?referer=#{current_page}"
|
||||
return "/redirect?referer=#{current_page}"
|
||||
else
|
||||
redirect_url = "https://redirect.invidious.io#{env.request.resource}"
|
||||
return "https://redirect.invidious.io#{env.request.resource}"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -194,7 +194,7 @@ def error_redirect_helper(env : HTTP::Server::Context)
|
||||
<a href="/redirect?referer=#{env.get("current_page")}">#{switch_instance}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a href="https://youtube.com#{env.request.resource}">#{go_to_youtube}</a>
|
||||
<a rel="noreferrer noopener" href="https://youtube.com#{env.request.resource}">#{go_to_youtube}</a>
|
||||
</li>
|
||||
</ul>
|
||||
END_HTML
|
||||
|
@ -97,7 +97,7 @@ class AuthHandler < Kemal::Handler
|
||||
if token = env.request.headers["Authorization"]?
|
||||
token = JSON.parse(URI.decode_www_form(token.lchop("Bearer ")))
|
||||
session = URI.decode_www_form(token["session"].as_s)
|
||||
scopes, expire, signature = validate_request(token, session, env.request, HMAC_KEY, nil)
|
||||
scopes, _, _ = validate_request(token, session, env.request, HMAC_KEY, nil)
|
||||
|
||||
if email = Invidious::Database::SessionIDs.select_email(session)
|
||||
user = Invidious::Database::Users.select!(email: email)
|
||||
|
@ -95,7 +95,6 @@ module I18next::Plurals
|
||||
"hr" => PluralForms::Special_Hungarian_Serbian,
|
||||
"it" => PluralForms::Special_Spanish_Italian,
|
||||
"pt" => PluralForms::Special_French_Portuguese,
|
||||
"pt" => PluralForms::Special_French_Portuguese,
|
||||
"sr" => PluralForms::Special_Hungarian_Serbian,
|
||||
}
|
||||
|
||||
@ -189,7 +188,7 @@ module I18next::Plurals
|
||||
|
||||
# Emulate the `rule.numbers.size == 2 && rule.numbers[0] == 1` check
|
||||
# from original i18next code
|
||||
private def is_simple_plural(form : PluralForms) : Bool
|
||||
private def simple_plural?(form : PluralForms) : Bool
|
||||
case form
|
||||
when .single_gt_one? then return true
|
||||
when .single_not_one? then return true
|
||||
@ -211,7 +210,7 @@ module I18next::Plurals
|
||||
idx = SuffixIndex.get_index(plural_form, count)
|
||||
|
||||
# Simple plurals are handled differently in all versions (but v4)
|
||||
if @simplify_plural_suffix && is_simple_plural(plural_form)
|
||||
if @simplify_plural_suffix && simple_plural?(plural_form)
|
||||
return (idx == 1) ? "_plural" : ""
|
||||
end
|
||||
|
||||
@ -262,9 +261,9 @@ module I18next::Plurals
|
||||
when .special_hebrew? then return special_hebrew(count)
|
||||
when .special_odia? then return special_odia(count)
|
||||
# Mixed v3/v4 forms
|
||||
when .special_spanish_italian? then return special_cldr_Spanish_Italian(count)
|
||||
when .special_french_portuguese? then return special_cldr_French_Portuguese(count)
|
||||
when .special_hungarian_serbian? then return special_cldr_Hungarian_Serbian(count)
|
||||
when .special_spanish_italian? then return special_cldr_spanish_italian(count)
|
||||
when .special_french_portuguese? then return special_cldr_french_portuguese(count)
|
||||
when .special_hungarian_serbian? then return special_cldr_hungarian_serbian(count)
|
||||
else
|
||||
# default, if nothing matched above
|
||||
return 0_u8
|
||||
@ -535,7 +534,7 @@ module I18next::Plurals
|
||||
#
|
||||
# This rule is mostly compliant to CLDR v42
|
||||
#
|
||||
def self.special_cldr_Spanish_Italian(count : Int) : UInt8
|
||||
def self.special_cldr_spanish_italian(count : Int) : UInt8
|
||||
return 0_u8 if (count == 1) # one
|
||||
return 1_u8 if (count != 0 && count % 1_000_000 == 0) # many
|
||||
return 2_u8 # other
|
||||
@ -545,7 +544,7 @@ module I18next::Plurals
|
||||
#
|
||||
# This rule is mostly compliant to CLDR v42
|
||||
#
|
||||
def self.special_cldr_French_Portuguese(count : Int) : UInt8
|
||||
def self.special_cldr_french_portuguese(count : Int) : UInt8
|
||||
return 0_u8 if (count == 0 || count == 1) # one
|
||||
return 1_u8 if (count % 1_000_000 == 0) # many
|
||||
return 2_u8 # other
|
||||
@ -555,7 +554,7 @@ module I18next::Plurals
|
||||
#
|
||||
# This rule is mostly compliant to CLDR v42
|
||||
#
|
||||
def self.special_cldr_Hungarian_Serbian(count : Int) : UInt8
|
||||
def self.special_cldr_hungarian_serbian(count : Int) : UInt8
|
||||
n_mod_10 = count % 10
|
||||
n_mod_100 = count % 100
|
||||
|
||||
|
@ -34,24 +34,11 @@ class Invidious::LogHandler < Kemal::BaseLogHandler
|
||||
context
|
||||
end
|
||||
|
||||
def puts(message : String)
|
||||
@io << message << '\n'
|
||||
@io.flush
|
||||
end
|
||||
|
||||
def write(message : String)
|
||||
@io << message
|
||||
@io.flush
|
||||
end
|
||||
|
||||
def set_log_level(level : String)
|
||||
@level = LogLevel.parse(level)
|
||||
end
|
||||
|
||||
def set_log_level(level : LogLevel)
|
||||
@level = level
|
||||
end
|
||||
|
||||
{% for level in %w(trace debug info warn error fatal) %}
|
||||
def {{level.id}}(message : String)
|
||||
if LogLevel::{{level.id.capitalize}} >= @level
|
||||
|
@ -53,7 +53,7 @@ module Invidious::Routes::Account
|
||||
return error_template(401, "Password is a required field")
|
||||
end
|
||||
|
||||
new_passwords = env.params.body.select { |k, v| k.match(/^new_password\[\d+\]$/) }.map { |k, v| v }
|
||||
new_passwords = env.params.body.select { |k, _| k.match(/^new_password\[\d+\]$/) }.map { |_, v| v }
|
||||
|
||||
if new_passwords.size <= 1 || new_passwords.uniq.size != 1
|
||||
return error_template(400, "New passwords must match")
|
||||
@ -240,7 +240,7 @@ module Invidious::Routes::Account
|
||||
return error_template(400, ex)
|
||||
end
|
||||
|
||||
scopes = env.params.body.select { |k, v| k.match(/^scopes\[\d+\]$/) }.map { |k, v| v }
|
||||
scopes = env.params.body.select { |k, _| k.match(/^scopes\[\d+\]$/) }.map { |_, v| v }
|
||||
callback_url = env.params.body["callbackUrl"]?
|
||||
expire = env.params.body["expire"]?.try &.to_i?
|
||||
|
||||
|
@ -219,7 +219,7 @@ module Invidious::Routes::API::V1::Videos
|
||||
|
||||
storyboard[:storyboard_count].times do |i|
|
||||
url = storyboard[:url]
|
||||
authority = /(i\d?).ytimg.com/.match(url).not_nil![1]?
|
||||
authority = /(i\d?).ytimg.com/.match!(url)[1]?
|
||||
url = url.gsub("$M", i).gsub(%r(https://i\d?.ytimg.com/sb/), "")
|
||||
url = "#{HOST_URL}/sb/#{authority}/#{url}"
|
||||
|
||||
@ -254,7 +254,7 @@ module Invidious::Routes::API::V1::Videos
|
||||
if CONFIG.cache_annotations && (cached_annotation = Invidious::Database::Annotations.select(id))
|
||||
annotations = cached_annotation.annotations
|
||||
else
|
||||
index = CHARS_SAFE.index(id[0]).not_nil!.to_s.rjust(2, '0')
|
||||
index = CHARS_SAFE.index!(id[0]).to_s.rjust(2, '0')
|
||||
|
||||
# IA doesn't handle leading hyphens,
|
||||
# so we use https://archive.org/details/youtubeannotations_64
|
||||
|
@ -124,7 +124,7 @@ struct Invidious::User
|
||||
playlist = create_playlist(title, privacy, user)
|
||||
Invidious::Database::Playlists.update_description(playlist.id, description)
|
||||
|
||||
videos = item["videos"]?.try &.as_a?.try &.each_with_index do |video_id, idx|
|
||||
item["videos"]?.try &.as_a?.try &.each_with_index do |video_id, idx|
|
||||
if idx > CONFIG.playlist_length_limit
|
||||
raise InfoException.new("Playlist cannot have more than #{CONFIG.playlist_length_limit} videos")
|
||||
end
|
||||
@ -182,7 +182,7 @@ struct Invidious::User
|
||||
if is_opml?(type, extension)
|
||||
subscriptions = XML.parse(body)
|
||||
user.subscriptions += subscriptions.xpath_nodes(%q(//outline[@type="rss"])).map do |channel|
|
||||
channel["xmlUrl"].match(/UC[a-zA-Z0-9_-]{22}/).not_nil![0]
|
||||
channel["xmlUrl"].match!(/UC[a-zA-Z0-9_-]{22}/)[0]
|
||||
end
|
||||
elsif extension == "json" || type == "application/json"
|
||||
subscriptions = JSON.parse(body)
|
||||
|
@ -394,10 +394,6 @@ end
|
||||
def fetch_video(id, region)
|
||||
info = extract_video_info(video_id: id)
|
||||
|
||||
allowed_regions = info
|
||||
.dig?("microformat", "playerMicroformatRenderer", "availableCountries")
|
||||
.try &.as_a.map &.as_s || [] of String
|
||||
|
||||
if reason = info["reason"]?
|
||||
if reason == "Video unavailable"
|
||||
raise NotFoundException.new(reason.as_s || "")
|
||||
|
@ -1,6 +1,6 @@
|
||||
<div class="flex-right flexible">
|
||||
<div class="icon-buttons">
|
||||
<a title="<%=translate(locale, "videoinfo_watch_on_youTube")%>" href="https://www.youtube.com/watch<%=endpoint_params%>">
|
||||
<a title="<%=translate(locale, "videoinfo_watch_on_youTube")%>" rel="noreferrer noopener" href="https://www.youtube.com/watch<%=endpoint_params%>">
|
||||
<i class="icon ion-logo-youtube"></i>
|
||||
</a>
|
||||
<a title="<%=translate(locale, "Audio mode")%>" href="/watch<%=endpoint_params%>&listen=1">
|
||||
|
@ -83,7 +83,7 @@
|
||||
|
||||
<% if !playlist.is_a? InvidiousPlaylist %>
|
||||
<div class="pure-u-2-3">
|
||||
<a href="https://www.youtube.com/playlist?list=<%= playlist.id %>">
|
||||
<a rel="noreferrer noopener" href="https://www.youtube.com/playlist?list=<%= playlist.id %>">
|
||||
<%= translate(locale, "View playlist on YouTube") %>
|
||||
</a>
|
||||
<span> | </span>
|
||||
|
@ -123,8 +123,8 @@ we're going to need to do it here in order to allow for translations.
|
||||
link_yt_embed = IV::HttpServer::Utils.add_params_to_url(link_yt_embed, link_yt_param)
|
||||
end
|
||||
-%>
|
||||
<a id="link-yt-watch" data-base-url="<%= link_yt_watch %>" href="<%= link_yt_watch %>"><%= translate(locale, "videoinfo_watch_on_youTube") %></a>
|
||||
(<a id="link-yt-embed" data-base-url="<%= link_yt_embed %>" href="<%= link_yt_embed %>"><%= translate(locale, "videoinfo_youTube_embed_link") %></a>)
|
||||
<a id="link-yt-watch" rel="noreferrer noopener" data-base-url="<%= link_yt_watch %>" href="<%= link_yt_watch %>"><%= translate(locale, "videoinfo_watch_on_youTube") %></a>
|
||||
(<a id="link-yt-embed" rel="noreferrer noopener" data-base-url="<%= link_yt_embed %>" href="<%= link_yt_embed %>"><%= translate(locale, "videoinfo_youTube_embed_link") %></a>)
|
||||
</span>
|
||||
|
||||
<p id="watch-on-another-invidious-instance">
|
||||
|
@ -24,7 +24,7 @@ struct YoutubeConnectionPool
|
||||
@pool = build_pool()
|
||||
end
|
||||
|
||||
def client(&block)
|
||||
def client(&)
|
||||
conn = pool.checkout
|
||||
begin
|
||||
response = yield conn
|
||||
@ -69,7 +69,7 @@ def make_client(url : URI, region = nil, force_resolve : Bool = false)
|
||||
return client
|
||||
end
|
||||
|
||||
def make_client(url : URI, region = nil, force_resolve : Bool = false, &block)
|
||||
def make_client(url : URI, region = nil, force_resolve : Bool = false, &)
|
||||
client = make_client(url, region, force_resolve)
|
||||
begin
|
||||
yield client
|
||||
|
@ -109,7 +109,6 @@ private module Parsers
|
||||
end
|
||||
|
||||
live_now = false
|
||||
paid = false
|
||||
premium = false
|
||||
|
||||
premiere_timestamp = item_contents.dig?("upcomingEventData", "startTime").try { |t| Time.unix(t.as_s.to_i64) }
|
||||
@ -856,7 +855,7 @@ end
|
||||
#
|
||||
# This function yields the container so that items can be parsed separately.
|
||||
#
|
||||
def extract_items(initial_data : InitialData, &block)
|
||||
def extract_items(initial_data : InitialData, &)
|
||||
if unpackaged_data = initial_data["contents"]?.try &.as_h
|
||||
elsif unpackaged_data = initial_data["response"]?.try &.as_h
|
||||
elsif unpackaged_data = initial_data.dig?("onResponseReceivedActions", 1).try &.as_h
|
||||
|
@ -83,5 +83,5 @@ end
|
||||
|
||||
def extract_selected_tab(tabs)
|
||||
# Extract the selected tab from the array of tabs Youtube returns
|
||||
return selected_target = tabs.as_a.select(&.["tabRenderer"]?.try &.["selected"]?.try &.as_bool)[0]["tabRenderer"]
|
||||
return tabs.as_a.select(&.["tabRenderer"]?.try &.["selected"]?.try &.as_bool)[0]["tabRenderer"]
|
||||
end
|
||||
|
Loading…
Reference in New Issue
Block a user