discourse/db/migrate/20131014203951_backfill_post_upload_reverse_index.rb
Sam Saffron 30990006a9 DEV: enable frozen string literal on all files
This reduces chances of errors where consumers of strings mutate inputs
and reduces memory usage of the app.

Test suite passes now, but there may be some stuff left, so we will run
a few sites on a branch prior to merging
2019-05-13 09:31:32 +08:00

77 lines
2.0 KiB
Ruby

# frozen_string_literal: true
class BackfillPostUploadReverseIndex < ActiveRecord::Migration[4.2]
def up
# clean the reverse index
execute "TRUNCATE TABLE post_uploads"
# fill the reverse index up
Post.select([:id, :cooked]).find_each do |post|
doc = Nokogiri::HTML::fragment(post.cooked)
# images
doc.search("img").each { |img| add_to_reverse_index(img['src'], post.id) }
# thumbnails and/or attachments
doc.search("a").each { |a| add_to_reverse_index(a['href'], post.id) }
end
end
def add_to_reverse_index(url, post_id)
# make sure we have a url to insert
return unless url.present?
# local uploads are relative
if index = url.index(local_base_url)
url = url[index..-1]
end
# filter out non-uploads
return unless is_local?(url) || is_on_s3?(url)
# update the reverse index
execute "INSERT INTO post_uploads (upload_id, post_id)
SELECT u.id, #{post_id}
FROM uploads u
WHERE u.url = '#{url}'
AND NOT EXISTS (SELECT 1 FROM post_uploads WHERE upload_id = u.id AND post_id = #{post_id})"
end
def local_base_url
@local_base_url ||= "/uploads/#{RailsMultisite::ConnectionManagement.current_db}"
end
def local_optimized_base_url
@local_optimized_base_url ||= "#{local_base_url}/_optimized"
end
def local_avatar_base_url
@local_avatar_base_url ||= "#{local_base_url}/avatars"
end
def s3_base_url
@s3_base_url ||= "//#{SiteSetting.s3_upload_bucket.downcase}.s3.amazonaws.com"
end
def s3_avatar_base_url
@s3_avatar_base_url ||= "#{s3_base_url}/avatars"
end
def is_local?(url)
url.starts_with?(local_base_url) && !is_local_thumbnail?(url) && !is_local_avatar?(url)
end
def is_local_thumbnail?(url)
url.starts_with?(local_optimized_base_url)
end
def is_local_avatar?(url)
url.starts_with?(local_avatar_base_url)
end
def is_on_s3?(url)
url.starts_with?(s3_base_url) && !is_s3_avatar?(url)
end
def is_s3_avatar?(url)
url.starts_with?(s3_avatar_base_url)
end
end