diff --git a/app/controllers/dmsf_files_controller.rb b/app/controllers/dmsf_files_controller.rb index e7b48f9e..7b63732f 100644 --- a/app/controllers/dmsf_files_controller.rb +++ b/app/controllers/dmsf_files_controller.rb @@ -142,10 +142,11 @@ class DmsfFilesController < ApplicationController revision.disk_filename = revision.new_storage_filename revision.mime_type = upload.mime_type revision.digest = upload.digest - revision.file.attach( + revision.shared_file.attach( io: File.open(upload.tempfile_path), filename: revision.disk_filename, - content_type: revision.mime_type + content_type: revision.mime_type, + identify: false ) end else diff --git a/app/helpers/dmsf_upload_helper.rb b/app/helpers/dmsf_upload_helper.rb index cfb5335f..0d6a9028 100644 --- a/app/helpers/dmsf_upload_helper.rb +++ b/app/helpers/dmsf_upload_helper.rb @@ -96,10 +96,11 @@ module DmsfUploadHelper a = Attachment.find_by_token(committed_file[:token]) committed_file[:tempfile_path] = a.diskfile if a end - new_revision.file.attach( + new_revision.shared_file.attach( io: File.open(committed_file[:tempfile_path]), filename: new_revision.name, - content_type: new_revision.mime_type + content_type: new_revision.mime_type, + identify: false ) file.last_revision = new_revision files.push file diff --git a/db/migrate/20251015130601_active_storage_migration.rb b/db/migrate/20251015130601_active_storage_migration.rb new file mode 100644 index 00000000..d4ec0719 --- /dev/null +++ b/db/migrate/20251015130601_active_storage_migration.rb @@ -0,0 +1,82 @@ +# frozen_string_literal: true + +# Redmine plugin for Document Management System "Features" +# +# Karel Pičman +# +# This file is part of Redmine DMSF plugin. +# +# Redmine DMSF plugin is free software: you can redistribute it and/or modify it under the terms of the GNU General +# Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any +# later version. +# +# Redmine DMSF plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even +# the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for +# more details. +# +# You should have received a copy of the GNU General Public License along with Redmine DMSF plugin. If not, see +# . + +# Migrate documents to/from Active Storage +class ActiveStorageMigration < ActiveRecord::Migration[7.0] + + # File system -> Active Storage + def up + $stdout.puts "It could be a very long process. Be patient...\n" + Dir.glob(DmsfFile.storage_path.join('**/*')).each do |path| + # Print out the currently processed directory + unless File.file?(path) + $stdout.puts path + next + end + # Process a file + disk_filename = File.basename(path) + DmsfFileRevision.where(disk_filename: disk_filename) + .order(source_dmsf_file_revision_id: :asc) + .find_each + .with_index do |r, i| + next if r.dmsf_file.project.id != 3886 # Dry run + + if i.zero? + r.shared_file.attach( + io: File.open(path), + filename: r.name, + content_type: r.mime_type, + identify: false + ) + # Remove the original file + FileUtils.rm path + key = r.shared_file.blob.key + $stdout.puts "#{path} => #{File.join(key[0..1], key[2..3], key)} (#{r.shared_file.blob.filename})" + else + # The other revisions should have set the source revision + unless r.source_dmsf_file_revision_id + warn "r#{r.id}.source_dmsf_file_revision_id is null" + end + end + end + end + $stdout.puts 'Done' + end + + # Active Storage -> File system + def down + n = DmsfFileRevision.all.size + $stdout.puts "#{n} revisions found. It could be a very long process. Be patient...\n" + DmsfFileRevision.find_each.with_index do |r, i| + $stdout.print "\r#{i * 100 / n}%" + next unless r.shared_file.attached? + next if r.dmsf_file.project.id != 3886 # Dry run + + new_path = r.disk_file(search_if_not_exists: false) + unless File.exist?(new_path) + r.shared_file.open do |f| + FileUtils.mv f.path, new_path + end + end + # Remove the original file + r.shared_file.purge + end + $stdout.puts 'Done' + end +end