Shrine: update image at S3

Created on 18 Mar 2021  路  1Comment  路  Source: shrinerb/shrine

Hi all, please help me
I have Shrine uploader with AWS store

How can I replace the old file with the new one from process(:edit) -> versions?

https://prnt.sc/10p5y4x

class Photo < ActiveRecord::Base
  include PhotoUploader::Attachment.new(:file)
end

class PhotosController
  ...
  def rotate
    @photo   = Photo.find(params[:id])
    uploader = @photo.file_attacher.store
    processing_params = {angle: 90}
    uploader.process(@photo.file[:original], action: :edit, params: processing_params)
    ...
  end
  ...
end


require 'image_processing/mini_magick'
class PhotoUploader < Shrine
  include ImageProcessing::MiniMagick
  include UploaderHepers

  ALLOWED_TYPES = %w[image/jpeg image/png image/gif].freeze
  MAX_SIZE      = (25 * 1024 * 1024)

  plugin :upload_endpoint, max_size: MAX_SIZE
  plugin :add_metadata

  plugin :processing
  plugin :delete_promoted
  plugin :versions

  plugin :determine_mime_type
  plugin :store_dimensions, analyzer: :mini_magick
  plugin :validation_helpers, default_messages: {
     ...  
   }

  plugin :remove_attachment
  plugin :pretty_location

  Attacher.validate do
    validate_max_size MAX_SIZE
    if validate_mime_type_inclusion(ALLOWED_TYPES)
      validate_max_width 6000
      validate_max_height 6000
    end
  end


  process(:store) do |io, context|
    versions = { original: io }
    record   = context[:record]

    io.download do |original|
      pipeline = ImageProcessing::MiniMagick.source(original)

      versions[:big] = pipeline.resize_to_fit!(960, 600)
      versions[:thumb]  = pipeline.resize_to_fit!(300, 167)
      versions[:search] = pipeline.resize_to_fit!(nil, 60)
    end

    file_data = JSON.parse(record.file_data)
    record.update(...)

    versions
  end

  process(:edit) do |io, context|
    versions = {}
    angle = context[:params][:angle]
    io.download do |original|
      pipeline = ImageProcessing::MiniMagick.source(original)
      versions[:original] = pipeline.rotate(angle).call
      versions[:big] = pipeline.rotate(angle).resize_to_fit!(960, 600)
      versions[:thumb]  = pipeline.rotate(angle).resize_to_fit!(300, 167)
      versions[:search] = pipeline.rotate(angle).resize_to_fit!(nil, 60)
    end

    versions
    #=> {:original=>#<File:/tmp/image_processing20210319-14199-l3umje.jpeg>,
    #       :big=>#<File:/tmp/image_processing20210319-14199-9qzoac.jpeg>,
    #       :thumb=>#<File:/tmp/image_processing20210319-14199-349oni.jpeg>,
    #       :search=>#<File:/tmp/image_processing20210319-14199-1xicv39.jpeg>}

  end

  def generate_location(io, context)
    ...
  end

  private
  ...
end

shrine - 2.19.3
image_processing - 1.9.3

Most helpful comment

You probably don't want to do this with a process block, but with custom code that lives outside of the uploader. Something like this should work:

new_versions = {}

photo.image[:original].download do |original|
  pipeline = ImageProcessor::MiniMagick
    .source(original)
    .rotate(params[:angle])

  new_versions[:original] = photo.image[:original].replace(pipeline.call)
  new_versions[:big] = photo.image[:big].replace(pipeline.resize_to_fit!(960, 600))
  new_versions[:thumb] = photo.image[:thumb].replace(pipeline.resize_to_fit!(300, 167)
  new_versions[:search = photo.image[:search].replace(pipeline.resize_to_fit!(nil, 60)
end

photo.update!(image_data: new_versions.to_json)

Note that usage questions should be asked on the Discourse forum, GitHub issues should only be used for bug reports.

>All comments

You probably don't want to do this with a process block, but with custom code that lives outside of the uploader. Something like this should work:

new_versions = {}

photo.image[:original].download do |original|
  pipeline = ImageProcessor::MiniMagick
    .source(original)
    .rotate(params[:angle])

  new_versions[:original] = photo.image[:original].replace(pipeline.call)
  new_versions[:big] = photo.image[:big].replace(pipeline.resize_to_fit!(960, 600))
  new_versions[:thumb] = photo.image[:thumb].replace(pipeline.resize_to_fit!(300, 167)
  new_versions[:search = photo.image[:search].replace(pipeline.resize_to_fit!(nil, 60)
end

photo.update!(image_data: new_versions.to_json)

Note that usage questions should be asked on the Discourse forum, GitHub issues should only be used for bug reports.

Was this page helpful?
0 / 5 - 0 ratings