hensei-api/lib/granblue/parsers/suggestion_parser.rb

195 lines
7.7 KiB
Ruby

# frozen_string_literal: true
module Granblue
module Parsers
# SuggestionParser extracts structured suggestions from wiki text
# for use in batch entity import flows
class SuggestionParser
# Parse character wiki text into suggestion fields
def self.parse_character(wiki_text)
return {} if wiki_text.blank?
data = parse_wiki_text(wiki_text)
suggestions = {}
suggestions[:name_en] = data['name'] if data['name'].present?
suggestions[:name_jp] = data['jpname'] if data['jpname'].present?
suggestions[:granblue_id] = data['id'] if data['id'].present?
# Character ID (for linking related characters)
if data['charid'].present?
char_ids = data['charid'].scan(/\b\d{4}\b/)
suggestions[:character_id] = char_ids if char_ids.any?
end
# Rarity
suggestions[:rarity] = Wiki.rarities[data['rarity']] if data['rarity'].present?
# Element
suggestions[:element] = Wiki.elements[data['element']] if data['element'].present?
# Gender
suggestions[:gender] = Wiki.genders[data['gender']] if data['gender'].present?
# Proficiencies
if data['weapon'].present?
profs = data['weapon'].split(',').map(&:strip)
suggestions[:proficiency1] = Wiki.proficiencies[profs[0]] if profs[0]
suggestions[:proficiency2] = Wiki.proficiencies[profs[1]] if profs[1]
end
# Races
if data['race'].present?
races = data['race'].split(',').map(&:strip)
suggestions[:race1] = Wiki.races[races[0]] if races[0]
suggestions[:race2] = Wiki.races[races[1]] if races[1]
end
# Stats
suggestions[:min_hp] = data['min_hp'].to_i if data['min_hp'].present?
suggestions[:max_hp] = data['max_hp'].to_i if data['max_hp'].present?
suggestions[:max_hp_flb] = data['flb_hp'].to_i if data['flb_hp'].present?
suggestions[:min_atk] = data['min_atk'].to_i if data['min_atk'].present?
suggestions[:max_atk] = data['max_atk'].to_i if data['max_atk'].present?
suggestions[:max_atk_flb] = data['flb_atk'].to_i if data['flb_atk'].present?
# Uncap status
suggestions[:flb] = Wiki.boolean.fetch(data['5star'], false) if data['5star'].present?
suggestions[:ulb] = data['max_evo'].to_i == 6 if data['max_evo'].present?
# Dates
suggestions[:release_date] = parse_date(data['release_date']) if data['release_date'].present?
suggestions[:flb_date] = parse_date(data['5star_date']) if data['5star_date'].present?
suggestions[:ulb_date] = parse_date(data['6star_date']) if data['6star_date'].present?
# External links
suggestions[:gamewith] = data['link_gamewith'] if data['link_gamewith'].present?
suggestions[:kamigame] = data['link_kamigame'] if data['link_kamigame'].present?
suggestions.compact
end
# Parse weapon wiki text into suggestion fields
def self.parse_weapon(wiki_text)
return {} if wiki_text.blank?
data = parse_wiki_text(wiki_text)
suggestions = {}
suggestions[:name_en] = data['name'] if data['name'].present?
suggestions[:name_jp] = data['jpname'] if data['jpname'].present?
suggestions[:granblue_id] = data['id'] if data['id'].present?
# Rarity
suggestions[:rarity] = Wiki.rarities[data['rarity']] if data['rarity'].present?
# Element
suggestions[:element] = Wiki.elements[data['element']] if data['element'].present?
# Proficiency (weapon type)
suggestions[:proficiency] = Wiki.proficiencies[data['type']] if data['type'].present?
# Stats
suggestions[:min_hp] = data['min_hp'].to_i if data['min_hp'].present?
suggestions[:max_hp] = data['max_hp'].to_i if data['max_hp'].present?
suggestions[:max_hp_flb] = data['flb_hp'].to_i if data['flb_hp'].present?
suggestions[:min_atk] = data['min_atk'].to_i if data['min_atk'].present?
suggestions[:max_atk] = data['max_atk'].to_i if data['max_atk'].present?
suggestions[:max_atk_flb] = data['flb_atk'].to_i if data['flb_atk'].present?
# Uncap status
suggestions[:flb] = Wiki.boolean.fetch(data['4star'], false) if data['4star'].present?
suggestions[:ulb] = Wiki.boolean.fetch(data['5star'], false) if data['5star'].present?
# Dates
suggestions[:release_date] = parse_date(data['release_date']) if data['release_date'].present?
suggestions[:flb_date] = parse_date(data['4star_date']) if data['4star_date'].present?
suggestions[:ulb_date] = parse_date(data['5star_date']) if data['5star_date'].present?
# External links
suggestions[:gamewith] = data['link_gamewith'] if data['link_gamewith'].present?
suggestions[:kamigame] = data['link_kamigame'] if data['link_kamigame'].present?
# Recruits (character recruited by this weapon)
suggestions[:recruits] = data['recruit'] if data['recruit'].present?
suggestions.compact
end
# Parse summon wiki text into suggestion fields
def self.parse_summon(wiki_text)
return {} if wiki_text.blank?
data = parse_wiki_text(wiki_text)
suggestions = {}
suggestions[:name_en] = data['name'] if data['name'].present?
suggestions[:name_jp] = data['jpname'] if data['jpname'].present?
suggestions[:granblue_id] = data['id'] if data['id'].present?
# Rarity
suggestions[:rarity] = Wiki.rarities[data['rarity']] if data['rarity'].present?
# Element
suggestions[:element] = Wiki.elements[data['element']] if data['element'].present?
# Stats
suggestions[:min_hp] = data['min_hp'].to_i if data['min_hp'].present?
suggestions[:max_hp] = data['max_hp'].to_i if data['max_hp'].present?
suggestions[:max_hp_flb] = data['flb_hp'].to_i if data['flb_hp'].present?
suggestions[:min_atk] = data['min_atk'].to_i if data['min_atk'].present?
suggestions[:max_atk] = data['max_atk'].to_i if data['max_atk'].present?
suggestions[:max_atk_flb] = data['flb_atk'].to_i if data['flb_atk'].present?
# Uncap status
suggestions[:flb] = Wiki.boolean.fetch(data['4star'], false) if data['4star'].present?
suggestions[:ulb] = Wiki.boolean.fetch(data['5star'], false) if data['5star'].present?
# Sub-aura
suggestions[:subaura] = Wiki.boolean.fetch(data['subaura'], false) if data['subaura'].present?
# Dates
suggestions[:release_date] = parse_date(data['release_date']) if data['release_date'].present?
suggestions[:flb_date] = parse_date(data['4star_date']) if data['4star_date'].present?
suggestions[:ulb_date] = parse_date(data['5star_date']) if data['5star_date'].present?
# External links
suggestions[:gamewith] = data['link_gamewith'] if data['link_gamewith'].present?
suggestions[:kamigame] = data['link_kamigame'] if data['link_kamigame'].present?
suggestions.compact
end
# Parse wiki text into a key-value hash
def self.parse_wiki_text(wiki_text)
lines = wiki_text.split("\n")
data = {}
stop_loop = false
lines.each do |line|
next if stop_loop
# Stop parsing at gameplay notes section
if line.include?('Gameplay Notes')
stop_loop = true
next
end
next unless line[0] == '|' && line.size > 2
key, value = line[1..].split('=', 2).map(&:strip)
data[key] = value if value.present?
end
data
end
# Parse a date string into a Date object
def self.parse_date(date_str)
Date.parse(date_str)
rescue ArgumentError, TypeError
nil
end
end
end
end