195 lines
7.7 KiB
Ruby
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
|