58 行
1.3 KiB
Ruby
58 行
1.3 KiB
Ruby
require 'digest'
|
|
require 'json'
|
|
|
|
class MaterialFileSha256
|
|
def self.blob_metadata blob
|
|
metadata = blob.metadata
|
|
return metadata if metadata.is_a?(Hash)
|
|
return { } if metadata.blank?
|
|
|
|
JSON.parse(metadata)
|
|
rescue JSON::ParserError
|
|
{ }
|
|
end
|
|
|
|
def self.metadata_sha256 blob
|
|
blob_metadata(blob)['sha256'].presence
|
|
end
|
|
|
|
def self.assign_metadata_sha256! blob, sha256
|
|
return if sha256.blank?
|
|
|
|
metadata = blob_metadata(blob)
|
|
metadata['sha256'] = sha256
|
|
blob.metadata = metadata
|
|
blob.save! if blob.changed?
|
|
end
|
|
|
|
def self.from_blob blob, allow_download: false
|
|
sha256 = metadata_sha256(blob)
|
|
return sha256 if sha256.present?
|
|
return nil unless allow_download
|
|
|
|
begin
|
|
blob.open do |file|
|
|
sha256 = Digest::SHA256.file(file.path).hexdigest
|
|
assign_metadata_sha256!(blob, sha256)
|
|
sha256
|
|
end
|
|
rescue ActiveStorage::FileNotFoundError, ArgumentError => error
|
|
Rails.logger.warn(
|
|
"MaterialFileSha256.from_blob failed for blob_id=#{blob.id}: " \
|
|
"#{error.class}: #{error.message}",
|
|
)
|
|
nil
|
|
end
|
|
end
|
|
|
|
def self.from_upload upload
|
|
tempfile = upload&.tempfile
|
|
return nil unless tempfile
|
|
|
|
tempfile.rewind
|
|
Digest::SHA256.file(tempfile.path).hexdigest.tap do
|
|
tempfile.rewind
|
|
end
|
|
end
|
|
end
|