Class: FilePipeline::VersionedFile
- Inherits:
-
Object
- Object
- FilePipeline::VersionedFile
- Extended by:
- Forwardable
- Includes:
- FileOperations::ExifManipulable
- Defined in:
- lib/file_pipeline/versioned_file.rb
Overview
VersionedFile creates a directory where it stores any versions of file.
Instance Attribute Summary collapse
-
#basename ⇒ Object
readonly
The basename of the versioned file.
-
#history ⇒ Object
readonly
A hash with file paths as keys, information on the modifications applied to create the version as values (instances of FileOperations::Results).
-
#original ⇒ Object
readonly
The path to the original file of self.
-
#target_suffix ⇒ Object
readonly
A String that is appended to the file basename when the file written by #finalize is not replacing the original.
Instance Method Summary collapse
-
#<<(version_info) ⇒ Object
Adds a new version to #history and returns self.
-
#changed? ⇒ Boolean
Returns
trueif there are #versions (file has been modified). -
#clone ⇒ Object
(also: #touch)
Creates a new identical version of #current.
-
#current ⇒ Object
Returns the path to the current file or the #original if no versions have been created.
-
#current_extension ⇒ Object
Returns the file extension for the #current file.
-
#directory ⇒ Object
Returns the path to the directory where the versioned of
selfare stored. -
#finalize(overwrite: false) ⇒ Object
Writes the #current version to #basename, optionally the #target_suffix, and the #current_extension in #original_dir.
-
#initialize(file, target_suffix: SecureRandom.hex(4)) ⇒ VersionedFile
constructor
Returns a new instance with
fileas the #original. -
#metadata(for_version: :current) ⇒ Object
Returns the Exif metadata.
-
#modify ⇒ Object
Creates a new version.
-
#original_dir ⇒ Object
Returns the directory where #original is stored.
-
#recovered_metadata ⇒ Object
Returns a hash into which all captured data from file operations with the FileOperations::CapturedDataTags::DROPPED_EXIF_DATA has been merged.
Methods included from FileOperations::ExifManipulable
#delete_tags, file_tags, #missing_exif_fields, #parse_exif_errors, parse_tag_error, #read_exif, strip_path, #write_exif
Constructor Details
#initialize(file, target_suffix: SecureRandom.hex(4)) ⇒ VersionedFile
Returns a new instance with file as the #original.
Arguments
-
file- Path to the file the instance will be based on. That file should not be touched unless #finalize is called with the:overwriteoption set totrue.
Caveat it can not be ruled out that buggy or malignant file operations modify the original.
Options
<tt>target_suffix</ttm> is a string to be appended to the file that will be written by #finalize (the last version) if #finalize is to preserve the original. It is recommended to use a randomized string (default) to avoid clashes with other files in the directory.
69 70 71 72 73 74 75 76 77 78 |
# File 'lib/file_pipeline/versioned_file.rb', line 69 def initialize(file, target_suffix: SecureRandom.hex(4)) raise Errors::MissingVersionFileError, file: file unless File.exist? file @original = file @basename = File.basename(file, '.*') @history = Versions::History.new @directory = nil @target_suffix = target_suffix history[original] = nil end |
Instance Attribute Details
#basename ⇒ Object (readonly)
The basename of the versioned file.
10 11 12 |
# File 'lib/file_pipeline/versioned_file.rb', line 10 def basename @basename end |
#history ⇒ Object (readonly)
A hash with file paths as keys, information on the modifications applied to create the version as values (instances of FileOperations::Results).
14 15 16 |
# File 'lib/file_pipeline/versioned_file.rb', line 14 def history @history end |
#original ⇒ Object (readonly)
The path to the original file of self.
17 18 19 |
# File 'lib/file_pipeline/versioned_file.rb', line 17 def original @original end |
#target_suffix ⇒ Object (readonly)
A String that is appended to the file basename when the file written by #finalize is not replacing the original.
21 22 23 |
# File 'lib/file_pipeline/versioned_file.rb', line 21 def target_suffix @target_suffix end |
Instance Method Details
#<<(version_info) ⇒ Object
Adds a new version to #history and returns self.
version_info must be a path to an existing file or an array with the path and optionally a FileOperations::Results instance: ['path/to/file', results_object]. Will raise MisplacedVersionFileError if it is in another directory.
86 87 88 89 90 91 92 93 94 |
# File 'lib/file_pipeline/versioned_file.rb', line 86 def <<(version_info) version, info = Versions::Validator[version_info, self] version ||= @current @history[version] = info self rescue StandardError => e reset raise e end |
#changed? ⇒ Boolean
Returns true if there are #versions (file has been modified).
Warning: It will also return true if the file has been cloned.
99 100 101 |
# File 'lib/file_pipeline/versioned_file.rb', line 99 def changed? current != original end |
#clone ⇒ Object Also known as: touch
Creates a new identical version of #current. Will only add the path of the file to history, but no FileOperations::Results.
105 106 107 108 109 |
# File 'lib/file_pipeline/versioned_file.rb', line 105 def clone filename = FilePipeline.new_basename + current_extension clone_file = Versions.copy(current, directory, filename) self << clone_file end |
#current ⇒ Object
Returns the path to the current file or the #original if no versions have been created.
113 114 115 |
# File 'lib/file_pipeline/versioned_file.rb', line 113 def current versions.last || original end |
#current_extension ⇒ Object
Returns the file extension for the #current file.
118 119 120 |
# File 'lib/file_pipeline/versioned_file.rb', line 118 def current_extension File.extname current end |
#directory ⇒ Object
Returns the path to the directory where the versioned of self are stored. Creates the directory if it does not exist.
124 125 126 |
# File 'lib/file_pipeline/versioned_file.rb', line 124 def directory @directory ||= workdir end |
#finalize(overwrite: false) ⇒ Object
Writes the #current version to #basename, optionally the #target_suffix, and the #current_extension in #original_dir. Deletes all versions and resets the #history to an empty Hash. Returns the path to the written file.
If the optional block is passed, it will be evaluated before the file is finalized.
Options
-
overwrite-trueorfalse-
false(default) - The #target_suffix will be appended to the #basename and the #original will be preserved. -
true- The finalized version will replace the #original.
-
142 143 144 145 146 147 148 149 150 151 |
# File 'lib/file_pipeline/versioned_file.rb', line 142 def finalize(overwrite: false) yield(self) if block_given? return original unless changed? filename = overwrite ? replacing_target : preserving_target FileUtils.rm original if overwrite @original = Versions.copy(current, original_dir, filename) ensure reset end |
#metadata(for_version: :current) ⇒ Object
Returns the Exif metadata
Options
-
:for_version-currentororiginal-
current(default) - Metadata for the #current file will be returned. -
original- Metadata for the #original file will be returned.
-
– TODO: when file is not an image file, this should return other metadata than exif. ++
166 167 168 169 170 171 172 173 174 |
# File 'lib/file_pipeline/versioned_file.rb', line 166 def (for_version: :current) file = case for_version when :current, :original public_send for_version else for_version end read_exif(file).first end |
#modify ⇒ Object
Creates a new version. Requires a block that must return a path to an existing file or an array with the path and optionally a FileOperations::Results instance: ['path/to/file', results_object].
The actual file modification logic will be in the block.
The block must take three arguments: for the #current file (from which the modified version will be created), the work #directory (to where the modified file will be written), and the #original file (which will only be used in modifications that need the original file for reference, such as modifications that restore file metadata that was lost in other modifications).
189 190 191 |
# File 'lib/file_pipeline/versioned_file.rb', line 189 def modify self << yield(current, directory, original) end |
#original_dir ⇒ Object
Returns the directory where #original is stored.
194 195 196 |
# File 'lib/file_pipeline/versioned_file.rb', line 194 def original_dir File.dirname original end |
#recovered_metadata ⇒ Object
Returns a hash into which all captured data from file operations with the FileOperations::CapturedDataTags::DROPPED_EXIF_DATA has been merged.
200 201 202 203 204 205 |
# File 'lib/file_pipeline/versioned_file.rb', line 200 def return unless changed? captured_data_with(FileOperations::CapturedDataTags::DROPPED_EXIF_DATA) &.reduce({}) { |recovered, data| recovered.merge data } end |