BigW Consortium Gitlab

file_uploader.rb 1.67 KB
Newer Older
1
class FileUploader < GitlabUploader
2
  include RecordsUploads
3
  include UploaderHelper
4

5
  MARKDOWN_PATTERN = %r{\!?\[.*?\]\(/uploads/(?<secret>[0-9a-f]{32})/(?<file>.*?)\)}
6

7 8
  storage :file

9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
  def self.absolute_path(upload_record)
    File.join(
      self.dynamic_path_segment(upload_record.model),
      upload_record.path
    )
  end

  # Returns the part of `store_dir` that can change based on the model's current
  # path
  #
  # This is used to build Upload paths dynamically based on the model's current
  # namespace and path, allowing us to ignore renames or transfers.
  #
  # model - Object that responds to `path_with_namespace`
  #
  # Returns a String without a trailing slash
  def self.dynamic_path_segment(model)
    File.join(CarrierWave.root, base_dir, model.path_with_namespace)
  end

29
  attr_accessor :model
30
  attr_reader :secret
31

32 33
  def initialize(model, secret = nil)
    @model = model
34
    @secret = secret || generate_secret
35 36 37
  end

  def store_dir
38
    File.join(dynamic_path_segment, @secret)
39 40
  end

41 42 43 44
  def relative_path
    self.file.path.sub("#{dynamic_path_segment}/", '')
  end

45 46 47 48
  def to_markdown
    to_h[:markdown]
  end

49
  def to_h
50
    filename = image_or_video? ? self.file.basename : self.file.filename
51 52
    escaped_filename = filename.gsub("]", "\\]")

53
    markdown = "[#{escaped_filename}](#{secure_url})"
54
    markdown.prepend("!") if image_or_video? || dangerous?
55 56 57

    {
      alt:      filename,
58
      url:      secure_url,
59 60 61
      markdown: markdown
    }
  end
62

63 64
  private

65 66 67 68
  def dynamic_path_segment
    self.class.dynamic_path_segment(model)
  end

69
  def generate_secret
70 71
    SecureRandom.hex
  end
72 73 74 75

  def secure_url
    File.join('/uploads', @secret, file.filename)
  end
76
end