Comments: Move link utility functions to own file + module

This commit is contained in:
Samantaz Fox 2023-05-06 20:20:27 +02:00
parent de78848039
commit df85265453
No known key found for this signature in database
GPG key ID: F42821059186176E
4 changed files with 82 additions and 79 deletions

View file

@ -1,76 +1,3 @@
def replace_links(html)
# Check if the document is empty
# Prevents edge-case bug with Reddit comments, see issue #3115
if html.nil? || html.empty?
return html
end
html = XML.parse_html(html)
html.xpath_nodes(%q(//a)).each do |anchor|
url = URI.parse(anchor["href"])
if url.host.nil? || url.host.not_nil!.ends_with?("youtube.com") || url.host.not_nil!.ends_with?("youtu.be")
if url.host.try &.ends_with? "youtu.be"
url = "/watch?v=#{url.path.lstrip('/')}#{url.query_params}"
else
if url.path == "/redirect"
params = HTTP::Params.parse(url.query.not_nil!)
anchor["href"] = params["q"]?
else
anchor["href"] = url.request_target
end
end
elsif url.to_s == "#"
begin
length_seconds = decode_length_seconds(anchor.content)
rescue ex
length_seconds = decode_time(anchor.content)
end
if length_seconds > 0
anchor["href"] = "javascript:void(0)"
anchor["onclick"] = "player.currentTime(#{length_seconds})"
else
anchor["href"] = url.request_target
end
end
end
html = html.xpath_node(%q(//body)).not_nil!
if node = html.xpath_node(%q(./p))
html = node
end
return html.to_xml(options: XML::SaveOptions::NO_DECL)
end
def fill_links(html, scheme, host)
# Check if the document is empty
# Prevents edge-case bug with Reddit comments, see issue #3115
if html.nil? || html.empty?
return html
end
html = XML.parse_html(html)
html.xpath_nodes("//a").each do |match|
url = URI.parse(match["href"])
# Reddit links don't have host
if !url.host && !match["href"].starts_with?("javascript") && !url.to_s.ends_with? "#"
url.scheme = scheme
url.host = host
match["href"] = url
end
end
if host == "www.youtube.com"
html = html.xpath_node(%q(//body/p)).not_nil!
end
return html.to_xml(options: XML::SaveOptions::NO_DECL)
end
def text_to_parsed_content(text : String) : JSON::Any def text_to_parsed_content(text : String) : JSON::Any
nodes = [] of JSON::Any nodes = [] of JSON::Any
# For each line convert line to array of nodes # For each line convert line to array of nodes

View file

@ -0,0 +1,76 @@
module Invidious::Comments
extend self
def replace_links(html)
# Check if the document is empty
# Prevents edge-case bug with Reddit comments, see issue #3115
if html.nil? || html.empty?
return html
end
html = XML.parse_html(html)
html.xpath_nodes(%q(//a)).each do |anchor|
url = URI.parse(anchor["href"])
if url.host.nil? || url.host.not_nil!.ends_with?("youtube.com") || url.host.not_nil!.ends_with?("youtu.be")
if url.host.try &.ends_with? "youtu.be"
url = "/watch?v=#{url.path.lstrip('/')}#{url.query_params}"
else
if url.path == "/redirect"
params = HTTP::Params.parse(url.query.not_nil!)
anchor["href"] = params["q"]?
else
anchor["href"] = url.request_target
end
end
elsif url.to_s == "#"
begin
length_seconds = decode_length_seconds(anchor.content)
rescue ex
length_seconds = decode_time(anchor.content)
end
if length_seconds > 0
anchor["href"] = "javascript:void(0)"
anchor["onclick"] = "player.currentTime(#{length_seconds})"
else
anchor["href"] = url.request_target
end
end
end
html = html.xpath_node(%q(//body)).not_nil!
if node = html.xpath_node(%q(./p))
html = node
end
return html.to_xml(options: XML::SaveOptions::NO_DECL)
end
def fill_links(html, scheme, host)
# Check if the document is empty
# Prevents edge-case bug with Reddit comments, see issue #3115
if html.nil? || html.empty?
return html
end
html = XML.parse_html(html)
html.xpath_nodes("//a").each do |match|
url = URI.parse(match["href"])
# Reddit links don't have host
if !url.host && !match["href"].starts_with?("javascript") && !url.to_s.ends_with? "#"
url.scheme = scheme
url.host = host
match["href"] = url
end
end
if host == "www.youtube.com"
html = html.xpath_node(%q(//body/p)).not_nil!
end
return html.to_xml(options: XML::SaveOptions::NO_DECL)
end
end

View file

@ -362,8 +362,8 @@ module Invidious::Routes::API::V1::Videos
return reddit_thread.to_json return reddit_thread.to_json
else else
content_html = Frontend::Comments.template_reddit(comments, locale) content_html = Frontend::Comments.template_reddit(comments, locale)
content_html = fill_links(content_html, "https", "www.reddit.com") content_html = Comments.fill_links(content_html, "https", "www.reddit.com")
content_html = replace_links(content_html) content_html = Comments.replace_links(content_html)
response = { response = {
"title" => reddit_thread.title, "title" => reddit_thread.title,
"permalink" => reddit_thread.permalink, "permalink" => reddit_thread.permalink,

View file

@ -101,8 +101,8 @@ module Invidious::Routes::Watch
comments, reddit_thread = Comments.fetch_reddit(id) comments, reddit_thread = Comments.fetch_reddit(id)
comment_html = Frontend::Comments.template_reddit(comments, locale) comment_html = Frontend::Comments.template_reddit(comments, locale)
comment_html = fill_links(comment_html, "https", "www.reddit.com") comment_html = Comments.fill_links(comment_html, "https", "www.reddit.com")
comment_html = replace_links(comment_html) comment_html = Comments.replace_links(comment_html)
end end
end end
elsif source == "reddit" elsif source == "reddit"
@ -110,8 +110,8 @@ module Invidious::Routes::Watch
comments, reddit_thread = Comments.fetch_reddit(id) comments, reddit_thread = Comments.fetch_reddit(id)
comment_html = Frontend::Comments.template_reddit(comments, locale) comment_html = Frontend::Comments.template_reddit(comments, locale)
comment_html = fill_links(comment_html, "https", "www.reddit.com") comment_html = Comments.fill_links(comment_html, "https", "www.reddit.com")
comment_html = replace_links(comment_html) comment_html = Comments.replace_links(comment_html)
rescue ex rescue ex
if preferences.comments[1] == "youtube" if preferences.comments[1] == "youtube"
comment_html = JSON.parse(Comments.fetch_youtube(id, nil, "html", locale, preferences.thin_mode, region))["contentHtml"] comment_html = JSON.parse(Comments.fetch_youtube(id, nil, "html", locale, preferences.thin_mode, region))["contentHtml"]