Skip to content

Commit

Permalink
Fix seeding custom logo from URL
Browse files Browse the repository at this point in the history
  • Loading branch information
oliverguenther committed Jan 23, 2025
1 parent 696d92d commit d529b3f
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 24 deletions.
72 changes: 50 additions & 22 deletions app/seeders/env_data/custom_design_seeder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
module EnvData
class CustomDesignSeeder < Seeder
def seed_data!
custom_style = CustomStyle.current || CustomStyle.new
custom_style = CustomStyle.current || CustomStyle.create!

print_status " ↳ Setting custom design colors" do
seed_colors
Expand All @@ -56,7 +56,7 @@ def seed_logos(custom_style)
if data.blank?
custom_style.public_send(:"remove_#{key}")
elsif data.match?(/^https?:\/\//)
custom_style.public_send(:"remote_#{key}_url=", data)
seed_remote_url(custom_style, key, data)
else
io = Base64StringIO.new(data, key.to_s)
custom_style.public_send(:"#{key}=", io)
Expand All @@ -83,36 +83,64 @@ def seed_export_color(custom_style)
value = Setting.seed_design["export_cover_text_color"]
custom_style.export_cover_text_color = value.presence
end
end

class Base64StringIO < StringIO
attr_reader :filename

def initialize(data_url, base_name)
metadata, encoded = data_url.split(",")
def seed_remote_url(custom_style, key, url)
response = HTTPX.get(url)
raise "Failed to set #{key} from #{url}: #{response}" unless response.status == 200

if metadata.blank? || encoded.blank? || !metadata.start_with?("data:")
raise ArgumentError, "Expected data URL, got #{data_url}"
build_attachable_file(key.to_s, response.body.to_s) do |file|
custom_style.public_send(:"#{key}=", file)
custom_style.save!
end
end

@filename = "#{base_name}.#{extension(metadata)}"
bytes = ::Base64.strict_decode64(encoded)
def build_attachable_file(file_name, data)
Tempfile.open(file_name) do |tempfile|
tempfile.binmode
tempfile.write(data)
tempfile.rewind

super(bytes)
end
content_type = OpenProject::ContentTypeDetector.new(tempfile.path).detect
mime_type = MIME::Types[content_type].last
raise ArgumentError, "Unknown mime type: #{content_type}" if mime_type.nil?

def original_filename
filename
file = OpenProject::Files.build_uploaded_file(tempfile,
content_type,
file_name: "#{file_name}.#{mime_type.preferred_extension}")

yield(file)
end
end

def extension(metadata)
content_type = metadata.match(%r{data:([^;]+)})&.captures&.first
raise ArgumentError, "Failed to parse content type from metadata: #{metadata}" if content_type.nil?
class Base64StringIO < StringIO
attr_reader :filename

def initialize(data_url, base_name)
metadata, encoded = data_url.split(",")

if metadata.blank? || encoded.blank? || !metadata.start_with?("data:")
raise ArgumentError, "Expected data URL, got #{data_url}"
end

@filename = "#{base_name}.#{extension(metadata)}"
bytes = ::Base64.strict_decode64(encoded)

super(bytes)
end

mime_type = MIME::Types[content_type].last
raise ArgumentError, "Unknown mime type: #{content_type}" if mime_type.nil?
def original_filename
filename
end

def extension(metadata)
content_type = metadata.match(%r{data:([^;]+)})&.captures&.first
raise ArgumentError, "Failed to parse content type from metadata: #{metadata}" if content_type.nil?

mime_type.preferred_extension
mime_type = MIME::Types[content_type].last
raise ArgumentError, "Unknown mime type: #{content_type}" if mime_type.nil?

mime_type.preferred_extension
end
end
end
end
56 changes: 56 additions & 0 deletions spec/fixtures/files/icon_logo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
38 changes: 36 additions & 2 deletions spec/seeders/env_data/custom_design_seeder_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,26 @@
let(:base64_data_url) do
"data:image/png;base64,#{base64_image}"
end
let(:stub) do
let(:png_stub) do
stub_request(:get, "http://test.foobar.com/image.png")
.to_return(
status: 200,
body: Rails.root.join("spec/fixtures/files/image.png").read
)
end
let(:svg_stub) do
stub_request(:get, "http://test.foobar.com/image.svg")
.to_return(
status: 200,
body: Rails.root.join("spec/fixtures/files/icon_logo.svg").read
)
end

subject(:seeder) { described_class.new(seed_data) }

before do
stub
png_stub
svg_stub
end

context "when not provided" do
Expand Down Expand Up @@ -87,6 +95,31 @@
expect(DesignColor.find_by(variable: "main-menu-bg-color").hexcode).to eq("#FFFFFF")
expect(DesignColor.find_by(variable: "main-menu-bg-selected-background").hexcode).to eq("#571EFA")
expect(DesignColor.find_by(variable: "main-menu-bg-hover-background").hexcode).to eq("#E5E5E5")

RequestStore.clear!
custom_style = CustomStyle.current
expect(custom_style.logo.file).to be_present
expect(custom_style.logo.file.content_type).to eq "image/png"

expect(custom_style.touch_icon.file).to be_present
expect(custom_style.touch_icon.file.content_type).to eq "image/png"
end
end

context "when setting logo as svg",
:settings_reset,
with_env: {
OPENPROJECT_SEED_DESIGN_LOGO: "http://test.foobar.com/image.svg"
} do
it "sets the content type" do
reset(:seed_design)

seeder.seed!

custom_style = CustomStyle.current

expect(custom_style.logo.file).to be_present
expect(custom_style.logo.file.content_type).to eq "image/svg+xml"
end
end

Expand All @@ -108,6 +141,7 @@

expect(custom_style.favicon.file).to be_nil
expect(custom_style.logo.file).to be_present
expect(custom_style.logo.file.content_type).to eq "image/png"
end
end

Expand Down

0 comments on commit d529b3f

Please sign in to comment.