* Fix avatar and header issues by using custom geometry detector Revert a part of #6508. The file passed to dynamic styles method was not actually a file, but an instance of Paperclip::Attachment, which broke all styles by always returning {} from the method. One problem with GIF avatars was that Paperclip::GeometryDetector reported wrong dimensions for them, e.g. 120x120 GIF avatar would for some reason be detected as 120x53. By writing our own geometry parser, we can use FastImage, which also happens to be faster than ImageMagick, to detect image dimensions, which are also correct. Unfortunately, this PR does not implement skipping a `convert` entirely if the dimensions are already correct, as I found no easy way to write that behaviour into Paperclip without rewriting the Paperclip::Thumbnail class. * Only invoke convert if dimension or format needs to be changed
		
			
				
	
	
		
			68 lines
		
	
	
	
		
			2.1 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
			
		
		
	
	
			68 lines
		
	
	
	
		
			2.1 KiB
		
	
	
	
		
			Ruby
		
	
	
	
	
	
| # frozen_string_literal: true
 | |
| # == Schema Information
 | |
| #
 | |
| # Table name: preview_cards
 | |
| #
 | |
| #  id                 :integer          not null, primary key
 | |
| #  url                :string           default(""), not null
 | |
| #  title              :string           default(""), not null
 | |
| #  description        :string           default(""), not null
 | |
| #  image_file_name    :string
 | |
| #  image_content_type :string
 | |
| #  image_file_size    :integer
 | |
| #  image_updated_at   :datetime
 | |
| #  type               :integer          default("link"), not null
 | |
| #  html               :text             default(""), not null
 | |
| #  author_name        :string           default(""), not null
 | |
| #  author_url         :string           default(""), not null
 | |
| #  provider_name      :string           default(""), not null
 | |
| #  provider_url       :string           default(""), not null
 | |
| #  width              :integer          default(0), not null
 | |
| #  height             :integer          default(0), not null
 | |
| #  created_at         :datetime         not null
 | |
| #  updated_at         :datetime         not null
 | |
| #  embed_url          :string           default(""), not null
 | |
| #
 | |
| 
 | |
| class PreviewCard < ApplicationRecord
 | |
|   IMAGE_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif'].freeze
 | |
| 
 | |
|   self.inheritance_column = false
 | |
| 
 | |
|   enum type: [:link, :photo, :video, :rich]
 | |
| 
 | |
|   has_and_belongs_to_many :statuses
 | |
| 
 | |
|   has_attached_file :image, styles: { original: { geometry: '400x400>', file_geometry_parser: FastGeometryParser } }, convert_options: { all: '-quality 80 -strip' }
 | |
| 
 | |
|   include Attachmentable
 | |
|   include Remotable
 | |
| 
 | |
|   validates :url, presence: true, uniqueness: true
 | |
|   validates_attachment_content_type :image, content_type: IMAGE_MIME_TYPES
 | |
|   validates_attachment_size :image, less_than: 1.megabytes
 | |
| 
 | |
|   before_save :extract_dimensions, if: :link?
 | |
| 
 | |
|   def save_with_optional_image!
 | |
|     save!
 | |
|   rescue ActiveRecord::RecordInvalid
 | |
|     self.image = nil
 | |
|     save!
 | |
|   end
 | |
| 
 | |
|   private
 | |
| 
 | |
|   def extract_dimensions
 | |
|     file = image.queued_for_write[:original]
 | |
| 
 | |
|     return if file.nil?
 | |
| 
 | |
|     width, height = FastImage.size(file.path)
 | |
| 
 | |
|     return nil if width.nil?
 | |
| 
 | |
|     self.width  = width
 | |
|     self.height = height
 | |
|   end
 | |
| end
 |