classAsset<ActiveRecord::Basehas_many:page_attachments,dependent: :destroyhas_many:pages,through: :page_attachmentshas_siteifrespond_to?:has_sitebelongs_to:created_by,class_name: 'User'belongs_to:updated_by,class_name: 'User'default_scope{order('created_at DESC')}scope:latest,lambda{|limit|order('created_at DESC').limit(limit)}scope:of_types,lambda{|types|mimes=AssetType.slice(*types).map(&:mime_types).flattenAsset.select{|x|mimes.include?(x.asset_content_type)}}scope:matching,lambda{|term|where(['LOWER(assets.asset_file_name) LIKE (:term) OR LOWER(title) LIKE (:term) OR LOWER(caption) LIKE (:term)',{term: "%#{term.downcase}%"}])}scope:excepting,lambda{|assets|ifassets.any?assets=assets.split(',')ifassets.is_a?(String)asset_ids=assets.first.is_a?(Asset)?assets.map(&:id):assetswhere(["assets.id NOT IN(#{asset_ids.map{'?'}.join(',')})",*asset_ids])else{}end}has_one_attached:assetvalidates:asset,presence: true,blob:
{content_type: %w[application/zip image/jpg image/jpeg image/png image/gif application/pdf text/css],size_range: 1..10.megabytes,}before_save:assign_titlebefore_save:assign_uuiddefasset_typeAssetType.for(asset)enddelegate:paperclip_processors,:paperclip_styles,:active_storage_styles,:style_dimensions,:style_format,to: :asset_typedefthumbnail(style_name='original')returnasset.urlifstyle_name.to_s=='original'||render_original(style_name)returnasset_variant(style_name.to_s).processed.urlifasset.variable?asset_type.icon(style_name.to_s)enddefself.ransackable_attributes(auth_object=nil)%w[asset_content_type asset_file_name asset_file_size caption created_at created_by_id id original_extension original_height original_width title updated_at updated_by_id uuid]enddefrender_original(style_name)style_name.to_s=='original'&&asset.key.include?('culturaldistrict')enddefasset_variant(style_name)casestyle_namewhen'thumbnail'asset.variant(gravity: 'Center',resize: '100x100^',crop: '100x100+0+0')when'small'asset.variant(gravity: 'Center',resize: '320x320^')when'normal'asset.variant(gravity: 'Center',resize_to_limit: [asset.metadata[:width],asset.metadata[:height]])when'icon'asset.variant(gravity: 'Center',resize: '50x50^')endenddefstyle?(style_name='original')style_name=='original'||paperclip_styles.keys.include?(style_name.to_sym)enddefbasenameFile.basename(asset_file_name,'.*')ifasset_file_nameenddefextension(style_name='original')ifstyle_name=='original'original_extensionelsifstyle=paperclip_styles[style_name.to_sym]style.formatelseoriginal_extensionendenddeforiginal_extensionreturnasset_file_name.split('.').last.downcaseifasset_file_nameenddefattached_to?(page)pages.include?(page)enddeforiginal_geometry@original_geometry||=Paperclip::Geometry.new(original_width,original_height)enddefgeometry(style_name='original')unlessstyle?(style_name)raisePaperclip::StyleError,"Requested style #{style_name} is not defined for this asset."end@geometry||={}begin@geometry[style_name]||=ifstyle_name.to_s=='original'original_geometryelsestyle=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 dimensionsendrescuePaperclip::TransformationError=>eRails.logger.warn"geometry transformation error: #{e}"original_geometry# returns a blank geometry if the real geometry cannot be calculatedendenddefaspect(style_name='original')geometry(style_name).aspectenddeforientation(style_name='original')a=aspect(style_name)ifa==nil?'unknown'elsifa<1.0'vertical'elsifa>1.0'horizontal'else'square'endenddefwidth(style_name='original')geometry(style_name).width.to_ienddefheight(style_name='original')geometry(style_name).height.to_ienddefsquare?(style_name='original')geometry(style_name).square?enddefvertical?(style_name='original')geometry(style_name).vertical?enddefhorizontal?(style_name='original')geometry(style_name).horizontal?enddefdimensions_known?original_width?&&original_height?endprivate# 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.defread_dimensionsifimage?&&file=asset.queued_for_write[:original]geometry=Paperclip::Geometry.from_file(file)self.original_width=geometry.widthself.original_height=geometry.heightself.original_extension=File.extname(file.path)endtrueenddefassign_titleself.title=asset.filename.baseenddefassign_uuidself.uuid=SecureRandom.uuidunlessuuid?endclass<<selfdefknown_typesAssetType.known_typesend# searching and pagination moved to the controllerdeffind_all_by_asset_types(asset_types,*args)with_asset_types(asset_types){where*args}enddefcount_with_asset_types(asset_types,*args)with_asset_types(asset_types){where(*args).count}enddefwith_asset_types(asset_types,&block)w_asset_types=AssetType.conditions_for(asset_types)with_scope(where(conditions: ["#{w_asset_types} = ?",block]))endend# called from AssetType to set type_condition? methods on Assetdefself.define_class_method(name,&block)eigenclass.send:define_method,name,&blockend# returns the return value of class << self block, which is self (as defined within that block)defself.eigenclassclass<<selfself;endend# for backwards compatibilitydefself.thumbnail_sizesAssetType.find(:image).paperclip_stylesenddefself.thumbnail_namesthumbnail_sizes.keysend# this is a convenience for image-pickersdefself.thumbnail_optionsasset_sizes=thumbnail_sizes.mapdo|k,v|size_id=ksize_description="#{k}: "size_description<<(v.is_a?(Array)?v.join(' as '):v)[size_description,size_id]end.sort_by{|pair|pair.last.to_s}asset_sizes.unshift['Original (as uploaded)','original']asset_sizesendend