diff --git a/app/models/spotlight/attachment.rb b/app/models/spotlight/attachment.rb index b85b9357d..d649295c1 100644 --- a/app/models/spotlight/attachment.rb +++ b/app/models/spotlight/attachment.rb @@ -4,11 +4,18 @@ module Spotlight ## # Sir-trevor image upload attachments class Attachment < ActiveRecord::Base + # Open to alternatives on how to do this, but this works + include Rails.application.routes.url_helpers + belongs_to :exhibit - mount_uploader :file, Spotlight::AttachmentUploader + has_one_attached :file - def as_json(options = nil) - file.as_json(options).merge(name: name, uid: uid, attachment: to_global_id) + def as_json(_options = nil) + # as_json has problems with single has_one_attached content + # https://github.com/rails/rails/issues/33036 + { + name: name, uid: uid, attachment: to_global_id, url: rails_blob_path(file, only_path: true) + } end end end diff --git a/app/models/spotlight/bulk_update.rb b/app/models/spotlight/bulk_update.rb index 87999fba5..236c9670b 100644 --- a/app/models/spotlight/bulk_update.rb +++ b/app/models/spotlight/bulk_update.rb @@ -2,7 +2,7 @@ module Spotlight class BulkUpdate < ActiveRecord::Base - mount_uploader :file, Spotlight::BulkUpdatesUploader + has_one_attached :file belongs_to :exhibit end end diff --git a/app/models/spotlight/featured_image.rb b/app/models/spotlight/featured_image.rb index 95a83d282..ffd63bcd9 100644 --- a/app/models/spotlight/featured_image.rb +++ b/app/models/spotlight/featured_image.rb @@ -4,16 +4,14 @@ module Spotlight ## # Featured images for browse categories, feature pages, and exhibits class FeaturedImage < ActiveRecord::Base - mount_uploader :image, Spotlight::FeaturedImageUploader + has_one_attached :image before_validation do next unless upload_id.present? && source == 'remote' # copy the image from the temp upload temp_image = Spotlight::TemporaryImage.find(upload_id) - self.image = CarrierWave::SanitizedFile.new tempfile: StringIO.new(temp_image.image.read), - filename: temp_image.image.filename || temp_image.image.identifier, - content_type: temp_image.image.content_type + image.attach(temp_image.image.blob) # Unset the incoming iiif_tilesource, which points at the temp image self.iiif_tilesource = nil @@ -24,13 +22,6 @@ class FeaturedImage < ActiveRecord::Base Spotlight::TemporaryImage.find(upload_id).delete if upload_id.present? end - after_save do - if image.present? - image.cache! unless image.cached? - image.store! - end - end - attr_accessor :upload_id def iiif_url @@ -60,7 +51,7 @@ def document end def file_present? - image.file.present? + image.blob.present? end def iiif_tilesource diff --git a/app/services/spotlight/carrierwave_file_resolver.rb b/app/services/spotlight/carrierwave_file_resolver.rb index 5b72ba2b9..d28240944 100644 --- a/app/services/spotlight/carrierwave_file_resolver.rb +++ b/app/services/spotlight/carrierwave_file_resolver.rb @@ -9,10 +9,10 @@ def initialize end def pattern(id) - uploaded_file = Spotlight::FeaturedImage.find(id).image.file + uploaded_file = Spotlight::FeaturedImage.find(id).image.blob raise Riiif::ImageNotFoundError, "unable to find file for #{id}" if uploaded_file.nil? - uploaded_file.file + ActiveStorage::Blob.service.path_for(uploaded_file.key) end end end diff --git a/app/services/spotlight/exhibit_import_export_service.rb b/app/services/spotlight/exhibit_import_export_service.rb index a5906c2f6..6ae317819 100644 --- a/app/services/spotlight/exhibit_import_export_service.rb +++ b/app/services/spotlight/exhibit_import_export_service.rb @@ -186,9 +186,9 @@ def from_hash!(hash) # dedupe by something?? ar = exhibit.attachments.build(attr) - ar.file = CarrierWave::SanitizedFile.new tempfile: StringIO.new(Base64.decode64(file[:content])), - filename: file[:filename], - content_type: file[:content_type] + ar.file.attach io: StringIO.new(Base64.decode64(file[:content])), + filename: file[:filename], + content_type: file[:content_type] end hash[:languages].each do |attr| @@ -212,9 +212,9 @@ def deserialize_featured_image(obj, method, data) image = obj.public_send("build_#{method}") image.update(data) if file - image.image = CarrierWave::SanitizedFile.new tempfile: StringIO.new(Base64.decode64(file[:content])), - filename: file[:filename], - content_type: file[:content_type] + image.image.attach io: StringIO.new(Base64.decode64(file[:content])), + filename: file[:filename], + content_type: file[:content_type] # Unset the iiif_tilesource field as the new image should be different, because # the source has been reloaded image.iiif_tilesource = nil @@ -301,11 +301,11 @@ def attach_featured_images(json) def serialize_featured_image(id) image = Spotlight::FeaturedImage.find(id) - file = image.image.file + file = image.image if file img = { image: { - filename: file.filename, content_type: file.content_type, content: Base64.encode64(file.read) + filename: file.filename, content_type: file.content_type, content: Base64.encode64(file.download) } } end diff --git a/app/uploaders/spotlight/attachment_uploader.rb b/app/uploaders/spotlight/attachment_uploader.rb deleted file mode 100644 index 34a57cda5..000000000 --- a/app/uploaders/spotlight/attachment_uploader.rb +++ /dev/null @@ -1,15 +0,0 @@ -# frozen_string_literal: true - -module Spotlight - ## - # Sir-trevor image widget uploads - class AttachmentUploader < CarrierWave::Uploader::Base - storage Spotlight::Engine.config.uploader_storage - - # Override the directory where uploaded files will be stored. - # This is a sensible default for uploaders that are meant to be mounted: - def store_dir - "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" - end - end -end diff --git a/app/uploaders/spotlight/bulk_updates_uploader.rb b/app/uploaders/spotlight/bulk_updates_uploader.rb deleted file mode 100644 index 628e60c2b..000000000 --- a/app/uploaders/spotlight/bulk_updates_uploader.rb +++ /dev/null @@ -1,7 +0,0 @@ -# frozen_string_literal: true - -module Spotlight - class BulkUpdatesUploader < CarrierWave::Uploader::Base - storage Spotlight::Engine.config.uploader_storage - end -end diff --git a/app/uploaders/spotlight/featured_image_uploader.rb b/app/uploaders/spotlight/featured_image_uploader.rb deleted file mode 100644 index 4aeb0ea10..000000000 --- a/app/uploaders/spotlight/featured_image_uploader.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -module Spotlight - ## - # Page, browse category, and exhibit featured image thumbnails - class FeaturedImageUploader < CarrierWave::Uploader::Base - storage Spotlight::Engine.config.uploader_storage - - def extension_allowlist - Spotlight::Engine.config.allowed_upload_extensions - end - - def store_dir - "uploads/#{model.class.to_s.underscore}/#{mounted_as}/#{model.id}" - end - end -end diff --git a/blacklight-spotlight.gemspec b/blacklight-spotlight.gemspec index 59ec9fe2d..1edd85448 100644 --- a/blacklight-spotlight.gemspec +++ b/blacklight-spotlight.gemspec @@ -28,7 +28,6 @@ these collections.) s.add_dependency 'bootstrap_form', '~> 4.1' s.add_dependency 'breadcrumbs_on_rails', '>= 3.0', '< 5' s.add_dependency 'cancancan' - s.add_dependency 'carrierwave', '~> 2.2' s.add_dependency 'clipboard-rails', '~> 1.5' s.add_dependency 'devise', '~> 4.1' s.add_dependency 'devise_invitable' diff --git a/lib/generators/spotlight/install_generator.rb b/lib/generators/spotlight/install_generator.rb index 0a0ff0334..63da8a0ad 100644 --- a/lib/generators/spotlight/install_generator.rb +++ b/lib/generators/spotlight/install_generator.rb @@ -29,6 +29,11 @@ def add_js run 'bundle exec rails webpacker:install' end + def setup_activestorage + run 'bundle exec rails active_storage:install' + run 'bundle exec rails db:migrate' + end + def inject_spotlight_routes route "mount Spotlight::Engine, at: 'spotlight'" gsub_file 'config/routes.rb', /^\s*root.*/ do |match| diff --git a/lib/spotlight/engine.rb b/lib/spotlight/engine.rb index 4ff809d1e..752daaec5 100644 --- a/lib/spotlight/engine.rb +++ b/lib/spotlight/engine.rb @@ -36,7 +36,6 @@ class Engine < ::Rails::Engine end end - require 'carrierwave' require 'underscore-rails' require 'github/markup' require 'sir_trevor_rails' diff --git a/lib/tasks/spotlight_tasks.rake b/lib/tasks/spotlight_tasks.rake index 83121e1c4..f81368b0e 100644 --- a/lib/tasks/spotlight_tasks.rake +++ b/lib/tasks/spotlight_tasks.rake @@ -77,6 +77,42 @@ namespace :spotlight do Migration::PageLanguage.run end + desc 'Migrate CarrierWave content to ActiveStorage' + task migrate_carrier_wave: :environment do + puts 'Mirating Spotlight::Attachment' + Spotlight::Attachment.find_each do |attachment| + next if attachment.file.blob + + attachment.file.attach( + io: File.open(Rails.root.join("public/uploads/spotlight/attachment/file/#{attachment.attributes['file']}")), + filename: attachment.attributes['file'], + content_type: Mime::Type.lookup_by_extension(File.extname(attachment.attributes['file'])[1..]) + ) + end + + puts 'Mirating Spotlight::FeaturedImage' + Spotlight::FeaturedImage.find_each do |featured_image| + next if featured_image.image.blob + + featured_image.image.attach( + io: File.open(Rails.root.join("public/uploads/spotlight/featured_image/image/#{featured_image.attributes['image']}")), + filename: featured_image.attributes['image'], + content_type: Mime::Type.lookup_by_extension(File.extname(featured_image.attributes['image'])[1..]) + ) + end + + puts 'Mirating Spotlight::BulkUpdate' + Spotlight::BulkUpdate.find_each do |bulk_update| + next if bulk_update.file.blob + + bulk_update.file.attach( + io: File.open(Rails.root.join("public/uploads/#{bulk_update.attributes['file']}")), + filename: bulk_update.attributes['file'], + content_type: Mime::Type.lookup_by_extension(File.extname(bulk_update.attributes['file'])[1..]) + ) + end + end + def prompt_to_create_user Spotlight::Engine.user_class.find_or_create_by!(email: prompt_for_email) do |u| puts 'User not found. Enter a password to create the user.' diff --git a/spec/test_app_templates/carrierwave.rb b/spec/test_app_templates/carrierwave.rb deleted file mode 100644 index a453b7dbd..000000000 --- a/spec/test_app_templates/carrierwave.rb +++ /dev/null @@ -1,8 +0,0 @@ -# frozen_string_literal: true - -if Rails.env.test? || Rails.env.cucumber? - CarrierWave.configure do |config| - config.storage = :file - config.enable_processing = false - end -end diff --git a/spec/test_app_templates/lib/generators/test_app_generator.rb b/spec/test_app_templates/lib/generators/test_app_generator.rb index 51f8526a8..2631aec9b 100644 --- a/spec/test_app_templates/lib/generators/test_app_generator.rb +++ b/spec/test_app_templates/lib/generators/test_app_generator.rb @@ -25,6 +25,7 @@ def run_blacklight_generator def run_spotlight_migrations rake 'spotlight:install:migrations' + rake 'active_storage:install' rake 'db:migrate' end @@ -40,10 +41,6 @@ def add_rake_tasks_to_app rakefile 'spotlight_test.rake', File.read(find_in_source_paths('spotlight_test.rake')) end - def disable_carrierwave_processing - copy_file 'carrierwave.rb', 'config/initializers/carrierwave.rb' - end - def add_theme_assets copy_file 'fixture.png', 'app/assets/images/spotlight/themes/default_preview.png' copy_file 'fixture.png', 'app/assets/images/spotlight/themes/modern_preview.png' diff --git a/spec/uploaders/spotlight/attachment_uploader_spec.rb b/spec/uploaders/spotlight/attachment_uploader_spec.rb deleted file mode 100644 index 2966fc8c2..000000000 --- a/spec/uploaders/spotlight/attachment_uploader_spec.rb +++ /dev/null @@ -1,27 +0,0 @@ -# frozen_string_literal: true - -describe Spotlight::AttachmentUploader do - subject(:attachment_uploader) { described_class.new(mounter, 'mounted_as') } - - let(:mounter) { Spotlight::Attachment.new(id: '5') } - - describe '#store_dir' do - let(:store_dir) { attachment_uploader.store_dir } - - it 'is prefixed with "uploads/spotlight"' do - expect(store_dir).to start_with 'uploads/spotlight/' - end - - it "includes the mounter's class name" do - expect(store_dir).to match '/attachment/' - end - - it 'includes the mounted_as option' do - expect(store_dir).to match '/mounted_as/' - end - - it "ends with the mounter's id" do - expect(store_dir).to end_with "/#{mounter.id}" - end - end -end diff --git a/spec/uploaders/spotlight/featured_image_uploader_spec.rb b/spec/uploaders/spotlight/featured_image_uploader_spec.rb deleted file mode 100644 index 9309a4e14..000000000 --- a/spec/uploaders/spotlight/featured_image_uploader_spec.rb +++ /dev/null @@ -1,33 +0,0 @@ -# frozen_string_literal: true - -describe Spotlight::FeaturedImageUploader do - subject(:featured_image_uploader) { described_class.new(mounter, 'mounted_as') } - - let(:mounter) { FactoryBot.create(:featured_image) } - - describe '#extension_allowlist' do - it 'is the configured array of approved extension to be uploaded' do - expect(featured_image_uploader.extension_allowlist).to eq Spotlight::Engine.config.allowed_upload_extensions - end - end - - describe '#store_dir' do - let(:store_dir) { featured_image_uploader.store_dir } - - it 'is prefixed with "uploads/spotlight"' do - expect(store_dir).to start_with 'uploads/spotlight/' - end - - it "includes the mounter's class name" do - expect(store_dir).to match '/featured_image/' - end - - it 'includes the mounted_as option' do - expect(store_dir).to match '/mounted_as/' - end - - it "ends with the mounter's id" do - expect(store_dir).to end_with "/#{mounter.id}" - end - end -end