From 9099849ee30e532175a4376e64d41d521e9b06f8 Mon Sep 17 00:00:00 2001 From: Justin Edmund Date: Sun, 12 Jan 2025 16:01:52 -0800 Subject: [PATCH] Add importers The Importer libraries take CSV data and import them into the database for each type. We currently support characters, summons and weapons. --- lib/granblue/importers/base_importer.rb | 97 ++++++++++++++++++++ lib/granblue/importers/character_importer.rb | 53 +++++++++++ lib/granblue/importers/summon_importer.rb | 51 ++++++++++ lib/granblue/importers/weapon_importer.rb | 54 +++++++++++ 4 files changed, 255 insertions(+) create mode 100644 lib/granblue/importers/base_importer.rb create mode 100644 lib/granblue/importers/character_importer.rb create mode 100644 lib/granblue/importers/summon_importer.rb create mode 100644 lib/granblue/importers/weapon_importer.rb diff --git a/lib/granblue/importers/base_importer.rb b/lib/granblue/importers/base_importer.rb new file mode 100644 index 0000000..0b42908 --- /dev/null +++ b/lib/granblue/importers/base_importer.rb @@ -0,0 +1,97 @@ +# frozen_string_literal: true + +module Granblue + module Importers + class BaseImporter + attr_reader :new_records + + def initialize(file_path, test_mode: false, verbose: false, logger: nil) + @file_path = file_path + @test_mode = test_mode + @verbose = verbose + @logger = logger + @new_records = Hash.new { |h, k| h[k] = [] } + end + + def import + CSV.foreach(@file_path, headers: true) do |row| + import_row(row) + end + @new_records + end + + private + + def import_row(row) + attributes = build_attributes(row) + record = create_record(attributes) + track_new_record(record) if record + end + + def create_record(attributes) + if @test_mode + log_test_creation(attributes) + nil + else + model_class.create!(attributes) + end + end + + def track_new_record(record) + type = model_class.name.demodulize.downcase + @new_records[type] << record.granblue_id + log_new_record(record) if @verbose + end + + def log_test_creation(attributes) + @logger&.send(:log_operation, "Create #{model_class.name}: #{attributes.inspect}") + end + + def log_new_record(record) + puts "Created #{model_class.name} with ID: #{record.granblue_id}" + end + + def parse_value(value) + return nil if value.nil? || value.strip.empty? + value + end + + def parse_integer(value) + return nil if value.nil? || value.strip.empty? + value.to_i + end + + def parse_float(value) + return nil if value.nil? || value.strip.empty? + value.to_f + end + + def parse_boolean(value) + return nil if value.nil? || value.strip.empty? + value == 'true' + end + + def parse_date(date_str) + return nil if date_str.nil? || date_str.strip.empty? + Date.parse(date_str) rescue nil + end + + def parse_array(array_str) + return [] if array_str.nil? || array_str.strip.empty? + array_str.tr('{}', '').split(',') + end + + def parse_integer_array(array_str) + parse_array(array_str).map(&:to_i) + end + + def model_class + raise NotImplementedError, 'Subclasses must define model_class' + end + + def build_attributes(row) + raise NotImplementedError, 'Subclasses must define build_attributes' + end + end + end +end diff --git a/lib/granblue/importers/character_importer.rb b/lib/granblue/importers/character_importer.rb new file mode 100644 index 0000000..2343fa0 --- /dev/null +++ b/lib/granblue/importers/character_importer.rb @@ -0,0 +1,53 @@ +# frozen_string_literal: true + +module Granblue + module Importers + class CharacterImporter < BaseImporter + private + + def model_class + Character + end + + def build_attributes(row) + { + name_en: parse_value(row['name_en']), + name_jp: parse_value(row['name_jp']), + granblue_id: parse_value(row['granblue_id']), + rarity: parse_integer(row['rarity']), + element: parse_integer(row['element']), + proficiency1: parse_integer(row['proficiency1']), + proficiency2: parse_integer(row['proficiency2']), + gender: parse_integer(row['gender']), + race1: parse_integer(row['race1']), + race2: parse_integer(row['race2']), + flb: parse_boolean(row['flb']), + min_hp: parse_integer(row['min_hp']), + max_hp: parse_integer(row['max_hp']), + max_hp_flb: parse_integer(row['max_hp_flb']), + min_atk: parse_integer(row['min_atk']), + max_atk: parse_integer(row['max_atk']), + max_atk_flb: parse_integer(row['max_atk_flb']), + base_da: parse_integer(row['base_da']), + base_ta: parse_integer(row['base_ta']), + ougi_ratio: parse_float(row['ougi_ratio']), + ougi_ratio_flb: parse_float(row['ougi_ratio_flb']), + special: parse_boolean(row['special']), + ulb: parse_boolean(row['ulb']), + max_hp_ulb: parse_integer(row['max_hp_ulb']), + max_atk_ulb: parse_integer(row['max_atk_ulb']), + character_id: parse_integer_array(row['character_id']), + wiki_en: parse_value(row['wiki_en']), + release_date: parse_value(row['release_date']), + flb_date: parse_value(row['flb_date']), + ulb_date: parse_value(row['ulb_date']), + wiki_ja: parse_value(row['wiki_ja']), + gamewith: parse_value(row['gamewith']), + kamigame: parse_value(row['kamigame']), + nicknames_en: parse_array(row['nicknames_en']), + nicknames_jp: parse_array(row['nicknames_jp']) + } + end + end + end +end diff --git a/lib/granblue/importers/summon_importer.rb b/lib/granblue/importers/summon_importer.rb new file mode 100644 index 0000000..7c97b3e --- /dev/null +++ b/lib/granblue/importers/summon_importer.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +module Granblue + module Importers + class SummonsImporter < BaseImporter + private + + def model_class + Summon + end + + def build_attributes(row) + { + name_en: parse_value(row['name_en']), + name_jp: parse_value(row['name_jp']), + granblue_id: parse_value(row['granblue_id']), + rarity: parse_integer(row['rarity']), + element: parse_integer(row['element']), + series: parse_value(row['series']), + flb: parse_boolean(row['flb']), + ulb: parse_boolean(row['ulb']), + max_level: parse_integer(row['max_level']), + min_hp: parse_integer(row['min_hp']), + max_hp: parse_integer(row['max_hp']), + max_hp_flb: parse_integer(row['max_hp_flb']), + max_hp_ulb: parse_integer(row['max_hp_ulb']), + min_atk: parse_integer(row['min_atk']), + max_atk: parse_integer(row['max_atk']), + max_atk_flb: parse_integer(row['max_atk_flb']), + max_atk_ulb: parse_integer(row['max_atk_ulb']), + subaura: parse_boolean(row['subaura']), + limit: parse_boolean(row['limit']), + transcendence: parse_boolean(row['transcendence']), + max_atk_xlb: parse_integer(row['max_atk_xlb']), + max_hp_xlb: parse_integer(row['max_hp_xlb']), + summon_id: parse_integer(row['summon_id']), + release_date: parse_value(row['release_date']), + flb_date: parse_value(row['flb_date']), + ulb_date: parse_value(row['ulb_date']), + wiki_en: parse_value(row['wiki_en']), + wiki_ja: parse_value(row['wiki_ja']), + gamewith: parse_value(row['gamewith']), + kamigame: parse_value(row['kamigame']), + transcendence_date: parse_value(row['transcendence_date']), + nicknames_en: parse_array(row['nicknames_en']), + nicknames_jp: parse_array(row['nicknames_jp']) + } + end + end + end +end diff --git a/lib/granblue/importers/weapon_importer.rb b/lib/granblue/importers/weapon_importer.rb new file mode 100644 index 0000000..4ec8b28 --- /dev/null +++ b/lib/granblue/importers/weapon_importer.rb @@ -0,0 +1,54 @@ +# frozen_string_literal: true + +module Granblue + module Importers + class WeaponsImporter < BaseImporter + private + + def model_class + Weapon + end + + def build_attributes(row) + { + name_en: parse_value(row['name_en']), + name_jp: parse_value(row['name_jp']), + granblue_id: parse_value(row['granblue_id']), + rarity: parse_integer(row['rarity']), + element: parse_integer(row['element']), + proficiency: parse_integer(row['proficiency']), + series: parse_integer(row['series']), + flb: parse_boolean(row['flb']), + ulb: parse_boolean(row['ulb']), + max_level: parse_integer(row['max_level']), + max_skill_level: parse_integer(row['max_skill_level']), + min_hp: parse_integer(row['min_hp']), + max_hp: parse_integer(row['max_hp']), + max_hp_flb: parse_integer(row['max_hp_flb']), + max_hp_ulb: parse_integer(row['max_hp_ulb']), + min_atk: parse_integer(row['min_atk']), + max_atk: parse_integer(row['max_atk']), + max_atk_flb: parse_integer(row['max_atk_flb']), + max_atk_ulb: parse_integer(row['max_atk_ulb']), + extra: parse_boolean(row['extra']), + ax_type: parse_integer(row['ax_type']), + limit: parse_boolean(row['limit']), + ax: parse_boolean(row['ax']), + recruits_id: parse_value(row['recruits_id']), + max_awakening_level: parse_integer(row['max_awakening_level']), + release_date: parse_value(row['release_date']), + flb_date: parse_value(row['flb_date']), + ulb_date: parse_value(row['ulb_date']), + wiki_en: parse_value(row['wiki_en']), + wiki_ja: parse_value(row['wiki_ja']), + gamewith: parse_value(row['gamewith']), + kamigame: parse_value(row['kamigame']), + nicknames_en: parse_array(row['nicknames_en']), + nicknames_jp: parse_array(row['nicknames_jp']), + transcendence: parse_boolean(row['transcendence']), + transcendence_date: parse_value(row['transcendence_date']) + } + end + end + end +end