144 lines
4.0 KiB
Ruby
144 lines
4.0 KiB
Ruby
# typed: false
|
|
module Domain::Fa::PostsHelper
|
|
def post_state_string(post)
|
|
if post.have_file?
|
|
"file"
|
|
elsif post.scanned?
|
|
"scanned"
|
|
else
|
|
post.state
|
|
end
|
|
end
|
|
|
|
def page_str(params)
|
|
if (params[:page] || 1).to_i > 1
|
|
"(page #{params[:page]})"
|
|
else
|
|
nil
|
|
end
|
|
end
|
|
|
|
def scanned_and_file_description(post)
|
|
parts = []
|
|
if post.scanned?
|
|
time_ago =
|
|
(post.scanned_at ? time_ago_in_words(post.scanned_at) : "(unknown)")
|
|
parts << "Scanned #{time_ago} ago"
|
|
else
|
|
parts << "Not scanned"
|
|
end
|
|
if post.file
|
|
parts << "file #{time_ago_in_words(post.file.created_at)} ago"
|
|
else
|
|
parts << "no file"
|
|
end
|
|
parts.join(", ")
|
|
end
|
|
|
|
def fa_post_description_sanitized(html)
|
|
fa_post_id_to_node = {}
|
|
fa_user_url_name_to_node = {}
|
|
|
|
sanitizer =
|
|
Sanitize.new(
|
|
elements: %w[br img b i span strong],
|
|
attributes: {
|
|
"span" => %w[style],
|
|
},
|
|
css: {
|
|
properties: %w[font-size color],
|
|
},
|
|
transformers: [
|
|
lambda do |env|
|
|
# Only allow and transform FA links
|
|
if env[:node_name] == "a"
|
|
node = env[:node]
|
|
|
|
# by default, assume the host is www.furaffinity.net
|
|
href = node["href"]&.downcase || ""
|
|
href = "//" + href if href.match?(/^(www\.)?furaffinity\.net/)
|
|
uri = URI.parse(href)
|
|
uri.host ||= "www.furaffinity.net"
|
|
path = uri.path
|
|
|
|
fa_host_matcher = /^(www\.)?furaffinity\.net$/
|
|
fa_post_matcher = %r{^/view/(\d+)/?$}
|
|
fa_user_matcher = %r{^/user/(\w+)/?$}
|
|
|
|
if fa_host_matcher.match?(uri.host) && path
|
|
if path.match?(fa_post_matcher)
|
|
fa_id = path.match(fa_post_matcher)[1].to_i
|
|
fa_post_id_to_node[fa_id] = node
|
|
next { node_whitelist: [node] }
|
|
elsif path.match?(fa_user_matcher)
|
|
fa_url_name = path.match(fa_user_matcher)[1]
|
|
fa_user_url_name_to_node[fa_url_name] = node
|
|
next { node_whitelist: [node] }
|
|
end
|
|
end
|
|
|
|
# Don't allow any other links
|
|
node.replace(node.children)
|
|
end
|
|
end,
|
|
],
|
|
)
|
|
|
|
fragment = Nokogiri::HTML5.fragment(sanitizer.send(:preprocess, html))
|
|
sanitizer.node!(fragment)
|
|
|
|
if fa_post_id_to_node.any?
|
|
# Batch load posts and their titles, ensuring fa_post_ids are strings
|
|
posts_by_id =
|
|
Domain::Fa::Post.where(fa_id: fa_post_id_to_node.keys).index_by(&:fa_id)
|
|
|
|
# Replace the link text with post titles if available
|
|
fa_post_id_to_node.each do |fa_id, node|
|
|
if (post = posts_by_id[fa_id])
|
|
node.replace(
|
|
Nokogiri::HTML5.fragment(
|
|
render(
|
|
partial: "domain/fa/posts/description_inline_link_fa_post",
|
|
locals: {
|
|
post: post,
|
|
},
|
|
),
|
|
),
|
|
)
|
|
else
|
|
node.replace(node.children)
|
|
end
|
|
end
|
|
end
|
|
|
|
if fa_user_url_name_to_node.any?
|
|
# Batch load users and their names, ensuring fa_user_url_names are strings
|
|
users_by_url_name =
|
|
Domain::Fa::User
|
|
.where(url_name: fa_user_url_name_to_node.keys)
|
|
.includes(:avatar)
|
|
.index_by(&:url_name)
|
|
|
|
# Replace the link text with user names if available
|
|
fa_user_url_name_to_node.each do |fa_url_name, node|
|
|
if (user = users_by_url_name[fa_url_name])
|
|
node.replace(
|
|
Nokogiri::HTML5.fragment(
|
|
render(
|
|
partial: "domain/fa/posts/description_inline_link_fa_user",
|
|
locals: {
|
|
user: user,
|
|
},
|
|
),
|
|
),
|
|
)
|
|
else
|
|
node.replace(node.children)
|
|
end
|
|
end
|
|
end
|
|
|
|
raw fragment.to_html(preserve_newline: true)
|
|
end
|
|
end
|