From 165dab411004980eccbed6e390d1088a9ef972a1 Mon Sep 17 00:00:00 2001
From: gyangupta10 <gyan@cottagelabs.com>
Date: Thu, 8 Feb 2024 16:05:47 +0530
Subject: [PATCH 1/2] handle meta json file for all modalities

---
 hyrax/app/models/complex_modality.rb          |   2 +-
 hyrax/app/models/complex_session.rb           |   2 +-
 hyrax/app/models/complex_subject.rb           |   3 +-
 .../app/models/concerns/s3_file_handleable.rb | 113 ++++++++++++++++++
 hyrax/app/models/crc_dataset.rb               |   7 +-
 5 files changed, 123 insertions(+), 4 deletions(-)

diff --git a/hyrax/app/models/complex_modality.rb b/hyrax/app/models/complex_modality.rb
index 414870fe..43c0eaf5 100644
--- a/hyrax/app/models/complex_modality.rb
+++ b/hyrax/app/models/complex_modality.rb
@@ -15,7 +15,7 @@ class ComplexModality < ActiveRecord::Base
   validates :s3_folder_name, uniqueness: { scope: :parent_source_identifier, message: ->(object, data) { I18n.t('rdms.errors.complex_modality.title.uniqueness', value: object.s3_folder_name) } }
 
   before_validation :set_s3_folder_name
-  after_save :save_work_meta_json_file_to_s3, :reindex_crc_dataset, :relocate_files_on_folder_name_change
+  after_save :save_work_meta_json_file_to_s3, :reindex_crc_dataset, :relocate_files_on_folder_name_change, :handle_meta_file_on_s3
 
   delegate :crc_dataset, to: :complex_session
   delegate :complex_subject, to: :complex_session
diff --git a/hyrax/app/models/complex_session.rb b/hyrax/app/models/complex_session.rb
index 9e906a89..0a917db7 100644
--- a/hyrax/app/models/complex_session.rb
+++ b/hyrax/app/models/complex_session.rb
@@ -17,7 +17,7 @@ class ComplexSession < ActiveRecord::Base
   validates :s3_folder_name, uniqueness: { scope: :parent_source_identifier,  message: ->(object, data) { I18n.t('rdms.errors.complex_session.title.uniqueness', value: object.s3_folder_name) } }
 
   before_validation :set_s3_folder_name
-  after_save :save_work_meta_json_file_to_s3, :reindex_crc_dataset, :relocate_files_on_folder_name_change
+  after_save :save_work_meta_json_file_to_s3, :reindex_crc_dataset, :relocate_files_on_folder_name_change, :handle_meta_file_on_s3
 
   delegate :crc_dataset, to: :complex_subject
 
diff --git a/hyrax/app/models/complex_subject.rb b/hyrax/app/models/complex_subject.rb
index 39486440..2972cdf1 100644
--- a/hyrax/app/models/complex_subject.rb
+++ b/hyrax/app/models/complex_subject.rb
@@ -5,6 +5,7 @@ class ComplexSubject < ActiveRecord::Base
   include S3FileHandleable
 
   has_many :complex_sessions, foreign_key: 'parent_source_identifier', primary_key: 'source_identifier', dependent: :destroy
+  has_many :complex_modalities, through: :complex_sessions
 
   attribute :source_identifier, :string, default: -> { SecureRandom.uuid }
 
@@ -15,7 +16,7 @@ class ComplexSubject < ActiveRecord::Base
   validates :s3_folder_name, uniqueness: { scope: :parent_source_identifier,  message: ->(object, data) { I18n.t('rdms.errors.complex_subject.title.uniqueness', value: object.s3_folder_name) } }
 
   before_validation :set_s3_folder_name
-  after_save :save_work_meta_json_file_to_s3, :reindex_crc_dataset, :relocate_files_on_folder_name_change
+  after_save :save_work_meta_json_file_to_s3, :reindex_crc_dataset, :relocate_files_on_folder_name_change, :handle_meta_file_on_s3
 
   scope :sort_by_title, ->(source_identifier) {
     where(parent_source_identifier: source_identifier)
diff --git a/hyrax/app/models/concerns/s3_file_handleable.rb b/hyrax/app/models/concerns/s3_file_handleable.rb
index 931f661c..4d671601 100644
--- a/hyrax/app/models/concerns/s3_file_handleable.rb
+++ b/hyrax/app/models/concerns/s3_file_handleable.rb
@@ -9,4 +9,117 @@ module S3FileHandleable
 
     Hyrax::HandleS3FolderNameJob.perform_later(self.class.name, self.id, name_changes)
   end
+
+  def handle_meta_file_on_s3
+    s3 = S3StorageService.new
+    s3.init_client
+
+    crc_dataset = self.class.name == "CrcDataset" ? self.class.find(self.id) : self.crc_dataset
+    bucket_name = s3.sanitise_name(crc_dataset.id)
+    complex_modalities = self.class.name == "ComplexModality" ? [self] : self.complex_modalities.flatten
+
+    complex_modalities.each do |modality|
+      subject = modality.complex_subject
+      session = modality.complex_session
+      meta_file_key = "#{subject.s3_folder_name}/#{session.s3_folder_name}/#{modality.s3_folder_name}/meta.json"
+      json_data = prepare_json(crc_dataset, subject, session, modality)
+
+      s3.add_content(bucket_name, meta_file_key, json_data)
+    end
+  end
+
+  private
+
+  def prepare_json(crc_dataset, subject, session, modality)
+    @meta = {}
+
+    data_from_crc_dataset(crc_dataset)
+    data_from_complex_subject(subject)
+    data_from_complex_session(session)
+    data_from_complex_modality(modality)
+
+    @meta.to_json
+  end
+
+  def data_from_complex_subject(subject)
+    @meta["Subject ID"] = subject.id
+    @meta["Subject Species"] = subject.subject_species
+    @meta["Subject type"] = subject.subject_type
+    @meta["Subject sex"] = subject.subject_sex
+    @meta["Subject age"] = subject.subject_age
+  end
+
+  def data_from_complex_session(session)
+    # TODO Date recorded curruntly fetch from ComplexDate we need to confirm is this correct?
+  end
+
+  def data_from_complex_modality(modality)
+    @meta["Modality"] =  modality.modality
+  end
+
+  def data_from_crc_dataset(crc_dataset)
+    @meta["DublinCore-Title"] = crc_dataset.title[0]
+    @meta["Experiment title"] = crc_dataset.title[0]
+    @meta["DataCite-Title"] = crc_dataset.title[0]
+    @meta["DublinCore-Language"] = crc_dataset.language[0]
+    @meta["DataCite-Language"] = crc_dataset.language[0]
+    @meta["Resource Type"] = crc_dataset.resource_type[0]
+    @meta["Experiment Description"] = crc_dataset.experiment_description[0]
+    @meta["Group ID"] = "" # Complex Identifier removed
+    @meta["Animal|Ethics approval No."] = crc_dataset.approval_number
+    @meta["DublinCore-Subject"] = crc_dataset.subject.join("; ")
+    @meta["DataCite-Subject"] = crc_dataset.subject.join("; ")
+    @meta["DublinCore-Publisher"] =  crc_dataset.publisher[0]
+    @meta["DataCite-Publisher"] =  crc_dataset.publisher[0]
+    @meta["DublinCore-Coverage"] = crc_dataset.coverage
+    @meta["Software version"] = "" # TODO we don't have for now
+    @meta["Extra information"] = crc_dataset.extra_information[0]
+
+    data_from_complex_person(crc_dataset.complex_person)
+    data_from_complex_date(crc_dataset.complex_date)
+    data_from_complex_funding_reference(crc_dataset.complex_funding_reference)
+  end
+
+  def data_from_complex_person(complex_person)
+    return unless complex_person.any?
+
+    complex_person = complex_person.group_by{ |p| p.role[0] }
+
+    unless complex_person["creator"].nil?
+      @meta["Creator"] = complex_person["creator"].map{ |creator| "#{creator.first_name[0]}, #{creator.last_name[0]}" }.compact.join("; ")
+      @meta["DataCite-creatorName"] = @meta["Creator"]
+      @meta["DublinCore-Creator"] = @meta["Creator"]
+      @meta["DataCite-creatorFamilyName"] = complex_person["creator"].map{ |creator| creator.first_name[0] }.compact.join("; ")
+      @meta["DataCite-creatorGivenName"] = complex_person["creator"].map{ |creator| creator.last_name[0] }.compact.join("; ")
+      @meta["DataCite-creatorAffiliation"] = complex_person["creator"].map{ |creator| creator.affiliation[0] }.compact.join("; ")
+      @meta["DataCite-creatorNameIdentifier"] = complex_person["creator"].map{ |creator| creator.orcid[0] }.compact.join("; ")
+    end
+
+    unless complex_person["contributor"].nil?
+      @meta["contributor"] = complex_person["contributor"].map{ |contributor| "#{contributor.first_name[0]}, #{contributor.last_name[0]}" }.compact.join("; ")
+      @meta["DataCite-contributorName"] = @meta["contributor"]
+      @meta["DublinCore-Contributor"] = @meta["contributor"]
+      @meta["DataCite-contributorFamilyName"] = complex_person["contributor"].map{ |contributor| contributor.first_name[0] }.compact.join("; ")
+      @meta["DataCite-contributorGivenName"] = complex_person["contributor"].map{ |contributor| contributor.last_name[0] }.compact.join("; ")
+      @meta["DataCite-contirbutorAffiliation"] = complex_person["contributor"].map{ |contributor| contributor.affiliation[0] }.compact.join("; ")
+      @meta["DataCite-contributorNameIdentifier"] = complex_person["contributor"].map{ |contributor| contributor.orcid[0] }.compact.join("; ")
+    end
+  end
+
+  def data_from_complex_funding_reference(complex_funding_reference)
+    return unless complex_funding_reference.any?
+
+    @meta["DataCite-FundingReference"] = complex_funding_reference.map{ |funding| funding.funder_name[0] }.compact.join("; ")
+    @meta["DataCite-funderIdentifier"] = complex_funding_reference.map{ |funding| funding.funder_identifier[0] }.compact.join("; ")
+  end
+
+  def data_from_complex_date(complex_dates)
+    return unless complex_dates.any?
+
+    @meta["Record date"] = complex_dates.map{ |complex_date| complex_date.date[0] if complex_date.description[0] == "Recorded" }.compact.join("; ")
+    @meta["DataCite-dateType"] = complex_dates.map{ |complex_date| complex_date.description[0] if complex_date.description[0] != "Recorded" }.compact.join("; ")
+    @meta["DataCite-Date"] = complex_dates.map{ |complex_date| complex_date.date[0] if complex_date.description[0] != "Recorded" }.compact.join("; ")
+    @meta["DublinCore-Date"] = @meta["DataCite-Date"]
+  end
+
 end
diff --git a/hyrax/app/models/crc_dataset.rb b/hyrax/app/models/crc_dataset.rb
index 2296d319..053d47f0 100755
--- a/hyrax/app/models/crc_dataset.rb
+++ b/hyrax/app/models/crc_dataset.rb
@@ -6,12 +6,13 @@ class CrcDataset < ActiveFedora::Base
   include ::Hyrax::WorkBehavior
   include ::Hyrax::TombstoneBehavior
   include ExternalServices
+  include S3FileHandleable
   self.indexer = CrcDatasetIndexer
   # Change this to restrict which works can be added as a child.
   # self.valid_child_concerns = []
   validates :title, presence: { message: 'Your CRC dataset must have a title.' }
   validate :validate_parent_collection
-  after_save :save_work_meta_json_file_to_s3
+  after_save :save_work_meta_json_file_to_s3, :handle_meta_file_on_s3
   after_create :set_default_source_and_tombstone_status
   after_create :register_ark
 
@@ -144,6 +145,10 @@ class CrcDataset < ActiveFedora::Base
     ComplexSubject.where(parent_source_identifier: source.first)
   end
 
+  def complex_modalities
+    complex_subjects.map(&:complex_modalities)
+  end
+
   def file_sets_fast_load_metadata
     FileSetFastLoadMetadata.sort_and_filter_by_title_and_source(source.first)
   end
-- 
GitLab


From c5451a59488daa4e1d7bc165440f6307f5042af6 Mon Sep 17 00:00:00 2001
From: gyangupta10 <gyan@cottagelabs.com>
Date: Mon, 12 Feb 2024 12:13:55 +0530
Subject: [PATCH 2/2] make some changes

---
 hyrax/app/models/concerns/s3_file_handleable.rb | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/hyrax/app/models/concerns/s3_file_handleable.rb b/hyrax/app/models/concerns/s3_file_handleable.rb
index 4d671601..a31f3b56 100644
--- a/hyrax/app/models/concerns/s3_file_handleable.rb
+++ b/hyrax/app/models/concerns/s3_file_handleable.rb
@@ -16,7 +16,7 @@ module S3FileHandleable
 
     crc_dataset = self.class.name == "CrcDataset" ? self.class.find(self.id) : self.crc_dataset
     bucket_name = s3.sanitise_name(crc_dataset.id)
-    complex_modalities = self.class.name == "ComplexModality" ? [self] : self.complex_modalities.flatten
+    complex_modalities = self.class.name == "ComplexModality" ? [self] : self.complex_modalities.to_a.flatten
 
     complex_modalities.each do |modality|
       subject = modality.complex_subject
-- 
GitLab