Class: DerivativeRodeo::StorageLocations::BaseLocation

Inherits:
Object
  • Object
show all
Defined in:
lib/derivative_rodeo/storage_locations/base_location.rb

Overview

The base location for storing files.

  • dir

    is the directory path

  • path

    is the full file path

  • uri

    is the full file path plus the uri prefix parts

A location represents a pointer to a storage location. The #exist? method can answer if a file exists at the path.

rubocop:disable Metrics/ClassLength

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(file_uri) ⇒ BaseLocation

Returns a new instance of BaseLocation.

Parameters:



126
127
128
# File 'lib/derivative_rodeo/storage_locations/base_location.rb', line 126

def initialize(file_uri)
  @file_uri = file_uri
end

Instance Attribute Details

#file_uriObject (readonly)

Returns the value of attribute file_uri.



133
134
135
# File 'lib/derivative_rodeo/storage_locations/base_location.rb', line 133

def file_uri
  @file_uri
end

Class Method Details

.build(from_uri:, template:, service: DerivativeRodeo::Services::ConvertUriViaTemplateService, **options) ⇒ StorageLocations::BaseLocation

Build a DerivativeRodeo::StorageLocations::BaseLocation by converting the :from_uri with the :template via the given :service.

Parameters:

Returns:



106
107
108
109
110
111
# File 'lib/derivative_rodeo/storage_locations/base_location.rb', line 106

def self.build(from_uri:, template:, service: DerivativeRodeo::Services::ConvertUriViaTemplateService, **options)
  # HACK: Ensuring that we have the correct scheme.  Maybe this is a hack?
  from_uri = "#{scheme}://#{from_uri}" unless from_uri.start_with?("#{scheme}://")
  to_uri = service.call(from_uri: from_uri, template: template, adapter: self, **options)
  new(to_uri)
end

.create_uri(path:, parts:) ⇒ String

Create a new uri of the classes type. Parts argument should have a default in implementing classes. Must support a number or the symbol :all

Parameters:

  • path (String)
  • parts (Integer, :all)

Returns:

  • (String)

Raises:

  • (NotImplementedError)

See Also:



93
94
95
# File 'lib/derivative_rodeo/storage_locations/base_location.rb', line 93

def self.create_uri(path:, parts:)
  raise NotImplementedError, "#{self.class}.create_uri"
end

.file_path_from_parts(path:, parts:) ⇒ String

Parameters:

  • path (String)
  • parts (Integer, :all)

Returns:

  • (String)


118
119
120
121
# File 'lib/derivative_rodeo/storage_locations/base_location.rb', line 118

def self.file_path_from_parts(path:, parts:)
  parts = - parts unless parts == :all || parts.negative?
  parts == :all ? path : path.split('/')[parts..-1].join('/')
end

.from_uri(file_uri) ⇒ BaseLocation

Parameters:

  • file_uri (String)

    of the form scheme://arbitrary-stuff

Returns:

Raises:



65
66
67
68
69
70
# File 'lib/derivative_rodeo/storage_locations/base_location.rb', line 65

def self.from_uri(file_uri)
  location_name = file_uri.split('://').first
  raise Errors::StorageLocationMissing.new(file_uri: file_uri) if location_name.blank?

  load_location(location_name).new(file_uri)
end

.inherited(subclass) ⇒ Object



32
33
34
35
# File 'lib/derivative_rodeo/storage_locations/base_location.rb', line 32

def self.inherited(subclass)
  locations << subclass.location_name
  super
end

.load_location(location_name) ⇒ Class

Parameters:

  • location_name (String)

Returns:

  • (Class)

Raises:



55
56
57
58
59
# File 'lib/derivative_rodeo/storage_locations/base_location.rb', line 55

def self.load_location(location_name)
  location_name = location_name.split("://").first
  raise Errors::StorageLocationNotFoundError.new(location_name: location_name) unless locations.include?(location_name)
  "DerivativeRodeo::StorageLocations::#{location_name.to_s.classify}Location".constantize
end

.location_nameString Also known as: scheme

Returns:

  • (String)


39
40
41
# File 'lib/derivative_rodeo/storage_locations/base_location.rb', line 39

def self.location_name
  to_s.demodulize.underscore.sub(/_location$/, '')
end

.locationsArray<String>

Returns:

  • (Array<String>)


28
29
30
# File 'lib/derivative_rodeo/storage_locations/base_location.rb', line 28

def self.locations
  @locations ||= []
end

.register_location(location_name) ⇒ Object

Registers the location with the main StorageLocation class to it can be used

Parameters:

  • location_name (String)


76
77
78
79
80
# File 'lib/derivative_rodeo/storage_locations/base_location.rb', line 76

def self.register_location(location_name)
  return if DerivativeRodeo::StorageLocations::BaseLocation.locations.include?(location_name.to_s)

  DerivativeRodeo::StorageLocations::BaseLocation.locations << location_name.to_s
end

Instance Method Details

#derived_file_from(template:, **options) ⇒ StorageLocations::BaseLocation



206
207
208
209
# File 'lib/derivative_rodeo/storage_locations/base_location.rb', line 206

def derived_file_from(template:, **options)
  klass = DerivativeRodeo::StorageLocations::BaseLocation.load_location(template)
  klass.build(from_uri: file_path, template: template, **options)
end

#exist?TrueClass, FalseClass Also known as: exists?

Returns:

  • (TrueClass)

    when the file exists in this storage

  • (FalseClass)

    when the file does not exist in this storage

Raises:

  • (NotImplementedError)


196
197
198
# File 'lib/derivative_rodeo/storage_locations/base_location.rb', line 196

def exist?
  raise NotImplementedError, "#{self.class}#exist?"
end

#file_basenameObject



254
255
256
# File 'lib/derivative_rodeo/storage_locations/base_location.rb', line 254

def file_basename
  @file_basename ||= File.basename(file_path, file_extension)
end

#file_dirObject



242
243
244
# File 'lib/derivative_rodeo/storage_locations/base_location.rb', line 242

def file_dir
  @file_dir ||= File.dirname(file_path)
end

#file_extensionObject



250
251
252
# File 'lib/derivative_rodeo/storage_locations/base_location.rb', line 250

def file_extension
  @file_extension ||= File.extname(file_path)
end

#file_nameObject



246
247
248
# File 'lib/derivative_rodeo/storage_locations/base_location.rb', line 246

def file_name
  @file_name ||= File.basename(file_path)
end

#file_pathObject



238
239
240
# File 'lib/derivative_rodeo/storage_locations/base_location.rb', line 238

def file_path
  @file_path ||= @file_uri.sub(%r{.+://}, '')
end

#matching_locations_in_file_dir(tail_regexp:) ⇒ Enumerable<StorageLocations::BaseLocation>

When you have a known location and want to check for files that are within that location, use the #matching_locations_in_file_dir method. In the case of Generators::PdfSplitGenerator we need to know the path to all of the image files we “split” off of the given PDF.

We can use the :file_path as the prefix the given :tail_glob as the suffix for a “fully qualified” Dir.glob type search.

Parameters:

  • tail_regexp (Regexp)

Returns:

Raises:

  • (NotImplementedError)


223
224
225
# File 'lib/derivative_rodeo/storage_locations/base_location.rb', line 223

def matching_locations_in_file_dir(tail_regexp:)
  raise NotImplementedError, "#{self.class}#matching_locations_in_file_dir"
end

#tmp_file_dir(&block) ⇒ Object

Raises:

  • (ArgumentError)


258
259
260
261
262
# File 'lib/derivative_rodeo/storage_locations/base_location.rb', line 258

def tmp_file_dir(&block)
  raise ArgumentError, 'Expected a block' unless block_given?

  Dir.mktmpdir(&block)
end

#with_existing_tmp_path {|tmp_file_path| ... } ⇒ StorageLocations::BaseLocation

Yield Parameters:

  • tmp_file_path (String)

Returns:

Raises:

  • (NotImplementedError)


152
153
154
# File 'lib/derivative_rodeo/storage_locations/base_location.rb', line 152

def with_existing_tmp_path
  raise NotImplementedError, "#{self.class}#with_existing_tmp_path"
end

#with_new_extension(extension) ⇒ String

Returns the path for the new extension; when given SAME re-use the file’s extension.

Parameters:

Returns:

  • (String)

    the path for the new extension; when given SAME re-use the file’s extension.



231
232
233
234
235
236
# File 'lib/derivative_rodeo/storage_locations/base_location.rb', line 231

def with_new_extension(extension)
  return file_path if extension == StorageLocations::SAME

  # NOTE: May need to revisit this
  "#{file_path.split('.')[0]}.#{extension}"
end

#with_new_tmp_path(auto_write_file: true) {|tmp_file_path| ... } ⇒ StorageLocations::BaseLocation

Parameters:

  • auto_write_file (Boolean) (defaults to: true)

    Provided as a testing helper method.

Yield Parameters:

  • tmp_file_path (String)

Returns:

See Also:



142
143
144
145
146
147
# File 'lib/derivative_rodeo/storage_locations/base_location.rb', line 142

def with_new_tmp_path(auto_write_file: true, &block)
  with_tmp_path(lambda { |_file_path, tmp_file_path, exist|
                  FileUtils.rm_rf(tmp_file_path) if exist
                  FileUtils.touch(tmp_file_path)
                }, auto_write_file: auto_write_file, &block)
end

#with_tmp_path(preamble_lambda, auto_write_file: false) {|tmp_file_path| ... } ⇒ StorageLocations::BaseLocation

Parameters:

  • preamble_lambda (Lambda, #call)

    the “function” we should call to prepare the temporary location before we yield it’s location.

  • auto_write_file (Boolean) (defaults to: false)

    Provided as a testing helper method. Given that we have both #with_new_tmp_path and #with_existing_tmp_path, we want the default to not automatically perform the write. But this is something we can easily forget when working with the #with_new_tmp_path

Yield Parameters:

  • tmp_file_path (String)

Returns:

Raises:

  • (ArgumentError)


168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
# File 'lib/derivative_rodeo/storage_locations/base_location.rb', line 168

def with_tmp_path(preamble_lambda, auto_write_file: false)
  raise ArgumentError, 'Expected a block' unless block_given?

  tmp_file_dir do |tmpdir|
    self.tmp_file_path = File.join(tmpdir, file_dir, file_name)
    FileUtils.mkdir_p(File.dirname(tmp_file_path))
    preamble_lambda.call(file_path, tmp_file_path, exist?)
    yield tmp_file_path
    write if auto_write_file
  end
  # TODO: Do we need to ensure this?
  self.tmp_file_path = nil

  # In returning self we again remove the need for those calling #with_new_tmp_path,
  # #with_tmp_path, and #with_new_tmp_path to remember to return the current Location.
  # In other words removing the jagged edges of the code.
  self
end

#writeObject

Write the tmp file to the file_uri

Raises:

  • (NotImplementedError)


189
190
191
# File 'lib/derivative_rodeo/storage_locations/base_location.rb', line 189

def write
  raise NotImplementedError, "#{self.class}#write"
end