Class: FFXIVLodestone::Character
- Inherits:
-
Object
- Object
- FFXIVLodestone::Character
- Defined in:
- lib/ffxiv-lodestone.rb
Overview
Represents an FFXIV character. Example:
FFXIVLodestone::Character.new(1015990)
Defined Under Namespace
Classes: AmbiguousNameError, NotFoundException, SkillList, StatList
Instance Attribute Summary collapse
-
#profile ⇒ Object
readonly
FFXIVLodestone::Character::SkillList.
-
#resistances ⇒ Object
readonly
FFXIVLodestone::Character::SkillList.
-
#skills ⇒ Object
(also: #jobs)
readonly
FFXIVLodestone::Character::SkillList.
-
#stats ⇒ Object
readonly
FFXIVLodestone::Character::SkillList.
Class Method Summary collapse
-
.search(args = {}) ⇒ Object
FFXIVLodestone::Character.search(:name => ‘Character Name’, :world => ‘Server’) => Array.
Instance Method Summary collapse
-
#initialize(args = {}) ⇒ Character
constructor
A new instance of Character.
- #method_missing(method) ⇒ Object
-
#name ⇒ Object
Returns first name / last name seperated by a space.
- #to_json(args = {}) ⇒ Object
Constructor Details
#initialize(args = {}) ⇒ Character
Returns a new instance of Character.
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 |
# File 'lib/ffxiv-lodestone.rb', line 167 def initialize(args={}) args = {:id => args} unless args.class == Hash raise ArgumentError, 'No search paremeters were given.' if args.empty? if args.key? :id character_id = args[:id] raise ArgumentError, 'No other arguments may be specified in conjunction with :id.' if args.size > 1 else characters = Character.search(args) raise NotFoundException, 'Character search yielded no results.' if characters.empty? raise AmbiguousNameError, 'Multiple characters matched that name.' if characters.size > 1 character_id = characters.first[:id] end @character_id = character_id doc = Nokogiri::HTML(Character.get_profile_html(@character_id)) # Did we get an error page? Invalid ID, etc. if !((doc.search('head title').first.content.match /error/i) == nil) raise NotFoundException, 'Bad character ID or Lodestone is broken.' end # The skills table doesn't have a unqiue ID or class to find it by, so take the first skill lable and go up two elements (table -> tr -> th.mianskill-lable) @skills = SkillList.new(doc.search('th.mainskill-label').first.parent.parent) @stats = StatList.new(doc.search("div.contents-subheader[contains('Attributes')]").first.next_sibling) @resistances = StatList.new(doc.search("div.contents-subheader[contains('Elements')]").first.next_sibling) # The character info box at the top ... actually has a useful ID! @profile = {} profile = doc.search("//div[starts-with(@id,'profile-plate')]") profile.search('tr th').each do |th| key = th.content.strip.downcase.gsub(':','').gsub(' ','_').to_sym value = th.next_sibling.content.strip_nbsp # HP/MP/TP are max values. They depend on the currently equipped job and are not very # meaningful pieces of data. XP will be handled seperately. unless [:hp, :mp, :tp, :experience_points].include? key @profile[key] = value end if key == :experience_points @profile[:current_exp] = value.split('/')[0].to_i @profile[:exp_to_next_level] = value.split('/')[1].to_i end end # Fix this datatype. @profile[:physical_level] = @profile[:physical_level].to_i # Parse the character name/world line... name_line = profile.search('#charname').first.content.gsub(')','').strip.split(' (') @profile[:world] = name_line[1] @profile[:first_name] = name_line[0].split(' ')[0] @profile[:last_name] = name_line[0].split(' ')[1] # Parse the "Seeker of the Sun Female / Miqo'te" line... fun~ race_line = profile.search('tr td').first.content.strip_nbsp.split(' / ') @profile[:race] = race_line.pop # horrible array splitting and popping trix. hidoi hidoi! race_line = race_line.first.split ' ' @profile[:gender] = race_line.pop @profile[:clan] = race_line.join ' ' @profile.merge! generate_portrait_urls(doc.search('div.image-mount-image img').first.attr('src').strip) @profile[:character_id] = @character_id.to_i end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method) ⇒ Object
288 289 290 291 |
# File 'lib/ffxiv-lodestone.rb', line 288 def method_missing(method) return @profile[method] if @profile.key? method super end |
Instance Attribute Details
#profile ⇒ Object (readonly)
FFXIVLodestone::Character::SkillList
165 166 167 |
# File 'lib/ffxiv-lodestone.rb', line 165 def profile @profile end |
#resistances ⇒ Object (readonly)
FFXIVLodestone::Character::SkillList
165 166 167 |
# File 'lib/ffxiv-lodestone.rb', line 165 def resistances @resistances end |
#skills ⇒ Object (readonly) Also known as: jobs
FFXIVLodestone::Character::SkillList
165 166 167 |
# File 'lib/ffxiv-lodestone.rb', line 165 def skills @skills end |
#stats ⇒ Object (readonly)
FFXIVLodestone::Character::SkillList
165 166 167 |
# File 'lib/ffxiv-lodestone.rb', line 165 def stats @stats end |
Class Method Details
.search(args = {}) ⇒ Object
FFXIVLodestone::Character.search(:name => ‘Character Name’, :world => ‘Server’) => Array
237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 |
# File 'lib/ffxiv-lodestone.rb', line 237 def self.search(args={}) raise ArgumentError, 'Search parameters must be hash.' unless args.class == Hash raise ArgumentError, ':name must be specified to use search.' unless args.key? :name world_id = nil if args.key? :world # :world can be passed as a string ('Figaro') or as the integer used by the search page (7). # This is so the library is not completely useless when new worlds are added - developers can # fall back to the integers until the gem is updated. if args[:world].class == String raise ArgumentError, 'Unknown world server.' unless FFXIVLodestone::SERVER_SEARCH_INDEXES.key? args[:world].downcase.to_sym world_id = FFXIVLodestone::SERVER_SEARCH_INDEXES[args[:world].downcase.to_sym] else world_id = args[:world].to_i # force it to an int to prevent any funny business. end end doc = Nokogiri::HTML(get_search_html(args[:name],world_id)) results = doc.search("table.contents-table1 tr th[contains('Character Name')]") return [] if results.empty? # No results = no results table header. results = results.last.parent.parent results.children.first.remove # discard the table headers results.children.map do |tr| name_element = tr.search('td:first table tr td:last a').first { :id => name_element.attr('href').gsub('/rc/character/top?cicuid=','').strip.to_i, :name => name_element.content.strip, :portrait_thumb_url => tr.search('td:first table tr td:first img').first.attr('src').strip, :world => tr.search('td:last').last.content.strip } end end |
Instance Method Details
#name ⇒ Object
Returns first name / last name seperated by a space.
274 275 276 |
# File 'lib/ffxiv-lodestone.rb', line 274 def name "#{@profile[:first_name]} #{@profile[:last_name]}" end |
#to_json(args = {}) ⇒ Object
278 279 280 281 282 283 284 285 286 |
# File 'lib/ffxiv-lodestone.rb', line 278 def to_json(args={}) data = {} data.merge!(@profile) data[:jobs] = @skills data[:attributes] = @stats data[:resistances] = @resistances data.to_json end |