From 750b4cefe02f360c06f9338e6a1d0da4b94af64a Mon Sep 17 00:00:00 2001 From: Shana Moore Date: Mon, 6 May 2024 15:55:14 -0700 Subject: [PATCH 1/5] =?UTF-8?q?=F0=9F=9A=A7=20i205=20-=20add=20ability=20t?= =?UTF-8?q?o=20upload=20thumbnails?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit is implemented following the precendence set by collection branding's banner and logo uploads. TODO: - add and update specs - attach image to collection thumbnails - thumbnails should link to the associated collection --- app/assets/javascripts/hyrax/fileupload.js | 9 +++ .../collections_controller_decorator.rb | 53 +++++++++---- .../forms/pcdm_collection_form_decorator.rb | 18 +++++ .../collections/_form_branding.html.erb | 74 +++++++++++++++++++ .../uploads/_js_templates_branding.html.erb | 37 ++++++++++ config/initializers/hyrax.rb | 20 ++++- .../collection_update_decorator.rb | 25 +++++++ .../steps/save_collection_thumbnail.rb | 59 +++++++++++++++ 8 files changed, 278 insertions(+), 17 deletions(-) create mode 100644 app/assets/javascripts/hyrax/fileupload.js create mode 100644 lib/hyrax/transactions/collection_update_decorator.rb create mode 100644 lib/hyrax/transactions/steps/save_collection_thumbnail.rb diff --git a/app/assets/javascripts/hyrax/fileupload.js b/app/assets/javascripts/hyrax/fileupload.js new file mode 100644 index 0000000000..bda9f4c911 --- /dev/null +++ b/app/assets/javascripts/hyrax/fileupload.js @@ -0,0 +1,9 @@ +//= require hyrax/uploader +// This file is the default initialization of the fileupload. If you want to call +// hyraxUploader with other options (like afterSubmit), then override this file. +Blacklight.onLoad(function() { + var options = {}; + $('#fileupload').hyraxUploader(options); + $('#fileuploadlogo').hyraxUploader({downloadTemplateId: 'logo-template-download'}); + $('#fileuploadthumbnail').hyraxUploader({downloadTemplateId: 'thumbnail-template-download'}); +}); diff --git a/app/controllers/hyrax/dashboard/collections_controller_decorator.rb b/app/controllers/hyrax/dashboard/collections_controller_decorator.rb index e7dc0e7f7c..367093573d 100644 --- a/app/controllers/hyrax/dashboard/collections_controller_decorator.rb +++ b/app/controllers/hyrax/dashboard/collections_controller_decorator.rb @@ -3,6 +3,9 @@ # OVERRIDE Hyrax v5.0.0rc2 # - Fix file upload in logo and banner # - Use work titles for collection thumbnail select & to add an option to reset to the default thumbnail + +# OVERRIDE Hyrax v5.0.0 to add the ability to upload a collection thumbnail + module Hyrax module Dashboard ## Shows a list of all collections to the admins @@ -14,16 +17,36 @@ def show super end - private - - def configure_show_sort_fields - # In the CollectionsControllerDecorator, we clear the sort fields and add our own to have - # the ability to sort the index with custom fields. However, this also affects the show page. - # Here we set the sort fields back to the defaults for the show page. - blacklight_config.sort_fields = CatalogController.blacklight_config.sort_fields + # OVERRIDE Hyrax v5.0.0 to add the ability to upload a collection thumbnail - START + def process_branding + process_banner_input + process_logo_input + process_thumbnail_input end - public + # rubocop:disable Metrics/AbcSize + def update_valkyrie_collection + return after_update_errors(form_err_msg(form)) unless form.validate(collection_params) + + result = transactions['change_set.update_collection'] + .with_step_args( + 'collection_resource.save_collection_banner' => { update_banner_file_ids: params["banner_files"], + banner_unchanged_indicator: params["banner_unchanged"] }, + 'collection_resource.save_collection_logo' => { update_logo_file_ids: params["logo_files"], + alttext_values: params["alttext"], + linkurl_values: params["linkurl"] }, + 'collection_resource.save_collection_thumbnail' => { update_thumbnail_file_ids: params["thumbnail_files"], + thumbnail_unchanged_indicator: params["thumbnail_unchanged"], + alttext_values: params["thumbnail_text"] } + ) + .call(form) + @collection = result.value_or { return after_update_errors(result.failure.first) } + + process_member_changes + after_update_response + end + # rubocop:enable Metrics/AbcSize + # OVERRIDE Hyrax v5.0.0 to add the ability to upload a collection thumbnail - END def edit form @@ -47,13 +70,6 @@ def update super end - def process_branding - super - - # TODO: does this still work? - process_uploaded_thumbnail(params[:collection][:thumbnail_upload]) if params[:collection][:thumbnail_upload] - end - # Deletes any previous thumbnails. The thumbnail indexer (see services/hyrax/indexes_thumbnails) # checks if an uploaded thumbnail exists in the public folder before indexing the thumbnail path. def delete_uploaded_thumbnail @@ -99,6 +115,13 @@ def files private + def configure_show_sort_fields + # In the CollectionsControllerDecorator, we clear the sort fields and add our own to have + # the ability to sort the index with custom fields. However, this also affects the show page. + # Here we set the sort fields back to the defaults for the show page. + blacklight_config.sort_fields = CatalogController.blacklight_config.sort_fields + end + # branding specific methods def process_banner_input return update_existing_banner if params["banner_unchanged"] == "true" diff --git a/app/forms/hyrax/forms/pcdm_collection_form_decorator.rb b/app/forms/hyrax/forms/pcdm_collection_form_decorator.rb index d7765a6f5b..ee5e377533 100644 --- a/app/forms/hyrax/forms/pcdm_collection_form_decorator.rb +++ b/app/forms/hyrax/forms/pcdm_collection_form_decorator.rb @@ -1,7 +1,25 @@ # frozen_string_literal: true +# OVERRIDE Hyraxv5.0.0 to add the ability to upload a collection thumbnail Hyrax::Forms::PcdmCollectionForm.class_eval do include Hyrax::FormFields(:basic_metadata) include Hyrax::FormFields(:bulkrax_metadata) include CollectionAccessFiltering + + ThumbnailInfoPrepopulator = lambda do |_options = nil| + self.thumbnail_info ||= begin + thumbnail_info = CollectionBrandingInfo.where(collection_id: id.to_s, role: "thumbnail").first + if thumbnail_info + thumbnail_file = File.split(thumbnail_info.local_path).last + alttext = thumbnail_info.alt_text + file_location = thumbnail_info.local_path + relative_path = "/" + thumbnail_info.local_path.split("/")[-4..-1].join("/") + { file: thumbnail_file, full_path: file_location, relative_path:, alttext: } + else + {} # Always return at least an empty hash + end + end + end + + property :thumbnail_info, virtual: true, prepopulator: ThumbnailInfoPrepopulator end diff --git a/app/views/hyrax/dashboard/collections/_form_branding.html.erb b/app/views/hyrax/dashboard/collections/_form_branding.html.erb index 14df747e2f..da3f3de2ba 100644 --- a/app/views/hyrax/dashboard/collections/_form_branding.html.erb +++ b/app/views/hyrax/dashboard/collections/_form_branding.html.erb @@ -163,4 +163,78 @@ + +
+ + + + + +
+
+ + + + <%= t('.choose_file') %> + + +
+ + +
+ +
+
+
+ +
 
+
+
+ +
+
+
+ <%# Where the request to display the branding comes from. %> + <% if f.object.thumbnail_info[:file] %> +
+
+
+ + <%= image_tag(f.object.thumbnail_info[:relative_path], + height: "36", + alt: f.object.thumbnail_info[:alttext].presence || f.object.thumbnail_info[:file]) %> + <%= f.object.thumbnail_info[:file] %> + + +
+
+ +
+ +
+ +
+
+
+ + <% else %> + + <% end %> + + + +
+
+
+
+ diff --git a/app/views/hyrax/uploads/_js_templates_branding.html.erb b/app/views/hyrax/uploads/_js_templates_branding.html.erb index be00d2b198..3093653abe 100644 --- a/app/views/hyrax/uploads/_js_templates_branding.html.erb +++ b/app/views/hyrax/uploads/_js_templates_branding.html.erb @@ -124,3 +124,40 @@ {% } %} + + + \ No newline at end of file diff --git a/config/initializers/hyrax.rb b/config/initializers/hyrax.rb index 444554a0ce..b61e79962c 100644 --- a/config/initializers/hyrax.rb +++ b/config/initializers/hyrax.rb @@ -145,10 +145,22 @@ # Temporary path to hold uploads before they are ingested into FCrepo. # This must be a lambda that returns a Pathname config.upload_path = lambda { - if Site.account&.s3_bucket + if Site.account&.s3_bucket.present? + # For S3, no need to create directories "uploads/#{Apartment::Tenant.current}" else - ENV['HYRAX_UPLOAD_PATH'].present? ? Pathname.new(File.join(ENV['HYRAX_UPLOAD_PATH'], Apartment::Tenant.current)) : Rails.public_path.join('uploads', Apartment::Tenant.current) + # Determine the base upload path + base_path = if ENV['HYRAX_UPLOAD_PATH'].present? + Pathname.new(File.join(ENV['HYRAX_UPLOAD_PATH'], Apartment::Tenant.current)) + else + Rails.root.join('uploads', Apartment::Tenant.current) + end + + # Create the directory if it doesn't exist + FileUtils.mkdir_p(base_path) unless Dir.exist?(base_path) + + # Return the path + base_path end } @@ -242,3 +254,7 @@ Hyrax::MemberPresenterFactory.file_presenter_class = Hyrax::IiifAv::IiifFileSetPresenter Hyrax::PcdmMemberPresenterFactory.file_presenter_class = Hyrax::IiifAv::IiifFileSetPresenter + +Hyrax::Transactions::Container.namespace('collection_resource') do |ops| + ops.register 'save_collection_thumbnail', Hyrax::Transactions::Steps::SaveCollectionThumbnail.new +end diff --git a/lib/hyrax/transactions/collection_update_decorator.rb b/lib/hyrax/transactions/collection_update_decorator.rb new file mode 100644 index 0000000000..3f5ec856a9 --- /dev/null +++ b/lib/hyrax/transactions/collection_update_decorator.rb @@ -0,0 +1,25 @@ +# frozen_string_literal: true + +# Require the necessary file at the beginning +require 'hyrax/transactions/transaction' + +# OVERRIDE Hyrax v5.0.0 to add the ability to upload a collection thumbnail +module Hyrax + module Transactions + # Use class_eval to reopen the class for modification + CollectionUpdate.class_eval do + # Override the initialize method to alter the default steps + def initialize(container: Container, steps: nil) + # Define the new steps array including the new thumbnail step + new_steps = ['change_set.apply', + 'collection_resource.save_collection_banner', + 'collection_resource.save_collection_logo', + 'collection_resource.save_collection_thumbnail', # Your new step + 'collection_resource.save_acl'].freeze + + # Use the new steps array if steps argument is nil, else use provided steps + super(container:, steps: steps || new_steps) + end + end + end +end diff --git a/lib/hyrax/transactions/steps/save_collection_thumbnail.rb b/lib/hyrax/transactions/steps/save_collection_thumbnail.rb new file mode 100644 index 0000000000..777865cb77 --- /dev/null +++ b/lib/hyrax/transactions/steps/save_collection_thumbnail.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true +module Hyrax + module Transactions + module Steps + ## + # Adds thumbnail info via `ChangeSet`. + # + # During the update collection process this step is called to update the file + # to be used as a the thumbnail for the collection. + # + class SaveCollectionThumbnail + include Dry::Monads[:result] + + ## + # @param [Hyrax::ChangeSet] change_set + # @param [Array] update_thumbnail_file_ids + # @param [Boolean] thumbnail_unchanged_indicator + # + # @return [Dry::Monads::Result] `Failure` if the thumbnail info fails to save; + # `Success(input)`, otherwise. + def call(collection_resource, update_thumbnail_file_ids: nil, thumbnail_unchanged_indicator: true, alttext_values: nil) + return Success(collection_resource) if ActiveModel::Type::Boolean.new.cast(thumbnail_unchanged_indicator) + collection_id = collection_resource.id.to_s + process_thumbnail_input(collection_id:, update_thumbnail_file_ids:, alttext_values:) + Success(collection_resource) + end + + private + + def process_thumbnail_input(collection_id:, update_thumbnail_file_ids:, alttext_values:) + remove_thumbnail(collection_id:) + add_new_thumbnail(collection_id:, uploaded_file_ids: update_thumbnail_file_ids, alttext_values:) if update_thumbnail_file_ids + end + + def remove_thumbnail(collection_id:) + thumbnail_info = CollectionBrandingInfo.where(collection_id:).where(role: "thumbnail") + thumbnail_info&.delete_all + end + + def add_new_thumbnail(collection_id:, uploaded_file_ids:, alttext_values:) + file = uploaded_files(uploaded_file_ids).first + thumbnail_info = CollectionBrandingInfo.new( + collection_id:, + filename: File.split(file.file_url).last, + role: "thumbnail", + alt_txt: alttext_values.first, + target_url: "TODO: link to the collection" + ) + thumbnail_info.save file.file_url + end + + def uploaded_files(uploaded_file_ids) + return [] if uploaded_file_ids.empty? + UploadedFile.find(uploaded_file_ids) + end + end + end + end +end From d6dd1d2660f89e735593e7c47137e565ee8f3893 Mon Sep 17 00:00:00 2001 From: Kirk Wang Date: Tue, 7 May 2024 15:12:35 -0700 Subject: [PATCH 2/5] Make collection thumbnails show in the views This commit will make the collection thumbnails show up in the views such as in the dashboard list of collections and also in the catalog search results. The gitignore was updated to ignore the path where the thumbnails are stored. --- .gitignore | 1 + app/assets/stylesheets/hyku.scss | 23 +++++++++++++++++++ app/helpers/application_helper.rb | 3 ++- .../hyrax/thumbnail_path_service_decorator.rb | 9 ++++++++ .../collections/_form_branding.html.erb | 7 ++++-- 5 files changed, 40 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index ff801b915b..30b8fc4a3c 100644 --- a/.gitignore +++ b/.gitignore @@ -57,3 +57,4 @@ docker-compose.override.yml *~undo-tree~ .DS_Store /bundler.d/ +/uploads diff --git a/app/assets/stylesheets/hyku.scss b/app/assets/stylesheets/hyku.scss index 2cb19d2b1a..0d1f6a2f48 100644 --- a/app/assets/stylesheets/hyku.scss +++ b/app/assets/stylesheets/hyku.scss @@ -649,3 +649,26 @@ span.constraint-value p, .facet-values p { tr[data-feature="use-iiif-print"] { display: none; } + +// collection branding thumbnail +div.branding-thumbnail-row { + border-top: solid 1px #dddddd; + padding-top: 10px; +} + +input.branding-thumbnail-input { + width: 250px; +} + +div.branding-thumbnail-input { + text-align: right; +} + +button.branding-thumbnail-remove, +button.branding-thumbnail-remove:hover { + background-color: #ffffff; + border-color: #ffffff; + color: $brand-danger; + font-weight: normal; + text-decoration: underline; +} diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index fd8844b4d8..3d51475777 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -12,7 +12,8 @@ def group_navigation_presenter @group_navigation_presenter ||= Hyku::Admin::Group::NavigationPresenter.new(params:) end - def collection_thumbnail(_document, _image_options = {}, _url_options = {}) + def collection_thumbnail(document, _image_options = {}, _url_options = {}) + return image_tag(document['thumbnail_path_ss']) if document['thumbnail_path_ss'].present? return super if Site.instance.default_collection_image.blank? image_tag(Site.instance.default_collection_image&.url) diff --git a/app/services/hyrax/thumbnail_path_service_decorator.rb b/app/services/hyrax/thumbnail_path_service_decorator.rb index 4cbc7d8b9a..7209aba6b7 100644 --- a/app/services/hyrax/thumbnail_path_service_decorator.rb +++ b/app/services/hyrax/thumbnail_path_service_decorator.rb @@ -4,6 +4,15 @@ module Hyrax module ThumbnailPathServiceDecorator + def call(object) + return super unless object.collection? + + collection_thumbnail = CollectionBrandingInfo.where(collection_id: object.id.to_s, role: "thumbnail").first + return collection_thumbnail.local_path.gsub(Rails.public_path.to_s, '') if collection_thumbnail + + default_image + end + def default_image Site.instance.default_work_image&.url || super end diff --git a/app/views/hyrax/dashboard/collections/_form_branding.html.erb b/app/views/hyrax/dashboard/collections/_form_branding.html.erb index da3f3de2ba..49465c2ee6 100644 --- a/app/views/hyrax/dashboard/collections/_form_branding.html.erb +++ b/app/views/hyrax/dashboard/collections/_form_branding.html.erb @@ -164,6 +164,9 @@ + +

<%= t('.thumbnail.description') %>

+
@@ -203,7 +206,7 @@ <%= image_tag(f.object.thumbnail_info[:relative_path], height: "36", alt: f.object.thumbnail_info[:alttext].presence || f.object.thumbnail_info[:file]) %> - <%= f.object.thumbnail_info[:file] %> + <%= f.object.thumbnail_info[:file] %>
@@ -236,5 +239,5 @@ - + From 56b57881041a37952003c001c56ddc585b19ee2d Mon Sep 17 00:00:00 2001 From: Kirk Wang Date: Tue, 7 May 2024 16:49:56 -0700 Subject: [PATCH 3/5] Fix bug with setting the thumbnail alt text This commit will fix a bug where if the user sets the thumbnail first and then later sets the alt text, they would have to have to remove the thumbnail and re-add it and set the alt text at the same time to get the alt text to be set. --- app/assets/stylesheets/hyku.scss | 15 ++++++------ .../hyrax/collection_presenter_decorator.rb | 10 ++++++++ .../hyrax/thumbnail_path_service_decorator.rb | 2 +- .../my/collections/_list_collections.html.erb | 2 +- .../steps/save_collection_thumbnail.rb | 20 +++++++++++----- .../steps/save_collection_thumbnail_spec.rb | 24 +++++++++++++++++++ 6 files changed, 58 insertions(+), 15 deletions(-) create mode 100644 spec/hyrax/transactions/steps/save_collection_thumbnail_spec.rb diff --git a/app/assets/stylesheets/hyku.scss b/app/assets/stylesheets/hyku.scss index 0d1f6a2f48..e090a3511b 100644 --- a/app/assets/stylesheets/hyku.scss +++ b/app/assets/stylesheets/hyku.scss @@ -651,21 +651,22 @@ tr[data-feature="use-iiif-print"] { } // collection branding thumbnail -div.branding-thumbnail-row { +.branding-thumbnail-row { border-top: solid 1px #dddddd; padding-top: 10px; } -input.branding-thumbnail-input { +.branding-thumbnail-input { + text-align: right; width: 250px; -} -div.branding-thumbnail-input { - text-align: right; + input { + text-align: left; + } } -button.branding-thumbnail-remove, -button.branding-thumbnail-remove:hover { +.branding-thumbnail-remove, +.branding-thumbnail-remove:hover { background-color: #ffffff; border-color: #ffffff; color: $brand-danger; diff --git a/app/presenters/hyrax/collection_presenter_decorator.rb b/app/presenters/hyrax/collection_presenter_decorator.rb index 7b3efc0505..6ad55ce569 100644 --- a/app/presenters/hyrax/collection_presenter_decorator.rb +++ b/app/presenters/hyrax/collection_presenter_decorator.rb @@ -81,6 +81,16 @@ def banner_file end end + def thumbnail_record + CollectionBrandingInfo.where(collection_id: id, role: "thumbnail") + .select(:local_path, :alt_text, :target_url).map do |thumbnail| + { alttext: thumbnail.alt_text, + file: File.split(thumbnail.local_path).last, + file_location: "/#{thumbnail.local_path.split('/')[-4..-1].join('/')}", + linkurl: thumbnail.target_url } + end + end + # Begin Featured Collections Methods def collection_featurable? user_can_feature_collection? && solr_document.public? diff --git a/app/services/hyrax/thumbnail_path_service_decorator.rb b/app/services/hyrax/thumbnail_path_service_decorator.rb index 7209aba6b7..2f44abbff1 100644 --- a/app/services/hyrax/thumbnail_path_service_decorator.rb +++ b/app/services/hyrax/thumbnail_path_service_decorator.rb @@ -5,7 +5,7 @@ module Hyrax module ThumbnailPathServiceDecorator def call(object) - return super unless object.collection? + return super unless object.try(:collection?) collection_thumbnail = CollectionBrandingInfo.where(collection_id: object.id.to_s, role: "thumbnail").first return collection_thumbnail.local_path.gsub(Rails.public_path.to_s, '') if collection_thumbnail diff --git a/app/views/hyrax/my/collections/_list_collections.html.erb b/app/views/hyrax/my/collections/_list_collections.html.erb index 109c3208e7..58c0bb3e3d 100644 --- a/app/views/hyrax/my/collections/_list_collections.html.erb +++ b/app/views/hyrax/my/collections/_list_collections.html.erb @@ -28,7 +28,7 @@ <% else %> <%# OVERRIDE begin %> - <%= image_tag(collection_presenter.thumbnail_path, alt: block_for(name: 'default_collection_image_text') || "#{collection_presenter.title_or_label} #{t('hyrax.dashboard.my.sr.thumbnail')}") %> + <%= image_tag(collection_presenter.thumbnail_path, alt: collection_presenter.thumbnail_record.first[:alttext] || block_for(name: 'default_collection_image_text') || "#{collection_presenter.title_or_label} #{t('hyrax.dashboard.my.sr.thumbnail')}") %> <%# OVERRIDE end %> <% end %> diff --git a/lib/hyrax/transactions/steps/save_collection_thumbnail.rb b/lib/hyrax/transactions/steps/save_collection_thumbnail.rb index 777865cb77..14036efc23 100644 --- a/lib/hyrax/transactions/steps/save_collection_thumbnail.rb +++ b/lib/hyrax/transactions/steps/save_collection_thumbnail.rb @@ -19,17 +19,25 @@ class SaveCollectionThumbnail # @return [Dry::Monads::Result] `Failure` if the thumbnail info fails to save; # `Success(input)`, otherwise. def call(collection_resource, update_thumbnail_file_ids: nil, thumbnail_unchanged_indicator: true, alttext_values: nil) - return Success(collection_resource) if ActiveModel::Type::Boolean.new.cast(thumbnail_unchanged_indicator) collection_id = collection_resource.id.to_s - process_thumbnail_input(collection_id:, update_thumbnail_file_ids:, alttext_values:) + process_thumbnail_input(collection_id:, update_thumbnail_file_ids:, thumbnail_unchanged_indicator:, alttext_values:) Success(collection_resource) end private - def process_thumbnail_input(collection_id:, update_thumbnail_file_ids:, alttext_values:) - remove_thumbnail(collection_id:) - add_new_thumbnail(collection_id:, uploaded_file_ids: update_thumbnail_file_ids, alttext_values:) if update_thumbnail_file_ids + def process_thumbnail_input(collection_id:, update_thumbnail_file_ids:, thumbnail_unchanged_indicator:, alttext_values:) + if !update_thumbnail_file_ids && !alttext_values + remove_thumbnail(collection_id:) + elsif update_thumbnail_file_ids && thumbnail_unchanged_indicator.nil? + remove_thumbnail(collection_id:) + add_new_thumbnail(collection_id:, uploaded_file_ids: update_thumbnail_file_ids, alttext_values:) + else + CollectionBrandingInfo + .where(collection_id:, role: 'thumbnail') + .first + .update_column(:alt_text, alttext_values.first) # rubocop:disable Rails/SkipsModelValidations + end end def remove_thumbnail(collection_id:) @@ -43,7 +51,7 @@ def add_new_thumbnail(collection_id:, uploaded_file_ids:, alttext_values:) collection_id:, filename: File.split(file.file_url).last, role: "thumbnail", - alt_txt: alttext_values.first, + alt_txt: alttext_values&.first || "", target_url: "TODO: link to the collection" ) thumbnail_info.save file.file_url diff --git a/spec/hyrax/transactions/steps/save_collection_thumbnail_spec.rb b/spec/hyrax/transactions/steps/save_collection_thumbnail_spec.rb new file mode 100644 index 0000000000..47e8a6f21a --- /dev/null +++ b/spec/hyrax/transactions/steps/save_collection_thumbnail_spec.rb @@ -0,0 +1,24 @@ +# frozen_string_literal: true +require 'rails_helper' +require 'hyrax/transactions' + +RSpec.describe Hyrax::Transactions::Steps::SaveCollectionThumbnail do + subject(:step) { described_class.new } + let(:collection) do + FactoryBot.valkyrie_create(:hyrax_collection, + title: "My Resource") + end + + context 'update the thumbnail' do + let(:uploaded) { FactoryBot.create(:uploaded_file) } + + it 'successfully updates the thumbnail' do + expect(step.call(collection, update_thumbnail_file_ids: [uploaded.id.to_s], thumbnail_unchanged_indicator: nil)).to be_success + + expect(CollectionBrandingInfo + .where(collection_id: collection.id.to_s, role: "thumbnail") + .where("local_path LIKE '%#{uploaded.file.filename}'")) + .to exist + end + end +end From 8cebf2f874c274da2901898b39c7635d972df3c1 Mon Sep 17 00:00:00 2001 From: Kirk Wang Date: Wed, 8 May 2024 15:03:57 -0700 Subject: [PATCH 4/5] Rake to migrate Hyku Commons collection thumbnails This commit will add a rake task to migrate the Hyku Commons collection thumbnails which uses the /uploads/uploaded_collection_thumbnails/ path as opposed to a downloads controller endpoint. --- ...ons_collection_thumbnails_to_valkyrie.rake | 41 +++++++++++++++++ ..._collection_thumbnails_to_valkyrie_spec.rb | 44 +++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 lib/tasks/migrate_hyku_commons_collection_thumbnails_to_valkyrie.rake create mode 100644 spec/tasks/migrate_hyku_commons_collection_thumbnails_to_valkyrie_spec.rb diff --git a/lib/tasks/migrate_hyku_commons_collection_thumbnails_to_valkyrie.rake b/lib/tasks/migrate_hyku_commons_collection_thumbnails_to_valkyrie.rake new file mode 100644 index 0000000000..bf4f98c4b7 --- /dev/null +++ b/lib/tasks/migrate_hyku_commons_collection_thumbnails_to_valkyrie.rake @@ -0,0 +1,41 @@ +# frozen_string_literal: true + +namespace :hyku do + desc 'migrate Hyku Commons collection thumbnails to Valkyrie' + task migrate_hyku_commons_collection_thumbnails_to_valkyrie: :environment do + in_each_account do + Collection.find_each do |collection| + # get collection solr document's thumbnail_path for each collection + doc = collection.to_solr + original_thumbnail_path = File.join(Rails.public_path, doc['thumbnail_path_ss']) + + next unless File.exist?(original_thumbnail_path) + + # save collection to make it a valkyrie resource + collection.save + collection_resource = Hyrax.query_service.find_by(id: collection.id) + + # make CollectionBrandingInfo object + CollectionBrandingInfo.new( + collection_id: collection_resource.id, + filename: File.basename(original_thumbnail_path), + role: "thumbnail", + alt_txt: "", + target_url: "TODO: link to the collection" + ).save(original_thumbnail_path) + + # update solr document + Hyrax.index_adapter.save(resource: collection_resource) + end + end + end + + def in_each_account + Account.find_each do |account| + puts "=============== #{account.name}============" + next if account.name == "search" + switch!(account) + yield + end + end +end diff --git a/spec/tasks/migrate_hyku_commons_collection_thumbnails_to_valkyrie_spec.rb b/spec/tasks/migrate_hyku_commons_collection_thumbnails_to_valkyrie_spec.rb new file mode 100644 index 0000000000..499b5e47de --- /dev/null +++ b/spec/tasks/migrate_hyku_commons_collection_thumbnails_to_valkyrie_spec.rb @@ -0,0 +1,44 @@ +# frozen_string_literal: true + +RSpec.describe 'migrate_hyku_commons_collection_thumbnails_to_valkyrie' do + let!(:account) { FactoryBot.create(:account) } + let(:collection) { FactoryBot.create(:collection, title: ['Hyku Commons Collection']) } + let(:thumbnail_path) { File.join('/', 'uploads', 'uploaded_collection_thumbnails', collection.id, "#{collection.id}_card.jpg") } + let(:new_thumbnail_path) { Rails.root.join('public', 'branding', collection.id.to_s, 'thumbnail', "#{collection.id}_card.jpg").to_s } + let(:old_thumbnail_path) { Rails.root.join(File.join('public', thumbnail_path)) } + + before do + Rails.application.load_tasks + FileUtils.mkdir_p(File.dirname(old_thumbnail_path)) + FileUtils.touch(old_thumbnail_path) + allow(Apartment::Tenant).to receive(:switch!).with(account.tenant) { |&block| block&.call } + allow(collection).to receive(:to_solr).and_return({ 'id' => collection.id, 'thumbnail_path_ss' => thumbnail_path }) + allow(Collection).to receive(:find_each).and_yield(collection) + end + + after do + FileUtils.rm_rf(File.dirname(thumbnail_path)) + Collection.destroy_all + end + + it 'migrates the old thumbnail to the branding directory' do + expect(File.exist?(old_thumbnail_path)).to eq true + expect(File.exist?(new_thumbnail_path)).to eq false + run_task('hyku:migrate_hyku_commons_collection_thumbnails_to_valkyrie') + expect(File.exist?(new_thumbnail_path)).to eq true + end + + it 'creates a CollectionBrandingInfo object for the new thumbnail path' do + expect(CollectionBrandingInfo.where(collection_id: collection.id, role: 'thumbnail').count).to eq 0 + run_task('hyku:migrate_hyku_commons_collection_thumbnails_to_valkyrie') + expect(CollectionBrandingInfo.where(collection_id: collection.id, role: 'thumbnail').count).to eq 1 + end + + it 'indexes the new thumbnail path onto the collection resource' do + original_thumbnail_path_ss = collection.to_solr['thumbnail_path_ss'] + expect(original_thumbnail_path_ss).to eq old_thumbnail_path.to_s.gsub(Rails.public_path.to_s, '') + run_task('hyku:migrate_hyku_commons_collection_thumbnails_to_valkyrie') + collection_resource = Hyrax.query_service.find_by(id: collection.id) + expect(collection_resource.to_solr['thumbnail_path_ss']).to eq new_thumbnail_path.to_s.gsub(Rails.public_path.to_s, '') + end +end From bea60db65d0c328bb18ed767f92450f3ecb2357b Mon Sep 17 00:00:00 2001 From: Kirk Wang Date: Mon, 13 May 2024 20:10:03 -0700 Subject: [PATCH 5/5] Address code review comments This commit will address the code review comments with the following: - remove the /uploads gitignore, turns out there was a deeper issue with where collection branding files were being saved - remove a stray comment - remove an unnecessary TODO - remove an unnecessary method definition in the new rake task --- .gitignore | 1 - .../hyku/collection_branding_behavior.rb | 21 +++++++++++++ .../collections_controller_decorator.rb | 15 ++-------- .../hyrax/collection_presenter_decorator.rb | 6 ++-- .../my/collections/_list_collections.html.erb | 2 +- config/initializers/hyrax.rb | 2 +- .../collection_update_decorator.rb | 2 +- .../steps/save_collection_banner_decorator.rb | 29 ++++++++++++++++++ .../steps/save_collection_logo_decorator.rb | 30 +++++++++++++++++++ .../steps/save_collection_thumbnail.rb | 7 +++-- ...ons_collection_thumbnails_to_valkyrie.rake | 11 +------ 11 files changed, 94 insertions(+), 32 deletions(-) create mode 100644 app/controllers/concerns/hyku/collection_branding_behavior.rb create mode 100644 lib/hyrax/transactions/steps/save_collection_banner_decorator.rb create mode 100644 lib/hyrax/transactions/steps/save_collection_logo_decorator.rb diff --git a/.gitignore b/.gitignore index 30b8fc4a3c..ff801b915b 100644 --- a/.gitignore +++ b/.gitignore @@ -57,4 +57,3 @@ docker-compose.override.yml *~undo-tree~ .DS_Store /bundler.d/ -/uploads diff --git a/app/controllers/concerns/hyku/collection_branding_behavior.rb b/app/controllers/concerns/hyku/collection_branding_behavior.rb new file mode 100644 index 0000000000..2c540dbc46 --- /dev/null +++ b/app/controllers/concerns/hyku/collection_branding_behavior.rb @@ -0,0 +1,21 @@ +# frozen_string_literal: true + +module Hyku + module CollectionBrandingBehavior + # This is used for saving the CollectionBrandingInfo files to 'public/uploads' directory. + # + # Originally, when `f.file_url` is called, there's a string sub that happens in + # CarrierWave that puts it into the 'uploads' dir instead. We want it in the 'public/uploads' dir instead + # @see https://github.com/carrierwaveuploader/carrierwave/blob/master/lib/carrierwave/uploader/url.rb#L24 + def process_file_location(f) + if /^http/.match?(f.file_url) + f.file.download!(f.file_url) + f.file_url + elsif %r{^\/}.match?(f.file_url) + f.file.path + else + f.file_url + end + end + end +end diff --git a/app/controllers/hyrax/dashboard/collections_controller_decorator.rb b/app/controllers/hyrax/dashboard/collections_controller_decorator.rb index 367093573d..4056376c6e 100644 --- a/app/controllers/hyrax/dashboard/collections_controller_decorator.rb +++ b/app/controllers/hyrax/dashboard/collections_controller_decorator.rb @@ -11,6 +11,8 @@ module Dashboard ## Shows a list of all collections to the admins # rubocop:disable Metrics/ModuleLength module CollectionsControllerDecorator + include Hyku::CollectionBrandingBehavior + def show configure_show_sort_fields @@ -189,19 +191,6 @@ def process_uploaded_thumbnail(uploaded_file) File.chmod(0o664, "#{dir_name}/#{@collection.id}_card.jpg") end # rubocop:enable Metrics/MethodLength - - ## OVERRIDE Hyrax v5.0.0rc2 handle file locations - def process_file_location(f) - if /^http/.match?(f.file_url) - f.file.download!(f.file_url) - f.file_url - elsif %r{^\/}.match?(f.file_url) - f.file.path - else - f.file_url - end - end - ## END OVERRIDE end end end diff --git a/app/presenters/hyrax/collection_presenter_decorator.rb b/app/presenters/hyrax/collection_presenter_decorator.rb index 6ad55ce569..faf1e2fdb6 100644 --- a/app/presenters/hyrax/collection_presenter_decorator.rb +++ b/app/presenters/hyrax/collection_presenter_decorator.rb @@ -81,9 +81,9 @@ def banner_file end end - def thumbnail_record - CollectionBrandingInfo.where(collection_id: id, role: "thumbnail") - .select(:local_path, :alt_text, :target_url).map do |thumbnail| + def thumbnail_file + @thumbnail_file ||= CollectionBrandingInfo.where(collection_id: id, role: "thumbnail") + .select(:local_path, :alt_text, :target_url).map do |thumbnail| { alttext: thumbnail.alt_text, file: File.split(thumbnail.local_path).last, file_location: "/#{thumbnail.local_path.split('/')[-4..-1].join('/')}", diff --git a/app/views/hyrax/my/collections/_list_collections.html.erb b/app/views/hyrax/my/collections/_list_collections.html.erb index 58c0bb3e3d..ea239ca2bd 100644 --- a/app/views/hyrax/my/collections/_list_collections.html.erb +++ b/app/views/hyrax/my/collections/_list_collections.html.erb @@ -28,7 +28,7 @@ <% else %> <%# OVERRIDE begin %> - <%= image_tag(collection_presenter.thumbnail_path, alt: collection_presenter.thumbnail_record.first[:alttext] || block_for(name: 'default_collection_image_text') || "#{collection_presenter.title_or_label} #{t('hyrax.dashboard.my.sr.thumbnail')}") %> + <%= image_tag(collection_presenter.thumbnail_path, alt: collection_presenter.thumbnail_file.first&.[](:alttext) || block_for(name: 'default_collection_image_text') || "#{collection_presenter.title_or_label} #{t('hyrax.dashboard.my.sr.thumbnail')}") %> <%# OVERRIDE end %> <% end %> diff --git a/config/initializers/hyrax.rb b/config/initializers/hyrax.rb index b61e79962c..3b627a2e26 100644 --- a/config/initializers/hyrax.rb +++ b/config/initializers/hyrax.rb @@ -153,7 +153,7 @@ base_path = if ENV['HYRAX_UPLOAD_PATH'].present? Pathname.new(File.join(ENV['HYRAX_UPLOAD_PATH'], Apartment::Tenant.current)) else - Rails.root.join('uploads', Apartment::Tenant.current) + Rails.root.join('public', 'uploads', Apartment::Tenant.current) end # Create the directory if it doesn't exist diff --git a/lib/hyrax/transactions/collection_update_decorator.rb b/lib/hyrax/transactions/collection_update_decorator.rb index 3f5ec856a9..12ff1d38d4 100644 --- a/lib/hyrax/transactions/collection_update_decorator.rb +++ b/lib/hyrax/transactions/collection_update_decorator.rb @@ -14,7 +14,7 @@ def initialize(container: Container, steps: nil) new_steps = ['change_set.apply', 'collection_resource.save_collection_banner', 'collection_resource.save_collection_logo', - 'collection_resource.save_collection_thumbnail', # Your new step + 'collection_resource.save_collection_thumbnail', 'collection_resource.save_acl'].freeze # Use the new steps array if steps argument is nil, else use provided steps diff --git a/lib/hyrax/transactions/steps/save_collection_banner_decorator.rb b/lib/hyrax/transactions/steps/save_collection_banner_decorator.rb new file mode 100644 index 0000000000..d5e8faa0dd --- /dev/null +++ b/lib/hyrax/transactions/steps/save_collection_banner_decorator.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +# OVERRIDE Hyrax v5.0.0 to save the collection banner in 'public/uploads' + +module Hyrax + module Transactions + module Steps + module SaveCollectionBannerDecorator + include Hyku::CollectionBrandingBehavior + + def add_new_banner(collection_id:, uploaded_file_ids:) + f = uploaded_files(uploaded_file_ids).first + file_location = process_file_location(f) + + banner_info = CollectionBrandingInfo.new( + collection_id:, + filename: File.split(f.file_url).last, + role: "banner", + alt_txt: "", + target_url: "" + ) + banner_info.save file_location + end + end + end + end +end + +Hyrax::Transactions::Steps::SaveCollectionBanner.prepend(Hyrax::Transactions::Steps::SaveCollectionBannerDecorator) diff --git a/lib/hyrax/transactions/steps/save_collection_logo_decorator.rb b/lib/hyrax/transactions/steps/save_collection_logo_decorator.rb new file mode 100644 index 0000000000..0b1af09ec7 --- /dev/null +++ b/lib/hyrax/transactions/steps/save_collection_logo_decorator.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +# OVERRIDE Hyrax v5.0.0 to save the collection logo in 'public/uploads' + +module Hyrax + module Transactions + module Steps + module SaveCollectionLogoDecorator + include Hyku::CollectionBrandingBehavior + + def create_logo_info(collection_id:, uploaded_file_id:, alttext:, linkurl:) + file = uploaded_files(uploaded_file_id) + file_location = process_file_location(file) + + logo_info = CollectionBrandingInfo.new( + collection_id:, + filename: File.split(file.file_url).last, + role: "logo", + alt_txt: alttext, + target_url: linkurl + ) + logo_info.save file_location + logo_info + end + end + end + end +end + +Hyrax::Transactions::Steps::SaveCollectionLogo.prepend(Hyrax::Transactions::Steps::SaveCollectionLogoDecorator) diff --git a/lib/hyrax/transactions/steps/save_collection_thumbnail.rb b/lib/hyrax/transactions/steps/save_collection_thumbnail.rb index 14036efc23..9f74df4ea2 100644 --- a/lib/hyrax/transactions/steps/save_collection_thumbnail.rb +++ b/lib/hyrax/transactions/steps/save_collection_thumbnail.rb @@ -10,6 +10,7 @@ module Steps # class SaveCollectionThumbnail include Dry::Monads[:result] + include Hyku::CollectionBrandingBehavior ## # @param [Hyrax::ChangeSet] change_set @@ -47,14 +48,16 @@ def remove_thumbnail(collection_id:) def add_new_thumbnail(collection_id:, uploaded_file_ids:, alttext_values:) file = uploaded_files(uploaded_file_ids).first + file_location = process_file_location(file) + thumbnail_info = CollectionBrandingInfo.new( collection_id:, filename: File.split(file.file_url).last, role: "thumbnail", alt_txt: alttext_values&.first || "", - target_url: "TODO: link to the collection" + target_url: "" ) - thumbnail_info.save file.file_url + thumbnail_info.save file_location end def uploaded_files(uploaded_file_ids) diff --git a/lib/tasks/migrate_hyku_commons_collection_thumbnails_to_valkyrie.rake b/lib/tasks/migrate_hyku_commons_collection_thumbnails_to_valkyrie.rake index bf4f98c4b7..de8a4cd56a 100644 --- a/lib/tasks/migrate_hyku_commons_collection_thumbnails_to_valkyrie.rake +++ b/lib/tasks/migrate_hyku_commons_collection_thumbnails_to_valkyrie.rake @@ -21,7 +21,7 @@ namespace :hyku do filename: File.basename(original_thumbnail_path), role: "thumbnail", alt_txt: "", - target_url: "TODO: link to the collection" + target_url: "" ).save(original_thumbnail_path) # update solr document @@ -29,13 +29,4 @@ namespace :hyku do end end end - - def in_each_account - Account.find_each do |account| - puts "=============== #{account.name}============" - next if account.name == "search" - switch!(account) - yield - end - end end