engine/app/models/theme_asset.rb

152 lines
4.1 KiB
Ruby
Raw Normal View History

2010-05-11 21:38:52 +00:00
class ThemeAsset
include Locomotive::Mongoid::Document
2010-05-11 21:38:52 +00:00
## fields ##
field :local_path
field :content_type
2010-05-11 21:38:52 +00:00
field :width, :type => Integer
field :height, :type => Integer
field :size, :type => Integer
field :folder, :default => nil
field :hidden, :type => Boolean, :default => false
2010-05-11 21:38:52 +00:00
mount_uploader :source, ThemeAssetUploader
2010-05-11 21:38:52 +00:00
## associations ##
referenced_in :site
2010-09-15 16:09:07 +00:00
## indexes ##
index :site_id
index [[:site_id, Mongo::ASCENDING], [:local_path, Mongo::ASCENDING]]
2010-09-15 16:09:07 +00:00
2010-05-11 21:38:52 +00:00
## callbacks ##
before_validation :store_plain_text
before_validation :sanitize_folder
before_validation :build_local_path
2010-05-11 21:38:52 +00:00
## validations ##
2010-05-12 00:16:39 +00:00
validates_presence_of :site, :source
validates_presence_of :plain_text_name, :if => Proc.new { |a| a.performing_plain_text? }
validates_uniqueness_of :local_path, :scope => :site_id
2010-05-11 21:38:52 +00:00
validates_integrity_of :source
2010-10-10 14:37:34 +00:00
validate :content_type_can_not_changed
## named scopes ##
scope :visible, lambda { |all| all ? {} : { :where => { :hidden => false } } }
2010-05-11 21:38:52 +00:00
## accessors ##
attr_accessor :plain_text_name, :plain_text, :performing_plain_text
2010-05-11 21:38:52 +00:00
## methods ##
%w{media image stylesheet javascript font}.each do |type|
2010-05-11 21:38:52 +00:00
define_method("#{type}?") do
self.content_type.to_s == type
end
2010-05-11 21:38:52 +00:00
end
2010-07-17 20:51:52 +00:00
def stylesheet_or_javascript?
self.stylesheet? || self.javascript?
end
def local_path(short = false)
if short
self.read_attribute(:local_path).gsub(/^#{self.content_type.to_s.pluralize}\//, '')
else
self.read_attribute(:local_path)
end
end
def plain_text_name
if not @plain_text_name_changed
@plain_text_name ||= self.safe_source_filename
end
@plain_text_name.gsub(/(\.[a-z0-9A-Z]+)$/, '') rescue nil
end
def plain_text_name=(name)
@plain_text_name_changed = true
@plain_text_name = name
end
2010-05-11 21:38:52 +00:00
def plain_text
2011-01-27 13:07:10 +00:00
if RUBY_VERSION =~ /1\.9/
2011-01-29 12:05:42 +00:00
@plain_text ||= (self.source.read.force_encoding('UTF-8') rescue nil)
2011-01-27 13:07:10 +00:00
else
@plain_text ||= self.source.read
end
2010-05-11 21:38:52 +00:00
end
2010-05-11 21:38:52 +00:00
def performing_plain_text?
2010-10-10 14:37:34 +00:00
Boolean.set(self.performing_plain_text) || false
2010-05-11 21:38:52 +00:00
end
2010-05-11 21:38:52 +00:00
def store_plain_text
data = self.performing_plain_text? ? self.plain_text : self.source.read
return if !self.stylesheet_or_javascript? || self.plain_text_name.blank? || data.blank?
sanitized_source = self.escape_shortcut_urls(data)
self.source = CarrierWave::SanitizedFile.new({
:tempfile => StringIO.new(sanitized_source),
:filename => "#{self.plain_text_name}.#{self.stylesheet? ? 'css' : 'js'}"
})
2010-05-11 21:38:52 +00:00
end
def to_liquid
{ :url => self.source.url }.merge(self.attributes)
end
def self.all_grouped_by_folder(site, include_all = true)
assets = site.theme_assets.visible(include_all).order_by([[:slug, :asc]])
assets.group_by { |a| a.folder.split('/').first.to_sym }
end
2010-05-11 21:38:52 +00:00
protected
def safe_source_filename
self.source_filename || self.source.send(:original_filename) rescue nil
end
2010-09-23 23:00:13 +00:00
def sanitize_folder
self.folder = self.content_type.to_s.pluralize if self.folder.blank?
2010-09-23 23:00:13 +00:00
# no accents, no spaces, no leading and ending trails
self.folder = ActiveSupport::Inflector.transliterate(self.folder).gsub(/(\s)+/, '_').gsub(/^\//, '').gsub(/\/$/, '')
2010-09-23 23:00:13 +00:00
# folder should begin by a root folder
if (self.folder =~ /^(stylesheets|javascripts|images|medias|fonts)/).nil?
self.folder = File.join(self.content_type.to_s.pluralize, self.folder)
2010-09-23 23:00:13 +00:00
end
end
def build_local_path
if filename = self.safe_source_filename
self.local_path = File.join(self.folder, filename)
else
nil
end
2010-05-11 21:38:52 +00:00
end
def escape_shortcut_urls(text)
return if text.blank?
text.gsub(/[("'](\/(stylesheets|javascripts|images|medias)\/(([^;.]+)\/)*([a-z_\-0-9]+)\.[a-z]{2,3})[)"']/) do |path|
2010-10-10 14:37:34 +00:00
sanitized_path = path.gsub(/[("')]/, '').gsub(/^\//, '')
if asset = self.site.theme_assets.where(:local_path => sanitized_path).first
"#{path.first}#{asset.source.url}#{path.last}"
else
path
end
2010-05-11 21:38:52 +00:00
end
end
2010-10-10 14:37:34 +00:00
def content_type_can_not_changed
self.errors.add(:source, :extname_changed) if !self.new_record? && self.content_type_changed?
end
end