Paperclip error processing the thumbnail - ruby-on-rails-3

I have an error using Paperclip with Jcrop i follow a rails cast to make it.
When i upload an image it work but when i try to crop it, i get this inside my console :
[paperclip] An error was received while processing: #<Paperclip::PaperclipError: There was an error processing the thumbnail for paperclip-reprocess20110822-2281-19969sz>
[paperclip] An error was received while processing: #<Paperclip::PaperclipError: There was an error processing the thumbnail for paperclip-reprocess20110822-2281-19969sz>
There is my model :
class User < ActiveRecord::Base
has_attached_file :avatar, :styles => { :small => ["100x100#", :jpg], :large => ["500x500>",:jpg] }, :processors => [:cropper]
attr_accessor :crop_x, :crop_y, :crop_w, :crop_h
after_update :reprocess_avatar, :if => :cropping?
def cropping?
!crop_x.blank? && !crop_y.blank? && !crop_w.blank? && !crop_h.blank?
end
def avatar_geometry(style = :original)
#geometry ||= {}
#geometry[style] ||= Paperclip::Geometry.from_file(avatar.path(style))
end
private
def reprocess_avatar
avatar.reprocess!
end
end
And my processor :
module Paperclip
class Cropper < Thumbnail
def transformation_command
if crop_command
crop_command + super.first.sub(/ -crop \S+/, '')
else
super
end
end
def crop_command
target = #attachment.instance
if target.cropping?
" -crop #{target.crop_w}x#{target.crop_h}+#{target.crop_x}+#{target.crop_y}"
end
end
end
end
Any idea to solve this ? (I'm on OS 10.7)

Solution find inside the comments of the railscast
In the model
#has_attached_file :avatar, :styles => { :small => ["100x100#", :jpg], :large => ["500x500>",:jpg] }, :processors => [:cropper]
has_attached_file :avatar, :styles => {
:small => {:geometry => "100x100#", :processors => [:cropper]},
:large => {:geometry => "500x500>"}
}
In the processor
#crop_command + super.sub(/ -crop \S+/, '')
crop_command + super.join(' ').sub(/ -crop \S+/, '').split(' ')

Related

Finding the content type of the uploaded file in rails

I am working on ruby on rails. I am trying to do a file attachment (image/audio/video) .
So i have a common method like
byteArray = StringIO.new(File.open("path").read)
Is it possible to find the content type of the byteArray to check whether the uploaded file is a image/audio/video/pdf in ruby.
I saw this was tagged paperclip, so I will give you how we do it with paperclip:
class Attachment < ActiveRecord::Base
has_attached_file :attachment,
styles: lambda { |a| a.instance.is_image? ? {:small => "x200>", :medium => "x300>", :large => "x400>"} : {:thumb => { :geometry => "100x100#", :format => 'jpg', :time => 10}, :medium => { :geometry => "300x300#", :format => 'jpg', :time => 10}}},
:processors => lambda { |a| a.is_video? ? [ :ffmpeg ] : [ :thumbnail ] }
def is_video?
attachment.instance.attachment_content_type =~ %r(video)
end
def is_image?
attachment.instance.attachment_content_type =~ %r(image)
end
end
If you manage to get your file into Paperclip, it basically cuts it up into content_type already. This means that if you use a lambda to determine whether the attachment content_type contains image or video
If you give me some more info on what you're trying to achieve, I can give you some refactored code to help with your issue specifically :)

Image resize issue with PaperClip and Rails 3

Having terrible trouble with my application image rendering since an upgrade to Ruby 1.9.3, Rails 3.1.0.rc4 and Paperclip 3.4.0.
No matter what variation of settings I give Paperclip the infile linked to below comes out blurred as is shown by the linked outfile.
The outfile must fit into a box of 620x412 as shown here.
Link to input file
Link to output file this code generates
The full code for the model is below ...
class Propertyimage < ActiveRecord::Base
belongs_to :property
validates_presence_of :description
validates_presence_of :sortorder
has_attached_file :image, :styles => { :export => {:geometry => "620x412#", :quality => 100, :format => 'JPG'} },
:path => ":rails_root/public/system/:attachment/:id/:style/:filename",
:url => "/system/:attachment/:id/:style/:filename"
end
I had a similar problem and was able to fix after a lot of trial and error using three criteria: image size specification, convert_options, and scaling the image. For example, in your Propertyimage class try:
has_attached_file :image,
:styles => { :original => ["640x480", :jpg], :export => {:geometry => "620x412#", :quality => 100, :format => 'JPG'} },
:convert_options => { :all => "-quality 100" },
:path => ":rails_root/public/system/:attachment/:id/:style/:filename",
:url => "/system/:attachment/:id/:style/:filename"
Then you can play with the sizes of your image tag, or as in my case using a PDF, Id used the scale option:
pdf.image the_file_name, :at => [0, 720], :scale => 0.75

Background Video Processing with Rails

I am trying to get uploaded videos to be converted in the background, running windows. Some of what I am using:
gem 'paperclip'
gem 'delayed_job_active_record'
gem 'ffmpeg'
I have edited the registry to allow the ffmpeg command to be ran from anywhere, I get a popup that I assume is ffmpeg because it goes away too quickly, guess the command is wrong so if anyone knows what's wrong with it please let me know. But the real problem is that it just hangs there, it says:
[2012-12-09 22:47:03] ERROR invalid body size.
[2012-12-09 22:47:03] ERROR Errno::ECONNABORTED: An established connection was a
borted by the software in your host machine.
C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/webrick/httpresponse.rb:396:i
n `write'
C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/webrick/httpresponse.rb:396:i
n `<<'
C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/webrick/httpresponse.rb:396:i
n `_write_data'
C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/webrick/httpresponse.rb:368:i
n `send_body_string'
C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/webrick/httpresponse.rb:249:i
n `send_body'
C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/webrick/httpresponse.rb:152:i
n `send_response'
C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/webrick/httpserver.rb:110:in
`run'
C:/RailsInstaller/Ruby1.9.3/lib/ruby/1.9.1/webrick/server.rb:191:in `blo
ck in start_thread'
Does anyone know how to properly get this working? I've went through a few tutorials that have bits and pieces of what I need but I can't get them working together. Here's what I have so far, lemme know if you need more:
Model:
class Video < ActiveRecord::Base
belongs_to :user
has_many :comments, dependent: :destroy
attr_accessible :video, :user_id, :video_file_name, :title, :public, :description, :views
has_attached_file :video, url: "/users/:user_id/videos/:id/:basename_:style.:extension"
#process_in_background :video #causes death
validates :video, presence: true
validates :description, presence: true, length: { minimum: 5, maximum: 100}
validates :title, presence: true, length: { minimum: 1, maximum: 15 }
validates_attachment_size :video, less_than: 1.gigabytes
validates_attachment :video, presence: true
default_scope order: 'created_at DESC'
Paperclip.interpolates :user_id do |attachment, style|attachment.instance.user_id
end
#before_post_process do |video|
# false if video.status == "converting"
#end
def perform
command = <<-end_command
start ffmpeg -i #{ '/public/users/:user_id/videos/:id/:basename_:style.:extension' } -ar 22050 -ab 32 -s 1280x720 -vcodec webm -r 25 -qscale 8 -f webm -y #{ '/public/users/:user_id/videos/:id/:basename_.webm' }
end_command
success = system(command)
logger.debug 'Converting File: ' + success.to_s
if success && $?.exitstatus.to_i == 0
#self.converted!
self.status = "converted"
else
#self.failure!
self.status = "failed"
end
end
handle_asynchronously :perform
def self.search(search)
if search
find(:all, conditions: ["public = 't' AND title LIKE ?", "%#{search}%"], order: "created_at DESC")
else
find(:all, conditions: ["public = 't'"], order: "created_at DESC")
end
end
def self.admin_search(search)
if search
find(:all, conditions: ['title LIKE ?', "%#{search}%"], order: "created_at DESC")
else
find(:all, order: "created_at DESC")
end
end
private
# This updates the stored filename with the new flash video file
def set_new_filename
#update_attribute(:filename, "#{filename}.#{id}.webm")
update_attribute(:content_type, "video/x-webm")
end
end
Controller:
class VideosController < ApplicationController
before_filter :signed_in_user, only: [:upload, :update, :destroy]
before_filter :admin_user, only: :admin_index
def upload
#video = Video.new
# generate a unique id for the upload
#uuid = (0..29).to_a.map {|x| rand(10)}
end
def create
#video = Video.new(params[:video])
#video.user_id = current_user.id
if #video.save
#video.delay.perform
flash[:success] = "Uploaded Succefully!"
redirect_to #video.user
Delayed::Worker.new.start
else
render 'upload'
end
end
def show
#video = Video.find(params[:id])
#comments = #video.comments.paginate(page: params[:page], per_page: 6)
if !#video.public
if !signed_in? || current_user.id != #video.user_id && !current_user.admin && !current_user.approved?(#video.user)
flash[:notice] = "Video is private"
redirect_to root_path
end
end
end
def update
#video = Video.find(params[:id])
if #video.update_attributes(params[:video])
flash[:success] = "Video preferences saved"
else
flash[:fail] = "Failed to update video preferences"
end
redirect_to :back
end
def destroy
#video = Video.find(params[:id])
#video.destroy
flash[:deleted] = "Deleted Succefully!"
redirect_to :back
end
def index
#videos = Video.paginate(page: params[:page], per_page: 6).search(params[:search])
end
def admin_index
#videos = Video.paginate(page: params[:page], per_page: 6).admin_search(params[:search])
end
def ajax_video_comments
#video = Video.find(params[:id])
#comments = #video.comments.paginate(page: params[:page], per_page: 6)
respond_to do |format|
format.js { render partial: 'shared/comments', content_type: 'text/html' }
end
end
def ajax_video_watched
#video = Video.find(params[:id])
#video.views += 1
#video.save
end
private
def signed_in_user
redirect_to root_path, notice: "Please Login." unless signed_in?
end
def admin_user
redirect_to(root_path) unless current_user.admin?
end
end
Your table should have these columns:
video_file_name
video_content_type
video_file_size
video_updated_at
video_meta
I added some additional paperclip magic to you model, obviously you can tweak the settings for ffmpeg. This is not all original code but I can't remember where I found bits and pieces so if someone recognizes it feel free to take credit.
class Video < ActiveRecord::Base
belongs_to :user
has_many :comments, dependent: :destroy
attr_accessible :video, :user_id, :video_file_name,
:title, :public, :description, :views
has_attached_file :video,
url: "/users/:user_id/videos/:id/:basename_:style.:extension"
styles: {
:original => { :geometry => "1280x720", :format => 'mp4', :streaming => true, :convert_options => { :input => {}, :output => {'c:v' => 'libx264', vprofile: 'high', preset: 'medium', 'b:v' => '1250k', maxrate: '1250k', bufsize: '2500k', pix_fmt: 'yuv420p', flags: '+mv4+aic', threads: 'auto', 'b:a' => '128k', strict: '-2'}} },
:medium => { :geometry => "854x480", :format => 'mp4', :streaming => true, :convert_options => { :input => {}, :output => {'c:v' => 'libx264', vprofile: 'high', preset: 'medium', 'b:v' => '750k', maxrate: '750k', bufsize: '1500k', pix_fmt: 'yuv420p', flags: '+mv4+aic', threads: 'auto', 'b:a' => '128k', strict: '-2'}} },
:small => { :geometry => '640x360', :format => 'mp4', :streaming => true, :convert_options => { :input => {}, :output => {'c:v' => 'libx264', vprofile: 'high', preset: 'medium', 'b:v' => '250k', maxrate: '250k', bufsize: '500k', pix_fmt: 'yuv420p', flags: '+mv4+aic', threads: 'auto', 'b:a' => '128k', strict: '-2'}} },
:thumb => { :geometry => "160x90", :format => 'jpg', :time => 10 }
},
processors: [:ffmpeg, :qtfaststart]
validates :video, presence: true
validates :description, presence: true, length: { minimum: 5, maximum: 100}
validates :title, presence: true, length: { minimum: 1, maximum: 15 }
validates_attachment_size :video, less_than: 1.gigabytes
validates_attachment :video, presence: true
default_scope order: 'created_at DESC'
# cancel post-processing now, and set flag...
before_post_process do |video|
if video.status == nil
video.status = "queuing"
false # halts processing
end
end
# ...and perform after save in background
after_commit do |video|
if video.status == "queuing"
Delayed::Job.enqueue VideoJob.new(video.id), :queue => 'video'
video.status == "queued"
video.save(validations: false)
end
end
# generate styles (downloads original first)
def regenerate_styles!
self.video.reprocess!
end
# detect if our source file has changed
def video_changed?
self.video_file_size_changed? ||
self.video_file_name_changed? ||
self.video_content_type_changed? ||
self.video_updated_at_changed?
end
# Class to perform with delayed jobs
class VideoJob < Struct.new(:video_id)
def perform
video = Video.find(self.video_id)
video.status = "processing"
video.save(validations: false)
video.regenerate_styles!
end
def success(job)
video = Video.find(self.video_id)
video.status = "complete"
video.save(:validate => false)
end
def error(job, exception)
video = Video.find(self.video_id)
video.status = "error"
video.save(:validate => false)
end
end
end
Paperclip Processors (/lib/paperclip_processors/ffmpeg.rb):
module Paperclip
class Ffmpeg < Processor
attr_accessor :geometry, :format, :whiny, :convert_options
# Creates a Video object set to work on the +file+ given. It
# will attempt to transcode the video into one defined by +target_geometry+
# which is a "WxH"-style string. +format+ should be specified.
# Video transcoding will raise no errors unless
# +whiny+ is true (which it is, by default. If +convert_options+ is
# set, the options will be appended to the convert command upon video transcoding.
def initialize file, options = {}, attachment = nil
#convert_options = {
:input => {},
:output => { :y => nil }
}
unless options[:convert_options].nil? || options[:convert_options].class != Hash
unless options[:convert_options][:input].nil? || options[:convert_options][:input].class != Hash
#convert_options[:input].reverse_merge! options[:convert_options][:input]
end
unless options[:convert_options][:output].nil? || options[:convert_options][:output].class != Hash
#convert_options[:output].reverse_merge! options[:convert_options][:output]
end
end
#geometry = options[:geometry]
#file = file
#keep_aspect = !#geometry.nil? && #geometry[-1,1] != '!'
#pad_only = #keep_aspect && #geometry[-1,1] == '#'
#enlarge_only = #keep_aspect && #geometry[-1,1] == '<'
#shrink_only = #keep_aspect && #geometry[-1,1] == '>'
#whiny = options[:whiny].nil? ? true : options[:whiny]
#format = options[:format]
#time = options[:time].nil? ? 3 : options[:time]
#current_format = File.extname(#file.path)
#basename = File.basename(#file.path, #current_format)
#meta = identify
#pad_color = options[:pad_color].nil? ? "black" : options[:pad_color]
attachment.instance_write(:meta, #meta)
end
# Performs the transcoding of the +file+ into a thumbnail/video. Returns the Tempfile
# that contains the new image/video.
def make
src = #file
dst = Tempfile.new([#basename, #format ? ".#{#format}" : ''])
dst.binmode
parameters = []
# Add geometry
if #geometry
# Extract target dimensions
if #geometry =~ /(\d*)x(\d*)/
target_width = $1
target_height = $2
end
# Only calculate target dimensions if we have current dimensions
unless #meta[:size].nil?
current_geometry = #meta[:size].split('x')
# Current width and height
current_width = current_geometry[0]
current_height = current_geometry[1]
if #keep_aspect
if #enlarge_only
if current_width.to_i < target_width.to_i
# Keep aspect ratio
width = target_width.to_i
height = (width.to_f / (#meta[:aspect].to_f)).to_i
#convert_options[:output][:s] = "#{width.to_i/2*2}x#{height.to_i/2*2}"
else
return nil
end
elsif #shrink_only
if current_width.to_i > target_width.to_i
# Keep aspect ratio
width = target_width.to_i
height = (width.to_f / (#meta[:aspect].to_f)).to_i
#convert_options[:output][:s] = "#{width.to_i/2*2}x#{height.to_i/2*2}"
else
return nil
end
elsif #pad_only
# Keep aspect ratio
width = target_width.to_i
height = (width.to_f / (#meta[:aspect].to_f)).to_i
# We should add half the delta as a padding offset Y
pad_y = (target_height.to_f - height.to_f) / 2
if pad_y > 0
#convert_options[:output][:vf] = "scale=#{width}:-1,pad=#{width.to_i}:#{target_height.to_i}:0:#{pad_y}:##pad_color"
else
#convert_options[:output][:vf] = "scale=#{width}:-1,crop=#{width.to_i}:#{height.to_i}"
end
else
# Keep aspect ratio
width = target_width.to_i
height = (width.to_f / (#meta[:aspect].to_f)).to_i
#convert_options[:output][:s] = "#{width.to_i/2*2}x#{height.to_i/2*2}"
end
else
# Do not keep aspect ratio
#convert_options[:output][:s] = "#{target_width.to_i/2*2}x#{target_height.to_i/2*2}"
end
end
end
# Add format
case #format
when 'jpg', 'jpeg', 'png', 'gif' # Images
#convert_options[:input][:ss] = #time
#convert_options[:output][:vframes] = 1
#convert_options[:output][:f] = 'image2'
end
# Add source
parameters << #convert_options[:input].map { |k,v| "-#{k.to_s} #{v} "}
parameters << "-i ':source'"
parameters << #convert_options[:output].map { |k,v| "-#{k.to_s} #{v} "}
parameters << "':dest'"
parameters = parameters.flatten.compact.join(" ").strip.squeeze(" ")
begin
success = Paperclip.run("ffmpeg", parameters, :source => "#{File.expand_path(src.path)}", :dest => File.expand_path(dst.path))
rescue Cocaine::ExitStatusError => e
raise Paperclip::Error, "error while processing video for #{#basename}: #{e}" if #whiny
end
dst
end
def identify
meta = {}
command = "ffmpeg -i \"#{File.expand_path(#file.path)}\" 2>&1"
ffmpeg = IO.popen(command)
ffmpeg.each("\r") do |line|
# Matching lines like:
# Video: h264, yuvj420p, 640x480 [PAR 72:72 DAR 4:3], 10301 kb/s, 30 fps, 30 tbr, 600 tbn, 600 tbc
if line.include?(' Video: ')
start = line.index('Video:')
items = line[start, 150].split(',')
size = items[2].strip!.split(' ').first
meta[:size] = size.to_s
meta[:aspect] = size.split('x').first.to_f / size.split('x').last.to_f
end
# Matching Duration: 00:01:31.66, start: 0.000000, bitrate: 10404 kb/s
if line =~ /Duration:(\s.?(\d*):(\d*):(\d*\.\d*))/
meta[:length] = $2.to_s + ":" + $3.to_s + ":" + $4.to_s
end
end
meta
end
end
class Attachment
def meta
instance_read(:meta)
end
end
end
Paperclip Processors (/lib/paperclip_processors/qtfaststart.rb):
module Paperclip
class Qtfaststart < Processor
attr_accessor :streaming, :format, :whiny
# Creates a Video object set to work on the +file+ given. It
# will attempt to reposition the moov atom in the video given
# if +streaming+ is set.
def initialize file, options = {}, attachment = nil
#streaming = options[:streaming]
#file = file
#whiny = options[:whiny].nil? ? true : options[:whiny]
#format = options[:format]
#current_format = File.extname(#file.path)
#basename = File.basename(#file.path, #current_format)
#meta = attachment.meta
attachment.instance_write(:meta, #meta)
end
# Performs the atom repositioning on +file+.
# Returns the Tempfile that contains the new video or the original
# file if +streaming+ wasn't set.
def make
return #file unless #streaming
src = #file
dst = Tempfile.new([#basename, #format ? ".#{#format}" : ''])
dst.binmode
parameters = []
# Add source
parameters << ":source"
# Add destination
parameters << ":dest"
parameters = parameters.flatten.compact.join(" ").strip.squeeze(" ")
Paperclip.log("[qtfaststart] #{parameters}")
begin
success = Paperclip.run("qt-faststart", parameters, :source => "#{File.expand_path(src.path)}", :dest => File.expand_path(dst.path))
rescue Cocaine::ExitStatusError => e
raise PaperclipError, "error while processing video for #{#basename}: #{e}" if #whiny
end
dst
end
end
class Attachment
def meta
instance_read(:meta)
end
end
end
You controller could use some more cleaning but I just made adjustments to make it work with my other changes.
class VideosController < ApplicationController
before_filter :signed_in_user, only: [:upload, :update, :destroy]
before_filter :admin_user, only: :admin_index
def upload
#video = Video.new
# generate a unique id for the upload
#uuid = (0..29).to_a.map {|x| rand(10)}
end
def create
#video = Video.new(params[:video])
#video.user_id = current_user.id
if #video.save
flash[:success] = "Uploaded Succefully!"
redirect_to #video.user
else
render 'upload'
end
end
def show
#video = Video.find(params[:id])
#comments = #video.comments.paginate(page: params[:page], per_page: 6)
if !#video.public
if !signed_in? || current_user.id != #video.user_id && !current_user.admin && !current_user.approved?(#video.user)
flash[:notice] = "Video is private"
redirect_to root_path
end
end
end
def update
#video = Video.find(params[:id])
if #video.update_attributes(params[:video])
flash[:success] = "Video preferences saved"
else
flash[:fail] = "Failed to update video preferences"
end
redirect_to :back
end
def destroy
#video = Video.find(params[:id])
#video.destroy
flash[:deleted] = "Deleted Succefully!"
redirect_to :back
end
def index
#videos = Video.paginate(page: params[:page], per_page: 6).search(params[:search])
end
def admin_index
#videos = Video.paginate(page: params[:page], per_page: 6).admin_search(params[:search])
end
def ajax_video_comments
#video = Video.find(params[:id])
#comments = #video.comments.paginate(page: params[:page], per_page: 6)
respond_to do |format|
format.js { render partial: 'shared/comments', content_type: 'text/html' }
end
end
def ajax_video_watched
#video = Video.find(params[:id])
#video.views += 1
#video.save
end
private
def signed_in_user
redirect_to root_path, notice: "Please Login." unless signed_in?
end
def admin_user
redirect_to(root_path) unless current_user.admin?
end
end
You can run a delayed_jobs worker thread how ever works best for you. I may have made some mistakes in here but I tried to adapt my method to your current model.
Bit late, but we use the paperclip-ffmeg gem - something you might want to check out
All you need to do is put them gem into your gemfile, and then you just have to define the processor as :ffmpeg.
Here's a live example from our code:
class Attachment < ActiveRecord::Base
has_attached_file :attachment,
styles: lambda { |a| a.instance.is_image? ? {:small => "x200>", :medium => "x300>", :large => "x400>"} : {:thumb => { :geometry => "100x100#", :format => 'jpg', :time => 10}, :medium => { :geometry => "300x300#", :format => 'jpg', :time => 10}}},
:processors => lambda { |a| a.is_video? ? [ :ffmpeg ] : [ :thumbnail ] }
def is_video?
attachment.instance.attachment_content_type =~ %r(video)
end
def is_image?
attachment.instance.attachment_content_type =~ %r(image)
end
end

Paperclip custom path with id belongs_to

I'm using paperclip inside a project.
The concerned model look like this :
class Asset < ActiveRecord::Base
has_paper_trail # Track model with paper_trail
has_attached_file :image, :styles => { :medium => "300x300>"},
:path => ":rails_root/public/attachments/project_#{:project_id}/ressources/:basename_:style.:extension"
belongs_to :project
end
As you see I want to have the id of concerned project in my image path, how can I make this ?
Try this
has_attached_file :image, :styles => { :medium => "300x300>"},
path => ":rails_root/public/attachments/:project_id/ressources/:basename_:style.:extension"
and then write
Paperclip.interpolates :project_id do |attachment, style|
"project_#{attachment.instance.project_id}"
end

Rails 3, Paperclip - Custom Interpolations

I've been having some troubles making custom Interpolation, gone through every example I could find on web, but no matter what I did, had no success.
At the moment I have this:
Model
has_attached_file :photo,
:path => ":rails_root/public/images/:img_name-:style.:extension",
:styles => {
:original => '100x100',
:thumb => '30x30'
}
initializers/paperclip.rb
Paperclip.interpolates :img_name do |attachment, style|
attachment.instance.img_name
end
img_name is field populated in form on upload with the image.
The error I get on upload is:
Invalid argument - (C:/Users/.../stream20110410-384-stl2lk20110230-213-1fm2bab, C:/.../photo_upload/public/images/:img_name-original.jpg)
Seems to work if it's directly in the model:
class Model < ActiveRecord::Base
Paperclip.interpolates :img_name do |attachment, style|
attachment.instance.img_name
end
has_attached_file :photo,
:path => ":rails_root/public/images/:img_name-:style.:extension",
:styles => {
:original => '100x100',
:thumb => '30x30'
}
end