diff --git a/patches/2444.patch b/patches/3-2444.patch similarity index 100% rename from patches/2444.patch rename to patches/3-2444.patch diff --git a/patches/4-2428.patch b/patches/4-2428.patch new file mode 100644 index 0000000..da99033 --- /dev/null +++ b/patches/4-2428.patch @@ -0,0 +1,1300 @@ +From 0614b52f037127591f12e54e78be0ee22e469b69 Mon Sep 17 00:00:00 2001 +From: syeopite +Date: Fri, 24 Sep 2021 18:51:07 -0700 +Subject: [PATCH 01/12] Fix Lint/RedundantStringCoercion issues + +--- + src/invidious/routes/video_playback.cr | 2 +- + src/invidious/yt_backend/youtube_api.cr | 6 +++--- + 2 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/invidious/routes/video_playback.cr b/src/invidious/routes/video_playback.cr +index acbf62b4e..5c64f6690 100644 +--- a/src/invidious/routes/video_playback.cr ++++ b/src/invidious/routes/video_playback.cr +@@ -20,7 +20,7 @@ module Invidious::Routes::VideoPlayback + host = "https://r#{fvip}---#{mns.pop}.googlevideo.com" + end + +- url = "/videoplayback?#{query_params.to_s}" ++ url = "/videoplayback?#{query_params}" + + headers = HTTP::Headers.new + REQUEST_HEADERS_WHITELIST.each do |header| +diff --git a/src/invidious/yt_backend/youtube_api.cr b/src/invidious/yt_backend/youtube_api.cr +index b3815f6a6..8ab2fe46d 100644 +--- a/src/invidious/yt_backend/youtube_api.cr ++++ b/src/invidious/yt_backend/youtube_api.cr +@@ -410,8 +410,8 @@ module YoutubeAPI + + # Logging + LOGGER.debug("YoutubeAPI: Using endpoint: \"#{endpoint}\"") +- LOGGER.trace("YoutubeAPI: ClientConfig: #{client_config.to_s}") +- LOGGER.trace("YoutubeAPI: POST data: #{data.to_s}") ++ LOGGER.trace("YoutubeAPI: ClientConfig: #{client_config}") ++ LOGGER.trace("YoutubeAPI: POST data: #{data}") + + # Send the POST request + if client_config.proxy_region +@@ -436,7 +436,7 @@ module YoutubeAPI + # Logging + LOGGER.error("YoutubeAPI: Got error #{code} when requesting #{endpoint}") + LOGGER.error("YoutubeAPI: #{message}") +- LOGGER.info("YoutubeAPI: POST data was: #{data.to_s}") ++ LOGGER.info("YoutubeAPI: POST data was: #{data}") + + raise InfoException.new("Could not extract JSON. Youtube API returned \ + error #{code} with message:
\"#{message}\"") + +From 20cb751ff65a179a694fde4ce2bb60dda0e68b30 Mon Sep 17 00:00:00 2001 +From: syeopite +Date: Fri, 24 Sep 2021 19:05:25 -0700 +Subject: [PATCH 02/12] Fix Lint/UnusedArgument issues + +--- + src/invidious.cr | 2 +- + src/invidious/channels/community.cr | 2 +- + src/invidious/channels/playlists.cr | 2 +- + src/invidious/channels/videos.cr | 2 +- + src/invidious/comments.cr | 4 ++-- + src/invidious/helpers/serialized_yt_data.cr | 2 +- + src/invidious/helpers/signatures.cr | 2 +- + src/invidious/playlists.cr | 6 +++--- + src/invidious/routes/api/v1/authenticated.cr | 2 +- + src/invidious/routes/login.cr | 4 ++-- + src/invidious/search.cr | 4 ++-- + 11 files changed, 16 insertions(+), 16 deletions(-) + +diff --git a/src/invidious.cr b/src/invidious.cr +index 570c33e69..e2c83bdad 100644 +--- a/src/invidious.cr ++++ b/src/invidious.cr +@@ -1351,7 +1351,7 @@ error 500 do |env, ex| + error_template(500, ex) + end + +-static_headers do |response, filepath, filestat| ++static_headers do | response | + response.headers.add("Cache-Control", "max-age=2629800") + end + +diff --git a/src/invidious/channels/community.cr b/src/invidious/channels/community.cr +index 97ab30ecd..a8bdd2e46 100644 +--- a/src/invidious/channels/community.cr ++++ b/src/invidious/channels/community.cr +@@ -242,7 +242,7 @@ def produce_channel_community_continuation(ucid, cursor) + }, + } + +- continuation = object.try { |i| Protodec::Any.cast_json(object) } ++ continuation = object.try { |i| Protodec::Any.cast_json(i) } + .try { |i| Protodec::Any.from_json(i) } + .try { |i| Base64.urlsafe_encode(i) } + .try { |i| URI.encode_www_form(i) } +diff --git a/src/invidious/channels/playlists.cr b/src/invidious/channels/playlists.cr +index 393b055e6..3072b21da 100644 +--- a/src/invidious/channels/playlists.cr ++++ b/src/invidious/channels/playlists.cr +@@ -84,7 +84,7 @@ def produce_channel_playlists_url(ucid, cursor, sort = "newest", auto_generated + object["80226972:embedded"]["3:string"] = Base64.urlsafe_encode(Protodec::Any.from_json(Protodec::Any.cast_json(object["80226972:embedded"]["3:base64"]))) + object["80226972:embedded"].delete("3:base64") + +- continuation = object.try { |i| Protodec::Any.cast_json(object) } ++ continuation = object.try { |i| Protodec::Any.cast_json(i) } + .try { |i| Protodec::Any.from_json(i) } + .try { |i| Base64.urlsafe_encode(i) } + .try { |i| URI.encode_www_form(i) } +diff --git a/src/invidious/channels/videos.cr b/src/invidious/channels/videos.cr +index 2c43bf0b1..48453bb71 100644 +--- a/src/invidious/channels/videos.cr ++++ b/src/invidious/channels/videos.cr +@@ -49,7 +49,7 @@ def produce_channel_videos_continuation(ucid, page = 1, auto_generated = nil, so + object["80226972:embedded"]["3:string"] = Base64.urlsafe_encode(Protodec::Any.from_json(Protodec::Any.cast_json(object["80226972:embedded"]["3:base64"]))) + object["80226972:embedded"].delete("3:base64") + +- continuation = object.try { |i| Protodec::Any.cast_json(object) } ++ continuation = object.try { |i| Protodec::Any.cast_json(i) } + .try { |i| Protodec::Any.from_json(i) } + .try { |i| Base64.urlsafe_encode(i) } + .try { |i| URI.encode_www_form(i) } +diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr +index 9c7882534..caeaa0e8d 100644 +--- a/src/invidious/comments.cr ++++ b/src/invidious/comments.cr +@@ -638,7 +638,7 @@ def produce_comment_continuation(video_id, cursor = "", sort_by = "top") + object["6:embedded"].as(Hash)["4:embedded"].as(Hash)["6:varint"] = 0_i64 + end + +- continuation = object.try { |i| Protodec::Any.cast_json(object) } ++ continuation = object.try { |i| Protodec::Any.cast_json(i) } + .try { |i| Protodec::Any.from_json(i) } + .try { |i| Base64.urlsafe_encode(i) } + .try { |i| URI.encode_www_form(i) } +@@ -673,7 +673,7 @@ def produce_comment_reply_continuation(video_id, ucid, comment_id) + }, + } + +- continuation = object.try { |i| Protodec::Any.cast_json(object) } ++ continuation = object.try { |i| Protodec::Any.cast_json(i) } + .try { |i| Protodec::Any.from_json(i) } + .try { |i| Base64.urlsafe_encode(i) } + .try { |i| URI.encode_www_form(i) } +diff --git a/src/invidious/helpers/serialized_yt_data.cr b/src/invidious/helpers/serialized_yt_data.cr +index a9798f0c0..1ba3f20ed 100644 +--- a/src/invidious/helpers/serialized_yt_data.cr ++++ b/src/invidious/helpers/serialized_yt_data.cr +@@ -62,7 +62,7 @@ struct SearchVideo + if xml + to_xml(HOST_URL, auto_generated, query_params, xml) + else +- XML.build do |json| ++ XML.build do |xml| + to_xml(HOST_URL, auto_generated, query_params, xml) + end + end +diff --git a/src/invidious/helpers/signatures.cr b/src/invidious/helpers/signatures.cr +index d8b1de659..ee09415bb 100644 +--- a/src/invidious/helpers/signatures.cr ++++ b/src/invidious/helpers/signatures.cr +@@ -30,7 +30,7 @@ struct DecryptFunction + + case op_body + when "{a.reverse()" +- operations[op_name] = ->(a : Array(String), b : Int32) { a.reverse } ++ operations[op_name] = ->(a : Array(String), _b : Int32) { a.reverse } + when "{a.splice(0,b)" + operations[op_name] = ->(a : Array(String), b : Int32) { a.delete_at(0..(b - 1)); a } + else +diff --git a/src/invidious/playlists.cr b/src/invidious/playlists.cr +index 7940dc1f0..70c74eb36 100644 +--- a/src/invidious/playlists.cr ++++ b/src/invidious/playlists.cr +@@ -51,7 +51,7 @@ struct PlaylistVideo + if xml + to_xml(auto_generated, xml) + else +- XML.build do |json| ++ XML.build do |xml| # Why was this `json`? + to_xml(auto_generated, xml) + end + end +@@ -143,7 +143,7 @@ struct Playlist + json.field "videos" do + json.array do + videos = get_playlist_videos(PG_DB, self, offset: offset, locale: locale, video_id: video_id) +- videos.each_with_index do |video, index| ++ videos.each do |video| + video.to_json(locale, json) + end + end +@@ -336,7 +336,7 @@ def produce_playlist_continuation(id, index) + }, + } + +- continuation = object.try { |i| Protodec::Any.cast_json(object) } ++ continuation = object.try { |i| Protodec::Any.cast_json(i) } + .try { |i| Protodec::Any.from_json(i) } + .try { |i| Base64.urlsafe_encode(i) } + .try { |i| URI.encode_www_form(i) } +diff --git a/src/invidious/routes/api/v1/authenticated.cr b/src/invidious/routes/api/v1/authenticated.cr +index b4e9e9c8b..f7a2ad781 100644 +--- a/src/invidious/routes/api/v1/authenticated.cr ++++ b/src/invidious/routes/api/v1/authenticated.cr +@@ -335,7 +335,7 @@ module Invidious::Routes::API::V1::Authenticated + + case env.request.headers["Content-Type"]? + when "application/x-www-form-urlencoded" +- 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? + when "application/json" +diff --git a/src/invidious/routes/login.cr b/src/invidious/routes/login.cr +index e7aef289f..b719b5716 100644 +--- a/src/invidious/routes/login.cr ++++ b/src/invidious/routes/login.cr +@@ -395,7 +395,7 @@ module Invidious::Routes::Login + return templated "login" + end + +- tokens = env.params.body.select { |k, v| k.match(/^token\[\d+\]$/) }.map { |k, v| v } ++ tokens = env.params.body.select { |k, _| k.match(/^token\[\d+\]$/) }.map { |_, v| v } + + answer ||= "" + captcha_type ||= "image" +@@ -419,7 +419,7 @@ module Invidious::Routes::Login + + found_valid_captcha = false + error_exception = Exception.new +- tokens.each_with_index do |token, i| ++ tokens.each do |token| + begin + validate_request(token, answer, env.request, HMAC_KEY, PG_DB, locale) + found_valid_captcha = true +diff --git a/src/invidious/search.cr b/src/invidious/search.cr +index d95d802ea..f59c9a141 100644 +--- a/src/invidious/search.cr ++++ b/src/invidious/search.cr +@@ -128,7 +128,7 @@ def produce_search_params(page = 1, sort : String = "relevance", date : String = + object.delete("2:embedded") + end + +- params = object.try { |i| Protodec::Any.cast_json(object) } ++ params = object.try { |i| Protodec::Any.cast_json(i) } + .try { |i| Protodec::Any.from_json(i) } + .try { |i| Base64.urlsafe_encode(i) } + .try { |i| URI.encode_www_form(i) } +@@ -161,7 +161,7 @@ def produce_channel_search_continuation(ucid, query, page) + }, + } + +- continuation = object.try { |i| Protodec::Any.cast_json(object) } ++ continuation = object.try { |i| Protodec::Any.cast_json(i) } + .try { |i| Protodec::Any.from_json(i) } + .try { |i| Base64.urlsafe_encode(i) } + .try { |i| URI.encode_www_form(i) } + +From 35d15c7c2b5d71582f7ce4b7875a777ccb0ebcd8 Mon Sep 17 00:00:00 2001 +From: syeopite +Date: Fri, 24 Sep 2021 19:15:23 -0700 +Subject: [PATCH 03/12] Fix Style/VariableNames issues + +--- + src/invidious.cr | 8 ++++---- + src/invidious/channels/playlists.cr | 8 ++++---- + src/invidious/comments.cr | 25 +++++++++++++------------ + src/invidious/routes/api/v1/videos.cr | 8 ++++---- + src/invidious/routes/embed.cr | 4 ++-- + src/invidious/routes/watch.cr | 4 ++-- + src/invidious/search.cr | 6 +++--- + src/invidious/videos.cr | 18 +++++++++--------- + src/invidious/views/watch.ecr | 2 +- + 9 files changed, 42 insertions(+), 41 deletions(-) + +diff --git a/src/invidious.cr b/src/invidious.cr +index e2c83bdad..f41ae6f80 100644 +--- a/src/invidious.cr ++++ b/src/invidious.cr +@@ -703,13 +703,13 @@ get "/subscription_manager" do |env| + xml.element("outline", text: title, title: title) do + subscriptions.each do |channel| + if format == "newpipe" +- xmlUrl = "https://www.youtube.com/feeds/videos.xml?channel_id=#{channel.id}" ++ xml_url = "https://www.youtube.com/feeds/videos.xml?channel_id=#{channel.id}" + else +- xmlUrl = "#{HOST_URL}/feed/channel/#{channel.id}" ++ xml_url = "#{HOST_URL}/feed/channel/#{channel.id}" + end + + xml.element("outline", text: channel.author, title: channel.author, +- "type": "rss", xmlUrl: xmlUrl) ++ "type": "rss", xmlUrl: xml_url) + end + end + end +@@ -1351,7 +1351,7 @@ error 500 do |env, ex| + error_template(500, ex) + end + +-static_headers do | response | ++static_headers do |response| + response.headers.add("Cache-Control", "max-age=2629800") + end + +diff --git a/src/invidious/channels/playlists.cr b/src/invidious/channels/playlists.cr +index 3072b21da..d5628f6ab 100644 +--- a/src/invidious/channels/playlists.cr ++++ b/src/invidious/channels/playlists.cr +@@ -1,17 +1,17 @@ + def fetch_channel_playlists(ucid, author, continuation, sort_by) + if continuation + response_json = YoutubeAPI.browse(continuation) +- continuationItems = response_json["onResponseReceivedActions"]? ++ continuation_items = response_json["onResponseReceivedActions"]? + .try &.[0]["appendContinuationItemsAction"]["continuationItems"] + +- return [] of SearchItem, nil if !continuationItems ++ return [] of SearchItem, nil if !continuation_items + + items = [] of SearchItem +- continuationItems.as_a.select(&.as_h.has_key?("gridPlaylistRenderer")).each { |item| ++ continuation_items.as_a.select(&.as_h.has_key?("gridPlaylistRenderer")).each { |item| + extract_item(item, author, ucid).try { |t| items << t } + } + +- continuation = continuationItems.as_a.last["continuationItemRenderer"]? ++ continuation = continuation_items.as_a.last["continuationItemRenderer"]? + .try &.["continuationEndpoint"]["continuationCommand"]["token"].as_s + else + url = "/channel/#{ucid}/playlists?flow=list&view=1" +diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr +index caeaa0e8d..3370b088c 100644 +--- a/src/invidious/comments.cr ++++ b/src/invidious/comments.cr +@@ -73,9 +73,9 @@ def fetch_youtube_comments(id, cursor, format, locale, thin_mode, region, sort_b + contents = nil + + if response["onResponseReceivedEndpoints"]? +- onResponseReceivedEndpoints = response["onResponseReceivedEndpoints"] ++ on_response_received_endpoints = response["onResponseReceivedEndpoints"] + header = nil +- onResponseReceivedEndpoints.as_a.each do |item| ++ on_response_received_endpoints.as_a.each do |item| + if item["reloadContinuationItemsCommand"]? + case item["reloadContinuationItemsCommand"]["slot"] + when "RELOAD_CONTINUATION_SLOT_HEADER" +@@ -97,7 +97,8 @@ def fetch_youtube_comments(id, cursor, format, locale, thin_mode, region, sort_b + contents = body["contents"]? + header = body["header"]? + if body["continuations"]? +- moreRepliesContinuation = body["continuations"][0]["nextContinuationData"]["continuation"].as_s ++ # Removable? Doesn't seem like this is used. ++ more_replies_continuation = body["continuations"][0]["nextContinuationData"]["continuation"].as_s + end + else + raise InfoException.new("Could not fetch comments") +@@ -111,10 +112,10 @@ def fetch_youtube_comments(id, cursor, format, locale, thin_mode, region, sort_b + end + end + +- continuationItemRenderer = nil ++ continuation_item_renderer = nil + contents.as_a.reject! do |item| + if item["continuationItemRenderer"]? +- continuationItemRenderer = item["continuationItemRenderer"] ++ continuation_item_renderer = item["continuationItemRenderer"] + true + end + end +@@ -232,14 +233,14 @@ def fetch_youtube_comments(id, cursor, format, locale, thin_mode, region, sort_b + end + end + +- if continuationItemRenderer +- if continuationItemRenderer["continuationEndpoint"]? +- continuationEndpoint = continuationItemRenderer["continuationEndpoint"] +- elsif continuationItemRenderer["button"]? +- continuationEndpoint = continuationItemRenderer["button"]["buttonRenderer"]["command"] ++ if continuation_item_renderer ++ if continuation_item_renderer["continuationEndpoint"]? ++ continuation_endpoint = continuation_item_renderer["continuationEndpoint"] ++ elsif continuation_item_renderer["button"]? ++ continuation_endpoint = continuation_item_renderer["button"]["buttonRenderer"]["command"] + end +- if continuationEndpoint +- json.field "continuation", continuationEndpoint["continuationCommand"]["token"].as_s ++ if continuation_endpoint ++ json.field "continuation", continuation_endpoint["continuationCommand"]["token"].as_s + end + end + end +diff --git a/src/invidious/routes/api/v1/videos.cr b/src/invidious/routes/api/v1/videos.cr +index 575e6fdf5..d483bca6b 100644 +--- a/src/invidious/routes/api/v1/videos.cr ++++ b/src/invidious/routes/api/v1/videos.cr +@@ -58,7 +58,7 @@ module Invidious::Routes::API::V1::Videos + captions.each do |caption| + json.object do + json.field "label", caption.name +- json.field "languageCode", caption.languageCode ++ json.field "languageCode", caption.language_code + json.field "url", "/api/v1/captions/#{id}?label=#{URI.encode_www_form(caption.name)}" + end + end +@@ -73,7 +73,7 @@ module Invidious::Routes::API::V1::Videos + env.response.content_type = "text/vtt; charset=UTF-8" + + if lang +- caption = captions.select { |caption| caption.languageCode == lang } ++ caption = captions.select { |caption| caption.language_code == lang } + else + caption = captions.select { |caption| caption.name == label } + end +@@ -84,7 +84,7 @@ module Invidious::Routes::API::V1::Videos + caption = caption[0] + end + +- url = URI.parse("#{caption.baseUrl}&tlang=#{tlang}").request_target ++ url = URI.parse("#{caption.base_url}&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 +@@ -96,7 +96,7 @@ module Invidious::Routes::API::V1::Videos + str << <<-END_VTT + WEBVTT + Kind: captions +- Language: #{tlang || caption.languageCode} ++ Language: #{tlang || caption.language_code} + + + END_VTT +diff --git a/src/invidious/routes/embed.cr b/src/invidious/routes/embed.cr +index 80d097893..ffbf8c14a 100644 +--- a/src/invidious/routes/embed.cr ++++ b/src/invidious/routes/embed.cr +@@ -168,11 +168,11 @@ module Invidious::Routes::Embed + + preferred_captions = captions.select { |caption| + params.preferred_captions.includes?(caption.name) || +- params.preferred_captions.includes?(caption.languageCode.split("-")[0]) ++ params.preferred_captions.includes?(caption.language_code.split("-")[0]) + } + preferred_captions.sort_by! { |caption| + (params.preferred_captions.index(caption.name) || +- params.preferred_captions.index(caption.languageCode.split("-")[0])).not_nil! ++ params.preferred_captions.index(caption.language_code.split("-")[0])).not_nil! + } + captions = captions - preferred_captions + +diff --git a/src/invidious/routes/watch.cr b/src/invidious/routes/watch.cr +index 2db133eed..abcf427e0 100644 +--- a/src/invidious/routes/watch.cr ++++ b/src/invidious/routes/watch.cr +@@ -153,11 +153,11 @@ module Invidious::Routes::Watch + + preferred_captions = captions.select { |caption| + params.preferred_captions.includes?(caption.name) || +- params.preferred_captions.includes?(caption.languageCode.split("-")[0]) ++ params.preferred_captions.includes?(caption.language_code.split("-")[0]) + } + preferred_captions.sort_by! { |caption| + (params.preferred_captions.index(caption.name) || +- params.preferred_captions.index(caption.languageCode.split("-")[0])).not_nil! ++ params.preferred_captions.index(caption.language_code.split("-")[0])).not_nil! + } + captions = captions - preferred_captions + +diff --git a/src/invidious/search.cr b/src/invidious/search.cr +index f59c9a141..f06ee7f6c 100644 +--- a/src/invidious/search.cr ++++ b/src/invidious/search.cr +@@ -14,13 +14,13 @@ def channel_search(query, page, channel) + continuation = produce_channel_search_continuation(ucid, query, page) + response_json = YoutubeAPI.browse(continuation) + +- continuationItems = response_json["onResponseReceivedActions"]? ++ continuation_items = response_json["onResponseReceivedActions"]? + .try &.[0]["appendContinuationItemsAction"]["continuationItems"] + +- return 0, [] of SearchItem if !continuationItems ++ return 0, [] of SearchItem if !continuation_items + + items = [] of SearchItem +- continuationItems.as_a.select(&.as_h.has_key?("itemSectionRenderer")).each { |item| ++ continuation_items.as_a.select(&.as_h.has_key?("itemSectionRenderer")).each { |item| + extract_item(item["itemSectionRenderer"]["contents"].as_a[0]) + .try { |t| items << t } + } +diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr +index 0e6bd77c4..0fe949c71 100644 +--- a/src/invidious/videos.cr ++++ b/src/invidious/videos.cr +@@ -426,7 +426,7 @@ struct Video + self.captions.each do |caption| + json.object do + json.field "label", caption.name +- json.field "languageCode", caption.languageCode ++ json.field "language_code", caption.language_code + json.field "url", "/api/v1/captions/#{id}?label=#{URI.encode_www_form(caption.name)}" + end + end +@@ -703,10 +703,10 @@ struct Video + return @captions.as(Array(Caption)) if @captions + captions = info["captions"]?.try &.["playerCaptionsTracklistRenderer"]?.try &.["captionTracks"]?.try &.as_a.map do |caption| + name = caption["name"]["simpleText"]? || caption["name"]["runs"][0]["text"] +- languageCode = caption["languageCode"].to_s +- baseUrl = caption["baseUrl"].to_s ++ language_code = caption["languageCode"].to_s ++ base_url = caption["baseUrl"].to_s + +- caption = Caption.new(name.to_s, languageCode, baseUrl) ++ caption = Caption.new(name.to_s, language_code, base_url) + caption.name = caption.name.split(" - ")[0] + caption + end +@@ -785,16 +785,16 @@ end + + struct Caption + property name +- property languageCode +- property baseUrl ++ property language_code ++ property base_url + + getter name : String +- getter languageCode : String +- getter baseUrl : String ++ getter language_code : String ++ getter base_url : String + + setter name + +- def initialize(@name, @languageCode, @baseUrl) ++ def initialize(@name, @language_code, @base_url) + end + end + +diff --git a/src/invidious/views/watch.ecr b/src/invidious/views/watch.ecr +index 398e25b6a..265d1628f 100644 +--- a/src/invidious/views/watch.ecr ++++ b/src/invidious/views/watch.ecr +@@ -184,7 +184,7 @@ we're going to need to do it here in order to allow for translations. + + <% end %> + <% captions.each do |caption| %> +- + <% end %> + +From e91421253e07903c973ddec758abfc633ed58cf9 Mon Sep 17 00:00:00 2001 +From: syeopite +Date: Fri, 24 Sep 2021 19:42:43 -0700 +Subject: [PATCH 04/12] Fix Style/VerboseBlock issues + +--- + src/invidious.cr | 10 ++++----- + src/invidious/channels/about.cr | 6 +++--- + src/invidious/channels/channels.cr | 2 +- + src/invidious/channels/community.cr | 4 ++-- + src/invidious/helpers/helpers.cr | 8 +++---- + src/invidious/helpers/static_file_handler.cr | 2 +- + src/invidious/helpers/tokens.cr | 8 +++---- + src/invidious/mixes.cr | 2 +- + src/invidious/routes/api/v1/authenticated.cr | 2 +- + src/invidious/routes/api/v1/search.cr | 2 +- + src/invidious/routes/channels.cr | 4 ++-- + src/invidious/search.cr | 2 +- + src/invidious/users.cr | 22 ++++++++++---------- + src/invidious/videos.cr | 12 +++++------ + src/invidious/yt_backend/proxy.cr | 2 +- + 15 files changed, 44 insertions(+), 44 deletions(-) + +diff --git a/src/invidious.cr b/src/invidious.cr +index f41ae6f80..21a12ff2e 100644 +--- a/src/invidious.cr ++++ b/src/invidious.cr +@@ -655,7 +655,7 @@ get "/subscription_manager" do |env| + end + + subscriptions = PG_DB.query_all("SELECT * FROM channels WHERE id = ANY(#{values})", as: InvidiousChannel) +- subscriptions.sort_by! { |channel| channel.author.downcase } ++ subscriptions.sort_by!(&.author.downcase) + + if action_takeout + if format == "json" +@@ -759,7 +759,7 @@ post "/data_control" do |env| + body = JSON.parse(body) + + if body["subscriptions"]? +- user.subscriptions += body["subscriptions"].as_a.map { |a| a.as_s } ++ user.subscriptions += body["subscriptions"].as_a.map(&.as_s) + user.subscriptions.uniq! + + user.subscriptions = get_batch_channels(user.subscriptions, PG_DB, false, false) +@@ -768,7 +768,7 @@ post "/data_control" do |env| + end + + if body["watch_history"]? +- user.watched += body["watch_history"].as_a.map { |a| a.as_s } ++ user.watched += body["watch_history"].as_a.map(&.as_s) + user.watched.uniq! + PG_DB.exec("UPDATE users SET watched = $1 WHERE email = $2", user.watched, user.email) + end +@@ -876,12 +876,12 @@ post "/data_control" do |env| + File.write(tempfile.path, entry.io.gets_to_end) + db = DB.open("sqlite3://" + tempfile.path) + +- user.watched += db.query_all("SELECT url FROM streams", as: String).map { |url| url.lchop("https://www.youtube.com/watch?v=") } ++ user.watched += db.query_all("SELECT url FROM streams", as: String).map(&.lchop("https://www.youtube.com/watch?v=")) + user.watched.uniq! + + PG_DB.exec("UPDATE users SET watched = $1 WHERE email = $2", user.watched, user.email) + +- user.subscriptions += db.query_all("SELECT url FROM subscriptions", as: String).map { |url| url.lchop("https://www.youtube.com/channel/") } ++ user.subscriptions += db.query_all("SELECT url FROM subscriptions", as: String).map(&.lchop("https://www.youtube.com/channel/")) + user.subscriptions.uniq! + + user.subscriptions = get_batch_channels(user.subscriptions, PG_DB, false, false) +diff --git a/src/invidious/channels/about.cr b/src/invidious/channels/about.cr +index 628d5b6fe..a72acc725 100644 +--- a/src/invidious/channels/about.cr ++++ b/src/invidious/channels/about.cr +@@ -62,7 +62,7 @@ def get_about_info(ucid, locale) + description_html = HTML.escape(description).gsub("\n", "
") + + is_family_friendly = initdata["microformat"]["microformatDataRenderer"]["familySafe"].as_bool +- allowed_regions = initdata["microformat"]["microformatDataRenderer"]["availableCountries"].as_a.map { |a| a.as_s } ++ allowed_regions = initdata["microformat"]["microformatDataRenderer"]["availableCountries"].as_a.map(&.as_s) + + related_channels = [] of AboutRelatedChannel + else +@@ -84,7 +84,7 @@ def get_about_info(ucid, locale) + description_html = HTML.escape(description).gsub("\n", "
") + + is_family_friendly = initdata["microformat"]["microformatDataRenderer"]["familySafe"].as_bool +- allowed_regions = initdata["microformat"]["microformatDataRenderer"]["availableCountries"].as_a.map { |a| a.as_s } ++ allowed_regions = initdata["microformat"]["microformatDataRenderer"]["availableCountries"].as_a.map(&.as_s) + + related_channels = initdata["contents"]["twoColumnBrowseResultsRenderer"] + .["secondaryContents"]?.try &.["browseSecondaryContentsRenderer"]["contents"][0]? +@@ -149,7 +149,7 @@ def get_about_info(ucid, locale) + end + end + end +- tabs = tabs_json.reject { |node| node["tabRenderer"]?.nil? }.map { |node| node["tabRenderer"]["title"].as_s.downcase } ++ tabs = tabs_json.reject { |node| node["tabRenderer"]?.nil? }.map(&.["tabRenderer"].["title"].as_s.downcase) + end + + sub_count = initdata["header"]["c4TabbedHeaderRenderer"]?.try &.["subscriberCountText"]?.try &.["simpleText"]?.try &.as_s? +diff --git a/src/invidious/channels/channels.cr b/src/invidious/channels/channels.cr +index 70623cc01..827b6534d 100644 +--- a/src/invidious/channels/channels.cr ++++ b/src/invidious/channels/channels.cr +@@ -101,7 +101,7 @@ struct ChannelVideo + def to_tuple + {% begin %} + { +- {{*@type.instance_vars.map { |var| var.name }}} ++ {{*@type.instance_vars.map(&.name)}} + } + {% end %} + end +diff --git a/src/invidious/channels/community.cr b/src/invidious/channels/community.cr +index a8bdd2e46..9a50f8931 100644 +--- a/src/invidious/channels/community.cr ++++ b/src/invidious/channels/community.cr +@@ -255,11 +255,11 @@ def extract_channel_community_cursor(continuation) + .try { |i| Base64.decode(i) } + .try { |i| IO::Memory.new(i) } + .try { |i| Protodec::Any.parse(i) } +- .try { |i| i["80226972:0:embedded"]["3:1:base64"].as_h } ++ .try(&.["80226972:0:embedded"]["3:1:base64"].as_h) + + if object["53:2:embedded"]?.try &.["3:0:embedded"]? + object["53:2:embedded"]["3:0:embedded"]["2:0:string"] = object["53:2:embedded"]["3:0:embedded"] +- .try { |i| i["2:0:base64"].as_h } ++ .try(&.["2:0:base64"].as_h) + .try { |i| Protodec::Any.cast_json(i) } + .try { |i| Protodec::Any.from_json(i) } + .try { |i| Base64.urlsafe_encode(i, padding: false) } +diff --git a/src/invidious/helpers/helpers.cr b/src/invidious/helpers/helpers.cr +index 2e61d21f9..9c053d74e 100644 +--- a/src/invidious/helpers/helpers.cr ++++ b/src/invidious/helpers/helpers.cr +@@ -89,14 +89,14 @@ def check_table(db, table_name, struct_type = nil) + struct_array = struct_type.type_array + column_array = get_column_array(db, table_name) + column_types = File.read("config/sql/#{table_name}.sql").match(/CREATE TABLE public\.#{table_name}\n\((?[\d\D]*?)\);/) +- .try &.["types"].split(",").map { |line| line.strip }.reject &.starts_with?("CONSTRAINT") ++ .try &.["types"].split(",").map(&.strip).reject &.starts_with?("CONSTRAINT") + + return if !column_types + + struct_array.each_with_index do |name, i| + if name != column_array[i]? + if !column_array[i]? +- new_column = column_types.select { |line| line.starts_with? name }[0] ++ new_column = column_types.select(&.starts_with?(name))[0] + LOGGER.info("check_table: ALTER TABLE #{table_name} ADD COLUMN #{new_column}") + db.exec("ALTER TABLE #{table_name} ADD COLUMN #{new_column}") + next +@@ -104,14 +104,14 @@ def check_table(db, table_name, struct_type = nil) + + # Column doesn't exist + if !column_array.includes? name +- new_column = column_types.select { |line| line.starts_with? name }[0] ++ new_column = column_types.select(&.starts_with?(name))[0] + db.exec("ALTER TABLE #{table_name} ADD COLUMN #{new_column}") + end + + # Column exists but in the wrong position, rotate + if struct_array.includes? column_array[i] + until name == column_array[i] +- new_column = column_types.select { |line| line.starts_with? column_array[i] }[0]?.try &.gsub("#{column_array[i]}", "#{column_array[i]}_new") ++ new_column = column_types.select(&.starts_with?(column_array[i]))[0]?.try &.gsub("#{column_array[i]}", "#{column_array[i]}_new") + + # There's a column we didn't expect + if !new_column +diff --git a/src/invidious/helpers/static_file_handler.cr b/src/invidious/helpers/static_file_handler.cr +index be9d36ab9..111518740 100644 +--- a/src/invidious/helpers/static_file_handler.cr ++++ b/src/invidious/helpers/static_file_handler.cr +@@ -173,7 +173,7 @@ module Kemal + return + end + +- if @cached_files.sum { |element| element[1][:data].bytesize } + (size = File.size(file_path)) < CACHE_LIMIT ++ if @cached_files.sum(&.[1].[:data].bytesize) + (size = File.size(file_path)) < CACHE_LIMIT + data = Bytes.new(size) + File.open(file_path) do |file| + file.read(data) +diff --git a/src/invidious/helpers/tokens.cr b/src/invidious/helpers/tokens.cr +index a09ce90ba..e6d383153 100644 +--- a/src/invidious/helpers/tokens.cr ++++ b/src/invidious/helpers/tokens.cr +@@ -46,7 +46,7 @@ def sign_token(key, hash) + next if key == "signature" + + if value.is_a?(JSON::Any) && value.as_a? +- value = value.as_a.map { |i| i.as_s } ++ value = value.as_a.map(&.as_s) + end + + case value +@@ -82,7 +82,7 @@ def validate_request(token, session, request, key, db, locale = nil) + raise InfoException.new("Erroneous token") + end + +- scopes = token["scopes"].as_a.map { |v| v.as_s } ++ scopes = token["scopes"].as_a.map(&.as_s) + scope = "#{request.method}:#{request.path.lchop("/api/v1/auth/").lstrip("/")}" + if !scopes_include_scope(scopes, scope) + raise InfoException.new("Invalid scope") +@@ -105,11 +105,11 @@ end + + def scope_includes_scope(scope, subset) + methods, endpoint = scope.split(":") +- methods = methods.split(";").map { |method| method.upcase }.reject { |method| method.empty? }.sort ++ methods = methods.split(";").map(&.upcase).reject(&.empty?).sort + endpoint = endpoint.downcase + + subset_methods, subset_endpoint = subset.split(":") +- subset_methods = subset_methods.split(";").map { |method| method.upcase }.sort ++ subset_methods = subset_methods.split(";").map(&.upcase).sort + subset_endpoint = subset_endpoint.downcase + + if methods.empty? +diff --git a/src/invidious/mixes.cr b/src/invidious/mixes.cr +index 63ea434fc..3f342b928 100644 +--- a/src/invidious/mixes.cr ++++ b/src/invidious/mixes.cr +@@ -72,7 +72,7 @@ def fetch_mix(rdid, video_id, cookies = nil, locale = nil) + videos += next_page.videos + end + +- videos.uniq! { |video| video.id } ++ videos.uniq!(&.id) + videos = videos.first(50) + return Mix.new({ + title: mix_title, +diff --git a/src/invidious/routes/api/v1/authenticated.cr b/src/invidious/routes/api/v1/authenticated.cr +index f7a2ad781..7950b3027 100644 +--- a/src/invidious/routes/api/v1/authenticated.cr ++++ b/src/invidious/routes/api/v1/authenticated.cr +@@ -339,7 +339,7 @@ module Invidious::Routes::API::V1::Authenticated + callback_url = env.params.body["callbackUrl"]? + expire = env.params.body["expire"]?.try &.to_i? + when "application/json" +- scopes = env.params.json["scopes"].as(Array).map { |v| v.as_s } ++ scopes = env.params.json["scopes"].as(Array).map(&.as_s) + callback_url = env.params.json["callbackUrl"]?.try &.as(String) + expire = env.params.json["expire"]?.try &.as(Int64) + else +diff --git a/src/invidious/routes/api/v1/search.cr b/src/invidious/routes/api/v1/search.cr +index f3a6fa06e..7234dcddb 100644 +--- a/src/invidious/routes/api/v1/search.cr ++++ b/src/invidious/routes/api/v1/search.cr +@@ -20,7 +20,7 @@ module Invidious::Routes::API::V1::Search + duration = env.params.query["duration"]?.try &.downcase + duration ||= "" + +- features = env.params.query["features"]?.try &.split(",").map { |feature| feature.downcase } ++ features = env.params.query["features"]?.try &.split(",").map(&.downcase) + features ||= [] of String + + content_type = env.params.query["type"]?.try &.downcase +diff --git a/src/invidious/routes/channels.cr b/src/invidious/routes/channels.cr +index 11c2f8692..bfcc3edd8 100644 +--- a/src/invidious/routes/channels.cr ++++ b/src/invidious/routes/channels.cr +@@ -30,7 +30,7 @@ module Invidious::Routes::Channels + end + end + items = items.select(&.is_a?(SearchPlaylist)).map(&.as(SearchPlaylist)) +- items.each { |item| item.author = "" } ++ items.each(&.author=("")) + else + sort_options = {"newest", "oldest", "popular"} + sort_by ||= "newest" +@@ -58,7 +58,7 @@ module Invidious::Routes::Channels + + items, continuation = fetch_channel_playlists(channel.ucid, channel.author, continuation, sort_by) + items = items.select { |item| item.is_a?(SearchPlaylist) }.map { |item| item.as(SearchPlaylist) } +- items.each { |item| item.author = "" } ++ items.each(&.author=("")) + + templated "playlists" + end +diff --git a/src/invidious/search.cr b/src/invidious/search.cr +index f06ee7f6c..2095721c8 100644 +--- a/src/invidious/search.cr ++++ b/src/invidious/search.cr +@@ -183,7 +183,7 @@ def process_search_query(query, page, user, region) + sort = "relevance" + subscriptions = nil + +- operators = query.split(" ").select { |a| a.match(/\w+:[\w,]+/) } ++ operators = query.split(" ").select(&.match(/\w+:[\w,]+/)) + operators.each do |operator| + key, value = operator.downcase.split(":") + +diff --git a/src/invidious/users.cr b/src/invidious/users.cr +index 8ea7bd4a9..584082bed 100644 +--- a/src/invidious/users.cr ++++ b/src/invidious/users.cr +@@ -248,17 +248,17 @@ def get_subscription_feed(db, user, max_results = 40, page = 1) + notifications = db.query_all("SELECT * FROM channel_videos WHERE id IN (#{args}) ORDER BY published DESC", args: notifications, as: ChannelVideo) + videos = [] of ChannelVideo + +- notifications.sort_by! { |video| video.published }.reverse! ++ notifications.sort_by!(&.published).reverse! + + case user.preferences.sort + when "alphabetically" +- notifications.sort_by! { |video| video.title } ++ notifications.sort_by!(&.title) + when "alphabetically - reverse" +- notifications.sort_by! { |video| video.title }.reverse! ++ notifications.sort_by!(&.title).reverse! + when "channel name" +- notifications.sort_by! { |video| video.author } ++ notifications.sort_by!(&.author) + when "channel name - reverse" +- notifications.sort_by! { |video| video.author }.reverse! ++ notifications.sort_by!(&.author).reverse! + else nil # Ignore + end + else +@@ -279,7 +279,7 @@ def get_subscription_feed(db, user, max_results = 40, page = 1) + videos = PG_DB.query_all("SELECT DISTINCT ON (ucid) * FROM #{view_name} ORDER BY ucid, published DESC", as: ChannelVideo) + end + +- videos.sort_by! { |video| video.published }.reverse! ++ videos.sort_by!(&.published).reverse! + else + if user.preferences.unseen_only + # Only show unwatched +@@ -299,15 +299,15 @@ def get_subscription_feed(db, user, max_results = 40, page = 1) + + case user.preferences.sort + when "published - reverse" +- videos.sort_by! { |video| video.published } ++ videos.sort_by!(&.published) + when "alphabetically" +- videos.sort_by! { |video| video.title } ++ videos.sort_by!(&.title) + when "alphabetically - reverse" +- videos.sort_by! { |video| video.title }.reverse! ++ videos.sort_by!(&.title).reverse! + when "channel name" +- videos.sort_by! { |video| video.author } ++ videos.sort_by!(&.author) + when "channel name - reverse" +- videos.sort_by! { |video| video.author }.reverse! ++ videos.sort_by!(&.author).reverse! + else nil # Ignore + end + +diff --git a/src/invidious/videos.cr b/src/invidious/videos.cr +index 0fe949c71..d38a66d8f 100644 +--- a/src/invidious/videos.cr ++++ b/src/invidious/videos.cr +@@ -880,7 +880,7 @@ def extract_video_info(video_id : String, proxy_region : String? = nil, context_ + + primary_results = player_response.try &.["contents"]?.try &.["twoColumnWatchNextResults"]?.try &.["results"]? + .try &.["results"]?.try &.["contents"]? +- sentiment_bar = primary_results.try &.as_a.select { |object| object["videoPrimaryInfoRenderer"]? }[0]? ++ sentiment_bar = primary_results.try &.as_a.select(&.["videoPrimaryInfoRenderer"]?)[0]? + .try &.["videoPrimaryInfoRenderer"]? + .try &.["sentimentBar"]? + .try &.["sentimentBarRenderer"]? +@@ -891,11 +891,11 @@ def extract_video_info(video_id : String, proxy_region : String? = nil, context_ + params["likes"] = JSON::Any.new(likes) + params["dislikes"] = JSON::Any.new(dislikes) + +- params["descriptionHtml"] = JSON::Any.new(primary_results.try &.as_a.select { |object| object["videoSecondaryInfoRenderer"]? }[0]? ++ params["descriptionHtml"] = JSON::Any.new(primary_results.try &.as_a.select(&.["videoSecondaryInfoRenderer"]?)[0]? + .try &.["videoSecondaryInfoRenderer"]?.try &.["description"]?.try &.["runs"]? + .try &.as_a.try { |t| content_to_comment_html(t).gsub("\n", "
") } || "

") + +- metadata = primary_results.try &.as_a.select { |object| object["videoSecondaryInfoRenderer"]? }[0]? ++ metadata = primary_results.try &.as_a.select(&.["videoSecondaryInfoRenderer"]?)[0]? + .try &.["videoSecondaryInfoRenderer"]? + .try &.["metadataRowContainer"]? + .try &.["metadataRowContainerRenderer"]? +@@ -928,7 +928,7 @@ def extract_video_info(video_id : String, proxy_region : String? = nil, context_ + end + end + +- author_info = primary_results.try &.as_a.select { |object| object["videoSecondaryInfoRenderer"]? }[0]? ++ author_info = primary_results.try &.as_a.select(&.["videoSecondaryInfoRenderer"]?)[0]? + .try &.["videoSecondaryInfoRenderer"]?.try &.["owner"]?.try &.["videoOwnerRenderer"]? + + params["authorThumbnail"] = JSON::Any.new(author_info.try &.["thumbnail"]? +@@ -1023,13 +1023,13 @@ end + def process_video_params(query, preferences) + annotations = query["iv_load_policy"]?.try &.to_i? + autoplay = query["autoplay"]?.try { |q| (q == "true" || q == "1").to_unsafe } +- comments = query["comments"]?.try &.split(",").map { |a| a.downcase } ++ comments = query["comments"]?.try &.split(",").map(&.downcase) + continue = query["continue"]?.try { |q| (q == "true" || q == "1").to_unsafe } + continue_autoplay = query["continue_autoplay"]?.try { |q| (q == "true" || q == "1").to_unsafe } + listen = query["listen"]?.try { |q| (q == "true" || q == "1").to_unsafe } + local = query["local"]?.try { |q| (q == "true" || q == "1").to_unsafe } + player_style = query["player_style"]? +- preferred_captions = query["subtitles"]?.try &.split(",").map { |a| a.downcase } ++ preferred_captions = query["subtitles"]?.try &.split(",").map(&.downcase) + quality = query["quality"]? + quality_dash = query["quality_dash"]? + region = query["region"]? +diff --git a/src/invidious/yt_backend/proxy.cr b/src/invidious/yt_backend/proxy.cr +index 3418d8878..c66fd337c 100644 +--- a/src/invidious/yt_backend/proxy.cr ++++ b/src/invidious/yt_backend/proxy.cr +@@ -256,7 +256,7 @@ def decrypt_port(p, x) + p = p.gsub(/\b\w+\b/, x) + + p = p.split(";") +- p = p.map { |item| item.split("=") } ++ p = p.map(&.split("=")) + + mapping = {} of String => Int32 + p.each do |item| + +From e969c1490a9b01173c05d2c3a10df8aec802b51d Mon Sep 17 00:00:00 2001 +From: syeopite +Date: Fri, 24 Sep 2021 19:50:56 -0700 +Subject: [PATCH 05/12] Fix Performance/ChainedCallWithNoBang issues + +--- + src/invidious/helpers/tokens.cr | 4 ++-- + src/invidious/jobs/pull_popular_videos_job.cr | 2 +- + src/invidious/routes/api/manifest.cr | 2 +- + src/invidious/yt_backend/proxy.cr | 2 +- + 4 files changed, 5 insertions(+), 5 deletions(-) + +diff --git a/src/invidious/helpers/tokens.cr b/src/invidious/helpers/tokens.cr +index e6d383153..3874799aa 100644 +--- a/src/invidious/helpers/tokens.cr ++++ b/src/invidious/helpers/tokens.cr +@@ -105,11 +105,11 @@ end + + def scope_includes_scope(scope, subset) + methods, endpoint = scope.split(":") +- methods = methods.split(";").map(&.upcase).reject(&.empty?).sort ++ methods = methods.split(";").map(&.upcase).reject(&.empty?).sort! + endpoint = endpoint.downcase + + subset_methods, subset_endpoint = subset.split(":") +- subset_methods = subset_methods.split(";").map(&.upcase).sort ++ subset_methods = subset_methods.split(";").map(&.upcase).sort! + subset_endpoint = subset_endpoint.downcase + + if methods.empty? +diff --git a/src/invidious/jobs/pull_popular_videos_job.cr b/src/invidious/jobs/pull_popular_videos_job.cr +index 7a8ab84ee..805016fd5 100644 +--- a/src/invidious/jobs/pull_popular_videos_job.cr ++++ b/src/invidious/jobs/pull_popular_videos_job.cr +@@ -16,7 +16,7 @@ class Invidious::Jobs::PullPopularVideosJob < Invidious::Jobs::BaseJob + loop do + videos = db.query_all(QUERY, as: ChannelVideo) + .sort_by(&.published) +- .reverse ++ .reverse! + + POPULAR_VIDEOS.set(videos) + +diff --git a/src/invidious/routes/api/manifest.cr b/src/invidious/routes/api/manifest.cr +index f8963587e..12687ec6c 100644 +--- a/src/invidious/routes/api/manifest.cr ++++ b/src/invidious/routes/api/manifest.cr +@@ -47,7 +47,7 @@ module Invidious::Routes::API::Manifest + end + + audio_streams = video.audio_streams +- video_streams = video.video_streams.sort_by { |stream| {stream["width"].as_i, stream["fps"].as_i} }.reverse ++ video_streams = video.video_streams.sort_by { |stream| {stream["width"].as_i, stream["fps"].as_i} }.reverse! + + manifest = XML.build(indent: " ", encoding: "UTF-8") do |xml| + xml.element("MPD", "xmlns": "urn:mpeg:dash:schema:mpd:2011", +diff --git a/src/invidious/yt_backend/proxy.cr b/src/invidious/yt_backend/proxy.cr +index c66fd337c..e150d887d 100644 +--- a/src/invidious/yt_backend/proxy.cr ++++ b/src/invidious/yt_backend/proxy.cr +@@ -236,7 +236,7 @@ def get_spys_proxies(country_code = "US") + proxies << {ip: ip, port: port, score: score} + end + +- proxies = proxies.sort_by { |proxy| proxy[:score] }.reverse ++ proxies = proxies.sort_by { |proxy| proxy[:score] }.reverse! + return proxies + end + + +From dd8c412abc90148b50cebc06546b750898b1fe8a Mon Sep 17 00:00:00 2001 +From: syeopite +Date: Fri, 24 Sep 2021 19:57:46 -0700 +Subject: [PATCH 06/12] Fix Style/IsAFilter issues + +--- + src/invidious/helpers/errors.cr | 2 -- + src/invidious/routes/channels.cr | 4 ++-- + src/invidious/routes/playlists.cr | 2 +- + src/invidious/yt_backend/extractors_utils.cr | 2 +- + 4 files changed, 4 insertions(+), 6 deletions(-) + +diff --git a/src/invidious/helpers/errors.cr b/src/invidious/helpers/errors.cr +index e1d025632..e5c77fbc7 100644 +--- a/src/invidious/helpers/errors.cr ++++ b/src/invidious/helpers/errors.cr +@@ -132,8 +132,6 @@ def error_redirect_helper(env : HTTP::Server::Context, locale : Hash(String, JSO + + + END_HTML +- +- return next_step_html + else + return "" + end +diff --git a/src/invidious/routes/channels.cr b/src/invidious/routes/channels.cr +index bfcc3edd8..619159a27 100644 +--- a/src/invidious/routes/channels.cr ++++ b/src/invidious/routes/channels.cr +@@ -29,7 +29,7 @@ module Invidious::Routes::Channels + item.author + end + end +- items = items.select(&.is_a?(SearchPlaylist)).map(&.as(SearchPlaylist)) ++ items = items.select(SearchPlaylist).map(&.as(SearchPlaylist)) + items.each(&.author=("")) + else + sort_options = {"newest", "oldest", "popular"} +@@ -57,7 +57,7 @@ module Invidious::Routes::Channels + end + + items, continuation = fetch_channel_playlists(channel.ucid, channel.author, continuation, sort_by) +- items = items.select { |item| item.is_a?(SearchPlaylist) }.map { |item| item.as(SearchPlaylist) } ++ items = items.select(SearchPlaylist).map { |item| item.as(SearchPlaylist) } + items.each(&.author=("")) + + templated "playlists" +diff --git a/src/invidious/routes/playlists.cr b/src/invidious/routes/playlists.cr +index 5ab15093e..13d99946d 100644 +--- a/src/invidious/routes/playlists.cr ++++ b/src/invidious/routes/playlists.cr +@@ -245,7 +245,7 @@ module Invidious::Routes::Playlists + if query + begin + search_query, count, items, operators = process_search_query(query, page, user, region: nil) +- videos = items.select { |item| item.is_a? SearchVideo }.map { |item| item.as(SearchVideo) } ++ videos = items.select(SearchVideo).map { |item| item.as(SearchVideo) } + rescue ex + videos = [] of SearchVideo + count = 0 +diff --git a/src/invidious/yt_backend/extractors_utils.cr b/src/invidious/yt_backend/extractors_utils.cr +index 97cc09972..add5f488b 100644 +--- a/src/invidious/yt_backend/extractors_utils.cr ++++ b/src/invidious/yt_backend/extractors_utils.cr +@@ -40,7 +40,7 @@ def extract_videos(initial_data : Hash(String, JSON::Any), author_fallback : Str + target << i + end + end +- return target.select(&.is_a?(SearchVideo)).map(&.as(SearchVideo)) ++ return target.select(SearchVideo).map(&.as(SearchVideo)) + end + + def extract_selected_tab(tabs) + +From 1adcac175e357853af1014b9e1bc792e11c7e8de Mon Sep 17 00:00:00 2001 +From: syeopite <70992037+syeopite@users.noreply.github.com> +Date: Sun, 26 Sep 2021 21:55:15 +0000 +Subject: [PATCH 07/12] Update src/invidious/routes/channels.cr + +Co-authored-by: Samantaz Fox +--- + src/invidious/routes/channels.cr | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/invidious/routes/channels.cr b/src/invidious/routes/channels.cr +index 619159a27..13beca17d 100644 +--- a/src/invidious/routes/channels.cr ++++ b/src/invidious/routes/channels.cr +@@ -57,7 +57,7 @@ module Invidious::Routes::Channels + end + + items, continuation = fetch_channel_playlists(channel.ucid, channel.author, continuation, sort_by) +- items = items.select(SearchPlaylist).map { |item| item.as(SearchPlaylist) } ++ items = items.select(SearchPlaylist).map(&.as(SearchPlaylist)) + items.each(&.author=("")) + + templated "playlists" + +From 88ad7c8d8d7728443eabcd48552531f35ff0f065 Mon Sep 17 00:00:00 2001 +From: syeopite <70992037+syeopite@users.noreply.github.com> +Date: Sun, 26 Sep 2021 21:55:25 +0000 +Subject: [PATCH 08/12] Update src/invidious/routes/playlists.cr + +Co-authored-by: Samantaz Fox +--- + src/invidious/routes/playlists.cr | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/invidious/routes/playlists.cr b/src/invidious/routes/playlists.cr +index 13d99946d..21126d7e9 100644 +--- a/src/invidious/routes/playlists.cr ++++ b/src/invidious/routes/playlists.cr +@@ -245,7 +245,7 @@ module Invidious::Routes::Playlists + if query + begin + search_query, count, items, operators = process_search_query(query, page, user, region: nil) +- videos = items.select(SearchVideo).map { |item| item.as(SearchVideo) } ++ videos = items.select(SearchVideo).map(&.as(SearchVideo)) + rescue ex + videos = [] of SearchVideo + count = 0 + +From 575c66efd342af56d3524645f7e3908e7469f56d Mon Sep 17 00:00:00 2001 +From: syeopite +Date: Sun, 26 Sep 2021 14:34:05 -0700 +Subject: [PATCH 09/12] Remove extra dot between [] from ambea copy-pasting. + +--- + src/invidious/channels/about.cr | 2 +- + src/invidious/helpers/static_file_handler.cr | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/invidious/channels/about.cr b/src/invidious/channels/about.cr +index a72acc725..c87c53e04 100644 +--- a/src/invidious/channels/about.cr ++++ b/src/invidious/channels/about.cr +@@ -149,7 +149,7 @@ def get_about_info(ucid, locale) + end + end + end +- tabs = tabs_json.reject { |node| node["tabRenderer"]?.nil? }.map(&.["tabRenderer"].["title"].as_s.downcase) ++ tabs = tabs_json.reject { |node| node["tabRenderer"]?.nil? }.map(&.["tabRenderer"]["title"].as_s.downcase) + end + + sub_count = initdata["header"]["c4TabbedHeaderRenderer"]?.try &.["subscriberCountText"]?.try &.["simpleText"]?.try &.as_s? +diff --git a/src/invidious/helpers/static_file_handler.cr b/src/invidious/helpers/static_file_handler.cr +index 111518740..630c2fd26 100644 +--- a/src/invidious/helpers/static_file_handler.cr ++++ b/src/invidious/helpers/static_file_handler.cr +@@ -173,7 +173,7 @@ module Kemal + return + end + +- if @cached_files.sum(&.[1].[:data].bytesize) + (size = File.size(file_path)) < CACHE_LIMIT ++ if @cached_files.sum(&.[1][:data].bytesize) + (size = File.size(file_path)) < CACHE_LIMIT + data = Bytes.new(size) + File.open(file_path) do |file| + file.read(data) + +From b8f27a42a75169c22c3fec5e24555fffcd29c499 Mon Sep 17 00:00:00 2001 +From: syeopite +Date: Sun, 26 Sep 2021 14:42:00 -0700 +Subject: [PATCH 10/12] Optimize assigning of on_response_received_endpoints + +--- + src/invidious/comments.cr | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/src/invidious/comments.cr b/src/invidious/comments.cr +index 3370b088c..ffdce0009 100644 +--- a/src/invidious/comments.cr ++++ b/src/invidious/comments.cr +@@ -72,8 +72,7 @@ def fetch_youtube_comments(id, cursor, format, locale, thin_mode, region, sort_b + response = YoutubeAPI.next(continuation: ctoken, client_config: client_config) + contents = nil + +- if response["onResponseReceivedEndpoints"]? +- on_response_received_endpoints = response["onResponseReceivedEndpoints"] ++ if on_response_received_endpoints = response["onResponseReceivedEndpoints"]? + header = nil + on_response_received_endpoints.as_a.each do |item| + if item["reloadContinuationItemsCommand"]? + +From 17e481c10720b273745d222770e2cc86edc608fc Mon Sep 17 00:00:00 2001 +From: syeopite +Date: Sun, 26 Sep 2021 14:58:48 -0700 +Subject: [PATCH 11/12] Reduce block verbosity further + +--- + src/invidious/playlists.cr | 2 +- + src/invidious/routes/channels.cr | 4 ++-- + src/invidious/yt_backend/proxy.cr | 2 +- + 3 files changed, 4 insertions(+), 4 deletions(-) + +diff --git a/src/invidious/playlists.cr b/src/invidious/playlists.cr +index 70c74eb36..443d19d72 100644 +--- a/src/invidious/playlists.cr ++++ b/src/invidious/playlists.cr +@@ -51,7 +51,7 @@ struct PlaylistVideo + if xml + to_xml(auto_generated, xml) + else +- XML.build do |xml| # Why was this `json`? ++ XML.build do |xml| + to_xml(auto_generated, xml) + end + end +diff --git a/src/invidious/routes/channels.cr b/src/invidious/routes/channels.cr +index 13beca17d..29748cd0e 100644 +--- a/src/invidious/routes/channels.cr ++++ b/src/invidious/routes/channels.cr +@@ -30,7 +30,7 @@ module Invidious::Routes::Channels + end + end + items = items.select(SearchPlaylist).map(&.as(SearchPlaylist)) +- items.each(&.author=("")) ++ items.each(&.author = "") + else + sort_options = {"newest", "oldest", "popular"} + sort_by ||= "newest" +@@ -58,7 +58,7 @@ module Invidious::Routes::Channels + + items, continuation = fetch_channel_playlists(channel.ucid, channel.author, continuation, sort_by) + items = items.select(SearchPlaylist).map(&.as(SearchPlaylist)) +- items.each(&.author=("")) ++ items.each(&.author = "") + + templated "playlists" + end +diff --git a/src/invidious/yt_backend/proxy.cr b/src/invidious/yt_backend/proxy.cr +index e150d887d..2d0fd4ba4 100644 +--- a/src/invidious/yt_backend/proxy.cr ++++ b/src/invidious/yt_backend/proxy.cr +@@ -236,7 +236,7 @@ def get_spys_proxies(country_code = "US") + proxies << {ip: ip, port: port, score: score} + end + +- proxies = proxies.sort_by { |proxy| proxy[:score] }.reverse! ++ proxies = proxies.sort_by!(&.[:score]).reverse! + return proxies + end + + +From e2bbc9a6fa401fb969130251ea1a67003051a667 Mon Sep 17 00:00:00 2001 +From: syeopite +Date: Sun, 26 Sep 2021 15:04:33 -0700 +Subject: [PATCH 12/12] Switch to #sort_by! in pull_popular_videos job + +--- + src/invidious/jobs/pull_popular_videos_job.cr | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/invidious/jobs/pull_popular_videos_job.cr b/src/invidious/jobs/pull_popular_videos_job.cr +index 805016fd5..38de816e7 100644 +--- a/src/invidious/jobs/pull_popular_videos_job.cr ++++ b/src/invidious/jobs/pull_popular_videos_job.cr +@@ -15,7 +15,7 @@ class Invidious::Jobs::PullPopularVideosJob < Invidious::Jobs::BaseJob + def begin + loop do + videos = db.query_all(QUERY, as: ChannelVideo) +- .sort_by(&.published) ++ .sort_by!(&.published) + .reverse! + + POPULAR_VIDEOS.set(videos)