Skip to content

Commit

Permalink
Adds Fix for deleting PhysicalInstantiations from Assets based on Med…
Browse files Browse the repository at this point in the history
…ia Type (#922)

Refactors some one-type scripts into more re-usable batch processing methods that can be run
from the ruby console or CLI.

* Delete Assets by ID list from file.
* Delete Physical Instantiations by Media Type and IDs from file.
* Change Media Type for instantiations by IDs from file.
  • Loading branch information
afred authored Sep 25, 2024
1 parent fed8d72 commit 3cc999b
Show file tree
Hide file tree
Showing 9 changed files with 275 additions and 210 deletions.
89 changes: 89 additions & 0 deletions lib/fix/batch_process.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
module Fix
class BatchProcess
attr_reader :ids, :log, :cli_ptions, :log_level

def initialize(ids_file:, log_level: Logger::INFO)
@ids = File.readlines(ids_file, chomp: true)
@cli_options = {}
@log = Logger.new(STDOUT)
@log.level = log_level
end

# asset_resources Returns an array of AssetResource instances for the given ids.
# @return [Array<AssetResource>] An array of AssetResource instances.
def asset_resources
@asset_resources ||= ids.map do |id|
log.info "Finding Asset Resource '#{id}'..."
begin
AssetResource.find(id)
rescue => e
log_error(e)
nil
end
end.compact
end

def log_error(e)
log.error "#{e.class}: #{e.message}"
log.debug "Backtrace:\n#{e.backtrace.join("\t\t\n")}\n\n"
end

# run! is the main method to be implemented by subclasses.
def run
log.warn "No action taken. Put your logic in the #{self.class}#run! method"
end

# self.cli_options A hash to store command line options.
def self.cli_options
@cli_options ||= {}
end

# self.option_parser Creates a default OptionParser for cli options and allows subclasses
# to add their own options.
# @param block [Proc] A block that takes an OptionParser instance as an argument.
# @return [OptionParser] The OptionParser instance.
# Usage:
# class MyBatchProcess < BatchProcess
# def initialize(my_option:, **args)
# super(**args)
# @my_option = my_option
# end
#
# option_parser do |opts|
# opts.on("-m", "--my-option", "My custom option") do |my_option_val|
# # Assign option values to the cli_options hash.
# cli_options[:my_option] = my_option_val
# end
# end
# end
def self.option_parser(&block)
# Set a default options for all BatchProcess classes
@option_parser ||= OptionParser.new do |opts|
# Allow verbose ouput
opts.on('-l', '--log-level [0-5]', '0=DEBUG, 1=INFO, 2=WARN, 3=ERROR, 4=FATAL, 5=UNKNOWN') do |log_level|
cli_options[:log_level] = log_level[/\d+/].to_i || 1
end

# Allow file input of AAPB IDs
opts.on("-f", "--file FILE", "List of AAPB IDs, one per line") do |file|
cli_options[:ids_file] = file
end
end

# Call the passed block with option parser instance if a block was given.
block.call(@option_parser) if block_given?

# Return the option parser.
@option_parser
end

# self.run_cli Parses command line options and runs the batch process.
def self.run_cli
# Call option_parser.parse! to set cli_options from $ARGV
option_parser.parse!

# Run the batch process with cli_options
new(**cli_options).run
end
end
end
53 changes: 28 additions & 25 deletions lib/fix/change_media_type.rb
Original file line number Diff line number Diff line change
@@ -1,53 +1,56 @@
require_relative '../../config/environment'
require_relative 'batch_process'

module Fix
class ChangeMediaType
MEDIA_TYPES = MediaTypeService.new.select_all_options
class ChangeMediaType < BatchProcess
MEDIA_TYPES = MediaTypeService.new.select_all_options.to_h.values

attr_reader :aapb_ids_filename, :aapb_ids
def initialize
@aapb_ids_filename = "#{File.dirname(File.expand_path(__FILE__))}/data/nebraska_public_media_ids.txt"
attr_reader :media_type

def initialize(media_type:, **args)
super(**args)
raise ArgumentError, "media_type must be one of '#{MEDIA_TYPES.join("', '")}', but '#{media_type}' was given" unless MEDIA_TYPES.include?(media_type)
@media_type = media_type
end

option_parser do |opts|
opts.banner = "Usage: ruby lib/fix/change_media_type.rb [options]"

def aapb_ids
@aapb_ids ||= File.readlines(aapb_ids_filename).map(&:strip)
opts.on("-t", "--media-type MEDIA_TYPE", "Either 'Sound' or 'Movind Image'") do |media_type|
cli_options[:media_type] = media_type
end
end

def asset_resources
@asset_resources ||= aapb_ids.map do |aapb_id|
puts "Looking up Asset #{aapb_id} ..."
begin
AssetResource.find(aapb_id)
rescue => e
puts "Error looking up Asset #{aapb_id}: #{e.class} -- #{e.message}"
def run
log.info "Running fix #{self.class.name} ..."
asset_resources.each do |ar|
if ar.physical_instantiation_resources.count == 0
log.warn "No Physical Instantiations for Asset Resource #{ar.id}, skipping."
next
end
end.compact
end

def run!
puts "Running Hotfix #{self.class.name} ..."
asset_resources.each do |asset_resource|
pi = asset_resource.physical_instantiation_resources.detect { |pi| pi.media_type != 'Moving Image' }
pi = ar.physical_instantiation_resources.detect { |pi| pi.media_type != media_type }
if !pi
puts "Nothing to fix for AssetResource #{asset_resource.id}, skipping ..."
log.warn "Asset Resource #{ar.id} has no Physical Instantiations without media type of #{media_type}, skipping."
next
end

# Change the metadata
pi.media_type = 'Moving Image'
pi.media_type = media_type

begin
pi.save
puts "PhysicalInstantiationResource #{pi.id} saved with media_type 'Moving Image'"
log.info "Physical Instantiation #{pi.id} for Asset Resource #{ar.id} saved with media_type '#{media_type}'"
rescue => e
puts "Error saving PhysicalInstantiationResource #{pi.id}: #{e.class} -- #{e.message}"
log_error e
end
end
log.info "Done."
end
end
end


if __FILE__ == $0
Fix::ChangeMediaType.new.run!
Fix::ChangeMediaType.run_cli
end
184 changes: 0 additions & 184 deletions lib/fix/data/nebraska_public_media_ids.txt

This file was deleted.

25 changes: 25 additions & 0 deletions lib/fix/delete_asset_resources.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
require_relative '../../config/environment'
require_relative 'batch_process'

module Fix
class DeleteAssetResources < BatchProcess
def run
asset_resources.each do |ar|
log.info "Destroying Asset Resource #{ar.id}"
begin
Hyrax.persister.delete(resource: ar)
Hyrax.index_adapter.delete(resource: ar)
Hyrax.index_adapter.connection.commit
log.info "Asset Resource #{ar.id} destroyed."
rescue => e
log_error e
end
end
puts "Done."
end
end
end

if __FILE__ == $0
Fix::DeleteAssetResources.run_cli
end
Loading

0 comments on commit 3cc999b

Please sign in to comment.