Modify importer to handle updates

This way we can also add FLBs and other uncaps easier.
This commit is contained in:
Justin Edmund 2025-01-12 17:27:06 -08:00
parent 3716eaa88f
commit 7c42693db1
3 changed files with 99 additions and 28 deletions

View file

@ -29,11 +29,22 @@ module Granblue
importer = create_importer(filename, file_path) importer = create_importer(filename, file_path)
return unless importer return unless importer
log_info "Processing #{filename} in #{@test_mode ? 'TEST' : 'LIVE'} mode..." log_info "Processing #{filename} in #{@test_mode ? 'test' : 'live'} mode..."
new_records = importer.import result = importer.import
log_import(filename) log_import(filename, result)
log_info "Successfully processed #{filename}" log_info "Successfully processed #{filename}"
new_records result
end
def log_import_results(result)
return unless @verbose
result[:new].each do |type, ids|
log_info "Created #{ids.size} new #{type.pluralize}" if ids.any?
end
result[:updated].each do |type, ids|
log_info "Updated #{ids.size} existing #{type.pluralize}" if ids.any?
end
end end
def create_importer(filename, file_path) def create_importer(filename, file_path)
@ -60,9 +71,19 @@ module Granblue
DataVersion.imported?(filename) DataVersion.imported?(filename)
end end
def log_import(filename) def log_import(filename, result = nil)
return if @test_mode return if @test_mode
DataVersion.mark_as_imported(filename) DataVersion.mark_as_imported(filename)
if result && @verbose
result[:new].each do |type, ids|
log_info "Created #{ids.size} new #{type.pluralize}" if ids.any?
end
result[:updated].each do |type, ids|
log_info "Updated #{ids.size} existing #{type.pluralize}" if ids.any?
end
end
end end
def log_operation(operation) def log_operation(operation)

View file

@ -3,7 +3,7 @@
module Granblue module Granblue
module Importers module Importers
class BaseImporter class BaseImporter
attr_reader :new_records attr_reader :new_records, :updated_records
def initialize(file_path, test_mode: false, verbose: false, logger: nil) def initialize(file_path, test_mode: false, verbose: false, logger: nil)
@file_path = file_path @file_path = file_path
@ -11,36 +11,65 @@ module Granblue
@verbose = verbose @verbose = verbose
@logger = logger @logger = logger
@new_records = Hash.new { |h, k| h[k] = [] } @new_records = Hash.new { |h, k| h[k] = [] }
@updated_records = Hash.new { |h, k| h[k] = [] }
end end
def import def import
CSV.foreach(@file_path, headers: true) do |row| CSV.foreach(@file_path, headers: true) do |row|
import_row(row) import_row(row)
end end
@new_records { new: @new_records, updated: @updated_records }
end end
private private
def import_row(row) def import_row(row)
attributes = build_attributes(row) attributes = build_attributes(row)
record = create_record(attributes) record = find_or_create_record(attributes)
track_new_record(record) if record track_record(record, attributes) if record
end end
def create_record(attributes) def find_or_create_record(attributes)
if @test_mode existing_record = model_class.find_by(granblue_id: attributes[:granblue_id])
log_test_creation(attributes)
nil if existing_record
if @test_mode
log_test_update(existing_record, attributes)
nil
else
update_record(existing_record, attributes)
end
else else
model_class.create!(attributes) if @test_mode
log_test_creation(attributes)
nil
else
model_class.create!(attributes)
end
end end
end end
def track_new_record(record) def update_record(record, attributes)
changed = attributes.any? { |key, value| record[key] != value }
record.update!(attributes) if changed
record
end
def track_record(record, attributes)
type = model_class.name.demodulize.downcase type = model_class.name.demodulize.downcase
@new_records[type] << record.granblue_id
log_new_record(record) if @verbose # For existing records, check if any attributes were actually changed
if record.persisted? && record.previous_changes.any?
@updated_records[type] << record.granblue_id
log_updated_record(record) if @verbose
elsif !record.persisted?
@new_records[type] << record.granblue_id
log_new_record(record) if @verbose
end
end
def log_test_update(record, attributes)
@logger&.send(:log_operation, "Update #{model_class.name} #{record.granblue_id}: #{attributes.inspect}")
end end
def log_test_creation(attributes) def log_test_creation(attributes)
@ -51,33 +80,43 @@ module Granblue
puts "Created #{model_class.name} with ID: #{record.granblue_id}" puts "Created #{model_class.name} with ID: #{record.granblue_id}"
end end
def log_updated_record(record)
puts "Updated #{model_class.name} with ID: #{record.granblue_id}"
end
def parse_value(value) def parse_value(value)
return nil if value.nil? || value.strip.empty? return nil if value.nil? || value.strip.empty?
value value
end end
def parse_integer(value) def parse_integer(value)
return nil if value.nil? || value.strip.empty? return nil if value.nil? || value.strip.empty?
value.to_i value.to_i
end end
def parse_float(value) def parse_float(value)
return nil if value.nil? || value.strip.empty? return nil if value.nil? || value.strip.empty?
value.to_f value.to_f
end end
def parse_boolean(value) def parse_boolean(value)
return nil if value.nil? || value.strip.empty? return nil if value.nil? || value.strip.empty?
value == 'true' value == 'true'
end end
def parse_date(date_str) def parse_date(date_str)
return nil if date_str.nil? || date_str.strip.empty? return nil if date_str.nil? || date_str.strip.empty?
Date.parse(date_str) rescue nil Date.parse(date_str) rescue nil
end end
def parse_array(array_str) def parse_array(array_str)
return [] if array_str.nil? || array_str.strip.empty? return [] if array_str.nil? || array_str.strip.empty?
array_str.tr('{}', '').split(',') array_str.tr('{}', '').split(',')
end end

View file

@ -12,6 +12,7 @@ class PostDeploymentManager
@verbose = options.fetch(:verbose, false) @verbose = options.fetch(:verbose, false)
@storage = options.fetch(:storage, :both) @storage = options.fetch(:storage, :both)
@new_records = Hash.new { |h, k| h[k] = [] } @new_records = Hash.new { |h, k| h[k] = [] }
@updated_records = Hash.new { |h, k| h[k] = [] }
end end
def run def run
@ -33,17 +34,26 @@ class PostDeploymentManager
end end
def process_imports(importer) def process_imports(importer)
importer.process_all_files do |file_records| importer.process_all_files do |result|
file_records.each do |type, ids| result[:new].each do |type, ids|
@new_records[type].concat(ids) @new_records[type].concat(ids)
end end
result[:updated].each do |type, ids|
@updated_records[type].concat(ids)
end
end end
end end
def display_import_summary def display_import_summary
log_step "\nImport Summary:" log_step "\nImport Summary:"
@new_records.each do |type, ids| display_record_summary("New", @new_records)
puts "#{type.capitalize}: #{ids.size} new records" display_record_summary("Updated", @updated_records)
end
def display_record_summary(label, records)
records.each do |type, ids|
next if ids.empty?
puts "#{type.capitalize}: #{ids.size} #{label.downcase} records"
puts "IDs: #{ids.inspect}" if @verbose puts "IDs: #{ids.inspect}" if @verbose
end end
end end
@ -52,15 +62,16 @@ class PostDeploymentManager
return if all_records_empty? return if all_records_empty?
if @test_mode if @test_mode
log_step "\nTEST MODE: Would download images for new records..." log_step "\nTEST MODE: Would download images for new and updated records..."
else else
log_step "\nDownloading images for new records..." log_step "\nDownloading images for new and updated records..."
end end
@new_records.each do |type, ids| [@new_records, @updated_records].each do |records|
next if ids.empty? records.each do |type, ids|
next if ids.empty?
download_type_images(type, ids) download_type_images(type, ids)
end
end end
end end
@ -94,7 +105,7 @@ class PostDeploymentManager
end end
def all_records_empty? def all_records_empty?
@new_records.values.all?(&:empty?) @new_records.values.all?(&:empty?) && @updated_records.values.all?(&:empty?)
end end
def log_step(message) def log_step(message)