Class: FileAsset

Inherits:
ActiveRecord::Base
  • Object
show all
Defined in:
app/models/file_asset.rb

Direct Known Subclasses

Image, Swf, TextFile

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(attributes = {}, options = {}) ⇒ FileAsset

Returns a new instance of FileAsset.



222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
# File 'app/models/file_asset.rb', line 222

def initialize(attributes = {}, options={})
  attributes ||= {}

  base_path = attributes.delete(:base_path)
  @type, directory, name, data = attributes.values_at(:type, :directory, :name, :data)
  base_path ||= data.original_filename if data.respond_to?(:original_filename)

  directory, name = FileAsset.split_path(base_path) if base_path and name.blank?
  directory.gsub!(Rails.root.to_s, '') if directory

  @type ||= FileAsset.type_for(name) if name
  @type = "TextFile" if @type.nil?
  @name = name

  data = StringIO.new(data) if data.is_a?(String)

  super attributes.merge(:directory => directory, :name => name, :data => data)
end

Class Method Details

.acceptable?(name) ⇒ Boolean

Returns:

  • (Boolean)


131
132
133
# File 'app/models/file_asset.rb', line 131

def acceptable?(name)
  valid_extensions.include?(File.extname(name))
end

.adjust_image(data, size = nil) ⇒ Object



108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'app/models/file_asset.rb', line 108

def adjust_image(data, size=nil)
  file_support = ErpTechSvcs::FileSupport::FileSystemManager.new
  name = "#{SecureRandom.uuid}.jpg"
  path = File.join(Rails.root, 'tmp', name)

  data = StringIO.new(data) if data.is_a?(String)
  File.open(path, 'wb+') { |f| f.write(data.read) }

  # resize
  if size
    Paperclip.run("convert", "#{path} -resize #{size}^ #{path}", :swallow_stderr => false)
  end

  # rotate
  Paperclip.run("convert", "#{path} -auto-orient #{path}", :swallow_stderr => false)

  #remove the file after we get the data
  data = file_support.get_contents(path)[0]
  FileUtils.rm(path)

  data
end

.all_valid_extensionsObject



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

def all_valid_extensions
  all_subclasses.map { |k| k.valid_extensions }.flatten.uniq
end

.apply_filters(filters, statement = nil) ⇒ ActiveRecord::Relation

Filter records

Parameters:

  • filters (Hash)

    a hash of filters to be applied,

  • statement (ActiveRecord::Relation) (defaults to: nil)

    the query being built

Returns:

  • (ActiveRecord::Relation)

    the query being built



172
173
174
175
176
177
178
179
180
181
182
183
184
# File 'app/models/file_asset.rb', line 172

def apply_filters(filters, statement=nil)
  statement = FileAsset unless statement

  if filters[:file_asset_holder_type].present? && filters[:file_asset_holder_id].present?
    statement = statement.joins(:file_asset_holders)
                    .where(file_asset_holders: {
                               file_asset_holder_id: filters[:file_asset_holder_id],
                               file_asset_holder_type: filters[:file_asset_holder_type]
                           })
  end

  statement
end

.scope_by_dba_organization(dba_organization) ⇒ ActiveRecord::Relation Also known as: scope_by_dba_org

scope by dba organization

Parameters:

  • dba_organization (Party)

    dba organization to scope by

Returns:

  • (ActiveRecord::Relation)


191
192
193
# File 'app/models/file_asset.rb', line 191

def scope_by_dba_organization(dba_organization)
  scope_by_party(dba_organization, {role_types: [RoleType.iid('dba_org')]})
end

.scope_by_party(party, options = {}) ⇒ ActiveRecord::Relation

scope by party

or an array of Party ids

Parameters:

  • party (Integer | Party | Array)

    either a id of Party record, a Party record, an array of Party records

  • options (Hash) (defaults to: {})

    options to apply to this scope

Options Hash (options):

  • :role_types (Array)

    role types to include in the scope

Returns:

  • (ActiveRecord::Relation)


205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# File 'app/models/file_asset.rb', line 205

def scope_by_party(party, options={})
  table_alias = String.random

  if options[:role_types]
    joins("inner join entity_party_roles as #{table_alias} on #{table_alias}.entity_record_type = 'FileAsset'
                                 and #{table_alias}.entity_record_id = file_assets.id and
                                 #{table_alias}.role_type_id in (#{RoleType.find_child_role_types(options[:role_types]).collect(&:id).join(',')})
                                 and #{table_alias}.party_id in (#{Party.select('id').where(id: party).to_sql})")

  else
    joins("inner join entity_party_roles as #{table_alias} on #{table_alias}.entity_record_type = 'FileAsset'
                                 and #{table_alias}.entity_record_id = file_assets.id
                                 and #{table_alias}.party_id in (#{Party.select('id').where(id: party).to_sql})")
  end
end

.split_path(path) ⇒ Object



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

def split_path(path)
  directory, name = ::File.split(path)
  directory = nil if directory == '.'
  [directory, name]
end

.type_by_extension(extension) ⇒ Object



140
141
142
143
144
# File 'app/models/file_asset.rb', line 140

def type_by_extension(extension)
  klass = all_subclasses.detect { |k| k.valid_extensions.include?(extension) }
  klass = TextFile if klass.nil?
  klass
end

.type_for(name) ⇒ Object



135
136
137
138
# File 'app/models/file_asset.rb', line 135

def type_for(name)
  classes = all_subclasses.uniq
  classes.detect { |k| k.acceptable?(name) }.try(:name)
end

.valid_extensionsObject



153
154
155
# File 'app/models/file_asset.rb', line 153

def valid_extensions
  read_inheritable_attribute(:valid_extensions) || []
end

.validate_extension(data, file) ⇒ Object



146
147
148
149
150
151
# File 'app/models/file_asset.rb', line 146

def validate_extension(data, file)
  if file.name && !file.class.valid_extensions.include?(File.extname(file.name))
    types = all_valid_extensions.map { |type| type.gsub(/^\./, '') }.join(', ')
    "#{file.name} is not a valid file type. Valid file types are #{types}."
  end
end

Instance Method Details

#basenameObject



318
319
320
# File 'app/models/file_asset.rb', line 318

def basename
  name.gsub(/\.#{extname}$/, "")
end

#check_name_uniquenessObject



250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
# File 'app/models/file_asset.rb', line 250

def check_name_uniqueness
  # check if name is already taken
  unless FileAsset.where('directory = ? and name = ?', self.directory, self.name).first.nil?
    # if it is keeping add incrementing by 1 until we have a good name
    counter = 0
    while true
      counter += 1

      # break after 25, we don't want in infinite loop
      break if counter == 25

      new_name = "#{basename}-#{counter}.#{extname}"

      if FileAsset.where('directory = ? and name = ?', self.directory, new_name).first.nil?
        self.name = new_name
        break
      end
    end
  end
end

#copy(path, name) ⇒ Object



275
276
277
278
279
# File 'app/models/file_asset.rb', line 275

def copy(path, name)
  file_support = ErpTechSvcs::FileSupport::Base.new(:storage => ErpTechSvcs::Config.file_storage)

  file_support.copy(self.path, path, name)
end

#extnameObject



330
331
332
# File 'app/models/file_asset.rb', line 330

def extname
  File.extname(name).gsub(/^\.+/, '')
end

#fully_qualified_urlObject



241
242
243
244
245
246
247
248
# File 'app/models/file_asset.rb', line 241

def fully_qualified_url
  case ErpTechSvcs::Config.file_storage
    when :filesystem
      "#{ErpTechSvcs::Config.file_protocol}://#{File.join(ErpTechSvcs::Config.installation_domain, data.url)}"
    when :s3
      data.url
  end
end

#get_contentsObject



350
351
352
353
# File 'app/models/file_asset.rb', line 350

def get_contents
  file_support = ErpTechSvcs::FileSupport::Base.new(:storage => ErpTechSvcs::Config.file_storage)
  file_support.get_contents(File.join(file_support.root, self.directory, self.data_file_name))
end

#is_secured?Boolean

Returns:

  • (Boolean)


271
272
273
# File 'app/models/file_asset.rb', line 271

def is_secured?
  self.protected_with_capability?('download')
end

#move(new_parent_path) ⇒ Object



355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
# File 'app/models/file_asset.rb', line 355

def move(new_parent_path)
  file_support = ErpTechSvcs::FileSupport::Base.new(:storage => ErpTechSvcs::Config.file_storage)

  if ErpTechSvcs::Config.file_storage == :filesystem and !self.directory.include?(Rails.root.to_s)
    old_path = File.join(Rails.root, self.directory, self.name)
  else
    old_path = File.join(self.directory, self.name)
  end

  result, message = file_support.save_move(old_path, new_parent_path)
  if result
    dir = new_parent_path.gsub(Regexp.new(Rails.root.to_s), '') # strip rails root from new_parent_path, we want relative path
    dir = '/' + dir unless dir.match(%r{^/})
    self.directory = dir
    self.save
  end

  return result, message
end

#pathObject

returns full path to local image or url to s3 image



287
288
289
290
291
292
293
294
295
296
297
298
# File 'app/models/file_asset.rb', line 287

def path
  file_support = ErpTechSvcs::FileSupport::Base.new(:storage => ErpTechSvcs::Config.file_storage)

  if ErpTechSvcs::Config.file_storage == :s3
    file_path = File.join(self.directory, self.name).sub(%r{^/}, '')
    options = {}
    options[:expires] = ErpTechSvcs::Config.s3_url_expires_in_seconds if self.is_secured?
    file_support.bucket.objects[file_path].url_for(:read, options).to_s
  else
    File.join(Rails.root, self.directory, self.name)
  end
end

#save_dimensionsObject



300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
# File 'app/models/file_asset.rb', line 300

def save_dimensions
  if @type == 'Image'
    begin
      tempfile = data.queued_for_write[:original]
      unless tempfile.nil?
        geometry = Paperclip::Geometry.from_file(tempfile)
        w = geometry.width.to_i
        h = geometry.height.to_i
        update_attribute(:width, w) if width != w
        update_attribute(:height, h) if height != h
      end
    rescue => ex
      Rails.logger.error('Could not save width and height of image. Make sure Image Magick and the identify command are accessible')
    end
  end
  #return true
end

#set_content_typeObject



338
339
340
341
342
343
344
# File 'app/models/file_asset.rb', line 338

def set_content_type
  unless @type.nil?
    klass = @type.constantize
    content_type = klass == Image ? "image/#{File.extname(@name).gsub(/^\.+/, '')}" : klass.content_type
    self.data.instance_write(:content_type, content_type)
  end
end

#set_data_file_nameObject



346
347
348
# File 'app/models/file_asset.rb', line 346

def set_data_file_name
  update_attribute :data_file_name, name if data_file_name != name
end

#set_stiObject



334
335
336
# File 'app/models/file_asset.rb', line 334

def set_sti
  update_attribute :type, @type
end

#thumbnail_srcObject



390
391
392
# File 'app/models/file_asset.rb', line 390

def thumbnail_src
  "#{ErpTechSvcs::Config.file_protocol}://#{File.join(ErpTechSvcs::Config.installation_domain, 'assets/default_file.png')}"
end

#to_data_hashObject



379
380
381
382
383
384
385
386
387
388
# File 'app/models/file_asset.rb', line 379

def to_data_hash
  data = to_hash(only: [:id, :directory, :width, :height, :name, :description])

  data[:url] = self.data.url
  data[:fully_qualified_url] = self.fully_qualified_url
  data[:tags] = self.tag_list.join(',')
  data[:thumbnail_src] = self.thumbnail_src

  data
end

#to_sObject



375
376
377
# File 'app/models/file_asset.rb', line 375

def to_s
  self.description
end

#trim_name(size) ⇒ Object



322
323
324
325
326
327
328
# File 'app/models/file_asset.rb', line 322

def trim_name(size)
  if self.name.length < size
    self.name
  else
    self.name[0..size]
  end
end

#urlObject

compass file download url



282
283
284
# File 'app/models/file_asset.rb', line 282

def url
  "/download/#{self.name}?path=#{self.directory}"
end