Extract pasted base64 images from RTE texts [SCI-5098]

This commit is contained in:
Martin Artnik 2023-01-12 13:24:31 +01:00
parent 99b1bd5b68
commit 662b9174fa
3 changed files with 46 additions and 2 deletions

View file

@ -10,6 +10,7 @@ module TinyMceImages
dependent: :destroy
before_save :clean_tiny_mce_image_urls
before_save :extract_base64_images
def prepare_for_report(field, base64_encoded_imgs = false)
description = self[field]
@ -162,5 +163,42 @@ module TinyMceImages
end
self[object_field] = parsed_description.to_html if image_changed
end
def extract_base64_images
# extracts and uploads any base64 encoded images,
# so they get stored as files instead of directly in the text
object_field = Extends::RICH_TEXT_FIELD_MAPPINGS[self.class.name]
text = public_send(object_field)
return unless text
ActiveRecord::Base.transaction do
text.scan(/src="(data:image\/[^;]+;base64[^"]+)"/i).flatten.each do |base64_src|
base64_data = base64_src.split('base64,').last
tiny_image = TinyMceAsset.create!(
team: @team,
object: self,
saved: true
)
tiny_image.image.attach(
io: StringIO.new(Base64.decode64(base64_data)),
filename: SecureRandom.hex(32)
)
encoded_id = Base62.encode(tiny_image.id)
text.gsub!(
"#{base64_src}\"",
"\" data-mce-token=\"#{encoded_id}\" alt=\"description-#{encoded_id}\""
)
end
assign_attributes(object_field => text)
end
end
end
end

View file

@ -1,7 +1,6 @@
class Step < ApplicationRecord
include SearchableModel
include SearchableByNameModel
include TinyMceImages
include ViewableModel
attr_accessor :skip_position_adjust # to be used in bulk deletion

View file

@ -21,7 +21,14 @@ class TinyMceAsset < ApplicationRecord
validates :estimated_size, presence: true
def self.update_images(object, images, current_user)
images = JSON.parse(images)
# image ids that are present in text
text_images =
object.public_send(Extends::RICH_TEXT_FIELD_MAPPINGS[self.class.name])
.scan(/data-mce-token="([^"]+)"/)
.flatten
images = JSON.parse(images) + text_images
current_images = object.tiny_mce_assets.pluck(:id)
images_to_delete = current_images.reject do |x|
(images.include? Base62.encode(x))