diff --git a/app/models/billboard.rb b/app/models/billboard.rb index bacbb8444..187f33dd3 100644 --- a/app/models/billboard.rb +++ b/app/models/billboard.rb @@ -220,13 +220,14 @@ class Billboard < ApplicationRecord extracted_process_markdown else # raw self.processed_html = Html::Parser.new(body_markdown) - .prefix_all_images(width: 880, synchronous_detail_detection: true).html + .prefix_all_images(width: 880, quality: 95, synchronous_detail_detection: true).html end end def extracted_process_markdown renderer = ContentRenderer.new(body_markdown || "", source: self) self.processed_html = renderer.process(prefix_images_options: { width: prefix_width, + quality: 95, synchronous_detail_detection: true }).processed_html self.processed_html = processed_html.delete("\n") end diff --git a/app/services/html/parser.rb b/app/services/html/parser.rb index ee353ee80..5257c9e90 100644 --- a/app/services/html/parser.rb +++ b/app/services/html/parser.rb @@ -32,7 +32,7 @@ module Html self end - def prefix_all_images(width: 880, synchronous_detail_detection: false) + def prefix_all_images(width: 880, synchronous_detail_detection: false, quality: "auto") # wrap with Cloudinary or allow if from giphy or githubusercontent.com doc = Nokogiri::HTML.fragment(@html) @@ -51,7 +51,7 @@ module Html img["src"] = if Giphy::Image.valid_url?(src) src.gsub("https://media.", "https://i.") else - img_of_size(src, width) + img_of_size(src, width, quality: quality) end end @@ -258,8 +258,8 @@ module Html private - def img_of_size(source, width = 880) - Images::Optimizer.call(source, width: width).gsub(",", "%2C") + def img_of_size(source, width = 880, quality: "auto") + Images::Optimizer.call(source, width: width, quality: quality).gsub(",", "%2C") end def all_children_are_blank?(node) diff --git a/spec/models/billboard_spec.rb b/spec/models/billboard_spec.rb index 4855f164a..4be71535d 100644 --- a/spec/models/billboard_spec.rb +++ b/spec/models/billboard_spec.rb @@ -196,7 +196,7 @@ RSpec.describe Billboard do options = { http_header: { "User-Agent" => "DEV(local) (http://forem.test)" }, timeout: 10 } expect(FastImage).to have_received(:size).with(image_url, options) # width is billboard.prefix_width - expect(Images::Optimizer).to have_received(:call).with(image_url, width: Billboard::POST_WIDTH) + expect(Images::Optimizer).to have_received(:call).with(image_url, width: Billboard::POST_WIDTH, quality: 95) # Images::Optimizer.call(source, width: width) end @@ -206,7 +206,7 @@ RSpec.describe Billboard do allow(Images::Optimizer).to receive(:call).and_return(image_url) image_md = "
Hello hey Hey hey
" create(:billboard, body_markdown: image_md, placement_area: "post_sidebar") - expect(Images::Optimizer).to have_received(:call).with(image_url, width: Billboard::SIDEBAR_WIDTH) + expect(Images::Optimizer).to have_received(:call).with(image_url, width: Billboard::SIDEBAR_WIDTH, quality: 95) end it "uses post width for feed location" do @@ -215,7 +215,7 @@ RSpec.describe Billboard do allow(Images::Optimizer).to receive(:call).and_return(image_url) image_md = "Hello hey Hey hey
" create(:billboard, body_markdown: image_md, placement_area: "feed_second") - expect(Images::Optimizer).to have_received(:call).with(image_url, width: Billboard::POST_WIDTH) + expect(Images::Optimizer).to have_received(:call).with(image_url, width: Billboard::POST_WIDTH, quality: 95) end it "keeps the same processed_html if markdown was not changed" do diff --git a/spec/services/images/optimizer_spec.rb b/spec/services/images/optimizer_spec.rb index cebe071b9..6b043917a 100644 --- a/spec/services/images/optimizer_spec.rb +++ b/spec/services/images/optimizer_spec.rb @@ -73,6 +73,17 @@ RSpec.describe Images::Optimizer, type: :service do expect(described_class.call(image_url, fetch_format: "jpg")).to eq(cloudinary_url) end + it "generates adjusted URL when quality is passed" do + cloudinary_url = cl_image_path(image_url, + type: "fetch", + quality: 81, + crop: "limit", + sign_url: true, + flags: "progressive", + fetch_format: "jpg") + expect(described_class.call(image_url, fetch_format: "jpg", quality: 81)).to eq(cloudinary_url) + end + it "generates correct crop with 'crop' passed" do cloudinary_url = cl_image_path(image_url, type: "fetch", @@ -137,30 +148,30 @@ RSpec.describe Images::Optimizer, type: :service do end it "generates correct url with crop default" do - imgproxy_url = described_class.imgproxy(image_url, width: 500, height: 500) + imgproxy_url = described_class.imgproxy(image_url, width: 50, height: 50) # mb = maximum bytes, defaults to 500_000 bytes # ar = autorotate, defaults to "true", serialized as "1" - expect(imgproxy_url).to match(%r{/rs:fit:500:500/g:sm/mb:500000/ar:1/aHR0cHM6Ly9pLmlt/Z3VyLmNvbS9mS1lL/Z280LnBuZw}) + expect(imgproxy_url).to match(%r{/rs:fit:50:50/g:sm/mb:500000/ar:1/aHR0cHM6Ly9pLmlt/Z3VyLmNvbS9mS1lL/Z280LnBuZw}) end it "generates correct crop with 'crop' passed" do - imgproxy_url = described_class.imgproxy(image_url, width: 500, height: 500, crop: "crop") - expect(imgproxy_url).to match(%r{/rs:fill:500:500/g:sm/mb:500000/ar:1/aHR0cHM6Ly9pLmlt/Z3VyLmNvbS9mS1lL/Z280LnBuZw}) + imgproxy_url = described_class.imgproxy(image_url, width: 50, height: 50, crop: "crop") + expect(imgproxy_url).to match(%r{/rs:fill:50:50/g:sm/mb:500000/ar:1/aHR0cHM6Ly9pLmlt/Z3VyLmNvbS9mS1lL/Z280LnBuZw}) end it "generates correct crop with 'crop' passed, and never_imagga" do - imgproxy_url = described_class.imgproxy(image_url, width: 500, height: 500, crop: "crop", never_imagga: true) - expect(imgproxy_url).to match(%r{/rs:fill:500:500/g:sm/mb:500000/ar:1/aHR0cHM6Ly9pLmlt/Z3VyLmNvbS9mS1lL/Z280LnBuZw}) + imgproxy_url = described_class.imgproxy(image_url, width: 50, height: 50, crop: "crop", never_imagga: true) + expect(imgproxy_url).to match(%r{/rs:fill:50:50/g:sm/mb:500000/ar:1/aHR0cHM6Ly9pLmlt/Z3VyLmNvbS9mS1lL/Z280LnBuZw}) end it "generates correct crop with 'limit' passed" do - imgproxy_url = described_class.imgproxy(image_url, width: 500, height: 500, crop: "limit") - expect(imgproxy_url).to match(%r{/rs:fit:500:500/g:sm/mb:500000/ar:1/aHR0cHM6Ly9pLmlt/Z3VyLmNvbS9mS1lL/Z280LnBuZw}) + imgproxy_url = described_class.imgproxy(image_url, width: 50, height: 50, crop: "limit") + expect(imgproxy_url).to match(%r{/rs:fit:50:50/g:sm/mb:500000/ar:1/aHR0cHM6Ly9pLmlt/Z3VyLmNvbS9mS1lL/Z280LnBuZw}) end it "generates correct crop with 'jiberish' passed" do - imgproxy_url = described_class.imgproxy(image_url, width: 500, height: 500, crop: "jiberish") - expect(imgproxy_url).to match(%r{/rs:fit:500:500/g:sm/mb:500000/ar:1/aHR0cHM6Ly9pLmlt/Z3VyLmNvbS9mS1lL/Z280LnBuZw}) + imgproxy_url = described_class.imgproxy(image_url, width: 50, height: 50, crop: "jiberish") + expect(imgproxy_url).to match(%r{/rs:fit:50:50/g:sm/mb:500000/ar:1/aHR0cHM6Ly9pLmlt/Z3VyLmNvbS9mS1lL/Z280LnBuZw}) end end