Recréer les versions à l'aide de Carrierwave avec Ruby
Le site que je suis en train de travailler sur passe par une refonte et en tant que tel, notre utilisateur les images doivent être de taille moyenne. Le site est actuellement à l'aide de carrierwave gem pour gérer toutes les images et le traitement de la vidéo, et chaque image a un fichier d'origine avec un nom de fichier unique basé sur les éléments suivants:
def filename
if original_filename
if model && model.read_attribute(:user_image).present?
model.read_attribute(:user_image)
else
@name ||= "#{secure_token}.#{file.extension}" if original_filename.present?
end
end
end
et secure_token être générés par
def secure_token
var = :"@#{mounted_as}_secure_token"
model.instance_variable_get(var) or model.instance_variable_set(var, SecureRandom.uuid)
end
La tâche qui est créé pour ce faire est:
##
# CarrierWave Amazon S3 File Reprocessor Rake Task
#
# Written (specifically) for:
# - CarrierWave
# - Ruby on Rails 3
# - Amazon S3
#
# Works with:
# - Any server of which you have write-permissions in the Rails.root/tmp directory
# - Works with Heroku
#
# Not tested with, but might work with:
# - Ruby on Rails 2
#
# Might work with, after a couple of tweaks:
# - File System Storage
# - Cloud Files Storage
# - GridFS
#
# Examples:
#
# Reprocess all versions of User#avatar
# rake carrierwave:reprocess class=User mounted_uploader=avatar
#
# Reprocess the versions: thumb, small, medium for User#avatar
# rake carrierwave:reprocess class=User mounted_uploader=avatar versions='thumb, small, medium'
#
# Reprocess for an underlying association, for things like Embedded MongoDB Documents
# which are models you cannot access directly, but rather through a regular Document
#
# Embeds One (picture) Association
# rake carrierwave:reprocess class=User association=picture mounted_uploader=image versions='thumb, small, medium'
#
# Embeds Many (pictures) Association
# rake carrierwave:reprocess class=User association=pictures mounted_uploader=image versions='thumb, small, medium'
#
# WARNING
# There is an issue with "Rake", that you cannot name your mounted_uploader "file".
# If you do this, then you will not be able to reprocess images through this rake task
# class User
# include Mongoid::Document
# mount_uploader :file, PictureUploader
# end
#
# This will NOT work with reprocessing through Rake because the mounted_uploader uses the "file" attribute.
namespace :carrierwave do
##
# Only tested with Amazon S3 Storage
# Needs some minor modifications if you want to use this for File System Store, Cloud Files and GridFS probably.
# This should work without Ruby on Rails as well, just set a different TMP_PATH.
desc "Reprocesses Carrier Wave file versions of a given model."
task :reprocess => :environment do
##
# Load in the OPEN URI library to be able
# to pull down and store the original file in a temp directory
require 'open-uri'
##
# Default constants
TMP_PATH = "#{Rails.root}/tmp/carrierwave"
##
# Set environment constants
CLASS = ENV['class'].capitalize
ASSOCIATION = ENV['association'] || nil
MOUNTED_UPLOADER = ENV['mounted_uploader'].to_sym
VERSIONS = ENV['versions'].nil? ? Array.new : ENV['versions'].split(',').map {|version| version.strip.to_sym}
##
# Find the Model
MODEL = Kernel.const_get(CLASS)
##
# Create the temp directory
%x(mkdir -p "#{TMP_PATH}")
##
# Find all records for the provided Model
records = MODEL.all
##
# Output to console
puts "\nCarrier Wave Version Reprocessing!"
puts "======================================="
puts "Model: #{CLASS}"
puts "Mounted Uploader: #{MOUNTED_UPLOADER}"
puts "Association: #{ASSOCIATION}" if ASSOCIATION
puts "Versions: #{VERSIONS.empty? ? "all" : VERSIONS.join(', ')}\n\n"
##
# Run through all records
records.each do |record|
##
# Set the mounted uploader object
# If it has a one-to-one association (singular) then that object
# will be returned and wrapped in an array so we can "iterate" through it below.
#
# If it has a one-to-many association then it will return the array of associated objects
#
# If no association is specified, it assumes the amounted uploader is attached to the specified CLASS
if ASSOCIATION
if ASSOCIATION.singular?
objects = [record.send(ASSOCIATION)]
else
objects = record.send(ASSOCIATION)
end
else
objects = [record]
end
##
# Iterates through the objects
objects.each do |object|
##
# Returns the mounted uploader object
mounted_object = object.send(MOUNTED_UPLOADER)
##
# Retrieve Filename
filename = mounted_object.path.split('/').last
##
# Output to console
puts "Reprocessing: #{filename}"
##
# Read out the original file from the remote location
# and write it out to the temp directory (TMP_PATH)
# This file will be used as the base file to reprocess
# the versions. Once all versions have been processed,
# this temp file will be directly removed.
open(mounted_object.url) do |original_object|
File.open(File.join(TMP_PATH, filename), 'w') do |temp_file|
temp_file.write(original_object.read)
end
end
##
# By default it will add all available versions to the versions variable
# which means that all available versions will be reprocessed.
# If the "versions" argument has been provided, then only the specified
# version(s) will be set to the versions variable, and thus, only these
# will be reprocessed.
versions = mounted_object.versions.map {|version| version[0]}
versions = VERSIONS unless VERSIONS.empty?
##
# Reprocesses the versions
versions.each do |version|
mounted_object.send(version).cache!(File.open(File.join(TMP_PATH, filename)))
mounted_object.send(version).store!
end
##
# Removes the temp file
%x(rm "#{TMP_PATH}/#{filename}")
end
end
end
end
Le problème c'est que s'il crée de nouvelles images, les fichiers sont enregistrés sous un nouveau nom de fichier, plutôt que de suivre le nommage définies dans l'image uploader, donc le site ne peut pas les trouver. Ce qui suit est un exemple de la façon dont les images sont stockées.
La façon dont il devrait être:
Fichier d'origine:
fdk392ks93_39ei.png
version miniature:
thumb_fdk392ks93_39ei.png
Comment il est:
Fichier d'origine:
fdk392ks93_39ei.png
version miniature:
thumb_fajeilkadifej_jakdjfi.png
Toute aide serait très appréciée.
Autres infos:
Modèle: Utilisateur
Uploader: user_image (c'est aussi le nom de la colonne qui contient le dossier/nom de fichier)
OriginalL'auteur CorreyS | 2013-02-15
Vous devez vous connecter pour publier un commentaire.
Après l'appel de
recreate_versions!
vous devez appelersave!
sur le modèle. Vous pouvez consulter cette question où quelqu'un a demandé fondamentalement la même chose.OriginalL'auteur stravid
Le fichier README indique clairement comment recréer Carrierwave versions:
https://github.com/jnicklas/carrierwave/blob/master/README.md
"Vous pourriez venir à une situation où vous souhaitez modifier rétroactivement une version ou en ajouter une nouvelle. Vous pouvez utiliser le recreate_versions! la méthode de recréer les versions du fichier de base. Il utilise une approche naïve, qui sera re-télécharger et processus de la version spécifiée ou toutes les versions, si aucun n'est passé comme argument.
Ou sur une montée uploader:
avez-vous jamais trouver une solution à cela?
Mon problème est que j'ai eu l'image originale dans une ancienne base de données, après j'ai cloné base de données ancienne à la plus récente du code source, j'ai besoin de régénérer version miniature de l'image pour ceux qui ont seulement de l'image d'origine qui ont été téléchargés par carrierwave de stockage amazon s3. L' .recreate_versions! succès pour m'aider à générer des vignettes de la version de l'image qui déclarent en uploader de fichier. merci.
OriginalL'auteur sevenseacat