27 votes

Enregistrement de fichiers à l'aide d'un Trombone, sans les télécharger

J'avais une petite question. Est-il possible d'enregistrer un fichier sans le télécharger via un formulaire?

Par exemple, disons que je suis à la recherche des pièces jointes de mails, et je veux les enregistrer à l'aide de trombones. Comment dois-je faire? Puis-je manuellement appeler un save_file(ou quelque chose de similaire) quelque part?

Toute aide serait grandement appréciée!

43voto

kikito Points 23229

J'ai une tâche rake qui charge les images (client logos) à partir d'un répertoire directement sur parperclip. Vous pouvez probablement s'adapter à vos besoins.

C'est mon simplifiée modèle Client:

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

Puis sur ma tâche rake 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

Ce qui concerne les!

9voto

Nate Points 9879

Sauvegarder le fichier dans le Trombone n'a pas à être téléchargés directement par le biais d'un formulaire.

Je suis à l'aide d'un Trombone dans un projet d'enregistrer des fichiers à partir d'Url de webcrawler résultats. Je ne suis pas sûr de savoir comment vous obtenez des pièces jointes (sont-ils sur le système de fichiers local du serveur? Votre application est une application de messagerie comme GMail?) mais aussi longtemps que vous pouvez obtenir un fichier de flux (par l'intermédiaire de quelque chose comme open(URI.parse(crawl_result)) dans mon cas...), vous pouvez joindre le fichier à votre modèle de champ qui est marqué has_attached_file.

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

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

Cet exemple montre une Photo du modèle qui a une Image en pièce jointe.

La technique que nous utilisons nécessite l'ajout d'une *_remote_url (string) de la colonne de votre attachement, qui est utilisé pour stocker l'URL d'origine. Donc, dans ce cas, nous avons besoin d'ajouter une colonne" image_remote_url les photos de la table.

# 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 la forme, nous avons ajouter un text_field appelés :image_url, afin que les gens peuvent 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 devons require open-uri, ajouter un attr_accessor :image_url, et ne la normale has_attached_file trucs. Ensuite, nous ajoutons une before_validation de rappel pour télécharger le fichier dans l' image_url d'attribut (si fourni) et enregistrer l'URL d'origine en tant que image_remote_url. Enfin, nous faisons 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 de la partie la plus dure dans le modèle, "téléchargement" un fichier via l'URL travaille de l'intérieur 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">

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X