Pregunta

Anteriormente: ejecutar un método de modelo en un accesorio de clips después de crear o actualizar (las devoluciones de llamada de PaperClip no parecen funcionar)

Editar (más tarde ese día)Resolví mi problema. El procesador aparentemente funciona con el archivo que se actualiza, pero no guarda ningún archivo hasta después del procesamiento. Cambié mi zip :: zipfile para abrir 'archivo' en lugar de 'adjunto. Esto solucionó el primer problema. Ahora tengo otros problemas que necesitaré para rastrear. Pero la respuesta a continuación es principalmente correcta.

Editar (1/31/2011):

Así que he tomado el consejo para crear un procesador para mi archivo adjunto que realizará todas las acciones necesarias. Hasta ahora, parece que debería funcionar; El procesador comienza y hace todas las cosas de inicialización, aparentemente. Sin embargo, cuando obtengo el punto en el que quiero acceder al archivo zip que se carga, recibo un error que dice que el archivo no se puede encontrar. El código para mi procesador está a continuación:

class Extractor < Processor
    attr_accessor :resolution, :whiny
    def initialize(file, options = {}, attachment = nil)
      super
      @file = file
      @whiny = options[:whiny].nil? ? true : options[:whiny]
      @basename = File.basename(@file.path, File.extname(@file.path))
      @attachment = attachment
      @instance = attachment.instance
    end
    def make
      # do your conversions here, you've got @file, @attachment and @basename to work with
      export_path = attachment.path.gsub('.zip', '_content')

      Zip::ZipFile.open(attachment.path) { |zip_file|
        zip_file.each { |image|
          image_path = File.join(export_path, image.name)
          FileUtils.mkdir_p(File.dirname(image_path))
          unless File.exist?(image_path)
            zip_file.extract(image, image_path)
            # ..stuff that it does..
          end
        }
      }
      # clean up source files, but leave the zip
      FileUtils.remove_dir(export_path)


      # you return a file handle which is the processed result
      dst = File.open result_file_path
    end
end

Y aquí está el contenido del error que recibo:

Zip::ZipError in GalleriesController#create

File /home/joshua/railscamp/moments_on_three/public/assets/archives/delrosario.zip not found

Rails.root: /home/joshua/railscamp/moments_on_three
Application Trace | Framework Trace | Full Trace

config/initializers/extractor.rb:16:in `make'
app/controllers/galleries_controller.rb:32:in `new'
app/controllers/galleries_controller.rb:32:in `create'

Request

Parameters:

{"utf8"=>"✓",
 "authenticity_token"=>"0s4L4MrlqjDTMjzjgkUdvUxeHklZNOIShDhT6fgOICY=",
 "gallery"=>{"name"=>"DelRosario",
 "public"=>"0",
 "owner_id"=>"1",
 "shoot_date(1i)"=>"2011",
 "shoot_date(2i)"=>"1",
 "shoot_date(3i)"=>"31",
 "category_id"=>"1",
 "archive"=>#<ActionDispatch::Http::UploadedFile:0x00000004148d78 @original_filename="delrosario.zip",
 @content_type="application/zip",
 @headers="Content-Disposition: form-data; name=\"gallery[archive]\"; filename=\"delrosario.zip\"\r\nContent-Type: application/zip\r\n",
 @tempfile=#<File:/tmp/RackMultipart20110131-9745-14u347v>>},
 "commit"=>"Create Gallery"}

Por lo que puedo decir que está buscando el archivo en el lugar correcto, pero el archivo aún no parece estar cargado para acceder a él. Hasta donde sé, PaperClip es lo suficientemente inteligente como para saber y esperar a que el archivo adjunto la cargue antes de que intente procesarlo. ¿Alguien puede detectar lo que estoy haciendo mal aquí?

Muchas gracias.

Cosas viejas:

Estoy desarrollando una aplicación de galería de fotos usando Rails 3 y PaperClip. El administrador puede crear una galería y cargar un archivo zip que contenga un montón de imágenes.

Lo que quiero pasar:

  1. Ingrese la información de la galería y el archivo zip para cargar en el formulario.
  2. Presione el botón 'Crear galería'.
  3. Se carga publicaciones de formulario, guardados de la galería y archivo zip.
  4. Después de cargar el archivo ZIP, ejecute el método: Extract_Photos (por cierto, este código funciona). 4.A. Al final de este método, el archivo ZIP se destruye.
  5. El administrador se redirige a la página de la galería con todas las fotos (donde Gallery ha_ Many Photos).

He tratado de hacer que esto funcione de varias maneras diferentes.

Antes, creé un método de controlador que permitiría al administrador hacer clic en un enlace que ejecutaba el método: Extract_Photos. Esto funcionó en mi computadora, pero por alguna razón el servidor tuvo problemas para enrutar esto en la computadora del cliente. Entonces es un no ir. Además, pensé que era una forma fea de hacerlo.

Recientemente, intenté usar métodos de devolución de llamada. After_save no funcionó porque aparentemente interrumpe la publicación del formulario y el archivo no se carga y el método: Extract_Photos no puede encontrar el archivo.

Revisé los métodos de devolución de llamada en la página de PaperClip GitHub, y habla sobre las devoluciones de llamada:

Antes y después del paso de procesamiento posterior, PaperClip vuelve al modelo con algunas devoluciones de llamada, lo que permite que el modelo cambie o cancele el paso de procesamiento. Las devoluciones de llamada son "antes_post_process" y "After_post_process" (que se llaman antes y después del procesamiento de cada archivo adjunto), y el accesorio "antes de antes de PostaS" y "AfterPost_process". Las devoluciones de llamada están destinadas a ser lo más cercanas a las devoluciones de llamada normales de Activerecord como sea posible, por lo que si devuelve falso (específicamente, devolver nulo no es lo mismo) en un filtro anterior, el paso de procesamiento posterior se detendrá. Devolver falso en un filtro posterior no detendrá nada, pero puede acceder al modelo y al archivo adjunto si es necesario.

He intentado usar antes_post_process y después de_post_process, pero no puede encontrar el archivo para ejecutar el proceso, por lo que el archivo obviamente no se carga cuando se llaman esos métodos (lo que creo que es extraño). Además, cuando intento antes de Post_Process y AfterPost_Process, obtengo un NomethodError.

Entonces, ¿cómo llamo a un método en un archivo adjunto cuando se crea o actualiza, pero después de que se carga el archivo y en el lugar correcto?

ACTUALIZAR

Probé el código a continuación, moviendo mi código del método de extracción al método Make del procesador. He llegado más lejos de lo que lo había hecho antes al tratar de escribir un procesador, pero sigue siendo un no-go. El proceso lanza una excepción tan pronto como intento abrir el archivo cargado para el procesamiento, diciendo que el archivo no existe. El esquema de nombres es correcto y todo, pero todavía Nada se está subiendo antes de que el proceso se active. ¿Alguien tiene alguna idea de por qué está sucediendo esto?

¿Fue útil?

Solución

Puede escribir su propio procesador para lograr esto.

En su modelo, al declarar las cosas de PaperClip, agregue un procesador personalizado

  has_attached_file :my_attachment, {
    :styles => {:original => {:processors => [:my_processor]}}
  }.merge(PAPERCLIP_SETTINGS)

Luego escriba su propio procesador y póngalo configuración/inicializadores:

module Paperclip
  class MyProcessor < Processor
    attr_accessor :resolution, :whiny
    def initialize(file, options = {}, attachment = nil)
      super
      @file = file
      @whiny = options[:whiny].nil? ? true : options[:whiny]
      @basename = File.basename(@file.path, File.extname(@file.path))
      @attachment = attachment
    end
    def make
      # do your conversions here, you've got @file, @attachment and @basename to work with

      # you return a file handle which is the processed result
      dst = File.open result_file_path
    end
  end
end

Estoy usando un procesador personalizado para cosas similares a lo que está haciendo con mucho procesamiento y conversión del archivo en el medio y parece funcionar bien.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top