2011-06-23 4 views
2

J'ai ~ 16.000 images que je suis en train de télécharger sur Amazon. En ce moment, ils sont sur mon système de fichiers local. Je voudrais les télécharger sur S3 en utilisant Paperclip, mais je ne veux pas les télécharger sur mon serveur en premier. J'utilise Heroku et ils limitent la taille des limaces.Uploading des milliers d'images avec Paperclip à S3

Existe-t-il un moyen d'utiliser une tâche rake pour télécharger les images directement depuis mon système de fichiers local vers S3 via Paperclip?

Répondre

3

Vous pouvez configurer votre application pour utiliser Amazon S3 pour le stockage paperclip dans le développement (see my example) et télécharger les fichiers à l'aide d'une tâche de râteau comme ceci:

de Disons que votre dossier d'images était your_app_folder/public/images, vous pouvez créer un Rake Tâche similaire à ceci.

namespace :images do 
    desc "Upload images." 
    task :create => :environment do 
    @images = Dir["#{RAILS_ROOT}/public/images/*.*"] 
    for image in @images 
     MyModel.create(:image => File.open(image)) 
    end 
    end 
end 
+0

Droite. C'est exactement ce que j'ai fait, mais cela prend beaucoup de temps (> 1 seconde par image). J'ai aussi le problème que paperclip utilise l'id de l'image dans le nom de fichier. Donc, même si j'exécute la tâche de rake que vous avez mentionnée, les identifiants de production ne correspondront pas aux identifiants en développement. – Chris

+0

Dans ce cas, vous pouvez simplement utiliser un téléchargeur de fichiers pour télécharger les fichiers vers quelque chose comme dropbox (ou même un s3 s3 temporaire) et ensuite exécuter cette tâche rake depuis votre application heroku (passer dans des liens distants) pour les déplacer vers votre seau/associez-les à votre modèle. – David

+0

Merci Johnny. Nous avons essayé celui-là aussi et avons eu du mal à accéder aux fichiers via FTP avec heroku. A terminé le téléchargement sur paperclip localement, puis afficher toutes les URL de l'image dans un fichier texte. Ensuite, nous mettons le fichier texte en production et lisons dans toutes les URL de l'image. Hack haful, mais ça a marché. Merci pour vos suggestions. – Chris

0

Bonne réponse Johnny Grass et bonne question Chris. J'avais quelques centaines de fichiers tif sur ma machine locale, Heroku, trombone, et s3. Certains des fichiers tiff étaient> 100 Mo, ce qui obligeait l'heroku à faire attention à ce long travail de retard et à du travail supplémentaire. Comme il s'agissait d'un processus par lots en une seule fois (5 formes d'images différentes créées à partir de 5 x mises en ligne), l'idée d'une tâche râteau correspond parfaitement. Ici, au cas où cela serait utile, est la tâche de rake que j'ai créée en supposant que Johnny a écrit que votre base de données de développement a des données actuelles (utilisez la sauvegarde pg pour obtenir un nouvel ensemble d'identifiants) et est connectée à S3.

J'ai un modèle appelé "Item" avec une pièce jointe "image". Je voulais vérifier si les éléments existants avaient déjà une image, et sinon, en télécharger un nouveau. L'effet est de mettre en miroir un répertoire de fichiers source. Les bonnes extensions pourraient être de vérifier les dates et voir si le tif local si mis à jour.

# lib/image_management.rake 
namespace :images do 
    desc 'upload images through paperclip with postprocessing' 
    task :create => :environment do 

    directory = "/Volumes/data/historicus/_projects/deeplandscapes/library/tifs/*.tif" 
    images = Dir[directory] 

    puts "\n\nProcessing #{ images.length } images in #{directory}..." 

    items_with_errors = [] 
    items_updated = [] 
    items_skipped = [] 

    images.each do |image| 
    # find the needed record 
     image_basename = File.basename(image) 
     id = image_basename.gsub("it_", "").gsub(".tif", "").to_i 
     if id > 0 
     item = Item.find(id) rescue nil 
     # check if it has an image already 
     if item 
      unless item.image.exists? 
      # create the image 
      success = item.update_attributes(:image => File.open(image)) 
      if success 
       items_updated << item 
       print ' u ' 
      else 
       items_with_errors << item 
       print ' e ' 
      end 
      else 
      items_skipped << item 
      print ' s ' 
      end 
     else 
      print "[#{id}] " 
     end 
     else 
     print " [no id for #{image_basename}] "  
     end 
    end 
    unless items_with_errors.empty? 
     puts "\n\nThe following items had errors: " 
     items_with_errors.each do |error_image| 
     puts "#{error_image.id}: #{error_image.errors.full_messages}" 
     end 
    end 

    puts "\n\nUpdated #{items_updated.length} items." 
    puts "Skipped #{items_skipped.length} items." 
    puts "Update complete.\n" 

    end 
end 
Questions connexes