BigW Consortium Gitlab

upload.rb 1.59 KB
Newer Older
1 2 3 4
class Upload < ActiveRecord::Base
  # Upper limit for foreground checksum processing
  CHECKSUM_THRESHOLD = 100.megabytes

5
  belongs_to :model, polymorphic: true # rubocop:disable Cop/PolymorphicAssociations
6 7 8 9 10 11

  validates :size, presence: true
  validates :path, presence: true
  validates :model, presence: true
  validates :uploader, presence: true

12 13
  before_save  :calculate_checksum!, if: :foreground_checksummable?
  after_commit :schedule_checksum,   if: :checksummable?
14

15 16
  def self.hexdigest(path)
    Digest::SHA256.file(path).hexdigest
17 18 19 20 21 22 23 24
  end

  def absolute_path
    return path unless relative_path?

    uploader_class.absolute_path(self)
  end

25 26 27
  def calculate_checksum!
    self.checksum = nil
    return unless checksummable?
28

29 30 31 32
    self.checksum = self.class.hexdigest(absolute_path)
  end

  def build_uploader
33
    uploader_class.new(model, mount_point, **uploader_context).tap do |uploader|
34 35 36
      uploader.upload = self
      uploader.retrieve_from_store!(identifier)
    end
37 38 39 40 41 42
  end

  def exist?
    File.exist?(absolute_path)
  end

43 44 45 46 47 48 49
  def uploader_context
    {
      identifier: identifier,
      secret: secret
    }.compact
  end

50 51
  private

52 53 54 55 56
  def checksummable?
    checksum.nil? && local? && exist?
  end

  def local?
Micaël Bergeron committed
57
    true
58 59 60 61
  end

  def foreground_checksummable?
    checksummable? && size <= CHECKSUM_THRESHOLD
62 63 64 65 66 67 68 69 70 71
  end

  def schedule_checksum
    UploadChecksumWorker.perform_async(id)
  end

  def relative_path?
    !path.start_with?('/')
  end

72 73 74 75
  def uploader_class
    Object.const_get(uploader)
  end

76 77 78 79
  def identifier
    File.basename(path)
  end

80 81
  def mount_point
    super&.to_sym
82 83
  end
end