Enregistrer des fichiers en utilisant Paperclip sans télécharger

j'ai eu une question rapide. Est-il possible d'enregistrer un fichier sans le télécharger via un formulaire?

par exemple, disons que je regarde les pièces jointes des e-mails, et je veux les sauver en utilisant un trombone. Comment dois-je faire? Dois-je appeler manuellement un fichier save_file(ou quelque chose de similaire) quelque part?

Toute aide serait grandement appréciée!

31
demandé sur Mayur Shah 2009-11-03 14:29:48

2 réponses

j'ai une tâche de ratissage qui charge des images (logos clients) d'un répertoire directement sur parperclip. Vous pouvez probablement s'adapter à vos besoins.

class Client < ActiveRecord::Base
  LOGO_STYLES = {
    :original => ['1024x768>', :jpg],
    :medium   => ['256x192#', :jpg],
    :small    => ['128x96#', :jpg]
  }

  has_attached_file :logo,
    :styles => Client::LOGO_STYLES,
    :url => "/clients/logo/:id.jpg?style=:style"
  attr_protected :logo_file_name, :logo_content_type, :logo_size

alors sur ma tâche de râteau je fais ceci:

# the logos are in a folder with path logos_dir
Dir.glob(File.join(logos_dir,'*')).each do |logo_path|
  if File.basename(logo_path)[0]!= '.' and !File.directory? logo_path

    client_code = File.basename(logo_path, '.*') #filename without extension
    client = Client.find_by_code(client_code) #you could use the ids, too
    raise "could not find client for client_code #{client_code}" if client.nil?

    File.open(logo_path) do |f|
      client.logo = f # just assign the logo attribute to a file
      client.save
    end #file gets closed automatically here
  end
end

Cordialement!

47
répondu kikito 2012-04-02 17:46:05

le fichier sauvegardé dans Paperclip n'a pas à être téléchargé directement via un formulaire.

J'utilise Paperclip dans un projet pour sauvegarder des fichiers à partir des URLs des résultats webcrawler. Je ne suis pas sûr comment vous obtiendriez des pièces jointes de courrier électronique (sont-elles sur le système de fichiers local du serveur? Votre application est-elle une application de messagerie comme GMail?) mais aussi longtemps que vous pouvez obtenir un flux de fichiers (via quelque chose comme open(URI.parse(crawl_result)) dans mon cas...) vous pouvez joindre ce fichier à votre champ model qui est marqué has_attached_file.

Ce billet de blog sur Téléchargement Facile via l'URL avec un Trombone m'a aidé à comprendre cela.

Puisqu'il apparaît maintenant le blog original n'est plus disponible - voici l'essentiel, c'tiré de la wayback machine:

cet exemple montre un modèle de Photo qui a une pièce jointe D'Image.

la technique que nous utilisons nécessite l'ajout d'un *_remote_url (string) colonne pour votre pièce jointe, qui est utilisée pour stocker le URL original. Donc, dans ce cas, nous devons ajouter une colonne nommée image_remote_url la table photos.

# db/migrate/20081210200032_add_image_remote_url_to_photos.rb

class AddImageRemoteUrlToPhotos < ActiveRecord::Migration
  def self.up
    add_column :photos, :image_remote_url, :string
  end

  def self.down
    remove_column :photos, :image_remote_url
  end
end

Rien de spécial n'est nécessaire pour le contrôleur...

# app/controllers/photos_controller.rb

class PhotosController < ApplicationController

  def create
    @photo = Photo.new(params[:photo])
    if @photo.save
      redirect_to photos_path
    else
      render :action => 'new'
    end
  end

end

Dans le formulaire, nous ajoutons un text_field appelé :image_url, pour que les gens puissent télécharger un fichier ou fournir une URL...

# app/views/photos/new.html.erb

<%= error_messages_for :photo %>
<% form_for :photo, :html => { :multipart => true } do |f| %>
  Upload a photo: <%= f.file_field :image %><br>
  ...or provide a URL: <%= f.text_field :image_url %><br>
  <%= f.submit 'Submit' %>
<% end %>

La viande des choses est dans la Photo de modèle. Nous avons besoin de require open-uri, ajouter un attr_accessor :image_url, et ne la normale has_attached_file trucs. Ensuite, nous ajoutons un before_validation rappel de télécharger le fichier dans le image_url attribut (si fourni) et enregistrer L'URL originale comme image_remote_url. Enfin, nous faisons un validates_presence_of :image_remote_url, ce qui nous permet de sauver de nombreuses exceptions qui peuvent être levées lorsque vous essayez de télécharger le fichier.

# app/models/photo.rb

require 'open-uri'

class Photo < ActiveRecord::Base

  attr_accessor :image_url

  has_attached_file :image # etc...

  before_validation :download_remote_image, :if => :image_url_provided?

  validates_presence_of :image_remote_url, :if => :image_url_provided?, :message => 'is invalid or inaccessible'

private

  def image_url_provided?
    !self.image_url.blank?
  end

  def download_remote_image
    self.image = do_download_remote_image
    self.image_remote_url = image_url
  end

  def do_download_remote_image
    io = open(URI.parse(image_url))
    def io.original_filename; base_uri.path.split('/').last; end
    io.original_filename.blank? ? nil : io
  rescue # catch url errors with validations instead of exceptions (Errno::ENOENT, OpenURI::HTTPError, etc...)
  end

end

Tout fonctionne normalement, y compris la création de vignettes, etc. De plus, puisque nous faisons tous les trucs durs dans le model, "uploader" un fichier via L'URL fonctionne aussi bien depuis script/console:

$ script/console
Loading development environment (Rails 2.2.2)
>> Photo.new(:image_url => 'http://www.google.com/intl/en_ALL/images/logo.gif')
=> #<Photo image_file_name: "logo.gif", image_remote_url: "http://www.google.com/intl/en_ALL/images/logo.gif">
11
répondu Nate 2013-12-17 15:36:28