Recreate versions using Carrierwave with Ruby - ruby-on-rails-3

The website I am working on is going through a redesign and as such, our user images need to be re-sized. The website is currently using carrierwave gem to handle all image and video processing, and each image has a original file with a unique file name based on the following:
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
and secure_token be generated by
def secure_token
var = :"##{mounted_as}_secure_token"
model.instance_variable_get(var) or model.instance_variable_set(var, SecureRandom.uuid)
end
The task that is created to do this is:
##
# 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
The problem is that while it creates the new images, the files are saved under a new file name rather than following the naming laid out in the image uploader, so the website cannot find them. The following is an example of how the images are stored.
How it should be:
Original file:
fdk392ks93_39ei.png
thumbnail version:
thumb_fdk392ks93_39ei.png
How it is:
Original file:
fdk392ks93_39ei.png
thumbnail version:
thumb_fajeilkadifej_jakdjfi.png
Any help would be very appreciated.
Other info:
Model: User
Uploader: user_image (this is also the column name which stores the folder/file name)

After calling recreate_versions! you have to call save! on the model. You can check out this question where someone asked basically the same thing.

The README clearly states how to recreate Carrierwave versions:
https://github.com/jnicklas/carrierwave/blob/master/README.md
"You might come to a situation where you want to retroactively change a version or add a new one. You can use the recreate_versions! method to recreate the versions from the base file. This uses a naive approach which will re-upload and process the specified version or all versions, if none is passed as an argument.
instance = MyUploader.new
instance.recreate_versions!(:thumb, :large)
Or on a mounted uploader:
User.all.each do |user|
user.avatar.recreate_versions!
end

Related

Unexpected require in my config/application.rb

I have an issue with the following line in the config/application.rb file of my generated spec/dummy rails application:
# railtie requires ...
Bundler.require(*Rails.groups)
require "tm_app_core" # This line should not exists according to rails application.rb template
module Dummy
class Application < Rails::Application
# ...
I am using Rails::Generators::AppGenerator to generate my dummy app. But according to Rails application.rb template it should not have the following line:
require "tm_app_core"
Where does this line comes from?
I'm using Rails 3.2.13. tm_app_core is the name of my root directory (will be different on my CI server for example).

Lighttpd - the fastcgi-backend /ffp/bin/php-cgi failed to start

I've been trying to make my lighttpd work for almost two weeks now, but without any luck.
I have a Zyxcel 310 with FFP 0.7 running on a stick. I have transmission working on it just fine (witch includes the "curl" install) but Lighttpd will not work.
This is the error I keep getting. (If I disable fastcgi I just get 503 forbidden).
2013-07-02 21:12:22: (log.c.166) server started
2013-07-02 21:12:22: (mod_fastcgi.c.1103) the fastcgi-backend /ffp/bin/php-cgi failed to start:
2013-07-02 21:12:22: (mod_fastcgi.c.1107) child exited with status 16 /ffp/bin/php-cgi
2013-07-02 21:12:22: (mod_fastcgi.c.1110) If you're trying to run your app as a FastCGI backend, make sure you're using the FastCGI-enabled version.
If this is PHP on Gentoo, add 'fastcgi' to the USE flags.
2013-07-02 21:12:22: (mod_fastcgi.c.1397) [ERROR]: spawning fcgi failed.
2013-07-02 21:12:22: (server.c.945) Configuration of plugins failed. Going down.
I have searched al over and nobody really seems to know what is up. Some fixed the issue but there fix didn't help me.
This is what some one suggested but I also get an error here:
root#nsa310:~# php -i
php: can't load library 'libxml2.so.2'
I bought a new website last week after months of building/testing it on localhost. It is far from done yet but I tought buying it would atleast be a start. The website would be www.volunteeringnews.com "sadly still empty now".
So if someone might have an idea or an error log where I might find some more information I would be very thankfull. Anyway, here are my conf settings. (Part of it, the beginning).
# lighttpd configuration file
#
# use it as a base for lighttpd 1.0.0 and above
#
# $Id: lighttpd.conf,v 1.7 2004/11/03 22:26:05 weigon Exp $
############ Options you really have to take care of ####################
## modules to load
# at least mod_access and mod_accesslog should be loaded
# all other module should only be loaded if really neccesary
# - saves some time
# - saves memory
server.modules = (
# "mod_rewrite",
"mod_redirect",
"mod_alias",
"mod_access",
# "mod_cml",
# "mod_trigger_b4_dl",
# "mod_auth",
# "mod_status",
# "mod_setenv",
"mod_fastcgi",
# "mod_proxy",
# "mod_simple_vhost",
# "mod_evhost",
# "mod_userdir",
"mod_cgi",
"mod_compress",
# "mod_ssi",
# "mod_usertrack",
# "mod_expire",
# "mod_secdownload",
# "mod_rrdtool",
"mod_accesslog" )
server.modules += ( "mod_fastcgi" )
## a static document-root, for virtual-hosting take look at the
## server.virtual-* options
server.document-root = "/mnt/HD_a2/public/website/www/"
server.upload-dirs = ( "/mnt/HD_a2/tmp" )
## where to send error-messages to
server.errorlog = "/mnt/HD_a2/public/website/logs/error.log"
# files to check for if .../ is requested
index-file.names = ( "index.php", "index.html",
"index.htm", "default.htm" )
## php support
## uncomment the following lines and the mod_fastcgi module above
fastcgi.server = ( ".php" => ((
"bin-path" => "/ffp/bin/php-cgi",
"socket" => "/tmp/php-cgi.socket",
"max-procs" => 2
)))
I fixed this by installing FFP 0.7 on my NAS direcly. :)

rubyZip Gem: Want to zip remote files in RoR

I want to download photos from my website after zipping. I am using rubyZip gem but unable to zip remote files. Following is the scenario:
I am trying to zip content from server. Content is something like this
http://myApplication.s3.amazonaws.com/xxxxxxxx/image/image1.jpeg,
So in "zipfile.add( attachment.document_file_name, attachment.document.url)", i assigned following values:
document_file_name = image1.jpeg/image2.jpeg/image3.jpeg
document.url = http://myApplication.s3.amazonaws.com/xxxxxxxx/image
Now here I am getting following error:
No such file or directory - myApplication.s3.amazonaws.com/xxxxxxxx/image
This gem is working fine if I zipped files from local file system (e.g: /home/user/images) but not for remote files.
Is I am doing something wrong? Can someone help me out? Or any other gem which can do this?
Thanks,
-Tahniyat
What you can do is read it first from s3 write it directly to the archive file (put archive file to your temporary directory), serve it then delete the temp archive file. Here's a little snippet:
require 'zip/zip'
s3 = Aws::S3.new(S3_KEY, S3_SECRET)
bucket_gen = Aws::S3Generator::Bucket.create(s3, S3_BUCKET)
archive_file = "#{Rails.root}/tmp/archive.zip"
Zip::ZipOutputStream.open(archive_file) do |zos|
list_of_files_to_loop.each do |file|
filename = file.filename
url = "#{S3_PATH}/#{filename}"
signed_url = bucket_gen.get(URI.unescape(URI.parse(URI.escape(url)).path[1..-1]), 1.minute)
zos.put_next_entry(filename) # Give it next file a filename
zos.print(URI.parse(signed_url).read) # Add file to zip
end
end # Write zip file
# TODO: Serve file
# TODO: Delete archived file from tmp directory
Reference:
http://rubyzip.sourceforge.net/classes/Zip/ZipOutputStream.html

rails3 with compass-rails

I'm trying to set up a rails 3.2 app with the new compass-rails gem
https://github.com/Compass/compass-rails
I want to compile the files in the assets folder with the compass watch command—as I want to deploy to heroku, but so far i'm unsuccessful.
The compass-rails gem page states:
Developing with the Compass watcher
When using the Compass watcher to update your stylesheets, your stylesheets are recompiled as soon as you save your Sass files. In this mode, compiled stylesheets will be written to your project's public folder and therefore will be served directly by your project's web server -- superceding the normal rails compilation.
In this mode, rails 3.0 or earlier users will experience a slight speed up by disabling the Sass::Plugin like so:
config.after_initialize do
Sass::Plugin.options[:never_update] = true
end
But i don't get where to put this config options
Any idea?
==EDIT==
I tried to add the config.after_initialize block in my application.rb
require File.expand_path('../boot', __FILE__)
# require 'rails/all'
require "action_controller/railtie"
require "action_mailer/railtie"
require "active_resource/railtie"
# require "sprockets/railtie"
if defined?(Bundler)
# If you precompile assets before deploying to production, use this line
Bundler.require(*Rails.groups(:assets => %w(development test)))
# If you want your assets lazily compiled in production, use this line
# Bundler.require(:default, :assets, Rails.env)
end
module Salsacaribecouk
class Application < Rails::Application
# Configure the default encoding used in templates for Ruby 1.9.
config.encoding = "utf-8"
# Configure sensitive parameters which will be filtered from the log file.
config.filter_parameters += [:password]
# Enable the asset pipeline
config.assets.enabled = true
# Version of your assets, change this if you want to expire all your assets
config.assets.version = '1.0'
config.after_initialize do
Sass::Plugin.options[:never_update] = true
end
end
end
but when i run the rails server I get an error message:
block in <class:Application>': uninitialized constant Sass::Plugin (NameError)
The config.after_initialize should be put in config\application.rb if you want it to be executed in all environments, or in config\environments\[development|test|production].rb to executed in a specific environment.

Ruby (Rack) Application Could Not be Started... again

Not sure where to start to look. Ive looked at the files mentioned in the backtrace but not seeing any problems with them. Maybe another set of eyes can see something I dont. Heres the backtrace:
The application has exited during startup (i.e. during the evaluation of config/environment.rb). The error message may have been written to the web servers log file. Please check the web servers log file (i.e. not the (Rails) applications log file) to find out why the application exited.
If that doesnt help, then please use the backtrace below to debug the problem.
Application root:
/home/marc_m3pt0/m3pt0.com
Backtrace:
# File Line Location
0 /usr/lib/ruby/gems/1.8/gems/bundler-1.0.7/lib/bundler/setup.rb 10 in exit
1 /usr/lib/ruby/gems/1.8/gems/bundler-1.0.7/lib/bundler/setup.rb 10
2 /usr/lib/ruby/1.8/rubygems/custom_require.rb 36 in gem_original_require
3 /usr/lib/ruby/1.8/rubygems/custom_require.rb 36 in require
4 /home/marc_m3pt0/m3pt0.com/config/boot.rb 6
5 /usr/lib/ruby/1.8/rubygems/custom_require.rb 31 in gem_original_require
6 /usr/lib/ruby/1.8/rubygems/custom_require.rb 31 in require
7 /home/marc_m3pt0/m3pt0.com/config/application.rb 1
8 /usr/lib/ruby/1.8/rubygems/custom_require.rb 31 in gem_original_require
9 /usr/lib/ruby/1.8/rubygems/custom_require.rb 31 in require
10 /home/marc_m3pt0/m3pt0.com/config/environment.rb 2
11 /usr/lib/ruby/1.8/rubygems/custom_require.rb 31 in gem_original_require
12 /usr/lib/ruby/1.8/rubygems/custom_require.rb 31 in require
13 config.ru 3
14 /usr/lib/ruby/gems/1.8/gems/rack-1.2.1/lib/rack/builder.rb 46 in instance_eval
15 /usr/lib/ruby/gems/1.8/gems/rack-1.2.1/lib/rack/builder.rb 46 in initialize
16 config.ru 1 in new
17 config.ru 1
environment.rb
# Load the rails application
require File.expand_path('../application', __FILE__)
# Initialize the rails application
M3p0::Application.initialize!
config.ru
# This file is used by Rack-based servers to start the application.
require ::File.expand_path('../config/environment', __FILE__)
run M3p0::Application
boot.rb
require 'rubygems'
# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
application.rb
require File.expand_path('../boot', __FILE__)
require 'rails/all'
if defined?(Bundler)
# If you precompile assets before deploying to production, use this line
Bundler.require *Rails.groups(:assets => %w(development test))
# If you want your assets lazily compiled in production, use this line
# Bundler.require(:default, :assets, Rails.env)
end
module M3p0
class Application < Rails::Application
config.autoload_paths << "#{config.root}/lib" # Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
# Custom directories with classes and modules you want to be autoloadable.
# config.autoload_paths += %W(#{config.root}/extras)
# Only load the plugins named here, in the order given (default is alphabetical).
# :all can be used as a placeholder for all plugins not explicitly named.
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]
# Activate observers that should always be running.
# config.active_record.observers = :cacher, :garbage_collector, :forum_observer
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
# config.time_zone = 'Central Time (US & Canada)'
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
# config.i18n.default_locale = :de
# Configure the default encoding used in templates for Ruby 1.9.
config.encoding = "utf-8"
# Configure sensitive parameters which will be filtered from the log file.
config.filter_parameters += [:password]
# Enable the asset pipeline
config.assets.enabled = true
# Version of your assets, change this if you want to expire all your assets
config.assets.version = '1.0'
end
end
The error message tells you to look in the web server error log file. Did you look in there? What is in the file?