papermill 0.5.7
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +94 -0
- data/Rakefile +69 -0
- data/VERSION +1 -0
- data/app/controllers/papermill_controller.rb +78 -0
- data/app/views/papermill/_asset.html.erb +11 -0
- data/app/views/papermill/_raw_asset.html.erb +1 -0
- data/app/views/papermill/_thumbnail_asset.html.erb +6 -0
- data/app/views/papermill/edit.html.erb +5 -0
- data/config/locales/papermill.yml +28 -0
- data/config/routes.rb +4 -0
- data/generators/papermill/USAGE +3 -0
- data/generators/papermill/papermill_generator.rb +22 -0
- data/generators/papermill/templates/migrate/papermill_migration.rb.erb +22 -0
- data/init.rb +1 -0
- data/install.rb +0 -0
- data/installation-template.txt +124 -0
- data/lib/core_extensions.rb +25 -0
- data/lib/papermill.rb +0 -0
- data/lib/papermill/form_builder.rb +101 -0
- data/lib/papermill/papermill_asset.rb +54 -0
- data/lib/papermill/papermill_helper.rb +48 -0
- data/lib/papermill/papermill_module.rb +177 -0
- data/papermill.gemspec +93 -0
- data/public/flashs/swfupload.swf +0 -0
- data/public/images/papermill/background.png +0 -0
- data/public/images/papermill/container-background.jpg +0 -0
- data/public/images/papermill/delete.png +0 -0
- data/public/images/papermill/upload-blank.png +0 -0
- data/public/images/papermill/upload.png +0 -0
- data/public/javascripts/papermill.js +83 -0
- data/public/stylesheets/papermill.css +33 -0
- data/rails/init.rb +13 -0
- data/tasks/papermill_tasks.rake +1 -0
- data/test/papermill_test.rb +9 -0
- data/test/test_helper.rb +3 -0
- data/uninstall.rb +1 -0
- metadata +135 -0
@@ -0,0 +1,25 @@
|
|
1
|
+
module HashExtensions
|
2
|
+
def deep_merge(hash)
|
3
|
+
target = dup
|
4
|
+
hash.keys.each do |key|
|
5
|
+
if hash[key].is_a? Hash and self[key].is_a? Hash
|
6
|
+
target[key] = target[key].deep_merge(hash[key])
|
7
|
+
next
|
8
|
+
end
|
9
|
+
target[key] = hash[key]
|
10
|
+
end
|
11
|
+
target
|
12
|
+
end
|
13
|
+
end
|
14
|
+
module StringExtensions
|
15
|
+
def simple_sql_sanitizer
|
16
|
+
gsub(/\\/, '\&\&').gsub(/'/, "''")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
module ObjectExtensions
|
21
|
+
# Nil if empty.
|
22
|
+
def nie
|
23
|
+
self.blank? ? nil : self
|
24
|
+
end
|
25
|
+
end
|
data/lib/papermill.rb
ADDED
File without changes
|
@@ -0,0 +1,101 @@
|
|
1
|
+
class ActionView::Helpers::FormBuilder
|
2
|
+
|
3
|
+
def assets_upload(key = nil, options = {})
|
4
|
+
papermill_upload_field key, { :thumbnail => false }.update(options)
|
5
|
+
end
|
6
|
+
def asset_upload(key = nil, options = {})
|
7
|
+
papermill_upload_field key, { :gallery => false, :thumbnail => false }.update(options)
|
8
|
+
end
|
9
|
+
def images_upload(key = nil, options = {})
|
10
|
+
papermill_upload_field key, options
|
11
|
+
end
|
12
|
+
def image_upload(key = nil, options = {})
|
13
|
+
papermill_upload_field key, { :gallery => false }.update(options)
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
def papermill_upload_field(key, options = {})
|
18
|
+
if key.is_a? Hash
|
19
|
+
options = key
|
20
|
+
key = nil
|
21
|
+
end
|
22
|
+
assetable = @template.instance_variable_get("@#{@object_name}")
|
23
|
+
options = if assetable && (association = (assetable.class.papermill_associations[key] || assetable.class.papermill_associations[:papermill_assets]))
|
24
|
+
association[:options].deep_merge(options)
|
25
|
+
else
|
26
|
+
raise Exception.new("Papermill: can't find #{key.to_s} association for #{assetable.class.to_s}.\n\n##{assetable.class.to_s.underscore}.rb\n#set either a catchall papermill association: \npapermill {your_option_hash}\n#or this specific association: \npapermill :#{key.to_s}, {your_option_hash}")
|
27
|
+
end
|
28
|
+
assetable_id = assetable && (assetable.id || assetable.timestamp) || nil
|
29
|
+
assetable_type = assetable && assetable.class.to_s.underscore || nil
|
30
|
+
id = "papermill_#{assetable_type}_#{assetable_id}_#{key ? key.to_s : 'nil'}"
|
31
|
+
if options[:thumbnail]
|
32
|
+
w = options[:thumbnail][:width] || options[:thumbnail][:height] && options[:thumbnail][:aspect_ratio] && (options[:thumbnail][:height] * options[:thumbnail][:aspect_ratio]).to_i || nil
|
33
|
+
h = options[:thumbnail][:height] || options[:thumbnail][:width] && options[:thumbnail][:aspect_ratio] && (options[:thumbnail][:width] / options[:thumbnail][:aspect_ratio]).to_i || nil
|
34
|
+
options[:thumbnail][:style] ||= (w || h) && "#{w || options[:thumbnail][:max_width]}x#{h || options[:thumbnail][:max_height]}>" || "original"
|
35
|
+
if options[:thumbnail][:inline_css]
|
36
|
+
size = []
|
37
|
+
size << "width:#{w}px" if w
|
38
|
+
size << "height:#{h}px" if h
|
39
|
+
size = size.join("; ")
|
40
|
+
@template.content_for :papermill_inline_css do
|
41
|
+
inline_css = ["\n"]
|
42
|
+
if options[:gallery]
|
43
|
+
vp = options[:gallery][:vpadding].to_i
|
44
|
+
hp = options[:gallery][:hpadding].to_i
|
45
|
+
vm = options[:gallery][:vmargin].to_i
|
46
|
+
hm = options[:gallery][:hmargin].to_i
|
47
|
+
b = options[:gallery][:border_thickness].to_i
|
48
|
+
gallery_width = (options[:gallery][:width] || w) && "width:#{options[:gallery][:width] || options[:gallery][:columns]*(w+(hp+hm+b)*2)}px;" || ""
|
49
|
+
gallery_height = (options[:gallery][:height] || h) && "#{options[:gallery][:autogrow] ? "" : "min-"}height:#{options[:gallery][:height] || options[:gallery][:lines]*(h+(vp+vm+b)*2)}px;" || ""
|
50
|
+
inline_css << %{##{id} { #{gallery_width} #{gallery_height} }}
|
51
|
+
inline_css << %{##{id} li { margin:#{vm}px #{hm}px; border-width:#{b}px; padding:#{vp}px #{hp}px; #{size}; }}
|
52
|
+
else
|
53
|
+
inline_css << %{##{id}, ##{id} li { #{size} }}
|
54
|
+
end
|
55
|
+
inline_css << %{##{id} .name { width:#{w || "100"}px; }}
|
56
|
+
inline_css.join("\n")
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
html = []
|
61
|
+
|
62
|
+
conditions = {:assetable_type => assetable.class.sti_name, :assetable_id => assetable_id}
|
63
|
+
conditions.merge!({:assetable_key => key.to_s}) if key
|
64
|
+
asset_class = options[:class_name] && options[:class_name].to_s.constantize || association && association[:class] || PapermillAsset
|
65
|
+
create_url = @template.url_for(:controller => "/papermill", :action => "create", :escape => false, :asset_class => asset_class.to_s, :assetable_key => key, :assetable_id => assetable_id, :assetable_type => assetable_type, :gallery => (options[:gallery] != false), :thumbnail_style => (options[:thumbnail] && options[:thumbnail][:style]))
|
66
|
+
if assetable && assetable.new_record? && !@timestamped
|
67
|
+
html << self.hidden_field(:timestamp, :value => assetable.timestamp)
|
68
|
+
@timestamped = true
|
69
|
+
end
|
70
|
+
collection = asset_class.find(:all, :conditions => conditions, :order => "position")
|
71
|
+
|
72
|
+
html << %{<div style="height: #{options[:swfupload][:button_height]}px;"><span id="browse_for_#{id}" class="swf_button"></span></div>}
|
73
|
+
html << @template.content_tag(:ul, :id => id, :class => "papermill #{(options[:thumbnail] ? "papermill-thumb-container" : "papermill-asset-container")} #{(options[:gallery] ? "papermill-multiple-items" : "papermill-unique-item")}") {
|
74
|
+
@template.render :partial => "papermill/asset", :collection => collection, :locals => { :thumbnail_style => (options[:thumbnail] && options[:thumbnail][:style]) }
|
75
|
+
}
|
76
|
+
@template.content_for :papermill_inline_js do
|
77
|
+
%{
|
78
|
+
#{%{$("##{id}").sortable({update:function(){jQuery.ajax({async:true, data:jQuery(this).sortable('serialize'), dataType:'script', type:'post', url:'#{@template.controller.send("sort_papermill_url")}'})}})} if options[:gallery]}
|
79
|
+
new SWFUpload({
|
80
|
+
upload_id: "#{id}",
|
81
|
+
upload_url: "#{@template.escape_javascript create_url}",
|
82
|
+
file_size_limit: "#{options[:file_size_limit_mb].megabytes}",
|
83
|
+
file_types: "#{options[:images_only] ? '*.jpg;*.jpeg;*.png;*.gif' : ''}",
|
84
|
+
file_types_description: "#{options[:thumbnail] ? 'Images' : 'Files'}",
|
85
|
+
file_queue_limit: "#{!options[:gallery] ? '1' : '0'}",
|
86
|
+
file_queued_handler: Upload.file_queued,
|
87
|
+
file_dialog_complete_handler: Upload.file_dialog_complete,
|
88
|
+
upload_start_handler: Upload.upload_start,
|
89
|
+
upload_progress_handler: Upload.upload_progress,
|
90
|
+
upload_error_handler: Upload.upload_error,
|
91
|
+
upload_success_handler: Upload.upload_success,
|
92
|
+
upload_complete_handler: Upload.upload_complete,
|
93
|
+
button_placeholder_id : "browse_for_#{id}",
|
94
|
+
#{options[:swfupload].map{ |key, value| ["false", "true"].include?(value.to_s) ? "#{key.to_s}: #{value.to_s}" : "#{key.to_s}: '#{value.to_s}'" }.compact.join(", ")}
|
95
|
+
});
|
96
|
+
}
|
97
|
+
end
|
98
|
+
html.reverse! if options[:button_after_container]
|
99
|
+
html.join("\n")
|
100
|
+
end
|
101
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'stringex'
|
2
|
+
require 'paperclip'
|
3
|
+
require 'mime/types'
|
4
|
+
require 'acts_as_list'
|
5
|
+
|
6
|
+
class PapermillAsset < ActiveRecord::Base
|
7
|
+
acts_as_list :scope => 'assetable_key=\'#{assetable_key.to_s.simple_sql_sanitizer}\' AND assetable_id=#{assetable_id} AND assetable_type=\'#{assetable_type}\''
|
8
|
+
|
9
|
+
belongs_to :assetable, :polymorphic => true
|
10
|
+
before_destroy :destroy_files
|
11
|
+
|
12
|
+
Paperclip::Attachment.interpolations[:escaped_basename] = proc do |attachment, style|
|
13
|
+
Paperclip::Attachment.interpolations[:basename].call(attachment, style).to_url
|
14
|
+
end
|
15
|
+
|
16
|
+
has_attached_file :file,
|
17
|
+
:path => "#{Papermill::PAPERMILL_DEFAULTS[:public_root]}/#{Papermill::PAPERMILL_DEFAULTS[:papermill_prefix]}/#{Papermill::PAPERCLIP_INTERPOLATION_STRING}",
|
18
|
+
:url => "/#{Papermill::PAPERMILL_DEFAULTS[:papermill_prefix]}/#{Papermill::PAPERCLIP_INTERPOLATION_STRING}"
|
19
|
+
validates_attachment_presence :file
|
20
|
+
|
21
|
+
def swfupload_file=(data)
|
22
|
+
data.content_type = MIME::Types.type_for(data.original_filename).to_s
|
23
|
+
self.file = data
|
24
|
+
end
|
25
|
+
|
26
|
+
def id_partition
|
27
|
+
("%09d" % self.id).scan(/\d{3}/).join("/")
|
28
|
+
end
|
29
|
+
|
30
|
+
def name
|
31
|
+
file_file_name
|
32
|
+
end
|
33
|
+
|
34
|
+
def size
|
35
|
+
file_file_size
|
36
|
+
end
|
37
|
+
|
38
|
+
def url(style = nil)
|
39
|
+
file.url(style && CGI::escape(style.to_s))
|
40
|
+
end
|
41
|
+
|
42
|
+
def content_type
|
43
|
+
file_content_type && file_content_type.split("/")
|
44
|
+
end
|
45
|
+
|
46
|
+
def image?
|
47
|
+
content_type && content_type.first == "image" && content_type[1]
|
48
|
+
end
|
49
|
+
|
50
|
+
def destroy_files
|
51
|
+
system "rm -rf #{Papermill::papermill_interpolated_path({":id_partition" => self.id_partition}, ':id_partition')}/"
|
52
|
+
true
|
53
|
+
end
|
54
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module PapermillHelper
|
2
|
+
|
3
|
+
# Sets all the javascript needed for papermill.
|
4
|
+
# If you already loaded jQuery and JQueryUI, call papermill_javascript_tag
|
5
|
+
# If you don't use jQuery or use some other library, call papermill_javascript_tag(:with_jquery => "no_conflict")
|
6
|
+
# If you want to rely on this helper to load jQuery/jQueryUI and use it, call papermill_javascript_tag(:with_jquery => true)
|
7
|
+
# If you loaded jQuery and need to load only jQueryUI, call papermill_javascript_tag(:with_jqueryui_only => true)
|
8
|
+
# If you changed the location of papermill.js, you'll need to set :root_folder (defaults to "javascripts")
|
9
|
+
def papermill_javascript_tag(options = {})
|
10
|
+
html = []
|
11
|
+
root_folder = options[:path] || "javascripts"
|
12
|
+
if options[:with_jquery] || options[:with_jqueryui]
|
13
|
+
html << %{<script src="http://www.google.com/jsapi"></script>}
|
14
|
+
html << %{<script type="text/javascript">}
|
15
|
+
html << %{google.load("jquery", "1");} if options[:with_jquery]
|
16
|
+
html << %{google.load("jqueryui", "1");} if options[:with_jquery] || options[:with_jqueryui_only]
|
17
|
+
html << %{jQuery.noConflict();} if options[:with_jquery] == "no_conflict"
|
18
|
+
html << %{</script>}
|
19
|
+
end
|
20
|
+
html << %{<script src="http://swfupload.googlecode.com/svn/swfupload/tags/swfupload_v2.2.0_core/swfupload.js"></script>}
|
21
|
+
html << %{<script type="text/javascript">\n//<![CDATA[}
|
22
|
+
["SWFUPLOAD_PENDING", "SWFUPLOAD_LOADING", "SWFUPLOAD_ERROR"].each do |js_constant|
|
23
|
+
html << %{var #{js_constant} = "#{I18n.t(js_constant, :scope => "papermill")}";}
|
24
|
+
end
|
25
|
+
html << %{//]]>\n</script>}
|
26
|
+
html << javascript_include_tag("/#{root_folder}/papermill", :cache => "swfupload-papermill")
|
27
|
+
unless @content_for_papermill_inline_js.blank?
|
28
|
+
html << '<script type="text/javascript">jQuery(document).ready(function() {'
|
29
|
+
html << @content_for_papermill_inline_js
|
30
|
+
html << '});</script>'
|
31
|
+
end
|
32
|
+
html.join("\n")
|
33
|
+
end
|
34
|
+
|
35
|
+
# Sets the css tags needed for papermill.
|
36
|
+
# If you changed the location of papermill.css, you'll need to set :root_folder (defaults to "stylesheets")
|
37
|
+
def papermill_stylesheet_tag(options = {})
|
38
|
+
html = []
|
39
|
+
root_folder = options[:path] || "stylesheets"
|
40
|
+
html << stylesheet_link_tag("/#{root_folder}/papermill")
|
41
|
+
unless @content_for_papermill_inline_css.blank?
|
42
|
+
html << %{<style type="text/css">}
|
43
|
+
html << @content_for_papermill_inline_css
|
44
|
+
html << %{</style>}
|
45
|
+
end
|
46
|
+
html.join("\n")
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,177 @@
|
|
1
|
+
module Papermill
|
2
|
+
|
3
|
+
# Override these defaults :
|
4
|
+
# - in your application (environment.rb, ..) => in your [environment, development, production].rb file with Papermill::OPTIONS = {thumbnails => {..}, :gallery => {..}, etc. }
|
5
|
+
# - in your class => papermill <assoc_name>, :class_name => MySTIedPapermillAssetSubClass, thumbnails => {<my_thumbnail_parameters>}, :gallery => {<my_gallery_parameters>}, etc.
|
6
|
+
# - in your helper call => images_upload :my_gallery, {thumbnails => {..}, :gallery => {..}, etc. }
|
7
|
+
# Options will cascade as you expect them to.
|
8
|
+
|
9
|
+
# sizes (widths, paddings, etc..) are CSS pixel values.
|
10
|
+
PAPERMILL_DEFAULTS = {
|
11
|
+
:thumbnail => {
|
12
|
+
# you clearly want to override these two values in your templates.
|
13
|
+
# the rest is very optionnal and will "cascade" nicely
|
14
|
+
:width => 100, # Recommended if :gallery[:width] is nil
|
15
|
+
:height => 100, # Recommended if :gallery[:height] is nil
|
16
|
+
# set :width OR :height to nil to use aspect_ratio value. Remember that 4/3 == 1 => Use : 4.0/3
|
17
|
+
:aspect_ratio => nil,
|
18
|
+
:max_width => 1000,
|
19
|
+
:max_height => 1000,
|
20
|
+
# You can override computed ImageMagick transformation strings that defaults to "#{:width}x#{:height}>"
|
21
|
+
# Note that this is required if PAPERMILL_DEFAULTS[:alias_only] is true
|
22
|
+
:style => nil,
|
23
|
+
# set to false if you don't want inline CSS
|
24
|
+
:inline_css => true
|
25
|
+
},
|
26
|
+
# gallery
|
27
|
+
:gallery => {
|
28
|
+
# if thumbnail.inline_css is true, css will be generated automagically with these values. Great for quick scaffolding, and complete enough for real use.
|
29
|
+
:width => nil, # overrides calculated width. Recommended if :thumbnail[:width] is nil.
|
30
|
+
:height => nil, # overrides calculated height. Recommended if :thumbnail[:height] is nil.
|
31
|
+
:columns => 8, # number of columns. If thumbnail.width has a value, sets a width for the gallery, calculated from thumbnails width multiplied by :columns.
|
32
|
+
:lines => 2, # number of default lines. (height will autogrow) If thumbnail.height has a value, sets a min-height for the gallery, calculated from thumbnails height multiplied by :lines
|
33
|
+
:vpadding => 0, # vertical padding around thumbnails
|
34
|
+
:hpadding => 0, # horizontal padding around thumbnails
|
35
|
+
:vmargin => 1, # vertical margin around thumbnails
|
36
|
+
:hmargin => 1, # horizontal margin around thumbnails
|
37
|
+
:border_thickness => 2, # border around thumbnails
|
38
|
+
:autogrow => false # sets a min-height instead of height for the gallery
|
39
|
+
},
|
40
|
+
# options passed on to SWFUpload. To remove an option when overriding, set it to nil.
|
41
|
+
:swfupload => {
|
42
|
+
# !!! Will only work if the swf file comes from the server to where the files are sent. (Flash same origin security policy)
|
43
|
+
:flash_url => '/flashs/swfupload.swf',
|
44
|
+
# You can use upload-blank.png with your own wording or upload.png with default "upload" wording (looks nicer)
|
45
|
+
:button_image_url => '/images/papermill/upload-blank.png',
|
46
|
+
:button_width => 61,
|
47
|
+
:button_height => 22,
|
48
|
+
# Wording and CSS processed through an Adobe Flash styler. Result is terrible. Feel free to put a CSS button overlayed directly on the SWF button. See swfupload website.
|
49
|
+
:button_text => %{<span class="button-text">#{I18n.t("upload-button-wording", :scope => :papermill)}</span>},
|
50
|
+
:button_text_style => %{.button-text { color: red; font-size: 12pt; font-weight: bold; }},
|
51
|
+
:button_disabled => "false",
|
52
|
+
:button_text_top_padding => 4,
|
53
|
+
:button_text_left_padding => 4,
|
54
|
+
:debug => "false",
|
55
|
+
:prevent_swf_caching => "false"
|
56
|
+
# See swfupload.js for details.
|
57
|
+
},
|
58
|
+
:images_only => false, # set to true to forbid upload of anything else than images
|
59
|
+
:file_size_limit_mb => 10, # file max size
|
60
|
+
:button_after_container => false, # set to true to move the upload button below the container
|
61
|
+
|
62
|
+
# DO NOT CHANGE THESE IN YOUR CLASSES. Only application wide (routes depend on it..)
|
63
|
+
:alias_only => false, # set to true so that only aliases are authorized in url/path
|
64
|
+
:aliases => {
|
65
|
+
# "example" => "100x100#",
|
66
|
+
},
|
67
|
+
# path to the root of your public directory
|
68
|
+
:public_root => ":rails_root/public",
|
69
|
+
# added to :public_root as the root folder for all papermill items
|
70
|
+
:papermill_prefix => "system/papermill"
|
71
|
+
}.deep_merge( Papermill.const_defined?("OPTIONS") ? Papermill::OPTIONS : {} )
|
72
|
+
|
73
|
+
PAPERCLIP_INTERPOLATION_STRING = ":id_partition/:style/:escaped_basename.:extension"
|
74
|
+
|
75
|
+
def self.included(base)
|
76
|
+
base.extend(ClassMethods)
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.papermill_interpolated_path(replacements_pairs, up_to)
|
80
|
+
replacements_pairs = {"other" => "*", ":rails_root" => RAILS_ROOT}.merge(replacements_pairs)
|
81
|
+
a = "#{PAPERMILL_DEFAULTS[:public_root]}/#{PAPERMILL_DEFAULTS[:papermill_prefix]}/#{PAPERCLIP_INTERPOLATION_STRING}".split("/")
|
82
|
+
"#{a[0..(up_to && a.index(up_to) || -1)].map{ |s| s.starts_with?(':') ? (replacements_pairs[s] || replacements_pairs['other'] || s) : s }.join('/')}"
|
83
|
+
end
|
84
|
+
|
85
|
+
module ClassMethods
|
86
|
+
attr_reader :papermill_associations
|
87
|
+
|
88
|
+
# papermill comes in 2 flavors:
|
89
|
+
#
|
90
|
+
# 1. generic declaration =>
|
91
|
+
# declare associations with => papermill {my_option_hash}
|
92
|
+
# create assets with => assets_upload(:my_key, {optional_option_hash})
|
93
|
+
# access assets with => assetable.papermill_assets(:key => :my_key)
|
94
|
+
#
|
95
|
+
# 2. association declaration =>
|
96
|
+
# declare associations with => papermill :my_association, {my_option_hash}
|
97
|
+
# create assets with => assets_upload(my_association, {optional_option_hash})
|
98
|
+
# access assets with => assetable.my_association
|
99
|
+
#
|
100
|
+
# In both case, you can specify a PapermillAsset subclass to use with :class_name => MyPapermillAssetSubclass in the option hash
|
101
|
+
def papermill(assoc_name = :papermill_assets, options = {})
|
102
|
+
if assoc_name.is_a? Hash
|
103
|
+
options = assoc_name
|
104
|
+
assoc_name = :papermill_assets
|
105
|
+
end
|
106
|
+
|
107
|
+
@papermill_associations ||= {}
|
108
|
+
begin
|
109
|
+
class_name = options.delete(:class_name)
|
110
|
+
asset_class = class_name && class_name.to_s.constantize || PapermillAsset
|
111
|
+
rescue
|
112
|
+
raise Exception.new("Papermill: can't find class #{class_name.to_s}.\n#{class_name.to_s} should be a subclass of PapermillAsset")
|
113
|
+
end
|
114
|
+
|
115
|
+
@papermill_associations.merge!({assoc_name => {:class => asset_class, :options => Papermill::PAPERMILL_DEFAULTS.deep_merge(options)}})
|
116
|
+
before_destroy :destroy_assets
|
117
|
+
after_create :rebase_assets
|
118
|
+
|
119
|
+
define_method assoc_name do |*options|
|
120
|
+
klass = self.class.papermill_associations[assoc_name.to_sym][:class]
|
121
|
+
options = options.first || {}
|
122
|
+
if (options.is_a?(Symbol) || options.is_a?(String))
|
123
|
+
key = options
|
124
|
+
options = {}
|
125
|
+
else
|
126
|
+
key = nil
|
127
|
+
end
|
128
|
+
conditions = {
|
129
|
+
:assetable_type => self.class.sti_name,
|
130
|
+
:assetable_id => self.id
|
131
|
+
}.merge(options.delete(:conditions) || {})
|
132
|
+
key ||= (assoc_name != :papermill_assets) && assoc_name.to_s
|
133
|
+
conditions.merge!({:assetable_key => key.to_s}) if key
|
134
|
+
|
135
|
+
hash = {
|
136
|
+
:conditions => conditions,
|
137
|
+
:order => options.delete(:order) || "position ASC"
|
138
|
+
}.merge(options)
|
139
|
+
asset_class.find(:all, hash)
|
140
|
+
end
|
141
|
+
|
142
|
+
class_eval <<-EOV
|
143
|
+
include Papermill::InstanceMethods
|
144
|
+
EOV
|
145
|
+
end
|
146
|
+
|
147
|
+
def inherited(subclass)
|
148
|
+
subclass.instance_variable_set("@papermill_associations", @papermill_associations)
|
149
|
+
super
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
module InstanceMethods
|
154
|
+
attr_writer :timestamp
|
155
|
+
def timestamp
|
156
|
+
@timestamp ||= "-#{(Time.now.to_f * 1000).to_i.to_s[4..-1]}"
|
157
|
+
end
|
158
|
+
|
159
|
+
private
|
160
|
+
|
161
|
+
def destroy_assets
|
162
|
+
PapermillAsset.find(:all, :conditions => {:assetable_id => self.id, :assetable_type => self.class.sti_name}).each do |asset|
|
163
|
+
asset.destroy
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
def rebase_assets
|
168
|
+
PapermillAsset.find(:all, :conditions => {:assetable_id => self.timestamp, :assetable_type => self.class.sti_name}).each do |asset|
|
169
|
+
if asset.created_at < 2.hours.ago
|
170
|
+
asset.destroy
|
171
|
+
else
|
172
|
+
asset.update_attribute(:assetable_id, self.id)
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
data/papermill.gemspec
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run `rake gemspec`
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{papermill}
|
8
|
+
s.version = "0.5.7"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Benoit B\303\251n\303\251zech"]
|
12
|
+
s.date = %q{2009-09-08}
|
13
|
+
s.description = %q{Paperclip Swfupload UploadHelper wrapper}
|
14
|
+
s.email = %q{benoit.benezech@gmail.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"README.rdoc"
|
17
|
+
]
|
18
|
+
s.files = [
|
19
|
+
".gitignore",
|
20
|
+
"MIT-LICENSE",
|
21
|
+
"README.rdoc",
|
22
|
+
"Rakefile",
|
23
|
+
"VERSION",
|
24
|
+
"app/controllers/papermill_controller.rb",
|
25
|
+
"app/views/papermill/_asset.html.erb",
|
26
|
+
"app/views/papermill/_raw_asset.html.erb",
|
27
|
+
"app/views/papermill/_thumbnail_asset.html.erb",
|
28
|
+
"app/views/papermill/edit.html.erb",
|
29
|
+
"config/locales/papermill.yml",
|
30
|
+
"config/routes.rb",
|
31
|
+
"generators/papermill/USAGE",
|
32
|
+
"generators/papermill/papermill_generator.rb",
|
33
|
+
"generators/papermill/templates/migrate/papermill_migration.rb.erb",
|
34
|
+
"init.rb",
|
35
|
+
"install.rb",
|
36
|
+
"installation-template.txt",
|
37
|
+
"lib/core_extensions.rb",
|
38
|
+
"lib/papermill.rb",
|
39
|
+
"lib/papermill/form_builder.rb",
|
40
|
+
"lib/papermill/papermill_asset.rb",
|
41
|
+
"lib/papermill/papermill_helper.rb",
|
42
|
+
"lib/papermill/papermill_module.rb",
|
43
|
+
"papermill.gemspec",
|
44
|
+
"public/.DS_Store",
|
45
|
+
"public/flashs/swfupload.swf",
|
46
|
+
"public/images/.DS_Store",
|
47
|
+
"public/images/papermill/.DS_Store",
|
48
|
+
"public/images/papermill/background.png",
|
49
|
+
"public/images/papermill/container-background.jpg",
|
50
|
+
"public/images/papermill/delete.png",
|
51
|
+
"public/images/papermill/upload-blank.png",
|
52
|
+
"public/images/papermill/upload.png",
|
53
|
+
"public/javascripts/papermill.js",
|
54
|
+
"public/stylesheets/papermill.css",
|
55
|
+
"rails/init.rb",
|
56
|
+
"tasks/papermill_tasks.rake",
|
57
|
+
"test/papermill_test.rb",
|
58
|
+
"test/test_helper.rb",
|
59
|
+
"uninstall.rb"
|
60
|
+
]
|
61
|
+
s.homepage = %q{http://github.com/BBenezech/papermill}
|
62
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
63
|
+
s.require_paths = ["lib"]
|
64
|
+
s.rubyforge_project = %q{papermill}
|
65
|
+
s.rubygems_version = %q{1.3.5}
|
66
|
+
s.summary = %q{Paperclip Swfupload UploadHelper wrapper}
|
67
|
+
s.test_files = [
|
68
|
+
"test/papermill_test.rb",
|
69
|
+
"test/test_helper.rb"
|
70
|
+
]
|
71
|
+
|
72
|
+
if s.respond_to? :specification_version then
|
73
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
74
|
+
s.specification_version = 3
|
75
|
+
|
76
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
77
|
+
s.add_runtime_dependency(%q<paperclip>, [">= 2.1.2"])
|
78
|
+
s.add_runtime_dependency(%q<mime-types>, [">= 1.16"])
|
79
|
+
s.add_runtime_dependency(%q<rsl-stringex>, [">= 1.0.0"])
|
80
|
+
s.add_runtime_dependency(%q<ryanb-acts-as-list>, [">= 0.1.2"])
|
81
|
+
else
|
82
|
+
s.add_dependency(%q<paperclip>, [">= 2.1.2"])
|
83
|
+
s.add_dependency(%q<mime-types>, [">= 1.16"])
|
84
|
+
s.add_dependency(%q<rsl-stringex>, [">= 1.0.0"])
|
85
|
+
s.add_dependency(%q<ryanb-acts-as-list>, [">= 0.1.2"])
|
86
|
+
end
|
87
|
+
else
|
88
|
+
s.add_dependency(%q<paperclip>, [">= 2.1.2"])
|
89
|
+
s.add_dependency(%q<mime-types>, [">= 1.16"])
|
90
|
+
s.add_dependency(%q<rsl-stringex>, [">= 1.0.0"])
|
91
|
+
s.add_dependency(%q<ryanb-acts-as-list>, [">= 0.1.2"])
|
92
|
+
end
|
93
|
+
end
|