Class: GitlabUploader

Inherits:
CarrierWave::Uploader::Base
  • Object
show all
Includes:
ContentTypeWhitelist::Concern
Defined in:
app/uploaders/gitlab_uploader.rb

Constant Summary collapse

PROTECTED_METHODS =
%i[filename cache_dir work_dir store_dir].freeze
ObjectNotReadyError =
Class.new(StandardError)

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(model, mounted_as = nil, **uploader_context) ⇒ GitlabUploader

Returns a new instance of GitlabUploader.



55
56
57
# File 'app/uploaders/gitlab_uploader.rb', line 55

def initialize(model, mounted_as = nil, **uploader_context)
  super(model, mounted_as)
end

Class Method Details

.absolute_path(upload_record) ⇒ Object



36
37
38
# File 'app/uploaders/gitlab_uploader.rb', line 36

def absolute_path(upload_record)
  File.join(root, upload_record.path)
end

.base_dirObject

represent the directory namespacing at the class level



28
29
30
# File 'app/uploaders/gitlab_uploader.rb', line 28

def base_dir
  options.fetch('base_dir', '')
end

.file_storage?Boolean

Returns:

  • (Boolean)


32
33
34
# File 'app/uploaders/gitlab_uploader.rb', line 32

def file_storage?
  storage == CarrierWave::Storage::File
end

.optionsObject



19
20
21
# File 'app/uploaders/gitlab_uploader.rb', line 19

def options
  ObjectStorage::Config::LOCATIONS.fetch(storage_location_identifier)
end

.rootObject



23
24
25
# File 'app/uploaders/gitlab_uploader.rb', line 23

def root
  options.storage_path
end

.storage_location(location) ⇒ Object

DSL setter



14
15
16
17
# File 'app/uploaders/gitlab_uploader.rb', line 14

def storage_location(location)
  self.storage_location_identifier = location
  _ = options # Ensures that we have a valid storage_location_identifier
end

.version(*args, **kwargs, &block) ⇒ Object



40
41
42
43
44
45
46
# File 'app/uploaders/gitlab_uploader.rb', line 40

def version(*args, **kwargs, &block)
  # CarrierWave uploaded file "versions" are not tracked in the uploads
  # table. Because of this they won't get replicated to Geo secondaries.
  # If we ever want to use versions, we need to fix that first. Also see
  # https://gitlab.com/gitlab-com/gl-infra/scalability/-/issues/1757.
  raise "using CarrierWave alternate file version is not supported"
end

Instance Method Details

#cache_dirObject



79
80
81
# File 'app/uploaders/gitlab_uploader.rb', line 79

def cache_dir
  File.join(root, base_dir, 'tmp/cache')
end

#cached_sizeObject



105
106
107
# File 'app/uploaders/gitlab_uploader.rb', line 105

def cached_size
  size
end

#exists?Boolean

Returns:

  • (Boolean)


75
76
77
# File 'app/uploaders/gitlab_uploader.rb', line 75

def exists?
  file.present?
end

#file_cache_storage?Boolean

Returns:

  • (Boolean)


63
64
65
# File 'app/uploaders/gitlab_uploader.rb', line 63

def file_cache_storage?
  cache_storage.is_a?(CarrierWave::Storage::File)
end

#filenameObject



87
88
89
# File 'app/uploaders/gitlab_uploader.rb', line 87

def filename
  super || file&.filename
end

#local_urlObject



101
102
103
# File 'app/uploaders/gitlab_uploader.rb', line 101

def local_url
  File.join('/', self.class.base_dir, dynamic_segment, filename)
end

#model_valid?Boolean

Returns:

  • (Boolean)


97
98
99
# File 'app/uploaders/gitlab_uploader.rb', line 97

def model_valid?
  !!model
end

#move_to_cacheObject



67
68
69
# File 'app/uploaders/gitlab_uploader.rb', line 67

def move_to_cache
  file_storage?
end

#move_to_storeObject



71
72
73
# File 'app/uploaders/gitlab_uploader.rb', line 71

def move_to_store
  file_storage?
end

#multi_read(offsets) ⇒ Object



127
128
129
130
131
132
133
134
# File 'app/uploaders/gitlab_uploader.rb', line 127

def multi_read(offsets)
  open do |stream|
    offsets.map do |start_offset, end_offset|
      stream.seek(start_offset)
      stream.read(end_offset - start_offset + 1)
    end
  end
end

#openObject



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'app/uploaders/gitlab_uploader.rb', line 109

def open
  stream =
    if file_storage?
      File.open(path, "rb") if path
    elsif url
      ::Gitlab::HttpIO.new(url, cached_size)
    end

  return unless stream
  return stream unless block_given?

  begin
    yield(stream)
  ensure
    stream.close
  end
end

#optionsObject



59
60
61
# File 'app/uploaders/gitlab_uploader.rb', line 59

def options
  self.class.options
end

#relative_pathObject



91
92
93
94
95
# File 'app/uploaders/gitlab_uploader.rb', line 91

def relative_path
  return path if pathname.relative?

  pathname.relative_path_from(Pathname.new(root))
end

#replace_file_without_saving!(file) ⇒ Object

Used to replace an existing upload with another file without modifying stored metadata Use this method only to repair/replace an existing upload, or to upload to a Geo secondary node

Parameters:

  • file (CarrierWave::SanitizedFile)

    that will replace existing upload

Returns:

  • CarrierWave::SanitizedFile

Raises:

  • (ArgumentError)


141
142
143
144
145
# File 'app/uploaders/gitlab_uploader.rb', line 141

def replace_file_without_saving!(file)
  raise ArgumentError, 'should be a CarrierWave::SanitizedFile' unless file.is_a? CarrierWave::SanitizedFile

  storage.store!(file)
end

#url_or_file_path(url_options = {}) ⇒ Object



147
148
149
150
151
152
153
# File 'app/uploaders/gitlab_uploader.rb', line 147

def url_or_file_path(url_options = {})
  if file_storage?
    'file://' + path
  else
    url(url_options)
  end
end

#work_dirObject



83
84
85
# File 'app/uploaders/gitlab_uploader.rb', line 83

def work_dir
  File.join(root, base_dir, 'tmp/work')
end