trusty-clipped-extension 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +22 -0
- data/README.md +191 -0
- data/Rakefile +109 -0
- data/app/assets/flash/ZeroClipboard.swf +0 -0
- data/app/assets/images/admin/add.png +0 -0
- data/app/assets/images/admin/archive_icon.png +0 -0
- data/app/assets/images/admin/audio_icon.png +0 -0
- data/app/assets/images/admin/audio_thumbnail.png +0 -0
- data/app/assets/images/admin/c_icon.png +0 -0
- data/app/assets/images/admin/copy.png +0 -0
- data/app/assets/images/admin/css_icon.png +0 -0
- data/app/assets/images/admin/database_icon.png +0 -0
- data/app/assets/images/admin/delete.png +0 -0
- data/app/assets/images/admin/document_icon.png +0 -0
- data/app/assets/images/admin/document_thumbnail.png +0 -0
- data/app/assets/images/admin/flash_icon.png +0 -0
- data/app/assets/images/admin/flash_thumbnail.png +0 -0
- data/app/assets/images/admin/font_icon.png +0 -0
- data/app/assets/images/admin/gzip_icon.png +0 -0
- data/app/assets/images/admin/html_icon.png +0 -0
- data/app/assets/images/admin/image_icon.png +0 -0
- data/app/assets/images/admin/image_thumbnail.png +0 -0
- data/app/assets/images/admin/java_icon.png +0 -0
- data/app/assets/images/admin/page_edit.png +0 -0
- data/app/assets/images/admin/perl_icon.png +0 -0
- data/app/assets/images/admin/php_icon.png +0 -0
- data/app/assets/images/admin/presentation_icon.png +0 -0
- data/app/assets/images/admin/python_icon.png +0 -0
- data/app/assets/images/admin/reorder_assets.png +0 -0
- data/app/assets/images/admin/ruby_icon.png +0 -0
- data/app/assets/images/admin/script_icon.png +0 -0
- data/app/assets/images/admin/spreadsheet_icon.png +0 -0
- data/app/assets/images/admin/tar_icon.png +0 -0
- data/app/assets/images/admin/unknown_icon.png +0 -0
- data/app/assets/images/admin/unknown_thumbnail.png +0 -0
- data/app/assets/images/admin/video_icon.png +0 -0
- data/app/assets/images/admin/video_thumbnail.png +0 -0
- data/app/assets/images/admin/xml_icon.png +0 -0
- data/app/assets/images/admin/zip_icon.png +0 -0
- data/app/assets/javascripts/admin/assets.js +261 -0
- data/app/assets/javascripts/admin/jquery.fileupload.js +1457 -0
- data/app/assets/javascripts/admin/jquery.iframe-transport.js +214 -0
- data/app/assets/javascripts/admin/jquery.ui.widget.js +558 -0
- data/app/assets/javascripts/admin/prototype_assets.js +166 -0
- data/app/assets/stylesheets/admin/assets.sass +224 -0
- data/app/assets/stylesheets/application.scss +0 -0
- data/app/controllers/admin/assets_controller.rb +67 -0
- data/app/controllers/admin/page_attachments_controller.rb +18 -0
- data/app/helpers/admin/assets_helper.rb +16 -0
- data/app/helpers/admin/page_attachments_helper.rb +2 -0
- data/app/models/asset.rb +241 -0
- data/app/models/asset_type.rb +241 -0
- data/app/models/old_page_attachment.rb +26 -0
- data/app/models/page_attachment.rb +20 -0
- data/app/views/admin/assets/_asset.html.haml +12 -0
- data/app/views/admin/assets/_asset_table.html.haml +30 -0
- data/app/views/admin/assets/_errors.html.haml +3 -0
- data/app/views/admin/assets/_form.html.haml +21 -0
- data/app/views/admin/assets/_page_assets.html.haml +12 -0
- data/app/views/admin/assets/_search.html.haml +17 -0
- data/app/views/admin/assets/_search_results.html.haml +17 -0
- data/app/views/admin/assets/edit.html.haml +40 -0
- data/app/views/admin/assets/index.html.haml +16 -0
- data/app/views/admin/assets/new.html.haml +24 -0
- data/app/views/admin/assets/refresh.html.haml +14 -0
- data/app/views/admin/assets/remove.html.haml +16 -0
- data/app/views/admin/configuration/_clipped_edit.html.haml +8 -0
- data/app/views/admin/configuration/_clipped_show.html.haml +12 -0
- data/app/views/admin/page_attachments/_attachment.html.haml +25 -0
- data/app/views/admin/page_parts/_page_part.html.haml +21 -0
- data/app/views/admin/pages/_asset_popups.html.haml +56 -0
- data/app/views/admin/pages/_assets.html.haml +14 -0
- data/app/views/admin/removed/_assets_bucket.html.haml +8 -0
- data/app/views/admin/removed/_assets_container.html.haml +58 -0
- data/app/views/admin/removed/_bucket.html.haml +11 -0
- data/app/views/admin/removed/_bucket_asset.html.haml +9 -0
- data/app/views/admin/removed/_show_bucket_link.html.haml +4 -0
- data/app/views/admin/removed/_upload_to_page.html.haml +12 -0
- data/app/views/admin/removed/bucket/_iframe.html.haml +1 -0
- data/artwork/icons.png +0 -0
- data/clipped_extension.rb +53 -0
- data/config/initializers/interpolation.rb +6 -0
- data/config/initializers/processors.rb +43 -0
- data/config/initializers/radiant_config.rb +66 -0
- data/config/locales/de.yml +109 -0
- data/config/locales/en.yml +110 -0
- data/config/locales/nl.yml +107 -0
- data/config/locales/ru.yml +110 -0
- data/config/routes.rb +17 -0
- data/cucumber.yml +1 -0
- data/db/migrate/001_create_assets.rb +12 -0
- data/db/migrate/002_create_paperclip_attributes.rb +13 -0
- data/db/migrate/003_create_user_observer.rb +13 -0
- data/db/migrate/004_create_page_attachments.rb +19 -0
- data/db/migrate/005_rename_users.rb +13 -0
- data/db/migrate/20110513205050_asset_uuid.rb +11 -0
- data/db/migrate/20110606111250_update_configuration.rb +34 -0
- data/db/migrate/20110609101438_dimensions.rb +13 -0
- data/features/support/env.rb +11 -0
- data/features/support/paths.rb +22 -0
- data/lib/asset_tags.rb +346 -0
- data/lib/clipped/engine.rb +5 -0
- data/lib/clipped_admin_ui.rb +32 -0
- data/lib/cloud.rb +41 -0
- data/lib/generators/templates/clipped_config.rb +53 -0
- data/lib/page_asset_associations.rb +13 -0
- data/lib/paperclip/frame_grab.rb +73 -0
- data/lib/paperclip/geometry_transformation.rb +80 -0
- data/lib/tasks/clipped_extension_tasks.rake +124 -0
- data/lib/tasks/paperclip_tasks.rake +79 -0
- data/lib/trusty-clipped-extension.rb +8 -0
- data/spec/ci/before_script +23 -0
- data/spec/ci/script +2 -0
- data/spec/controllers/admin/assets_controller_spec.rb +50 -0
- data/spec/controllers/admin/page_attachments_controller_spec.rb +50 -0
- data/spec/datasets/assets_dataset.rb +36 -0
- data/spec/fixtures/5k.png +0 -0
- data/spec/fixtures/test.flv +0 -0
- data/spec/lib/asset_tags_spec.rb +107 -0
- data/spec/lib/frame_grab_spec.rb +17 -0
- data/spec/lib/geometry_transformation_spec.rb +63 -0
- data/spec/models/asset_spec.rb +72 -0
- data/spec/models/asset_type_spec.rb +70 -0
- data/spec/models/post_processing_spec.rb +62 -0
- data/spec/spec.opts +7 -0
- data/spec/spec_helper.rb +36 -0
- data/trusty-clipped-extension.gemspec +29 -0
- data/wireframes/edit-page-assets-2.bmml +453 -0
- data/wireframes/edit-page-assets-2.png +0 -0
- data/wireframes/edit-page-assets-3.bmml +454 -0
- data/wireframes/edit-page-assets-3.png +0 -0
- data/wireframes/edit-page-assets.bmml +433 -0
- data/wireframes/edit-page-assets.png +0 -0
- data/wireframes/edit-page.bmml +174 -0
- data/wireframes/edit-page.png +0 -0
- 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
|
data/app/models/asset.rb
ADDED
@@ -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
|