FIX: Pull hotlinked images for lightbox links as well.

This commit is contained in:
Guo Xiang Tan 2019-05-23 15:43:25 +08:00
parent 1059aafc55
commit df1e6eed5a
3 changed files with 76 additions and 9 deletions

View File

@ -56,8 +56,8 @@ module Jobs
has_new_broken_image = false
has_downloaded_image = false
extract_images_from(post.cooked).each do |image|
src = original_src = image['src']
extract_images_from(post.cooked).each do |node|
src = original_src = node['src'] || node['href']
src = "#{SiteSetting.force_https ? "https" : "http"}:#{src}" if src.start_with?("//")
if should_download_image?(src)
@ -91,9 +91,20 @@ module Jobs
if downloaded_urls[src].present?
url = downloaded_urls[src]
escaped_src = Regexp.escape(original_src)
# there are 6 ways to insert an image in a post
# HTML tag - <img src="http://...">
raw.gsub!(/src=["']#{escaped_src}["']/i, "src='#{url}'")
if (original_path = Upload.extract_url(original_src)&.to_s) &&
(path = Upload.extract_url(url)&.to_s)
raw.gsub!(
/src=["']\S*#{Regexp.escape(original_path)}["']/i,
"src='#{url}'"
)
end
# BBCode tag - [img]http://...[/img]
raw.gsub!(/\[img\]#{escaped_src}\[\/img\]/i, "[img]#{url}[/img]")
# Markdown linked image - [![alt](http://...)](http://...)
@ -136,7 +147,7 @@ module Jobs
def extract_images_from(html)
doc = Nokogiri::HTML::fragment(html)
doc.css("img[src]") - doc.css("img.avatar") - doc.css(".lightbox img[src]")
doc.css("img[src], a.lightbox[href]") - doc.css("img.avatar") - doc.css(".lightbox img[src]")
end
def should_download_image?(src)

View File

@ -6,6 +6,9 @@ Fabricator(:optimized_image) do
extension ".png"
width 100
height 200
url "138569_100x200.png"
version OptimizedImage::VERSION
after_build do |optimized_image, _|
optimized_image.url = Discourse.store.get_path_for_optimized_image(optimized_image)
end
end

View File

@ -68,6 +68,25 @@ describe Jobs::PullHotlinkedImages do
expect(post.raw).to match(/^<img src='\/uploads/)
end
it 'replaces optimized images' do
optimized_image = Fabricate(:optimized_image)
url = "#{Discourse.base_url}#{optimized_image.url}"
stub_request(:get, url)
.to_return(status: 200, body: file_from_fixtures("smallest.png"))
post = Fabricate(:post, raw: "<img src='#{url}'>")
expect { Jobs::PullHotlinkedImages.new.execute(post_id: post.id) }
.to change { Upload.count }.by(1)
upload = Upload.last
post.reload
expect(post.raw).to eq("<img src='#{upload.url}'>")
expect(post.uploads).to contain_exactly(upload)
end
describe 'onebox' do
let(:media) { "File:Brisbane_May_2013201.jpg" }
let(:url) { "https://commons.wikimedia.org/wiki/#{media}" }
@ -172,18 +191,52 @@ describe Jobs::PullHotlinkedImages do
describe "with a lightboxed image" do
fab!(:upload) { Fabricate(:upload) }
fab!(:user) { Fabricate(:user) }
before do
FastImage.expects(:size).returns([1750, 2000])
FastImage.expects(:size).returns([1750, 2000]).at_least_once
OptimizedImage.stubs(:resize).returns(true)
Jobs.run_immediately!
end
it 'replaces missing local uploads in lightbox link' do
post = PostCreator.create!(
user,
raw: "<img src='#{Discourse.base_url}#{upload.url}'>",
title: "Some title that is long enough"
)
expect(post.reload.cooked).to have_tag(:a, with: { class: "lightbox" })
stub_request(:get, "#{Discourse.base_url}#{upload.url}")
.to_return(status: 200, body: file_from_fixtures("smallest.png"))
upload.delete
expect { Jobs::PullHotlinkedImages.new.execute(post_id: post.id) }
.to change { Upload.count }.by(1)
post.reload
expect(post.raw).to eq("<img src='#{Upload.last.url}'>")
expect(post.uploads.count).to eq(1)
end
it "doesn't remove optimized images from lightboxes" do
post = Fabricate(:post, raw: "![alt](#{upload.short_url})")
Jobs::ProcessPost.new.execute(post_id: post.id)
post = PostCreator.create!(
user,
raw: "![alt](#{upload.short_url})",
title: "Some title that is long enough"
)
expect { Jobs::PullHotlinkedImages.new.execute(post_id: post.id) }.not_to change { Upload.count }
expect(post.reload.cooked).to include "/uploads/default/optimized/" # Ensure the lightbox was actually rendered
expect(post.reload.cooked).to have_tag(:a, with: { class: "lightbox" })
expect { Jobs::PullHotlinkedImages.new.execute(post_id: post.id) }
.not_to change { Upload.count }
post.reload
expect(post.raw).to eq("![alt](#{upload.short_url})")
end
end