このコミットが含まれているのは:
@@ -28,6 +28,13 @@ class MaterialSyncImporter
|
||||
Material
|
||||
.unscoped
|
||||
.find_or_initialize_by(normalized_source_key: key)
|
||||
if unchanged?(material, source)
|
||||
return Result.new(material:,
|
||||
action: :unchanged,
|
||||
suppressed: false,
|
||||
suppression: nil)
|
||||
end
|
||||
|
||||
event_type =
|
||||
if material.new_record?
|
||||
:create
|
||||
@@ -43,7 +50,7 @@ class MaterialSyncImporter
|
||||
MaterialVersionRecorder.ensure_snapshot!(material,
|
||||
created_by_user: @attributes[:updated_by_user])
|
||||
end
|
||||
material.assign_attributes(material_attributes.merge(source))
|
||||
material.assign_attributes(material_attributes_for(material).merge(source))
|
||||
material.discarded_at = nil if material.respond_to?(:discarded_at=)
|
||||
material.file.attach(uploaded_blob) if uploaded_blob
|
||||
material.save!
|
||||
@@ -81,10 +88,28 @@ class MaterialSyncImporter
|
||||
source_file_id: source[:source_file_id])
|
||||
end
|
||||
|
||||
def material_attributes
|
||||
@attributes.except(:source_kind, :source_uri, :source_path, :source_file_id,
|
||||
:file_blob, :file_tempfile, :filename, :content_type,
|
||||
:file_sha256, :export_path, :profile)
|
||||
def material_attributes_for material
|
||||
attrs =
|
||||
@attributes
|
||||
.except(:source_kind, :source_uri, :source_path, :source_file_id,
|
||||
:file_blob, :file_tempfile, :file_downloader,
|
||||
:filename, :content_type,
|
||||
:file_sha256, :export_path, :profile, :tag, :url)
|
||||
|
||||
if material.new_record?
|
||||
attrs[:tag] = @attributes[:tag] if @attributes.key?(:tag)
|
||||
attrs[:url] = @attributes[:url] if @attributes.key?(:url)
|
||||
return attrs
|
||||
end
|
||||
|
||||
if @attributes.key?(:tag) && @attributes[:tag].present?
|
||||
attrs[:tag] = @attributes[:tag]
|
||||
end
|
||||
if @attributes.key?(:url) && @attributes[:url].present?
|
||||
attrs[:url] = @attributes[:url]
|
||||
end
|
||||
|
||||
attrs
|
||||
end
|
||||
|
||||
def suppression_for source
|
||||
@@ -100,7 +125,7 @@ class MaterialSyncImporter
|
||||
def uploaded_blob!
|
||||
return @attributes[:file_blob] if @attributes[:file_blob]
|
||||
|
||||
tempfile = @attributes[:file_tempfile]
|
||||
tempfile = upload_tempfile
|
||||
return nil unless tempfile
|
||||
|
||||
tempfile.rewind
|
||||
@@ -115,18 +140,22 @@ class MaterialSyncImporter
|
||||
blob
|
||||
end
|
||||
|
||||
def upload_tempfile
|
||||
return @upload_tempfile if defined?(@upload_tempfile)
|
||||
|
||||
@upload_tempfile = @attributes[:file_tempfile]
|
||||
if @upload_tempfile.blank? && @attributes[:file_downloader]
|
||||
@upload_tempfile = @attributes[:file_downloader].call
|
||||
end
|
||||
@upload_tempfile
|
||||
end
|
||||
|
||||
def upsert_export_item! material
|
||||
export_path = @attributes[:export_path].to_s.strip
|
||||
export_path = resolved_export_path(material)
|
||||
return if export_path.blank?
|
||||
|
||||
profile = @attributes[:profile].presence || 'legacy_drive'
|
||||
path = export_path
|
||||
if export_path_taken_by_other?(material, profile, path)
|
||||
path = MaterialSyncExportPath.uniquify(path, @attributes[:source_file_id])
|
||||
end
|
||||
|
||||
item = material.material_export_items.find_or_initialize_by(profile:)
|
||||
item.export_path = path
|
||||
item = material.material_export_items.find_or_initialize_by(profile: effective_profile)
|
||||
item.export_path = export_path
|
||||
item.enabled = true
|
||||
item.created_by_user ||= @attributes[:created_by_user]
|
||||
item.save!
|
||||
@@ -140,11 +169,78 @@ class MaterialSyncImporter
|
||||
end
|
||||
|
||||
def close_tempfile!
|
||||
tempfile = @attributes[:file_tempfile]
|
||||
tempfile = upload_tempfile
|
||||
return unless tempfile
|
||||
|
||||
tempfile.close! unless tempfile.closed?
|
||||
rescue StandardError
|
||||
nil
|
||||
end
|
||||
|
||||
def unchanged? material, source
|
||||
return false if material.new_record? || material.discarded?
|
||||
return false unless same_source_attributes?(material, source)
|
||||
return false unless same_export_path?(material)
|
||||
return false unless same_material_attributes?(material)
|
||||
|
||||
same_file_snapshot?(material)
|
||||
end
|
||||
|
||||
def same_source_attributes? material, source
|
||||
material.source_kind == source[:source_kind] \
|
||||
&& material.source_uri == source[:source_uri] \
|
||||
&& material.source_path == source[:source_path] \
|
||||
&& material.source_file_id == source[:source_file_id]
|
||||
end
|
||||
|
||||
def same_export_path? material
|
||||
expected = resolved_export_path(material)
|
||||
current = material.material_export_items.find { |item| item.profile == effective_profile }
|
||||
|
||||
return current.blank? if expected.blank?
|
||||
|
||||
current&.enabled && current.export_path == expected
|
||||
end
|
||||
|
||||
def same_material_attributes? material
|
||||
same_tag_attribute?(material) && same_url_attribute?(material)
|
||||
end
|
||||
|
||||
def same_file_snapshot? material
|
||||
expected_sha256 = @attributes[:file_sha256].to_s.presence
|
||||
|
||||
if expected_sha256.present?
|
||||
return false unless material.file.attached?
|
||||
|
||||
return material.file.blob.metadata['sha256'] == expected_sha256
|
||||
end
|
||||
|
||||
!material.file.attached?
|
||||
end
|
||||
|
||||
def effective_profile
|
||||
@attributes[:profile].presence || 'legacy_drive'
|
||||
end
|
||||
|
||||
def resolved_export_path material
|
||||
export_path = @attributes[:export_path].to_s.strip
|
||||
return export_path if export_path.blank?
|
||||
return export_path unless export_path_taken_by_other?(material, effective_profile, export_path)
|
||||
|
||||
MaterialSyncExportPath.uniquify(export_path, @attributes[:source_file_id])
|
||||
end
|
||||
|
||||
def same_tag_attribute? material
|
||||
return true unless @attributes.key?(:tag)
|
||||
return true if @attributes[:tag].blank?
|
||||
|
||||
material.tag_id == @attributes[:tag].id
|
||||
end
|
||||
|
||||
def same_url_attribute? material
|
||||
return true unless @attributes.key?(:url)
|
||||
return true if @attributes[:url].blank?
|
||||
|
||||
material.url == @attributes[:url]
|
||||
end
|
||||
end
|
||||
|
||||
新しい課題から参照
ユーザをブロックする