Class: AssetType

Inherits:
Object
  • Object
show all
Defined in:
app/models/asset_type.rb

Constant Summary collapse

@@types =

The Asset Type encapsulates a type of attachment. Conventionally this would a sensible category like ‘image’ or ‘video’ that should be processed and presented in a particular way. An AssetType currently provides:

* processor definitions for paperclip
* styles definitions for paperclip
* mime type list for file recognition
* selectors and scopes for retrieving this (or not this) category of asset
* radius tags for those subsets of assets (temporarily removed pending discussion of interface)
[]
@@type_lookup =
{}
@@extension_lookup =
{}
@@mime_lookup =
{}
@@default_type =
nil

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name, options = {}) ⇒ AssetType

Returns a new instance of AssetType.



20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
# File 'app/models/asset_type.rb', line 20

def initialize(name, options = {})
  options = options.symbolize_keys
  @name = name
  @icon_name = options[:icon] || name
  @processors = options[:processors] || []
  @styles = options[:styles] || {}
  @styles = standard_styles if @styles == :standard
  @default_radius_tag = options[:default_radius_tag] || 'link'
  @extensions = options[:extensions] || []
  @extensions.each { |ext| @@extension_lookup[ext] ||= self }
  @mimes = options[:mime_types] || []
  @mimes.each { |mimetype| @@mime_lookup[mimetype] ||= self }

  this = self
  Asset.send :define_method, "#{name}?".intern do this.mime_types.include?(asset_content_type) end 
  Asset.send :define_class_method, "#{name}_condition".intern do this.condition; end
  Asset.send :define_class_method, "not_#{name}_condition".intern do this.non_condition; end
  Asset.send :named_scope, plural.to_sym, :conditions => condition
  Asset.send :named_scope, "not_#{plural}".to_sym, :conditions => non_condition
  
  self.define_radius_tags
  @@types.push self
  @@type_lookup[@name] = self
end

Instance Attribute Details

#catchallObject (readonly)

Returns the value of attribute catchall.



18
19
20
# File 'app/models/asset_type.rb', line 18

def catchall
  @catchall
end

#default_radius_tagObject (readonly)

Returns the value of attribute default_radius_tag.



18
19
20
# File 'app/models/asset_type.rb', line 18

def default_radius_tag
  @default_radius_tag
end

#icon_nameObject (readonly)

Returns the value of attribute icon_name.



18
19
20
# File 'app/models/asset_type.rb', line 18

def icon_name
  @icon_name
end

#nameObject (readonly)

Returns the value of attribute name.



18
19
20
# File 'app/models/asset_type.rb', line 18

def name
  @name
end

#processorsObject (readonly)

Returns the value of attribute processors.



18
19
20
# File 'app/models/asset_type.rb', line 18

def processors
  @processors
end

#stylesObject (readonly)

Returns the value of attribute styles.



18
19
20
# File 'app/models/asset_type.rb', line 18

def styles
  @styles
end

Class Method Details

.[](type) ⇒ Object



209
210
211
# File 'app/models/asset_type.rb', line 209

def self.[](type)
  find(type)
end

.allObject



213
214
215
# File 'app/models/asset_type.rb', line 213

def self.all
  @@types
end

.catchallObject



194
195
196
# File 'app/models/asset_type.rb', line 194

def self.catchall
  @@default_type ||= self.find(:other)
end

.conditions_for(*names) ⇒ Object



229
230
231
# File 'app/models/asset_type.rb', line 229

def self.conditions_for(*names)
  names.collect{ |name| self.find(name).sanitized_condition }.join(' OR ')
end

.find(type) ⇒ Object



206
207
208
# File 'app/models/asset_type.rb', line 206

def self.find(type)
  @@type_lookup[type] if type
end

.for(attachment) ⇒ Object

class methods



181
182
183
184
# File 'app/models/asset_type.rb', line 181

def self.for(attachment)
  extension = File.extname(attachment.original_filename).sub(/^\.+/, "")
  from_extension(extension) || from_mimetype(attachment.instance_read(:content_type)) || catchall
end

.from_extension(extension) ⇒ Object



186
187
188
# File 'app/models/asset_type.rb', line 186

def self.from_extension(extension)
  @@extension_lookup[extension]
end

.from_mimetype(mimetype) ⇒ Object



190
191
192
# File 'app/models/asset_type.rb', line 190

def self.from_mimetype(mimetype)
  @@mime_lookup[mimetype]
end

.known?(name) ⇒ Boolean

Returns:

  • (Boolean)


198
199
200
# File 'app/models/asset_type.rb', line 198

def self.known?(name)
  !self.find(name).nil?
end

.known_mimetypesObject



221
222
223
# File 'app/models/asset_type.rb', line 221

def self.known_mimetypes
  @@mime_lookup.keys
end

.known_typesObject



217
218
219
# File 'app/models/asset_type.rb', line 217

def self.known_types
  @@types.map(&:name) # to preserve order
end

.mime_types_for(*names) ⇒ Object



225
226
227
# File 'app/models/asset_type.rb', line 225

def self.mime_types_for(*names)
  names.collect{ |name| find(name).mime_types }.flatten
end

.non_other_conditionObject



233
234
235
# File 'app/models/asset_type.rb', line 233

def self.non_other_condition
  ["asset_content_type IN (#{known_mimetypes.map{'?'}.join(',')})", *known_mimetypes]
end

.other_conditionObject



237
238
239
# File 'app/models/asset_type.rb', line 237

def self.other_condition
  ["NOT asset_content_type IN (#{known_mimetypes.map{'?'}.join(',')})", *known_mimetypes]
end

.slice(*types) ⇒ Object



202
203
204
# File 'app/models/asset_type.rb', line 202

def self.slice(*types)
  @@type_lookup.slice(*types.map(&:to_sym)).values if types   # Hash#slice is provided by will_paginate
end

Instance Method Details

#conditionObject



61
62
63
64
65
66
67
# File 'app/models/asset_type.rb', line 61

def condition
  if @mimes.any?
    ["asset_content_type IN (#{@mimes.map{'?'}.join(',')})", *@mimes]
  else
    self.class.other_condition
  end
end

#configured_stylesObject

Paperclip styles are defined in the config entry ‘assets.thumbnails.asset_type`, with the format: foo:key-x,key=y,key=z|bar:key-x,key=y,key=z where ’key’ can be any parameter understood by your paperclip processors. Usually they include :geometry and :format. A typical entry would be:

standard:geometry=640x640>,format=jpg

This method parses that string and returns the defined styles as a hash of style-defining strings that will later be normalized into hashes.



146
147
148
149
150
151
152
153
154
155
# File 'app/models/asset_type.rb', line 146

def configured_styles
  @configured_styles ||= if style_definitions = Radiant.config["assets.thumbnails.#{name}"]
    style_definitions.split('|').each_with_object({}) do |definition, styles|
      name, rule = definition.split(':')
      styles[name.strip.to_sym] = rule.to_s.strip
    end
  else
    {}
  end
end

#define_radius_tagsObject



167
168
169
170
171
172
173
174
175
176
177
# File 'app/models/asset_type.rb', line 167

def define_radius_tags
  type = self.name
  Page.class_eval {
    tag "asset:if_#{type}" do |tag|
      tag.expand if find_asset(tag, tag.attr.dup).send("#{type}?".to_sym)
    end
    tag "asset:unless_#{type}" do |tag|
      tag.expand unless find_asset(tag, tag.attr.dup).send("#{type}?".to_sym)
    end
  }
end

#icon(style_name = 'icon') ⇒ Object



49
50
51
52
53
54
55
# File 'app/models/asset_type.rb', line 49

def icon(style_name='icon')
  if File.exist?(Rails.root + "public/images/admin/assets/#{icon_name}_#{style_name.to_s}.png")
    return "/images/admin/assets/#{icon_name}_#{style_name.to_s}.png"
  else
    return "/images/admin/assets/#{icon_name}_icon.png"
  end
end

#icon_path(style_name = 'icon') ⇒ Object



57
58
59
# File 'app/models/asset_type.rb', line 57

def icon_path(style_name='icon')
  Rails.root + "public#{icon(style_name)}"
end

#legacy_stylesObject



157
158
159
# File 'app/models/asset_type.rb', line 157

def legacy_styles
  Radiant::config["assets.additional_thumbnails"].to_s.gsub(' ','').split(',').collect{|s| s.split('=')}.inject({}) {|ha, (k, v)| ha[k.to_sym] = v; ha}
end

#mime_typesObject



85
86
87
# File 'app/models/asset_type.rb', line 85

def mime_types
  @mimes
end

#non_conditionObject



73
74
75
76
77
78
79
# File 'app/models/asset_type.rb', line 73

def non_condition
  if @mimes.any?
    ["NOT asset_content_type IN (#{@mimes.map{'?'}.join(',')})", *@mimes]
  else
    self.class.non_other_condition
  end
end

#normalize_style_rules(styles = {}) ⇒ Object

Takes a motley collection of differently-defined styles and renders them into the standard hash-of-hashes format. Solitary strings are assumed to be TODO: define permitted and/or expected options for the asset type and pass through that subset of the style-definition hash



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
# File 'app/models/asset_type.rb', line 113

def normalize_style_rules(styles={})
  styles.each_pair do |name, rule|
    unless rule.is_a? Hash
      if rule =~ /\=/
        parameters = rule.split(',').collect{ |parameter| parameter.split('=') }              # array of pairs
        rule = Hash[parameters].symbolize_keys                                     # into hash of :first => last
      else
        rule = {:geometry => rule}                                                 # simplest case: name:geom|name:geom
      end
    end
    rule[:geometry] ||= rule.delete(:size)
    styles[name.to_sym] = rule
  end
  styles
end

#paperclip_processorsObject



89
90
91
# File 'app/models/asset_type.rb', line 89

def paperclip_processors
  Radiant.config["assets.create_#{name}_thumbnails?"] ? processors : []
end

#paperclip_stylesObject

Parses and combines the various ways in which paperclip styles can be defined, and normalises them into the format that paperclip expects. Note that :styles => :standard has already been replaced with the results of a call to standard_styles. Styles are passed to paperclip as a hash and arbitrary keys can be passed through from configuration.



98
99
100
101
102
103
104
105
106
107
# File 'app/models/asset_type.rb', line 98

def paperclip_styles
  # Styles are not relevant if processors are not defined.
  # TODO: should this default to an icon set?
  @paperclip_styles ||= if paperclip_processors.any?
    normalize_style_rules(configured_styles.merge(styles))
  else
    {}
  end
  @paperclip_styles
end

#pluralObject



45
46
47
# File 'app/models/asset_type.rb', line 45

def plural
  name.to_s.pluralize
end

#sanitized_conditionObject



69
70
71
# File 'app/models/asset_type.rb', line 69

def sanitized_condition
  ActiveRecord::Base.send :sanitize_sql_array, condition
end

#sanitized_non_conditionObject



81
82
83
# File 'app/models/asset_type.rb', line 81

def sanitized_non_condition
  ActiveRecord::Base.send :sanitize_sql_array, non_condition
end

#standard_stylesObject



129
130
131
132
133
134
135
# File 'app/models/asset_type.rb', line 129

def standard_styles
  {
    :native => { :geometry => "", :format => :jpg },
    :icon => { :geometry => '42x42#', :format => :png },
    :thumbnail => { :geometry => '100x100#', :format => :png }
  }
end

#style_dimensions(style_name) ⇒ Object



161
162
163
164
165
# File 'app/models/asset_type.rb', line 161

def style_dimensions(style_name)
  if style = paperclip_styles[style_name.to_sym]
    style[:size]
  end
end