lib/hijack/output_drivers/radiant/asset.rb
require 'paperclip'
module Hijack
module OutputDrivers
module Radiant
#
# +Hijack::OutputDrivers::Radiant::Asset+
#
# This is essentially a lif-off of the clipped extension asset class
# which pulls the minimal set needed for Hijack Radiant OutputDriver
# to do its work properly
#
class Asset < Base
include Paperclip::Glue
has_many :page_attachments, :dependent => :destroy, :class_name => 'Hijack::OutputDrivers::Radiant::PageAttachment'
has_many :pages, :through => :page_attachments, :class_name => 'Hijack::OutputDrivers::Radiant::Page'
has_site if respond_to? :has_site
belongs_to :created_by, :class_name => 'User'
belongs_to :updated_by, :class_name => 'User'
default_scope { order('created_at DESC') }
has_attached_file :asset,
:styles => lambda { |attachment|
AssetType.for(attachment).paperclip_styles
},
:processors => lambda { |asset|
asset.paperclip_processors
},
:whiny => false,
:storage => Hijack::OutputDrivers::Radiant::Config.storage,
:path => Hijack::OutputDrivers::Radiant::Config.path #,
# :url => Hijack::OutputDrivers::Radiant::Config.url,
# :fog_credentials => RadiantClippedExtension::Cloud.credentials,
# :fog_directory => Hijack::Config.radiant_config["paperclip.fog.directory"],
# :fog_public => Hijack::Config.radiant_config["paperclip.fog.public?"] || true,
# :fog_host => RadiantClippedExtension::Cloud.host
before_save :assign_title
before_save :assign_uuid
after_post_process :read_dimensions
# validates_attachment_presence :asset, :message => "You must choose a file to upload!"
# if Radiant.config["paperclip.skip_filetype_validation"] != "true" && Radiant.config['paperclip.content_types']
# validates_attachment_content_type :asset, :content_type => Radiant.config["paperclip.content_types"].gsub(' ','').split(',')
# end
# validates_attachment_size :asset, :less_than => ( Radiant.config["assets.max_asset_size"] || 5 ).to_i.megabytes
def asset_type
AssetType.for(asset)
end
delegate :paperclip_processors, :paperclip_styles, :style_dimensions, :style_format, :to => :asset_type
def thumbnail(style_name='original')
return asset.url if style_name.to_sym == :original
return asset.url(style_name.to_sym) if has_style?(style_name)
return asset_type.icon(style_name)
end
def has_style?(style_name='original')
style_name == 'original' || paperclip_styles.keys.include?(style_name.to_sym)
end
def basename
File.basename(asset_file_name, ".*") if asset_file_name
end
def extension(style_name='original')
if style_name == 'original'
return original_extension
elsif style = paperclip_styles[style_name.to_sym]
return style.format
else
return original_extension
end
end
def original_extension
return asset_file_name.split('.').last.downcase if asset_file_name
end
def attached_to?(page)
pages.include?(page)
end
def original_geometry
@original_geometry ||= Paperclip::Geometry.new(original_width, original_height)
end
def geometry(style_name='original')
raise Paperclip::StyleError, "Requested style #{style_name} is not defined for this asset." unless has_style?(style_name)
@geometry ||= {}
begin
@geometry[style_name] ||= if style_name.to_s == 'original'
original_geometry
else
style = self.asset.styles[style_name.to_sym]
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
end
rescue Paperclip::TransformationError => e
Rails.logger.warn "geometry transformation error: #{e}"
original_geometry # returns a blank geometry if the real geometry cannot be calculated
end
end
def aspect(style_name='original')
geometry(style_name).aspect
end
def orientation(style_name='original')
a = aspect(style_name)
case
when a == nil?
'unknown'
when a < 1.0
'vertical'
when a > 1.0
'horizontal'
else
'square'
end
end
def width(style_name='original')
geometry(style_name).width.to_i
end
def height(style_name='original')
geometry(style_name).height.to_i
end
def square?(style_name='original')
geometry(style_name).square?
end
def vertical?(style_name='original')
geometry(style_name).vertical?
end
def horizontal?(style_name='original')
geometry(style_name).horizontal?
end
def dimensions_known?
original_width? && original_height?
end
private
# at this point the file queue will not have been written
# but the upload should be in place. We read dimensions from the
# original file and calculate thumbnail dimensions later, on demand.
def read_dimensions
if image?
if file = asset.queued_for_write[:original]
geometry = Paperclip::Geometry.from_file(file)
self.original_width = geometry.width
self.original_height = geometry.height
self.original_extension = File.extname(file.path)
end
end
true
end
def assign_title
self.title = basename unless title?
end
def assign_uuid
self.uuid = UUIDTools::UUID.timestamp_create.to_s unless uuid?
end
class << self
def known_types
AssetType.known_types
end
# searching and pagination moved to the controller
def find_all_by_asset_types(asset_types, *args)
with_asset_types(asset_types) { find *args }
end
def count_with_asset_types(asset_types, *args)
with_asset_types(asset_types) { count *args }
end
def with_asset_types(asset_types, &block)
with_scope(:find => { :conditions => AssetType.conditions_for(asset_types) }, &block)
end
end
# called from AssetType to set type_condition? methods on Asset
def self.define_class_method(name, &block)
eigenclass.send :define_method, name, &block
end
# returns the return value of class << self block, which is self (as defined within that block)
def self.eigenclass
class << self; self; end
end
# for backwards compatibility
def self.thumbnail_sizes
AssetType.find(:image).paperclip_styles
end
def self.thumbnail_names
thumbnail_sizes.keys
end
# this is a convenience for image-pickers
def self.thumbnail_options
asset_sizes = thumbnail_sizes.collect{|k,v|
size_id = k
size_description = "#{k}: "
size_description << (v.is_a?(Array) ? v.join(' as ') : v)
[size_description, size_id]
}.sort_by{|pair| pair.last.to_s}
asset_sizes.unshift ['Original (as uploaded)', 'original']
asset_sizes
end
end
end
end
end