SpeciesFileGroup/taxonworks

View on GitHub
app/models/download.rb

Summary

Maintainability
A
0 mins
Test Coverage
# A Download represents an expirable file (mostly ZIP files) users can download.
#
# @!attribute name
# @return [String]
#   The name for this download (not file name).
#
# @!attribute description
# @return [String]
#   A description for this download.
#
# @!attribute filename
# @return [String]
#   The filename of this download.
#
# @!attribute type
# @return [String]
#   The type of Download, e.g. `Download::DwCArchive`.
#
# @!attribute request
# @return [String]
#   The request URI path this download was generated from. This attribute may be used for caching.
#
# @!attribute expires
# @return [Datetime]
#   The date and time this download is elegible for removal.
#
# @!attribute times_downloaded
# @return [Integer]
#   The number of times the file was downloaded.
#
# @!attribute project_id
# @return [Integer]
#   the project ID
#
# @!attribute is_public
# @return [Boolean, nil]
#     whether the Download should be shared on the API
#
# @!attribute total_records
#   @return [Integer, nil]
#     and _estimate_ of the total records (rows of data) in this Download.
#     Because Downloads can be variously create some generating might not accurate count the total
#
class Download < ApplicationRecord
  include Housekeeping
  include Shared::IsData

  default_scope { where('expires >= ?', Time.now) }

  after_save :save_file
  after_destroy :delete_file

  validates_presence_of :name
  validates_presence_of :filename
  validates_presence_of :expires
  validates_presence_of :type

  # Gets the downloads storage path
  def self.storage_path
    STORAGE_PATH
  end

  # Used as argument for :new.
  def source_file_path=(path)
    @source_file_path = path
  end

  # @return [Pathname]
  #   Retrieves the full-path of stored file
  def file_path
    dir_path.join(filename)
  end

  def file
    File.read(file_path)
  end

  # @return [Boolean]
  #   Tells whether the download expiry date has been surpassed.
  def expired?
    expires < Time.now
  end

  # @return [Boolean]
  #   Tells whether the download is ready to be downloaded.
  def ready?
    !expired? && file_path.exist?
  end

  # Deletes associated file from storage
  def delete_file
    path = dir_path
    raise 'Download: dir_path not pointing inside storage path! Aborting deletion' unless path.to_s.start_with?(STORAGE_PATH.to_s)

    FileUtils.rm_rf(path)
  end

  private

  STORAGE_PATH = Rails.root.join(Rails.env.test? ? 'tmp' : '', "downloads#{ENV['TEST_ENV_NUMBER']}").freeze

  def dir_path
    str = id.to_s.rjust(9, '0')
    STORAGE_PATH.join(str[-str.length..-7], str[-6..-4], str[-3..-1])
  end

  def save_file
    FileUtils.mkdir_p(dir_path)
    FileUtils.cp(@source_file_path, file_path) if @source_file_path
  end
end

require_dependency 'download/basic_nomenclature'
require_dependency 'download/bibtex'
require_dependency 'download/coldp'
require_dependency 'download/dwc_archive'
require_dependency 'download/project_dump/sql'
require_dependency 'download/project_dump/tsv'
require_dependency 'download/text'