papermill 0.7.0 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.rdoc CHANGED
@@ -20,7 +20,7 @@ Asset management made easy.
20
20
 
21
21
  papermill my_option_hash # in your papermilled assetable model
22
22
  assets_upload(:my_key, my_option_hash) # form helper call
23
- @assetable.papermill_assets(:my_key) # data access in your view
23
+ @assetable.assets(:my_key) # data access in your view
24
24
 
25
25
  === Association specific declaration
26
26
 
@@ -66,11 +66,11 @@ See papermill_module.rb for the complete list of options.
66
66
  === In your assetable model:
67
67
 
68
68
  # You can set a catch-all papermill association :
69
- papermill :class_name => Asset
69
+ papermill :class_name => MyAssetClass
70
70
 
71
71
  # or create an association for the specific :my_gallery key
72
- papermill :my_gallery,
73
- :class_name => GalleryAsset,
72
+ papermill :my_gallery_assets,
73
+ :class_name => MyGalleryAsset,
74
74
  :thumbnail => {
75
75
  :width => 90,
76
76
  :height => 30
@@ -80,7 +80,7 @@ See papermill_module.rb for the complete list of options.
80
80
 
81
81
  <%= papermill_stylesheet_tag %>
82
82
  <%= papermill_javascript_tag :with_jquery => "no_conflict" %>
83
- # you won't need :with_jquery if you use it already, obviously.
83
+ # you won't need :with_jquery if you have already loaded it.
84
84
 
85
85
  === In your edit form:
86
86
 
@@ -90,9 +90,18 @@ See papermill_module.rb for the complete list of options.
90
90
 
91
91
  === Access them with:
92
92
 
93
- @assetable.my_gallery.each{ |image| image_tag image.url("100x100") }
94
- @assetable.papermill_assets(:my_assets).each{ |asset| asset.url }
95
- @assetable.papermill_assets(:my_other_asset).first.url
93
+ @assetable.my_gallery_assets.each{ |image| image_tag image.url("100x100") }
94
+ # equivalent to:
95
+ @assetable.assets(:my_gallery_assets).each{ |image| image_tag image.url("100x100") }
96
+ # also equivalent to:
97
+ @assetable.assets(:conditions => {:assetable_key => 'my_gallery_assets'}).each{ |image| image_tag image.url("100x100") }
98
+
99
+
100
+ @assetable.assets(:my_assets).each{ |asset| asset.url }
101
+ # if your association name is singularizable, you can do smtg like :
102
+ @assetable.asset(:my_other_asset).try(:url)
103
+ # equivalent to:
104
+ @assetable.assets(:my_other_asset).first.try(:url)
96
105
 
97
106
  Also see http://github.com/bbenezech/papermill/raw/master/installation-template.txt for more precises installation steps.
98
107
  Have a look at the API here http://rdoc.info/projects/BBenezech/papermill
data/TODO.txt CHANGED
@@ -1,4 +1,2 @@
1
- * check necessity for escaped_filename
2
- * check necessity for Mime::Type
3
- * assets without assetable
4
- * non-regression tests
1
+ * non-regression tests
2
+ * check for necessity for requires over gemspec dependencies
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.7.0
1
+ 0.8.0
@@ -52,14 +52,13 @@ class PapermillController < ApplicationController
52
52
  end
53
53
 
54
54
  def create
55
- params[:assetable_id] = params[:assetable_id].nie
56
55
  asset_class = params[:asset_class].constantize
57
- params[:assetable_type] = params[:assetable_type] && params[:assetable_type].to_s.camelize.nie
56
+ params[:assetable_type] = params[:assetable_type].camelize if params[:assetable_type]
58
57
  params[:swfupload_file] = params.delete(:Filedata)
59
58
  unless params[:gallery]
60
- @old_asset = asset_class.find(:first, :conditions => {:assetable_key => params[:assetable_key], :assetable_type => params[:assetable_type], :assetable_id => params[:assetable_id]})
59
+ @old_asset = asset_class.find(:first, :conditions => params.reject{|k, v| ![:assetable_key, :assetable_type, :assetable_id].include?(k)})
61
60
  end
62
- @asset = asset_class.new(params.reject{|key, value| !(PapermillAsset.columns.map(&:name)+["swfupload_file"]).include?(key.to_s)})
61
+ @asset = asset_class.new(params.reject{|k, v| !(PapermillAsset.columns.map(&:name)+["swfupload_file"]).include?(k)})
63
62
 
64
63
  if @asset.save
65
64
  @old_asset.destroy if @old_asset
@@ -7,7 +7,7 @@ rake "db:migrate"
7
7
  file "app/models/article.rb", <<-END
8
8
  class Article < ActiveRecord::Base
9
9
  validates_presence_of :title
10
- papermill :thumbnail => {:width => 100, :height => 75} # catch-all for non-specified associations
10
+ papermill :thumbnail => {:width => 100, :height => 75} # catch-all for non-specified associations, will create assets/asset methods. You can change it: :base_association_name, with Papermill::OPTIONS in your environment.rb
11
11
  papermill :image_gallery, :class_name => ImageAsset, :images_only => true, :thumbnail => {:width => 75, :height => 100}
12
12
  # image_gallery association (set with define_method)
13
13
  end
@@ -75,24 +75,24 @@ file "app/views/articles/show.html.erb", <<-END
75
75
  <% end %>
76
76
  </p>
77
77
  <br /><br />
78
- <b>@article.papermill_assets(:my_other_image).first :</b>
78
+ <b>@article.assets(:my_other_image).first :</b>
79
79
  <p>
80
- <% image = @article.papermill_assets(:my_other_image).first %>
80
+ <% image = @article.asset(:my_other_image) %>
81
81
  <%= link_to(image_tag(image.url("100x100#")), image.url) if image %>
82
82
  </p>
83
83
  <br /><br />
84
- <b>@article.papermill_assets(:my_assets).each :</b>
84
+ <b>@article.assets(:my_assets).each :</b>
85
85
  <p>
86
86
  <ul>
87
- <% @article.papermill_assets(:my_assets).each do |asset| %>
87
+ <% @article.assets(:my_assets).each do |asset| %>
88
88
  <li><%= link_to asset.name, asset.url %></li>
89
89
  <% end %>
90
90
  </ul>
91
91
  </p>
92
92
  <br /><br />
93
- <b>@article.papermill_assets(:my_other_asset).first :</b>
93
+ <b>@article.asset(:my_other_asset) :</b>
94
94
  <p>
95
- <% asset = @article.papermill_assets(:my_other_asset).first %>
95
+ <% asset = @article.asset(:my_other_asset) %>
96
96
  <%= link_to(asset.name, asset.url) if asset %>
97
97
  </p>
98
98
 
@@ -1,3 +1,5 @@
1
+ class PapermillException < Exception; end
2
+
1
3
  module HashExtensions
2
4
  def deep_merge(hash)
3
5
  target = dup
@@ -1,32 +1,39 @@
1
1
  module ActionView::Helpers::FormTagHelper
2
2
 
3
3
  def assets_upload_tag(assetable, key = nil, options = {})
4
- papermill_upload_field_tag key, { :thumbnail => false, :assetable => assetable }.update(options)
4
+ papermill_upload_tag key, { :thumbnail => false, :assetable => assetable }.update(options)
5
5
  end
6
+
6
7
  def asset_upload_tag(assetable, key = nil, options = {})
7
- papermill_upload_field_tag key, { :gallery => false, :thumbnail => false, :assetable => assetable }.update(options)
8
+ papermill_upload_tag key, { :gallery => false, :thumbnail => false, :assetable => assetable }.update(options)
8
9
  end
10
+
9
11
  def images_upload_tag(assetable, key = nil, options = {})
10
- papermill_upload_field_tag key, { :assetable => assetable }.update(options)
12
+ papermill_upload_tag key, { :assetable => assetable }.update(options)
11
13
  end
14
+
12
15
  def image_upload_tag(assetable, key = nil, options = {})
13
- papermill_upload_field_tag key, { :gallery => false, :assetable => assetable }.update(options)
16
+ papermill_upload_tag key, { :gallery => false, :assetable => assetable }.update(options)
14
17
  end
15
18
 
16
19
  private
17
- def papermill_upload_field_tag(key, options)
18
- if key.is_a? Hash
19
- options = key
20
- key = nil
20
+ def papermill_upload_tag(key, options)
21
+ # asset_upload_tag(:my_key)
22
+ if key.nil? && (options[:assetable].is_a?(Symbol) || options[:assetable].is_a?(String))
23
+ key = options[:assetable]
24
+ options[:assetable] = nil
21
25
  end
26
+
22
27
  assetable = options[:assetable] || @template.instance_variable_get("@#{@object_name}")
23
28
  options = if assetable && (association = (assetable.class.papermill_associations[key] || assetable.class.papermill_associations[:papermill_assets]))
24
29
  association[:options].deep_merge(options)
30
+ elsif assetable.nil?
31
+ Papermill::PAPERMILL_DEFAULTS.deep_merge(options)
25
32
  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}")
33
+ raise PapermillException.new("Can't find '#{key.to_s}' association for '#{assetable.class.to_s}'.\n\n##{assetable.class.to_s.underscore}.rb\nYou can take on of these actions: \n1. set either a catchall papermill association: 'papermill {your_option_hash}'\n2. or a specific association: 'papermill :#{key.to_s}, {your_option_hash}'")
27
34
  end
28
35
  assetable_id = assetable && (assetable.id || assetable.timestamp) || nil
29
- assetable_type = assetable && assetable.class.to_s.underscore || nil
36
+ assetable_type = assetable && assetable.class.to_s || nil
30
37
  id = "papermill_#{assetable_type}_#{assetable_id}_#{key ? key.to_s : 'nil'}"
31
38
  if options[:thumbnail]
32
39
  w = options[:thumbnail][:width] || options[:thumbnail][:height] && options[:thumbnail][:aspect_ratio] && (options[:thumbnail][:height] * options[:thumbnail][:aspect_ratio]).to_i || nil
@@ -59,14 +66,28 @@ module ActionView::Helpers::FormTagHelper
59
66
  end
60
67
  html = []
61
68
 
62
- conditions = {:assetable_type => assetable.class.sti_name, :assetable_id => assetable_id}
63
- conditions.merge!({:assetable_key => key.to_s}) if key
64
69
  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]))
70
+ url_options = {
71
+ :controller => "/papermill",
72
+ :action => "create",
73
+ :escape => false,
74
+ :asset_class => asset_class.to_s,
75
+ :assetable_key => key,
76
+ :gallery => (options[:gallery] != false),
77
+ :thumbnail_style => (options[:thumbnail] && options[:thumbnail][:style])
78
+ }
79
+ url_options.merge!({
80
+ :assetable_id => assetable_id,
81
+ :assetable_type => assetable_type.underscore,
82
+ }) if assetable
83
+ create_url = @template.url_for(url_options)
66
84
  if assetable && assetable.new_record? && !@timestamped
67
85
  html << @template.hidden_field(assetable.class.to_s.underscore, :timestamp, :value => assetable.timestamp)
68
86
  @timestamped = true
69
87
  end
88
+
89
+ conditions = {:assetable_type => assetable_type, :assetable_id => assetable_id}
90
+ conditions.merge!({:assetable_key => key.to_s}) if key
70
91
  collection = asset_class.find(:all, :conditions => conditions, :order => "position")
71
92
 
72
93
  html << %{<div style="height: #{options[:swfupload][:button_height]}px;"><span id="browse_for_#{id}" class="swf_button"></span></div>}
@@ -105,15 +126,15 @@ class ActionView::Helpers::FormBuilder
105
126
  include ActionView::Helpers::FormTagHelper
106
127
 
107
128
  def assets_upload(key = nil, options = {})
108
- papermill_upload_field_tag key, { :thumbnail => false }.update(options)
129
+ papermill_upload_tag key, { :thumbnail => false }.update(options)
109
130
  end
110
131
  def asset_upload(key = nil, options = {})
111
- papermill_upload_field_tag key, { :gallery => false, :thumbnail => false }.update(options)
132
+ papermill_upload_tag key, { :gallery => false, :thumbnail => false }.update(options)
112
133
  end
113
134
  def images_upload(key = nil, options = {})
114
- papermill_upload_field_tag key, options
135
+ papermill_upload_tag key, options
115
136
  end
116
137
  def image_upload(key = nil, options = {})
117
- papermill_upload_field_tag key, { :gallery => false }.update(options)
138
+ papermill_upload_tag key, { :gallery => false }.update(options)
118
139
  end
119
140
  end
@@ -4,7 +4,7 @@ require 'mime/types'
4
4
  require 'acts_as_list'
5
5
 
6
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}\''
7
+ acts_as_list :scope => 'assetable_key'
8
8
 
9
9
  belongs_to :assetable, :polymorphic => true
10
10
  before_destroy :destroy_files
@@ -55,11 +55,12 @@ module Papermill
55
55
  :prevent_swf_caching => "false"
56
56
  # See swfupload.js for details.
57
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..)
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 or associations may depend on it)
63
+ :base_association_name => 'assets',
63
64
  :alias_only => false, # set to true so that only aliases are authorized in url/path
64
65
  :aliases => {
65
66
  # "example" => "100x100#",
@@ -90,7 +91,7 @@ module Papermill
90
91
  # 1. generic declaration =>
91
92
  # declare associations with => papermill {my_option_hash}
92
93
  # create assets with => assets_upload(:my_key, {optional_option_hash})
93
- # access assets with => assetable.papermill_assets(:key => :my_key)
94
+ # access assets with => assetable.assets(:my_key)
94
95
  #
95
96
  # 2. association declaration =>
96
97
  # declare associations with => papermill :my_association, {my_option_hash}
@@ -103,40 +104,79 @@ module Papermill
103
104
  options = assoc_name
104
105
  assoc_name = :papermill_assets
105
106
  end
106
-
107
+ base_association_name = PAPERMILL_DEFAULTS[:base_association_name]
108
+ if [base_association_name.to_s.singularize, base_association_name.to_s].include?(assoc_name.to_s)
109
+ raise PapermillException.new(
110
+ "':#{assoc_name.to_s}' and ':#{assoc_name.to_s.singularize}' are the default papermill associations name.\n" +
111
+ "You can take one of these actions: \n" +
112
+ "1. use another association name instead of ':#{assoc_name.to_s}'. Eg: 'papermill :my_lovely_assets {my_options}'\n" +
113
+ "2. change :base_association_name to something else than '#{base_association_name.to_s}' in the application-wide papermill option hash (change 'Papermill::OPTIONS[:base_association_name]' in your environment.rb)\n" +
114
+ "3. use a catch-all 'papermill {your_options}' declaration instead of 'papermill :#{assoc_name.to_s} {your_options}'\n\n" +
115
+ "If you want to take advantage of pluralized/singularized associations, always specify a singularizable name. Eg: 'my_assets' is ok, 'my_assix' is not ;). \n" +
116
+ "(Anyway you can add exceptions in your config/initializer/inflections.rb)\n\n\n")
117
+ end
107
118
  @papermill_associations ||= {}
108
119
  begin
109
120
  class_name = options.delete(:class_name)
110
121
  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")
122
+ rescue NameError
123
+ raise PapermillException.new("'#{class_name.to_s}' class doesn't exist.\n'#{class_name.to_s}' should be a subclass of PapermillAsset")
113
124
  end
114
125
 
115
- @papermill_associations.merge!({assoc_name => {:class => asset_class, :options => Papermill::PAPERMILL_DEFAULTS.deep_merge(options)}})
126
+ @papermill_associations.merge!({assoc_name.to_sym => {:class => asset_class, :options => Papermill::PAPERMILL_DEFAULTS.deep_merge(options)}})
127
+
116
128
  before_destroy :destroy_assets
117
129
  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
130
+
131
+ # Defines for catch-all association :
132
+ # Assetable#assets(*options)
133
+ # Assetable#asset(*options)
134
+ unless self.respond_to?(base_association_name)
135
+ [base_association_name.to_s.singularize, base_association_name].each_with_index do |association, index|
136
+ define_method association do |*options|
137
+ # case Assetable#asset<s>(:key)
138
+ if (options.is_a?(Symbol) || options.is_a?(String))
139
+ key = options
140
+ options = {}
141
+ # case Assetable#asset<s>(:key, options = {})
142
+ elsif (options.first.is_a?(Symbol) || options.first.is_a?(String))
143
+ key = options.first
144
+ options = options[1..-1]
145
+ end
146
+ options = options.first || {}
147
+ conditions = {
148
+ :assetable_type => self.class.sti_name,
149
+ :assetable_id => self.id
150
+ }.merge(options.delete(:conditions) || {})
151
+ conditions.merge!({:assetable_key => key.to_s}) if key
152
+ hash = {
153
+ :conditions => conditions,
154
+ :order => options.delete(:order) || "position ASC"
155
+ }.merge(options)
156
+ PapermillAsset.find((index == 0 ? :first : :all), hash)
157
+ end
158
+ end
159
+ end
160
+
161
+ # Defines for declared association :
162
+ # Assetable#assoc.singularize(*options)
163
+ # Assetable#assoc(*options)
164
+ unless assoc_name.to_sym == :papermill_assets
165
+ [assoc_name.to_s.singularize, assoc_name.to_s].each_with_index do |association, index|
166
+ define_method assoc_name do |*options|
167
+ options = options.first || {}
168
+ conditions = {
169
+ :assetable_type => self.class.sti_name,
170
+ :assetable_id => self.id,
171
+ :assetable_key => assoc_name.to_s
172
+ }.merge(options.delete(:conditions) || {})
173
+ hash = {
174
+ :conditions => conditions,
175
+ :order => options.delete(:order) || "position ASC"
176
+ }.merge(options)
177
+ asset_class.find((index == 0 ? :first : :all), hash)
178
+ end
127
179
  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
180
  end
141
181
 
142
182
  class_eval <<-EOV
data/papermill.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{papermill}
8
- s.version = "0.7.0"
8
+ s.version = "0.8.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Benoit B\303\251n\303\251zech"]
12
- s.date = %q{2009-09-17}
12
+ s.date = %q{2009-09-23}
13
13
  s.description = %q{Paperclip Swfupload UploadHelper wrapper}
14
14
  s.email = %q{benoit.benezech@gmail.com}
15
15
  s.extra_rdoc_files = [
@@ -22,7 +22,7 @@
22
22
  .papermill-asset-container .progress { float:left; margin-top:6px; margin-left:5px; width:100px; }
23
23
  .papermill-asset-container .delete { float:left; margin-top:2px; margin-right:5px; }
24
24
 
25
- .papermill-asset-container.papermill-multiple-items { padding-left:10px; border-left:5px solid #EEE; min-height:40px; }
25
+ .papermill-asset-container.papermill-multiple-items { padding-left:10px; border-left:5px solid #EEE; min-height:44px; }
26
26
  .papermill-asset-container.papermill-multiple-items li { cursor:row-resize; }
27
27
  .papermill-thumb-container.papermill-multiple-items li { cursor:move; }
28
28
  .papermill-asset-container.papermill-unique-item { padding-left:5px; min-height:22px; }
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: papermill
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.0
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - "Benoit B\xC3\xA9n\xC3\xA9zech"
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-09-17 00:00:00 +02:00
12
+ date: 2009-09-23 00:00:00 +02:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency