diff --git a/backend/app/controllers/materials_controller.rb b/backend/app/controllers/materials_controller.rb index ffc4e6d..d438a73 100644 --- a/backend/app/controllers/materials_controller.rb +++ b/backend/app/controllers/materials_controller.rb @@ -523,10 +523,7 @@ class MaterialsController < ApplicationController content_type: file.content_type, ) - if file_sha256.present? - blob.metadata['sha256'] = file_sha256 - blob.save! if blob.changed? - end + MaterialFileSha256.assign_metadata_sha256!(blob, file_sha256) blob ensure diff --git a/backend/app/models/material.rb b/backend/app/models/material.rb index f8536e1..dd0aa22 100644 --- a/backend/app/models/material.rb +++ b/backend/app/models/material.rb @@ -1,6 +1,9 @@ class Material < ApplicationRecord include MyDiscard + SOURCE_KINDS = ['uri', 'google_drive_path', 'google_drive_file', + 'legacy_drive_path'].freeze + default_scope -> { kept } belongs_to :parent, class_name: 'Material', optional: true @@ -20,7 +23,7 @@ class Material < ApplicationRecord validates :tag_id, uniqueness: true, allow_nil: true validates :source_kind, - inclusion: { in: MaterialSyncSuppression::SOURCE_KINDS }, + inclusion: { in: SOURCE_KINDS }, allow_blank: true validate :file_must_be_attached diff --git a/backend/app/services/material_file_sha256.rb b/backend/app/services/material_file_sha256.rb index f9a19b0..31ad4d0 100644 --- a/backend/app/services/material_file_sha256.rb +++ b/backend/app/services/material_file_sha256.rb @@ -1,16 +1,39 @@ 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 = blob.metadata['sha256'] + 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 - blob.metadata['sha256'] = sha256 - blob.save! if blob.changed? + assign_metadata_sha256!(blob, sha256) sha256 end rescue ActiveStorage::FileNotFoundError, ArgumentError => error diff --git a/backend/app/services/material_sync_importer.rb b/backend/app/services/material_sync_importer.rb index 34c0357..1912446 100644 --- a/backend/app/services/material_sync_importer.rb +++ b/backend/app/services/material_sync_importer.rb @@ -148,8 +148,7 @@ class MaterialSyncImporter io: tempfile, filename: @attributes[:filename], content_type: @attributes[:content_type]) - blob.metadata['sha256'] = file_sha256 if file_sha256.present? - blob.save! if blob.changed? + MaterialFileSha256.assign_metadata_sha256!(blob, file_sha256) tempfile.rewind blob end @@ -226,7 +225,7 @@ class MaterialSyncImporter if expected_sha256.present? return false unless material.file.attached? - return material.file.blob.metadata['sha256'] == expected_sha256 + return MaterialFileSha256.metadata_sha256(material.file.blob) == expected_sha256 end !material.file.attached? diff --git a/backend/app/services/material_version_recorder.rb b/backend/app/services/material_version_recorder.rb index 6a91a31..8f268f7 100644 --- a/backend/app/services/material_version_recorder.rb +++ b/backend/app/services/material_version_recorder.rb @@ -57,7 +57,7 @@ class MaterialVersionRecorder < VersionRecorder file_content_type: blob.content_type, file_byte_size: blob.byte_size, file_checksum: blob.checksum, - file_sha256: blob.metadata['sha256'] } + file_sha256: MaterialFileSha256.metadata_sha256(blob) } end def empty_file_snapshot