trusty-clipped-extension 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. data/LICENSE +22 -0
  2. data/README.md +191 -0
  3. data/Rakefile +109 -0
  4. data/app/assets/flash/ZeroClipboard.swf +0 -0
  5. data/app/assets/images/admin/add.png +0 -0
  6. data/app/assets/images/admin/archive_icon.png +0 -0
  7. data/app/assets/images/admin/audio_icon.png +0 -0
  8. data/app/assets/images/admin/audio_thumbnail.png +0 -0
  9. data/app/assets/images/admin/c_icon.png +0 -0
  10. data/app/assets/images/admin/copy.png +0 -0
  11. data/app/assets/images/admin/css_icon.png +0 -0
  12. data/app/assets/images/admin/database_icon.png +0 -0
  13. data/app/assets/images/admin/delete.png +0 -0
  14. data/app/assets/images/admin/document_icon.png +0 -0
  15. data/app/assets/images/admin/document_thumbnail.png +0 -0
  16. data/app/assets/images/admin/flash_icon.png +0 -0
  17. data/app/assets/images/admin/flash_thumbnail.png +0 -0
  18. data/app/assets/images/admin/font_icon.png +0 -0
  19. data/app/assets/images/admin/gzip_icon.png +0 -0
  20. data/app/assets/images/admin/html_icon.png +0 -0
  21. data/app/assets/images/admin/image_icon.png +0 -0
  22. data/app/assets/images/admin/image_thumbnail.png +0 -0
  23. data/app/assets/images/admin/java_icon.png +0 -0
  24. data/app/assets/images/admin/page_edit.png +0 -0
  25. data/app/assets/images/admin/perl_icon.png +0 -0
  26. data/app/assets/images/admin/php_icon.png +0 -0
  27. data/app/assets/images/admin/presentation_icon.png +0 -0
  28. data/app/assets/images/admin/python_icon.png +0 -0
  29. data/app/assets/images/admin/reorder_assets.png +0 -0
  30. data/app/assets/images/admin/ruby_icon.png +0 -0
  31. data/app/assets/images/admin/script_icon.png +0 -0
  32. data/app/assets/images/admin/spreadsheet_icon.png +0 -0
  33. data/app/assets/images/admin/tar_icon.png +0 -0
  34. data/app/assets/images/admin/unknown_icon.png +0 -0
  35. data/app/assets/images/admin/unknown_thumbnail.png +0 -0
  36. data/app/assets/images/admin/video_icon.png +0 -0
  37. data/app/assets/images/admin/video_thumbnail.png +0 -0
  38. data/app/assets/images/admin/xml_icon.png +0 -0
  39. data/app/assets/images/admin/zip_icon.png +0 -0
  40. data/app/assets/javascripts/admin/assets.js +261 -0
  41. data/app/assets/javascripts/admin/jquery.fileupload.js +1457 -0
  42. data/app/assets/javascripts/admin/jquery.iframe-transport.js +214 -0
  43. data/app/assets/javascripts/admin/jquery.ui.widget.js +558 -0
  44. data/app/assets/javascripts/admin/prototype_assets.js +166 -0
  45. data/app/assets/stylesheets/admin/assets.sass +224 -0
  46. data/app/assets/stylesheets/application.scss +0 -0
  47. data/app/controllers/admin/assets_controller.rb +67 -0
  48. data/app/controllers/admin/page_attachments_controller.rb +18 -0
  49. data/app/helpers/admin/assets_helper.rb +16 -0
  50. data/app/helpers/admin/page_attachments_helper.rb +2 -0
  51. data/app/models/asset.rb +241 -0
  52. data/app/models/asset_type.rb +241 -0
  53. data/app/models/old_page_attachment.rb +26 -0
  54. data/app/models/page_attachment.rb +20 -0
  55. data/app/views/admin/assets/_asset.html.haml +12 -0
  56. data/app/views/admin/assets/_asset_table.html.haml +30 -0
  57. data/app/views/admin/assets/_errors.html.haml +3 -0
  58. data/app/views/admin/assets/_form.html.haml +21 -0
  59. data/app/views/admin/assets/_page_assets.html.haml +12 -0
  60. data/app/views/admin/assets/_search.html.haml +17 -0
  61. data/app/views/admin/assets/_search_results.html.haml +17 -0
  62. data/app/views/admin/assets/edit.html.haml +40 -0
  63. data/app/views/admin/assets/index.html.haml +16 -0
  64. data/app/views/admin/assets/new.html.haml +24 -0
  65. data/app/views/admin/assets/refresh.html.haml +14 -0
  66. data/app/views/admin/assets/remove.html.haml +16 -0
  67. data/app/views/admin/configuration/_clipped_edit.html.haml +8 -0
  68. data/app/views/admin/configuration/_clipped_show.html.haml +12 -0
  69. data/app/views/admin/page_attachments/_attachment.html.haml +25 -0
  70. data/app/views/admin/page_parts/_page_part.html.haml +21 -0
  71. data/app/views/admin/pages/_asset_popups.html.haml +56 -0
  72. data/app/views/admin/pages/_assets.html.haml +14 -0
  73. data/app/views/admin/removed/_assets_bucket.html.haml +8 -0
  74. data/app/views/admin/removed/_assets_container.html.haml +58 -0
  75. data/app/views/admin/removed/_bucket.html.haml +11 -0
  76. data/app/views/admin/removed/_bucket_asset.html.haml +9 -0
  77. data/app/views/admin/removed/_show_bucket_link.html.haml +4 -0
  78. data/app/views/admin/removed/_upload_to_page.html.haml +12 -0
  79. data/app/views/admin/removed/bucket/_iframe.html.haml +1 -0
  80. data/artwork/icons.png +0 -0
  81. data/clipped_extension.rb +53 -0
  82. data/config/initializers/interpolation.rb +6 -0
  83. data/config/initializers/processors.rb +43 -0
  84. data/config/initializers/radiant_config.rb +66 -0
  85. data/config/locales/de.yml +109 -0
  86. data/config/locales/en.yml +110 -0
  87. data/config/locales/nl.yml +107 -0
  88. data/config/locales/ru.yml +110 -0
  89. data/config/routes.rb +17 -0
  90. data/cucumber.yml +1 -0
  91. data/db/migrate/001_create_assets.rb +12 -0
  92. data/db/migrate/002_create_paperclip_attributes.rb +13 -0
  93. data/db/migrate/003_create_user_observer.rb +13 -0
  94. data/db/migrate/004_create_page_attachments.rb +19 -0
  95. data/db/migrate/005_rename_users.rb +13 -0
  96. data/db/migrate/20110513205050_asset_uuid.rb +11 -0
  97. data/db/migrate/20110606111250_update_configuration.rb +34 -0
  98. data/db/migrate/20110609101438_dimensions.rb +13 -0
  99. data/features/support/env.rb +11 -0
  100. data/features/support/paths.rb +22 -0
  101. data/lib/asset_tags.rb +346 -0
  102. data/lib/clipped/engine.rb +5 -0
  103. data/lib/clipped_admin_ui.rb +32 -0
  104. data/lib/cloud.rb +41 -0
  105. data/lib/generators/templates/clipped_config.rb +53 -0
  106. data/lib/page_asset_associations.rb +13 -0
  107. data/lib/paperclip/frame_grab.rb +73 -0
  108. data/lib/paperclip/geometry_transformation.rb +80 -0
  109. data/lib/tasks/clipped_extension_tasks.rake +124 -0
  110. data/lib/tasks/paperclip_tasks.rake +79 -0
  111. data/lib/trusty-clipped-extension.rb +8 -0
  112. data/spec/ci/before_script +23 -0
  113. data/spec/ci/script +2 -0
  114. data/spec/controllers/admin/assets_controller_spec.rb +50 -0
  115. data/spec/controllers/admin/page_attachments_controller_spec.rb +50 -0
  116. data/spec/datasets/assets_dataset.rb +36 -0
  117. data/spec/fixtures/5k.png +0 -0
  118. data/spec/fixtures/test.flv +0 -0
  119. data/spec/lib/asset_tags_spec.rb +107 -0
  120. data/spec/lib/frame_grab_spec.rb +17 -0
  121. data/spec/lib/geometry_transformation_spec.rb +63 -0
  122. data/spec/models/asset_spec.rb +72 -0
  123. data/spec/models/asset_type_spec.rb +70 -0
  124. data/spec/models/post_processing_spec.rb +62 -0
  125. data/spec/spec.opts +7 -0
  126. data/spec/spec_helper.rb +36 -0
  127. data/trusty-clipped-extension.gemspec +29 -0
  128. data/wireframes/edit-page-assets-2.bmml +453 -0
  129. data/wireframes/edit-page-assets-2.png +0 -0
  130. data/wireframes/edit-page-assets-3.bmml +454 -0
  131. data/wireframes/edit-page-assets-3.png +0 -0
  132. data/wireframes/edit-page-assets.bmml +433 -0
  133. data/wireframes/edit-page-assets.png +0 -0
  134. data/wireframes/edit-page.bmml +174 -0
  135. data/wireframes/edit-page.png +0 -0
  136. metadata +265 -0
@@ -0,0 +1,18 @@
1
+ class Admin::PageAttachmentsController < Admin::ResourceController
2
+ helper 'admin/assets'
3
+
4
+ def new
5
+ render :partial => 'attachment', :object => model
6
+ end
7
+
8
+ def load_model
9
+ begin
10
+ @asset = Asset.find(params[:asset_id])
11
+ @page = params[:page_id].blank? ? Page.new : Page.find_by_id(params[:page_id])
12
+ rescue ActiveRecord::RecordNotFound
13
+ render :nothing => true, :layout => false
14
+ end
15
+ self.model = PageAttachment.new(:asset => @asset, :page => @page)
16
+ end
17
+
18
+ end
@@ -0,0 +1,16 @@
1
+ module Admin::AssetsHelper
2
+
3
+ def automatic_size_descriptions
4
+ Asset.thumbnail_sizes.collect{|k,v| "#{k} (#{(v.to_s).match(/\d+x\d+/)})"}.join(', ')
5
+ end
6
+
7
+ def asset_insertion_link(asset)
8
+ radius_tag = asset.asset_type.default_radius_tag || 'link';
9
+ link_to t('clipped_extension.insert'), '#', :class => 'insert_asset', :rel => "#{radius_tag}_#{TrustyCms.config['assets.insertion_size']}_#{asset.id}"
10
+ end
11
+
12
+ def asset_attachment_link(asset)
13
+ link_to t("clipped_extension.attach"), new_admin_page_attachment_path(:asset_id => asset.id), :class => 'attach_asset', :rel => "attach_#{asset.id}"
14
+ end
15
+
16
+ end
@@ -0,0 +1,2 @@
1
+ module Admin::PageAttachmentsHelper
2
+ end
@@ -0,0 +1,241 @@
1
+ class Asset < ActiveRecord::Base
2
+ include Paperclip::Glue
3
+
4
+ has_many :page_attachments, :dependent => :destroy
5
+ has_many :pages, :through => :page_attachments
6
+ has_site if respond_to? :has_site
7
+
8
+ belongs_to :created_by, :class_name => 'User'
9
+ belongs_to :updated_by, :class_name => 'User'
10
+
11
+ default_scope :order => "created_at DESC"
12
+
13
+ scope :latest, lambda { |limit|
14
+ { :order => "created_at DESC", :limit => limit }
15
+ }
16
+
17
+ scope :of_types, lambda { |types|
18
+ mimes = AssetType.slice(*types).map(&:mime_types).flatten
19
+ { :conditions => ["asset_content_type IN (#{mimes.map{'?'}.join(',')})", *mimes] }
20
+ }
21
+
22
+ scope :matching, lambda { |term|
23
+ { :conditions => ["LOWER(assets.asset_file_name) LIKE (:term) OR LOWER(title) LIKE (:term) OR LOWER(caption) LIKE (:term)", {:term => "%#{term.downcase}%" }] }
24
+ }
25
+
26
+ scope :except, lambda { |assets|
27
+ if assets.any?
28
+ assets = assets.split(',') if assets.is_a?(String)
29
+ asset_ids = assets.first.is_a?(Asset) ? assets.map(&:id) : assets
30
+ { :conditions => ["assets.id NOT IN(#{asset_ids.map{ '?' }.join(',')})", *asset_ids] }
31
+ else
32
+ {}
33
+ end
34
+ }
35
+
36
+ has_attached_file :asset,
37
+ :styles => lambda { |attachment|
38
+ AssetType.for(attachment).paperclip_styles
39
+ },
40
+ :processors => lambda { |asset|
41
+ asset.paperclip_processors
42
+ },
43
+ :whiny => false,
44
+ :storage => TrustyCms.config["paperclip.storage"],
45
+ :path => TrustyCms.config["paperclip.path"],
46
+ :url => TrustyCms.config["paperclip.url"],
47
+ :fog_credentials => TrustyCmsClippedExtension::Cloud.credentials,
48
+ :fog_directory => TrustyCms.config["paperclip.fog.directory"],
49
+ :fog_public => TrustyCms.config["paperclip.fog.public?"] || true,
50
+ :fog_host => TrustyCmsClippedExtension::Cloud.host
51
+
52
+ validates_attachment_content_type :asset, :content_type => ["image/jpg", "image/jpeg", "image/png", "image/gif", "application/pdf", "application/javascript", "text/javascript", "text/css"]
53
+
54
+ before_save :assign_title
55
+ before_save :assign_uuid
56
+
57
+ after_post_process :read_dimensions
58
+
59
+ validates_attachment_presence :asset, :message => "You must choose a file to upload!"
60
+ if TrustyCms.config["paperclip.skip_filetype_validation"] != "true" && TrustyCms.config['paperclip.content_types']
61
+ validates_attachment_content_type :asset, :content_type => TrustyCms.config["paperclip.content_types"].gsub(' ','').split(',')
62
+ end
63
+ validates_attachment_size :asset, :less_than => ( TrustyCms.config["assets.max_asset_size"] || 5 ).to_i.megabytes
64
+
65
+ def asset_type
66
+ AssetType.for(asset)
67
+ end
68
+ delegate :paperclip_processors, :paperclip_styles, :style_dimensions, :style_format, :to => :asset_type
69
+
70
+ def thumbnail(style_name='original')
71
+ return asset.url if style_name.to_sym == :original
72
+ return asset.url(style_name.to_sym) if has_style?(style_name)
73
+ return asset_type.icon(style_name)
74
+ end
75
+
76
+ def has_style?(style_name='original')
77
+ style_name == 'original' || paperclip_styles.keys.include?(style_name.to_sym)
78
+ end
79
+
80
+ def basename
81
+ File.basename(asset_file_name, ".*") if asset_file_name
82
+ end
83
+
84
+ def extension(style_name='original')
85
+ if style_name == 'original'
86
+ return original_extension
87
+ elsif style = paperclip_styles[style_name.to_sym]
88
+ return style.format
89
+ else
90
+ return original_extension
91
+ end
92
+ end
93
+
94
+ def original_extension
95
+ return asset_file_name.split('.').last.downcase if asset_file_name
96
+ end
97
+
98
+ def attached_to?(page)
99
+ pages.include?(page)
100
+ end
101
+
102
+ def original_geometry
103
+ @original_geometry ||= Paperclip::Geometry.new(original_width, original_height)
104
+ end
105
+
106
+ def geometry(style_name='original')
107
+ raise Paperclip::StyleError, "Requested style #{style_name} is not defined for this asset." unless has_style?(style_name)
108
+ @geometry ||= {}
109
+ begin
110
+ @geometry[style_name] ||= if style_name.to_s == 'original'
111
+ original_geometry
112
+ else
113
+ style = self.asset.styles[style_name.to_sym]
114
+ original_geometry.transformed_by(style.geometry) # this can return dimensions for fully specified style sizes but not for relative sizes when there are no original dimensions
115
+ end
116
+ rescue Paperclip::TransformationError => e
117
+ Rails.logger.warn "geometry transformation error: #{e}"
118
+ original_geometry # returns a blank geometry if the real geometry cannot be calculated
119
+ end
120
+ end
121
+
122
+ def aspect(style_name='original')
123
+ geometry(style_name).aspect
124
+ end
125
+
126
+ def orientation(style_name='original')
127
+ a = aspect(style_name)
128
+ case
129
+ when a == nil?
130
+ 'unknown'
131
+ when a < 1.0
132
+ 'vertical'
133
+ when a > 1.0
134
+ 'horizontal'
135
+ else
136
+ 'square'
137
+ end
138
+ end
139
+
140
+ def width(style_name='original')
141
+ geometry(style_name).width.to_i
142
+ end
143
+
144
+ def height(style_name='original')
145
+ geometry(style_name).height.to_i
146
+ end
147
+
148
+ def square?(style_name='original')
149
+ geometry(style_name).square?
150
+ end
151
+
152
+ def vertical?(style_name='original')
153
+ geometry(style_name).vertical?
154
+ end
155
+
156
+ def horizontal?(style_name='original')
157
+ geometry(style_name).horizontal?
158
+ end
159
+
160
+ def dimensions_known?
161
+ original_width? && original_height?
162
+ end
163
+
164
+ private
165
+
166
+ # at this point the file queue will not have been written
167
+ # but the upload should be in place. We read dimensions from the
168
+ # original file and calculate thumbnail dimensions later, on demand.
169
+
170
+ def read_dimensions
171
+ if image?
172
+ if file = asset.queued_for_write[:original]
173
+ geometry = Paperclip::Geometry.from_file(file)
174
+ self.original_width = geometry.width
175
+ self.original_height = geometry.height
176
+ self.original_extension = File.extname(file.path)
177
+ end
178
+ end
179
+ true
180
+ end
181
+
182
+ def assign_title
183
+ self.title = basename unless title?
184
+ end
185
+
186
+ def assign_uuid
187
+ self.uuid = UUIDTools::UUID.timestamp_create.to_s unless uuid?
188
+ end
189
+
190
+ class << self
191
+ def known_types
192
+ AssetType.known_types
193
+ end
194
+
195
+ # searching and pagination moved to the controller
196
+
197
+ def find_all_by_asset_types(asset_types, *args)
198
+ with_asset_types(asset_types) { where *args }
199
+ end
200
+
201
+ def count_with_asset_types(asset_types, *args)
202
+ with_asset_types(asset_types) { where(*args).count }
203
+ end
204
+
205
+ def with_asset_types(asset_types, &block)
206
+ with_scope(where(AssetType.conditions_for(asset_types)), &block)
207
+ end
208
+ end
209
+
210
+ # called from AssetType to set type_condition? methods on Asset
211
+ def self.define_class_method(name, &block)
212
+ eigenclass.send :define_method, name, &block
213
+ end
214
+
215
+ # returns the return value of class << self block, which is self (as defined within that block)
216
+ def self.eigenclass
217
+ class << self; self; end
218
+ end
219
+
220
+ # for backwards compatibility
221
+ def self.thumbnail_sizes
222
+ AssetType.find(:image).paperclip_styles
223
+ end
224
+
225
+ def self.thumbnail_names
226
+ thumbnail_sizes.keys
227
+ end
228
+
229
+ # this is a convenience for image-pickers
230
+ def self.thumbnail_options
231
+ asset_sizes = thumbnail_sizes.collect{|k,v|
232
+ size_id = k
233
+ size_description = "#{k}: "
234
+ size_description << (v.is_a?(Array) ? v.join(' as ') : v)
235
+ [size_description, size_id]
236
+ }.sort_by{|pair| pair.last.to_s}
237
+ asset_sizes.unshift ['Original (as uploaded)', 'original']
238
+ asset_sizes
239
+ end
240
+
241
+ end
@@ -0,0 +1,241 @@
1
+ class AssetType
2
+
3
+ # The Asset Type encapsulates a type of attachment.
4
+ # Conventionally this would a sensible category like 'image' or 'video'
5
+ # that should be processed and presented in a particular way.
6
+ # An AssetType currently provides:
7
+ # * processor definitions for paperclip
8
+ # * styles definitions for paperclip
9
+ # * mime type list for file recognition
10
+ # * selectors and scopes for retrieving this (or not this) category of asset
11
+ # * radius tags for those subsets of assets (temporarily removed pending discussion of interface)
12
+
13
+ @@types = []
14
+ @@type_lookup = {}
15
+ @@extension_lookup = {}
16
+ @@mime_lookup = {}
17
+ @@default_type = nil
18
+ attr_reader :name, :processors, :styles, :icon_name, :catchall, :default_radius_tag
19
+
20
+ def initialize(name, options = {})
21
+ options = options.symbolize_keys
22
+ @name = name
23
+ @icon_name = options[:icon] || name
24
+ @processors = options[:processors] || []
25
+ @styles = options[:styles] || {}
26
+ @styles = standard_styles if @styles == :standard
27
+ @default_radius_tag = options[:default_radius_tag] || 'link'
28
+ @extensions = options[:extensions] || []
29
+ @extensions.each { |ext| @@extension_lookup[ext] ||= self }
30
+ @mimes = options[:mime_types] || []
31
+ @mimes.each { |mimetype| @@mime_lookup[mimetype] ||= self }
32
+
33
+ this = self
34
+ Asset.send :define_method, "#{name}?".intern do this.mime_types.include?(asset_content_type) end
35
+ Asset.send :define_class_method, "#{name}_condition".intern do this.condition; end
36
+ Asset.send :define_class_method, "not_#{name}_condition".intern do this.non_condition; end
37
+ Asset.send :scope, plural.to_sym, :conditions => condition
38
+ Asset.send :scope, "not_#{plural}".to_sym, :conditions => non_condition
39
+
40
+ self.define_radius_tags
41
+ @@types.push self
42
+ @@type_lookup[@name] = self
43
+ end
44
+
45
+ def plural
46
+ name.to_s.pluralize
47
+ end
48
+
49
+ def icon(style_name='icon')
50
+ if File.exist?(Rails.root + "public/images/admin/assets/#{icon_name}_#{style_name.to_s}.png")
51
+ return "/images/admin/assets/#{icon_name}_#{style_name.to_s}.png"
52
+ else
53
+ return "/images/admin/assets/#{icon_name}_icon.png"
54
+ end
55
+ end
56
+
57
+ def icon_path(style_name='icon')
58
+ Rails.root + "public#{icon(style_name)}"
59
+ end
60
+
61
+ def condition
62
+ if @mimes.any?
63
+ ["asset_content_type IN (#{@mimes.map{'?'}.join(',')})", *@mimes]
64
+ else
65
+ self.class.other_condition
66
+ end
67
+ end
68
+
69
+ def sanitized_condition
70
+ ActiveRecord::Base.send :sanitize_sql_array, condition
71
+ end
72
+
73
+ def non_condition
74
+ if @mimes.any?
75
+ ["NOT asset_content_type IN (#{@mimes.map{'?'}.join(',')})", *@mimes]
76
+ else
77
+ self.class.non_other_condition
78
+ end
79
+ end
80
+
81
+ def sanitized_non_condition
82
+ ActiveRecord::Base.send :sanitize_sql_array, non_condition
83
+ end
84
+
85
+ def mime_types
86
+ @mimes
87
+ end
88
+
89
+ def paperclip_processors
90
+ TrustyCms.config["assets.create_#{name}_thumbnails?"] ? processors : []
91
+ end
92
+
93
+ # Parses and combines the various ways in which paperclip styles can be defined, and normalises them into
94
+ # the format that paperclip expects. Note that :styles => :standard has already been replaced with the
95
+ # results of a call to standard_styles.
96
+ # Styles are passed to paperclip as a hash and arbitrary keys can be passed through from configuration.
97
+ #
98
+ def paperclip_styles
99
+ # Styles are not relevant if processors are not defined.
100
+ # TODO: should this default to an icon set?
101
+ @paperclip_styles ||= if paperclip_processors.any?
102
+ normalize_style_rules(configured_styles.merge(styles))
103
+ else
104
+ {}
105
+ end
106
+ @paperclip_styles
107
+ end
108
+
109
+ # Takes a motley collection of differently-defined styles and renders them into the standard hash-of-hashes format.
110
+ # Solitary strings are assumed to be
111
+ #TODO: define permitted and/or expected options for the asset type and pass through that subset of the style-definition hash
112
+ #
113
+ def normalize_style_rules(styles={})
114
+ styles.each_pair do |name, rule|
115
+ unless rule.is_a? Hash
116
+ if rule =~ /\=/
117
+ parameters = rule.split(',').collect{ |parameter| parameter.split('=') } # array of pairs
118
+ rule = Hash[parameters].symbolize_keys # into hash of :first => last
119
+ else
120
+ rule = {:geometry => rule} # simplest case: name:geom|name:geom
121
+ end
122
+ end
123
+ rule[:geometry] ||= rule.delete(:size)
124
+ styles[name.to_sym] = rule
125
+ end
126
+ styles
127
+ end
128
+
129
+ def standard_styles
130
+ {
131
+ :native => { :geometry => "", :format => :jpg },
132
+ :icon => { :geometry => '42x42#', :format => :png },
133
+ :thumbnail => { :geometry => '100x100#', :format => :png }
134
+ }
135
+ end
136
+
137
+ # Paperclip styles are defined in the config entry `assets.thumbnails.asset_type`, with the format:
138
+ # foo:key-x,key=y,key=z|bar:key-x,key=y,key=z
139
+ # where 'key' can be any parameter understood by your paperclip processors. Usually they include :geometry and :format.
140
+ # A typical entry would be:
141
+ #
142
+ # standard:geometry=640x640>,format=jpg
143
+ #
144
+ # This method parses that string and returns the defined styles as a hash of style-defining strings that will later be normalized into hashes.
145
+ #
146
+ def configured_styles
147
+ @configured_styles ||= if style_definitions = TrustyCms.config["assets.thumbnails.#{name}"]
148
+ style_definitions.split('|').each_with_object({}) do |definition, styles|
149
+ name, rule = definition.split(':')
150
+ styles[name.strip.to_sym] = rule.to_s.strip
151
+ end
152
+ else
153
+ {}
154
+ end
155
+ end
156
+
157
+ def legacy_styles
158
+ TrustyCms::config["assets.additional_thumbnails"].to_s.gsub(' ','').split(',').collect{|s| s.split('=')}.inject({}) {|ha, (k, v)| ha[k.to_sym] = v; ha}
159
+ end
160
+
161
+ def style_dimensions(style_name)
162
+ if style = paperclip_styles[style_name.to_sym]
163
+ style[:size]
164
+ end
165
+ end
166
+
167
+ def define_radius_tags
168
+ type = self.name
169
+ Page.class_eval {
170
+ tag "asset:if_#{type}" do |tag|
171
+ tag.expand if find_asset(tag, tag.attr.dup).send("#{type}?".to_sym)
172
+ end
173
+ tag "asset:unless_#{type}" do |tag|
174
+ tag.expand unless find_asset(tag, tag.attr.dup).send("#{type}?".to_sym)
175
+ end
176
+ }
177
+ end
178
+
179
+ # class methods
180
+
181
+ def self.for(attachment)
182
+ extension = File.extname(attachment.original_filename).sub(/^\.+/, "")
183
+ from_extension(extension) || from_mimetype(attachment.instance_read(:content_type)) || catchall
184
+ end
185
+
186
+ def self.from_extension(extension)
187
+ @@extension_lookup[extension]
188
+ end
189
+
190
+ def self.from_mimetype(mimetype)
191
+ @@mime_lookup[mimetype]
192
+ end
193
+
194
+ def self.catchall
195
+ @@default_type ||= self.find(:other)
196
+ end
197
+
198
+ def self.known?(name)
199
+ !self.find(name).nil?
200
+ end
201
+
202
+ def self.slice(*types)
203
+ @@type_lookup.slice(*types.map(&:to_sym)).values if types # Hash#slice is provided by will_paginate
204
+ end
205
+
206
+ def self.find(type)
207
+ @@type_lookup[type] if type
208
+ end
209
+ def self.[](type)
210
+ find(type)
211
+ end
212
+
213
+ def self.all
214
+ @@types
215
+ end
216
+
217
+ def self.known_types
218
+ @@types.map(&:name) # to preserve order
219
+ end
220
+
221
+ def self.known_mimetypes
222
+ @@mime_lookup.keys
223
+ end
224
+
225
+ def self.mime_types_for(*names)
226
+ names.collect{ |name| find(name).mime_types }.flatten
227
+ end
228
+
229
+ def self.conditions_for(*names)
230
+ names.collect{ |name| self.find(name).sanitized_condition }.join(' OR ')
231
+ end
232
+
233
+ def self.non_other_condition
234
+ ["asset_content_type IN (#{known_mimetypes.map{'?'}.join(',')})", *known_mimetypes]
235
+ end
236
+
237
+ def self.other_condition
238
+ ["NOT asset_content_type IN (#{known_mimetypes.map{'?'}.join(',')})", *known_mimetypes]
239
+ end
240
+
241
+ end