colin (owner)

Fork Of

gist: 127725 by Traz Small tips for building a p...

Revisions

gist: 159836 Download_button fork
public
Public Clone URL: git://gist.github.com/159836.git
Embed All Files: show embed
add_attachment_data_to_wrapper.rb #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class AddAttachmentsDataToWrapper < ActiveRecord::Migration
  def self.up
    add_column :wrappers, :data_file_name, :string
    add_column :wrappers, :data_content_type, :string
    add_column :wrappers, :data_file_size, :integer
    add_column :wrappers, :data_updated_at, :datetime
  end
 
  def self.down
    remove_column :wrappers, :data_file_name
    remove_column :wrappers, :data_content_type
    remove_column :wrappers, :data_file_size
    remove_column :wrappers, :data_updated_at
  end
end
audio_tag_processor.rb #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
module Paperclip
class AudioTag < Processor
def initialize file, options = {}, attachment = nil
super
@file = file
@data = attachment
end
 
def make
begin
src = @file
src.close
mp3 = Mp3Info.open(File.expand_path(src.path))
@data.instance.info = mp3.tag.to_a.inject("#{@data.instance.info}\n---\n"){|result, element|
result + "*#{element.first}* : #{element.last}\n".titleize}
rescue PaperclipCommandLineError
raise PaperclipError, "There was an error processing the tag extraction for #{@basename}" if @whiny
end
 
nil
 
end
end
end
create_wrapper.rb #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class CreateWrappers < ActiveRecord::Migration
  def self.up
    create_table :wrappers do |t|
      t.string :name
      t.references :user
      t.references :attachable, :polymorphic => true
      t.boolean :private, :default => false
      t.text :info
      t.text :doc_type
 
      t.timestamps
    end
    add_index :wrappers, :user_id
    add_index :wrappers, :attachable_type
    add_index :wrappers, :attachable_id
  end
 
  def self.down
    drop_table :wrappers
  end
end
empty_processor.rb #
1
2
3
4
5
6
7
8
9
10
11
12
module Paperclip
class Empty < Processor
 
def initialize file, options = {}, attachment = nil
end
 
def make
nil
end
 
end
end
paperclip.rb #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
  Paperclip.interpolates :zfull_path do |d,s|
    att = d.instance.attachable_type || "_no_type"
    prn = d.instance.proc_name
    ext = d.instance.data_file_name.scan(/.*\.([^.]*?)$/).to_s
    if (s == :original) or
        (prn == 'image') or
        ((prn == 'video') and (s == :thumb)) or
        ((prn == 'pdf') and (s != :small)) then
      "wrappers/#{att}/:style/:basename.:id.:extension"
    elsif (prn == 'video' and s == :large)
       "wrappers/#{att}/#{s}/:basename.:id.flv"
    else
      "images/styles/#{ext}.:style.png"
    end
  end
pdf_processor.rb #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
module Paperclip
  # Handles thumbnailing images that are uploaded.
  class Pdf < Processor
 
attr_accessor :current_geometry, :target_geometry, :format, :whiny, :convert_options
 
# Creates a Thumbnail object set to work on the +file+ given. It
# will attempt to transform the image into one defined by +target_geometry+
# which is a "WxH"-style string. +format+ will be inferred from the +file+
# unless specified. Thumbnail creation 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 image conversion
def initialize file, options = {}, attachment = nil
super
geometry = options[:geometry]
@file = file
@crop = geometry[-1,1] == '#'
@target_geometry = Geometry.parse geometry
@current_geometry = Geometry.from_file @file
@convert_options = options[:convert_options]
@whiny = options[:whiny].nil? ? true : options[:whiny]
@format = options[:format]
 
@current_format = File.extname(@file.path)
@basename = File.basename(@file.path, @current_format)
end
 
# Returns true if the +target_geometry+ is meant to crop.
def crop?
@crop
end
 
# Returns true if the image is meant to make use of additional convert options.
def convert_options?
not @convert_options.blank?
end
 
# Performs the conversion of the +file+ into a thumbnail. Returns the Tempfile
# that contains the new image.
def make
src = @file
dst = Tempfile.new([@basename, @format].compact.join("."))
dst.binmode
################## added -density 196 *before* the file call for better rendering
command = <<-end_command
-density 196
"#{ File.expand_path(src.path) }[0]"
#{ transformation_command }
"#{ File.expand_path(dst.path) }"
end_command
 
begin
success = Paperclip.run("convert", command.gsub(/\s+/, " "))
rescue PaperclipCommandLineError
raise PaperclipError, "There was an error processing the thumbnail for #{@basename}" if @whiny
end
 
dst
end
 
# Returns the command ImageMagick's +convert+ needs to transform the image
# into the thumbnail.
def transformation_command
scale, crop = @current_geometry.transformation_to(@target_geometry, crop?)
trans = "-resize \"#{scale}\""
trans << " -crop \"#{crop}\" +repage" if crop
trans << " #{convert_options}" if convert_options?
trans
end
  end
end
some kind of rapid tests in console #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
lst = ["zip", "txt", "doc", "ppt", "mp3", "jpg", "xls", "xlsx", "docx", "flv", "wmv", "avi", "pdf"]
id = 1
ty = 'testing'
lst.each do |fic|
w = Wrapper.new
w.id = id
w.attachable_type = ty
File.open("test.#{fic}",'rb'){|f| w.data = f}
puts "test.#{fic} --> #{w.proc_name} -- #{w.data.content_type}"
puts "-------"
puts w.info
[:original,:small,:thumb,:large].each{|s| puts w.data.path(s)}
puts "------------------------------------"
w.save
id+=1
end
video_convert_processor.rb #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
module Paperclip
  class VideoConvert < Processor
 
attr_accessor :whiny, :tt, :file, :basename
 
def initialize(file, options = {}, attachment = nil)
super
@file = file
@whiny = options[:whiny].nil? ? true : options[:whiny]
@basename = File.basename(file.path, File.extname(file.path))
@data = attachment
end
 
def make
src = @file
flv = Tempfile.new([ @basename, 'flv' ].compact.join("."))
flv.close
 
command = <<-end_command
-i #{File.expand_path(src.path)} -ar 22050 -ab 32 -acodec libmp3lame
-s 480x360 -vcodec flv -r 25 -qscale 8 -f flv -y #{File.expand_path(flv.path)}
end_command
command.gsub!(/\s+/, " ")
@tt = command
 
begin
success = Paperclip.run('ffmpeg', command)
rescue PaperclipCommandLineError
raise PaperclipError, "There was an error processing the video convert for #{@basename}" if whiny
end
flv
end
 
  end
end
video_thumb_processor.rb #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
module Paperclip
  class VideoThumb < Processor
 
attr_accessor :time_offset, :geometry, :whiny
 
def initialize(file, options = {}, attachment = nil)
super
@data = attachment
@time_offset = options[:time_offset] || '-4'
unless options[:geometry].nil? || (@geometry = Geometry.parse(options[:geometry])).nil?
@geometry.width = (@geometry.width / 2.0).floor * 2.0
@geometry.height = (@geometry.height / 2.0).floor * 2.0
@geometry.modifier = ''
end
@whiny = options[:whiny].nil? ? true : options[:whiny]
@basename = File.basename(file.path, File.extname(file.path))
end
 
def make
dst = Tempfile.new([ @basename, 'jpg' ].compact.join("."))
dst.binmode
 
cmd = %Q[-itsoffset #{time_offset} -i "#{File.expand_path(file.path)}" -y -vcodec mjpeg -vframes 1 -an -f rawvideo ]
cmd << "-s #{geometry.to_s} " unless geometry.nil?
cmd << %Q["#{File.expand_path(dst.path)}"]
 
begin
success = Paperclip.run('ffmpeg', cmd)
rescue PaperclipCommandLineError
raise PaperclipError, "There was an error processing the thumbnail for #{@basename}" if whiny
end
dst
end
  end
end
wrapper.rb #
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
class Wrapper < ActiveRecord::Base
  
  TypesWrapper = [ 'application/x-docx',
      'application/x-doc', 'application/x-rtf',
      'application/x-pps', 'application/x-ppt', 'application/x-pptx',
      'application/x-xls', 'application/x-xlsx','application/x-csv',
      'application/x-msg',
      'application/x-zip',
      'text/plain',
      'application/x-pdf','application/pdf',
      'application/mp3', 'application/x-mp3', 'audio/mpeg', 'audio/mp3',
      'image/gif', 'image/png', 'image/x-png', 'image/jpeg', 'image/jpg',
      'video/mpeg', 'application/x-flv', 'video/quicktime' ,'application/x-wmv',
      'application/x-avi']
  
  acts_as_commentable
  acts_as_textiled :name, :info
  belongs_to :user
 
has_attached_file :data,
    :url => "/:zfull_path",
    :path => ":rails_root/public/:zfull_path",
    :whiny => true
 
  
  attr_protected :data_file_name, :data_content_type, :data_size
  
  before_post_process :validate_processor
  
  validates_attachment_size :data, :less_than => 10.megabytes
  validates_attachment_content_type :data, :content_type => TypesWrapper
  
 
  def proc_name
    type, detail = data.content_type.scan(/^(video|audio|application|text|image)\/(.*?)$/).flatten
    case type
      when 'image' then 'image'
      when 'video','audio' then type
      when 'text' then 'text'
      when 'application'
        case detail
          when /pdf$/ then 'pdf'
          when /mp3$/ then 'audio'
          when /mov|flv|wmv|avi$/ then 'video'
          when /csv|xls.?$/ then 'excel'
          when /doc.?|txt|rtf$/ then 'word'
          when /pp..?/ then 'powerpoint'
          when 'msg' then 'message'
          when /^(?:x-)?zip$/ then 'zip'
          else 'document'
        end
    end
  end
  
  def validate_processor
    case proc_name
      when "image" then
         data.styles[:small] = { :geometry => "64x64>", :format => "png", :processors => "thumbnail" }
         data.styles[:thumb] = { :geometry => "128x128#", :format => "png", :processors => "thumbnail" }
         data.styles[:large] = { :geometry => "300x400#", :format => "png", :processors => "thumbnail" }
      when "document",'excel','word','powerpoint','text'
         data.styles[:small] = { :geometry => "64x64>", :format => "png", :processors => "empty" }
         data.styles[:thumb] = { :geometry => "128x128#", :format => "png", :processors => "empty" }
         data.styles[:large] = { :geometry => "300x400#", :format => "png", :processors => "empty" }
      when "zip"
         data.styles[:small] = { :geometry => "64x64>", :format => "png", :processors => "empty" }
         data.styles[:thumb] = { :geometry => "128x128#", :format => "png", :processors => "empty" }
         data.styles[:large] = { :geometry => "300x400#", :format => "png", :processors => "zip_info" }
      when "video"
         data.styles[:small] = { :geometry => "64x64>", :format => "png", :processors => "empty" }
         data.styles[:thumb] = { :geometry => "128x128#", :format => "png", :processors => "video_thumb" }
         data.styles[:large] = { :geometry => "300x400#", :format => "flv", :processors => "video_convert"}
      when "audio"
         data.styles[:small] = { :geometry => "64x64>", :format => "png", :processors => "audio_tag" }
         data.styles[:thumb] = { :geometry => "128x128#", :format => "png", :processors => "empty" }
         data.styles[:large] = { :geometry => "300x400#", :format => "png", :processors => "empty" }
      when "pdf"
         data.styles[:small] = { :geometry => "64x64>", :format => "png", :processors => "empty" }
         data.styles[:thumb] = { :geometry => "128x128#", :format => "png", :processors => "pdf" }
         data.styles[:large] = { :geometry => "300x400#", :format => "png", :processors => "pdf" }
    end
    true
  end
  
end