add season/series/gacha_available to importer and parser

This commit is contained in:
Justin Edmund 2025-12-02 05:48:22 -08:00
parent 033e50a1c8
commit e0a82bc7a4
3 changed files with 128 additions and 1 deletions

View file

@ -59,6 +59,9 @@ module Granblue
# @option attributes [String] :kamigame Kamigame link
# @option attributes [Array<String>] :nicknames_en English nicknames
# @option attributes [Array<String>] :nicknames_jp Japanese nicknames
# @option attributes [Integer] :season Character season (gacha availability window)
# @option attributes [Array<Integer>] :series Character series (identity/pool membership)
# @option attributes [Boolean] :gacha_available Whether character can be pulled from gacha
#
# @raise [ImportError] If required attributes are missing or invalid
def build_attributes(row)
@ -97,7 +100,10 @@ module Granblue
gamewith: parse_value(row['gamewith']),
kamigame: parse_value(row['kamigame']),
nicknames_en: parse_array(row['nicknames_en']),
nicknames_jp: parse_array(row['nicknames_jp'])
nicknames_jp: parse_array(row['nicknames_jp']),
season: parse_integer(row['season']),
series: parse_integer_array(row['series']),
gacha_available: parse_boolean(row['gacha_available'])
}
end
end

View file

@ -194,6 +194,10 @@ module Granblue
kamigame: hash['link_kamigame']
}
info[:series] = series_from_hash(hash)
info[:season] = season_from_hash(hash)
info[:gacha_available] = gacha_available_from_hash(hash)
info.compact
end
@ -207,6 +211,10 @@ module Granblue
@character.gamewith = hash[:links][:gamewith] if hash[:links].key?(:gamewith)
@character.kamigame = hash[:links][:kamigame] if hash[:links].key?(:kamigame)
@character.series = hash[:series] if hash[:series].present?
@character.season = hash[:season] if hash[:season].present?
@character.gacha_available = hash[:gacha_available] unless hash[:gacha_available].nil?
if @character.save
ap "#{@character.granblue_id}: Successfully saved info for #{@character.name_en}" if @debug
puts
@ -230,6 +238,86 @@ module Granblue
end.reduce({}, :merge)
end
# Extracts series (identity/pool membership) from wiki hash
# Returns an array of series IDs based on |series= and |obtain= fields
def series_from_hash(hash)
series = []
# Primary series from |series= field
wiki_series = hash['series'].to_s.downcase.strip
primary_series = Granblue::Parsers::Wiki.character_series[wiki_series]
series << primary_series if primary_series
# Additional series indicators from |obtain= field
obtain = hash['obtain'].to_s.downcase
series << 2 if obtain.include?('grand') && !series.include?(2) # Grand
series << 3 if obtain.include?('zodiac') && !series.include?(3) # Zodiac
# Seasonal series based on page name or obtain field
page_name = @character.wiki_en.to_s.downcase
if page_name.include?('summer') || page_name.include?('(swimsuit)')
series << 10 unless series.include?(10) # Summer
end
if page_name.include?('yukata')
series << 11 unless series.include?(11) # Yukata
end
if page_name.include?('valentine')
series << 12 unless series.include?(12) # Valentine
end
if page_name.include?('halloween')
series << 13 unless series.include?(13) # Halloween
end
if page_name.include?('(formal)') || page_name.include?('formal ')
series << 14 unless series.include?(14) # Formal
end
if page_name.include?('holiday') || page_name.include?('(holiday)')
series << 1 unless series.include?(1) # Standard for now, Holiday chars usually just standard series
end
# Default to Standard if no series found and character is gacha-available
series << 1 if series.empty? && gacha_available_from_hash(hash)
series.uniq.sort
end
# Extracts season (gacha availability window) from wiki hash
# Returns a single season ID based on seasonal indicators
def season_from_hash(hash)
page_name = @character.wiki_en.to_s.downcase
obtain = hash['obtain'].to_s.downcase
# Check page name for seasonal indicators
return 2 if page_name.include?('valentine')
return 3 if page_name.include?('(formal)') || page_name.include?('formal ')
return 4 if page_name.include?('summer') || page_name.include?('yukata') || page_name.include?('(swimsuit)')
return 5 if page_name.include?('halloween')
return 6 if page_name.include?('holiday') || page_name.include?('(holiday)')
# Check obtain field for seasonal banners
return 2 if obtain.include?('valentine')
return 3 if obtain.include?('formal')
return 4 if obtain.include?('summer')
return 5 if obtain.include?('halloween')
return 6 if obtain.include?('holiday')
# Default to Standard for gacha-available characters
1 if gacha_available_from_hash(hash)
end
# Determines if character can be pulled from gacha based on obtain field and series
def gacha_available_from_hash(hash)
wiki_series = hash['series'].to_s.downcase.strip
obtain = hash['obtain'].to_s.downcase
# Non-gacha series
non_gacha_series = %w[eternal evoker archangel event promo collab]
return false if non_gacha_series.include?(wiki_series)
# Check obtain field for gacha indicators
gacha_indicators = %w[premium flash legend classic grand zodiac valentine summer halloween holiday formal]
gacha_indicators.any? { |indicator| obtain.include?(indicator) }
end
# Parses a date string into a Date object
def parse_date(date_str)
Date.parse(date_str) unless date_str.blank?

View file

@ -15,6 +15,8 @@ module Granblue
class_attribute :races
class_attribute :bullets
class_attribute :boolean
class_attribute :character_series
class_attribute :character_seasons
self.base_uri = 'https://gbf.wiki/api.php'
@ -74,6 +76,37 @@ module Granblue
'no' => false
}.freeze
# Maps wiki |series= values to CHARACTER_SERIES enum values
# Wiki uses lowercase, single values like "grand", "zodiac", etc.
self.character_series = {
'normal' => 1, # Standard
'grand' => 2, # Grand
'zodiac' => 3, # Zodiac
'promo' => 4, # Promo
'collab' => 5, # Collab
'eternal' => 6, # Eternal
'evoker' => 7, # Evoker
'archangel' => 8, # Saint (Archangels)
'fantasy' => 9, # Fantasy
'summer' => 10, # Summer
'yukata' => 11, # Yukata
'valentine' => 12, # Valentine
'halloween' => 13, # Halloween
'formal' => 14, # Formal
'event' => 15 # Event
}.freeze
# Maps wiki seasonal indicators to CHARACTER_SEASONS enum values
# Determined from page name suffix or |obtain= field
self.character_seasons = {
'standard' => 1, # Standard (year-round in their pool)
'valentine' => 2, # Valentine
'formal' => 3, # Formal
'summer' => 4, # Summer (includes Yukata)
'halloween' => 5, # Halloween
'holiday' => 6 # Holiday
}.freeze
def initialize(props: ['wikitext'], debug: false)
@debug = debug
@props = props.join('|')