xiv_lodestone 0.0.3 → 0.0.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7f1bf8d0c6f4dcc49e331b28bfc3f94d222f1128
4
- data.tar.gz: b04e3acc0ac3ff917ce5d7fdc7273632dbac1b60
3
+ metadata.gz: d232080a2b27816989b05574d6d11c40fb424766
4
+ data.tar.gz: dba67820e7bd6a137f5d28f5ec0245bfa47e400e
5
5
  SHA512:
6
- metadata.gz: 44b54c61f2e69813af22345415b3d93f2c5ae9d772b67043ecc7197e660c82025203c10ed8dd372689f035e3db9a12804a3ed4474d6c978d27e5ad6d558f5358
7
- data.tar.gz: 19e54b62a6febe1c7ea5bfdb875a7e246080fe5e9e70d7f12a6a22cfb8bbb339c7591a38b10030fee310cb3f3c57e56e4fafc802077a2d20c04b1860d15d860c
6
+ metadata.gz: daabe0be0130d7c981f18decb3fc982400fad31f526a6402d560a74282d0b3a677628f82ec4d5db2546089bfc4e3c88f05597f966341986036ded7ff28a94b65
7
+ data.tar.gz: 23e74f384445e88841081d3dc674d95a5c149b2d9fc170b9c6bd1c129ed607a8fbfda7ba62b3d47831668d693259ebb0ea571b7c988b3438c53d603406fbbaf7
data/.travis.yml CHANGED
@@ -2,6 +2,7 @@ language: ruby
2
2
  rvm:
3
3
  - 2.2.0
4
4
  sudo: false
5
+ cache: bundler
5
6
  addons:
6
7
  code_climate:
7
8
  repo_token:
data/CHANGELOG.md CHANGED
@@ -8,16 +8,30 @@ Features:
8
8
  - Gear List - Shows item name, ilevel, slot, ffxiv db url, calculates total ilevel
9
9
  - Disciple List(Classes) - Shows class name, level, current exp, total exp, icon url, calculates experience to next level
10
10
  - All character attributes
11
+ - Converts Character profile to json
11
12
 
12
13
  ## Alpha: 0.0.2 (2015-01-05)
13
14
 
14
15
  Bugfixes:
15
16
  - Added required Ruby version to gemspec
16
17
 
17
- ## Alpha: 0.0.3 (2015-01-06)
18
+ ## Alpha: 0.0.3 (2015-01-05)
18
19
 
19
20
  Bugfixes:
20
21
  - Added nokogiri dependency to gemspec
21
22
  - Remove rake dependency from spec
22
23
  - Fixed ilevel calculation, forgot to double 2handed ilevel as offhand
23
24
  - Refactored Paser#get_classes()., Parser#get_gear
25
+
26
+ ## Alpha: 0.0.4 (2015-01-07)
27
+
28
+ Features
29
+ - Added new method to creating a Character class, Character.new("Benpi Kancho"), can pass name without server if you have an extremely rare name
30
+ - Added server name method
31
+ - Character, DiscipleList, GearList class have had a to_json method added to them
32
+ - Added first_name and last_name methods
33
+ - Added minion parser + mounts parser
34
+
35
+ Bugfixes
36
+ - Rewriting more comprehensive tests
37
+ - Change the way Character.new arguments work
data/Gemfile CHANGED
@@ -2,10 +2,6 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
- gem 'nokogiri', '~> 1.6.5'
6
-
7
5
  group :test do
8
- gem 'rake', '~> 10.0'
9
- gem 'rspec', '~> 3.1'
10
6
  gem 'codeclimate-test-reporter', require: nil
11
7
  end
data/README.md CHANGED
@@ -1,12 +1,16 @@
1
1
  # XIVLodestone - A simple FFXIV lodestone scraper [![Build Status](https://travis-ci.org/benjiro/XIV-lodestone.svg)](https://travis-ci.org/benjiro/XIV-lodestone) [![Code Climate](https://codeclimate.com/github/benjiro/XIV-lodestone/badges/gpa.svg)](https://codeclimate.com/github/benjiro/XIV-lodestone) [![Test Coverage](https://codeclimate.com/github/benjiro/XIV-lodestone/badges/coverage.svg)](https://codeclimate.com/github/benjiro/XIV-lodestone) [![Dependency Status](https://gemnasium.com/benjiro/XIV-lodestone.svg)](https://gemnasium.com/benjiro/XIV-lodestone)
2
2
 
3
3
  A simple API for scraping information from FFXIV lodestone community website.
4
+ The API uses a technique called metaprogramming, this means that additional
5
+ disciples added to the game will be detected and add automatically.
4
6
 
5
- Please note this gem is currently in Alpha stage of development expect bugs, submit a issue for bug or feature requests.
7
+ Please note this gem is currently in Alpha stage of development expect bugs,
8
+ submit a issue for bug or feature requests.
6
9
 
7
10
  ## Features
8
11
  - Character Search (via ID number or Name and Server)
9
12
  - Character profile
13
+ - name, server, portrait image url
10
14
  - HP, MP, TP
11
15
  - Race, Sex, Clan, Nameday, Guardian, City, Grand Company, Free Company
12
16
  - Gear List - Shows item name, ilevel, slot, ffxiv db url, calculates total ilevel
@@ -14,8 +18,10 @@ Please note this gem is currently in Alpha stage of development expect bugs, sub
14
18
  - All character attributes
15
19
 
16
20
  ## TODO
17
- - Profile picture
18
- - Achievements, Blogs, Friends list
21
+ - Server Status parser
22
+ - Job detection, soul crystal
23
+ - To Json functionality
24
+ - Achievements, Blogs, Friends list, Mounts, Pets
19
25
  - Free Company Search/Gather Member information
20
26
  - Clean up smelly code 24/7
21
27
 
@@ -37,9 +43,8 @@ Or install it yourself as:
37
43
 
38
44
  ## Usage
39
45
 
40
- TODO: Write a more indepth guide
41
-
42
- Once the gem is installed include it in your project.
46
+ This usage of the gem is pretty straight forward most of the method names are
47
+ directly taken from the lodestone naming conversation.
43
48
 
44
49
  ```ruby
45
50
  require 'xiv_lodestone'
@@ -47,13 +52,44 @@ require 'xiv_lodestone'
47
52
 
48
53
  To parse a character
49
54
  ```ruby
50
- $ character = XIVLodestone::Character("Benpi Kancho", "Tonberry")
51
- $ character = XIVLodestone::Character(1549391)
55
+ character = XIVLodestone::Character("Benpi Kancho", "Tonberry")
56
+ character = XIVLodestone::Character("Benpi Kancho")
57
+ character = XIVLodestone::Character(1549391)
52
58
  ```
53
59
 
54
60
  Basic examples
55
61
 
56
62
  ```ruby
63
+ character.name #=> character full name #String
64
+ character.first_name #=> character first name #String
65
+ character.last_name #=> character last name #String
66
+ character.server #=> server name #String
67
+ character.introduction #=> character profile introduction #String
68
+ character.title #=> character title #String
69
+ character.portrait #=> character portrait image url #String
70
+ character.hp #=> character hp #Integer
71
+ character.mp #=> character mp #Integer
72
+ character.tp #=> character tp #Integer
73
+ character.sex #=> character sex #String
74
+ character.race #=> character race #String
75
+ character.clan #=> character clan #String
76
+ character.nameday #=> character nameday #String
77
+ character.guardian #=> character guardian #String
78
+ character.city #=> character home city #String
79
+ character.grand_company #=> character grand company #String
80
+
81
+ # Character Attributes
82
+ str, dex, vit, int, mnd, pie, fire, ice, wind, earth, lighting, water, accuracy,
83
+ critical_hite_rate, determination, defense, parry, magical_defense, attack_power,
84
+ skill_speed, attack_magic_potency, healing_magic_potency, spell_speed, blunt,
85
+ piercing, slashing, heavy_resistance, bind_resistance, sleep_resistance,
86
+ stun_resistance, poison_resistance, blind_resistance, silence_resistance,
87
+ slow_resistance
88
+
89
+ # Available Gear Slot
90
+ weapon, head, body, hands, belt, legs, feet, shield, necklace, earrings,
91
+ bracelets, ring1, ring2
92
+
57
93
  character.gear.weapon # => Hash of below data
58
94
  character.gear.weapon.name # => weapon name #String
59
95
  character.gear.weapon.ilevel # => item level Integer
@@ -61,6 +97,11 @@ character.gear.weapon.slot # => item slot #String
61
97
  character.gear.weapon.url # => url to ffxivdb #String
62
98
  character.gear.ilevel # => Character ilevel
63
99
 
100
+ # Available Disciples
101
+ gladiator, marauder, archer, pugilist, lancer, rogue, conjurer, thaumaturge,
102
+ arcanist, carpenter, armorer, leatherworker, alchemist, blacksmith, goldsmith,
103
+ weaver, culinarian, miner, botanist, fisher
104
+
64
105
  character.disciple.rogue # => Hash of below data
65
106
  character.disciple.rogue.name # => class name #String
66
107
  character.disciple.rogue.level # => current level #Integer
@@ -68,9 +109,6 @@ character.disciple.rogue.current_exp # => current experience #Interger
68
109
  character.disciple.rogue.total_exp # => total experience #Integer
69
110
  character.disciple.rogue.icon_url # => class icon url #String
70
111
  character.disciple.rogue.next_level # => experience to required to level #Integer
71
-
72
- character.str # => Character strength value
73
- # More to come
74
112
  ```
75
113
 
76
114
  ## Contributing
@@ -80,3 +118,6 @@ character.str # => Character strength value
80
118
  3. Commit your changes (`git commit -am 'Add some feature'`)
81
119
  4. Push to the branch (`git push origin my-new-feature`)
82
120
  5. Create a new Pull Request
121
+
122
+ If you would like to say hi, i live on Tonberry - JP you can find me on my main
123
+ Benpi Kancho most of the time.
@@ -1,115 +1,72 @@
1
1
  require 'xiv_lodestone/lodestone_helper'
2
- require 'xiv_lodestone/lodestone_parser'
2
+ require 'xiv_lodestone/lodestone_character_gear'
3
+ require 'xiv_lodestone/lodestone_character_disciple'
4
+ require 'xiv_lodestone/lodestone_character_attribute'
5
+ require 'xiv_lodestone/lodestone_character_mount'
3
6
 
4
7
  module XIVLodestone
5
- # A Object that representation a FFXIV:ARR character,
8
+ # A Object that represents a FFXIV:ARR character,
6
9
  # all information is obtained from the lodestone website.
7
10
  class Character
8
- def initialize(*args)
9
- parser = nil
10
- if args.count == 1 && args.all? {|x| x.is_a? Fixnum}
11
- parser = Parser.new(Helper.open_id(args.first))
12
- elsif args.count == 2 && args.all? {|x| x.is_a? String}
13
- parser = Parser.new(Helper.open_url(args.at(0), args.at(1)))
14
- else
15
- fail ArgumentError, "Invalid Arguments: player_id(Fixnum) or player_name(String), server_name(String)]"
16
- end
17
-
18
- @profile = Hash.new
19
- @profile[:disciple] = DiscipleList.new(parser.get_classes)
20
- @profile[:gear] = GearList.new(parser.get_gear)
21
- @profile.merge!(parser.get_attributes)
22
- @profile[:hp] = parser.get_hp
23
- @profile[:mp] = parser.get_mp
24
- @profile[:tp] = parser.get_tp
25
- @profile[:sex] = parser.get_sex
26
- @profile[:race] = parser.get_race
27
- @profile[:clan] = parser.get_clan
28
- @profile[:nameday] = parser.get_nameday
29
- @profile[:guardian] = parser.get_guardian
30
- @profile[:city] = parser.get_city
31
- @profile[:grand_company] = parser.get_grand_company
32
- @profile[:free_company] = parser.get_free_company
33
-
34
- parser = nil #Close the reference so Nokogiri cleans up itself
11
+ # default constructor, handles styles of arguments
12
+ # 1. Character.new(:name => "CHARACTER_NAME", :server => "SERVER_NAME")
13
+ # 2. Character.new(:name => "CHARACTER_NAME")
14
+ # 3. Character.new(:id => ID_NUMBER)
15
+ def initialize(args = Hash.new)
16
+ @profile = Hash.new()
17
+ initialise_profile(Helper.process_args(args))
35
18
  end
36
-
37
- def method_missing(method)
38
- return @profile[method] if @profile.key?(method)
39
- super
19
+ # Returns a #String with characters first name
20
+ def first_name()
21
+ @profile[:name].split(/ /).first
40
22
  end
41
- end
42
- # A Object that represents a list of Gear pieces
43
- # The initialiser takes a hash of items in the following layout
44
- # { :weapon => ["Fist", 110, "Weapon", "http://...."], ... }
45
- class GearList
46
- def initialize(gear_list)
47
- @list = Hash.new
48
- gear_list.each do |key, value|
49
- gear = Gear.new(value[0], value[1], value[2], value[3])
50
- @list[key] = gear
51
- end
23
+ # Returns a #String with characters last name
24
+ def last_name()
25
+ @profile[:name].split(/ /).last
26
+ end
27
+ # Returns a #Array of characters mounts
28
+ def mounts()
29
+ @mounts.list
52
30
  end
53
- # Calculates the total gear list ilevel
54
- # Rounds to the nearest whole number like FFXIV ingame calculation
55
- # returns a #Integer
56
- def ilevel()
57
- ilevel = 0
58
- ilevel = @list[:weapon].ilevel if Helper.is_2hand_weapon(@list[:weapon].slot)
59
- @list.each_value do |value|
60
- ilevel += value.ilevel
61
- end
62
- (ilevel/13).round
31
+ # Returns a #Array of characters minions
32
+ def minions()
33
+ @minions.list
63
34
  end
64
- # Generates access methods for each item slot
35
+ # Generates missing methods from @profile hash keys
65
36
  def method_missing(method)
66
- return @list[method] if @list.key?(method)
37
+ return @profile[method] if @profile.key?(method)
67
38
  super
68
39
  end
69
- # A object representation of a peacie of gear.
70
- # TODO Add more information
71
- class Gear
72
- attr_reader :name, :ilevel, :slot, :url
73
-
74
- def initialize(name, ilevel, slot, url)
75
- @name = name
76
- @ilevel = ilevel
77
- @slot = slot
78
- @url = url
79
- end
40
+ # Uses gem Oj to dump Character Object to JSON
41
+ def to_json()
42
+ Oj.dump(@profile)
80
43
  end
81
- end
82
- # A object representation of disciples(classes)
83
- # The initialiser takes a hash of Disciple, that layout follows
84
- # { :rogue => ["Rogue", 1, 0, 300, "http://..."] }
85
- class DiscipleList
86
- def initialize(disciple_list)
87
- @list = Hash.new
88
- disciple_list.each do |key, value|
89
- disciple = Disciple.new(value[0], value[1], value[2], value[3], value[4])
90
- @list[key.to_sym] = disciple
91
- end
92
- # Generates access methods for each disciple slot
93
- def method_missing(method)
94
- return @list[method] if @list.key?(method)
95
- super
96
- end
44
+ #### Private Methods ####
45
+ # Initialises all characters information from lodestone
46
+ def initialise_profile(page)
47
+ @profile[:name] = Helper.get_name(page)
48
+ @profile[:server] = Helper.get_server(page)
49
+ @profile[:introduction] = Helper.get_introduction(page)
50
+ @profile[:title] = Helper.get_title(page)
51
+ @profile[:portrait] = Helper.get_portrait(page)
52
+ @profile[:hp] = Helper.get_hp(page)
53
+ @profile[:mp] = Helper.get_mp(page)
54
+ @profile[:tp] = Helper.get_tp(page)
55
+ @profile[:sex] = Helper.get_sex(page)
56
+ @profile[:race] = Helper.get_race(page)
57
+ @profile[:clan] = Helper.get_clan(page)
58
+ @profile[:nameday] = Helper.get_nameday(page)
59
+ @profile[:guardian] = Helper.get_guardian(page)
60
+ @profile[:city] = Helper.get_city(page)
61
+ @profile[:grand_company] = Helper.get_grand_company(page)
62
+ @profile[:free_company] = Helper.get_free_company(page)
63
+ @profile[:disciple] = DiscipleList.new(page.xpath("//table[@class='class_list']/tr/td"))
64
+ @profile[:gear] = GearList.new(page.xpath("(//div[@class='item_detail_box'])[position() < 13]"))
65
+ @profile[:attribute] = AttributeList.new(page.xpath('//div[starts-with(@class, "param_left_area_inner")]/ul/li'))
66
+ @mounts = MountList.new(page.xpath('(//div[@class="minion_box clearfix"])[1]/a'))
67
+ @minions = MountList.new(page.xpath('(//div[@class="minion_box clearfix"])[2]/a'))
97
68
  end
98
- # A object representation of a disciple
99
- class Disciple
100
- attr_reader :name, :level, :current_exp, :total_exp, :icon_url
101
69
 
102
- def initialize(name, level, curr, req, icon)
103
- @name = name
104
- @level = level
105
- @current_exp = curr
106
- @total_exp = req
107
- @icon_url = icon
108
- end
109
- # Returns the required experience to the next level
110
- def next_level()
111
- @total_exp - @current_exp
112
- end
113
- end
70
+ private :initialise_profile
114
71
  end
115
72
  end
@@ -0,0 +1,39 @@
1
+ require 'xiv_lodestone/lodestone_helper'
2
+ require 'oj'
3
+
4
+ module XIVLodestone
5
+ # A Object that represents a set of atrributes from
6
+ # lodestone website. The class parsers a given xpath
7
+ # for attributes and stores them in a Hash. All method
8
+ # names are based of names of attributes from lodestone website
9
+ class AttributeList
10
+ def initialize(attribute_path)
11
+ @attributes = Hash.new
12
+ parse_attributes(attribute_path)
13
+ end
14
+ # Generate methods from each key in the @attribute hash
15
+ def method_missing(method)
16
+ return @attributes[method] if @attributes.key?(@attributes)
17
+ super
18
+ end
19
+ # Uses OJ to dump @attribute to json
20
+ def to_json()
21
+ Oj.dump(@attributes)
22
+ end
23
+ #### Private Methods ####
24
+ # Parsers attributes from a document into @attribute hash
25
+ def parse_attributes(attribute_path)
26
+ attribute_path.each_with_index do |li, index|
27
+ # For some weird reason the first 6 elements don't use span tags like the rest.
28
+ if index < 6
29
+ @attributes[Helper.replace_downcase(li['class']).to_sym] = li.text.to_i
30
+ else
31
+ ele = li.text.split(/(?<=\D)(?=\d)/)
32
+ @attributes[Helper.replace_downcase(ele[0]).to_sym] = ele[1].to_i
33
+ end
34
+ end
35
+ end
36
+
37
+ private :parse_attributes
38
+ end
39
+ end
@@ -0,0 +1,54 @@
1
+ require 'nokogiri'
2
+ require 'oj'
3
+
4
+ module XIVLodestone
5
+ # A object representation of disciples(classes)
6
+ # The initialiser takes a hash of Disciple, that layout follows
7
+ # { :rogue => ["Rogue", 1, 0, 300, "http://..."] }
8
+ class DiscipleList
9
+ def initialize(disciple_path)
10
+ @disciple = Hash.new
11
+ parse_disciple(disciple_path)
12
+ end
13
+ # Uses gem Oj to dump DiscipleList Object to JSON
14
+ def to_json()
15
+ Oj.dump(@disciple)
16
+ end
17
+ # Generates missing methods using @disciple hash keys
18
+ def method_missing(method)
19
+ return @disciple[method] if @disciple.key?(method)
20
+ super
21
+ end
22
+ #### Private Methods ####
23
+ def parse_disciple(disciple_path)
24
+ disciple_path.each_slice(3) do |table|
25
+ next if table[0].text.empty? #skip empty cols
26
+ @disciple[table[0].text.downcase.to_sym] = Disciple.new(
27
+ table[0].text,
28
+ table[1].text.to_i,
29
+ table[2].text.split(/\//)[0].to_i,
30
+ table[2].text.split(/\//)[1].to_i,
31
+ table[0].at_css('img')['src'])
32
+ end
33
+ end
34
+
35
+ private :parse_disciple
36
+
37
+ # A object representation of a disciple
38
+ class Disciple
39
+ attr_reader :name, :level, :current_exp, :total_exp, :icon_url
40
+
41
+ def initialize(name, level, curr, req, icon)
42
+ @name = name
43
+ @level = level
44
+ @current_exp = curr
45
+ @total_exp = req
46
+ @icon_url = icon
47
+ end
48
+ # Returns the required experience to the next level
49
+ def next_level()
50
+ @total_exp - @current_exp
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,78 @@
1
+ require 'nokogiri'
2
+ require 'oj'
3
+
4
+ module XIVLodestone
5
+ # A Object that represents a list of Gear pieces
6
+ # The initialiser takes a hash of items in the following layout
7
+ # { :weapon => ["Fist", 110, "Weapon", "http://...."], ... }
8
+ class GearList
9
+ def initialize(gear_path)
10
+ @items = Hash.new
11
+ parse_gear(gear_path)
12
+ end
13
+ # Calculates the total gear list ilevel
14
+ # Rounds to the nearest whole number like FFXIV ingame calculation
15
+ # returns a #Integer
16
+ def ilevel()
17
+ ilevel = 0
18
+ ilevel = @items[:weapon].ilevel if Helper.is_2hand_weapon(@items[:weapon].slot)
19
+ @items.each_value do |value|
20
+ ilevel += value.ilevel
21
+ end
22
+ (ilevel/13).round
23
+ end
24
+ # Uses gem Oj to dump GearList Object to JSON
25
+ def to_json()
26
+ Oj.dump(@items)
27
+ end
28
+ # Generates access methods for each item slot
29
+ def method_missing(method)
30
+ return @items[method] if @items.key?(method)
31
+ super
32
+ end
33
+ #### Private Methods ####
34
+ # Parses each piece of gear and stores it in @items hash
35
+ def parse_gear(gear_path)
36
+ gear_path.each do |item|
37
+ @items[type(item.at_css('h3.category_name').text).to_sym] = Gear.new(
38
+ item.css('h2').text,
39
+ item.at_css('div.pt3.pb3').text.split(/ /).last.to_i,
40
+ item.at_css('h3').text,
41
+ "http://na.finalfantasyxiv.com#{item.at_css('a')['href']}")
42
+ end
43
+ end
44
+ # Returns a string representation of item slot
45
+ def type(name)
46
+ if name =~ /(Arm|Arms|Grimoire|Primary Tool)/i
47
+ return "weapon"
48
+ elsif name =~ /Shield/i
49
+ return "shield"
50
+ elsif name.eql?("Ring")
51
+ return "ring#{ring_inc}"
52
+ else
53
+ return name.downcase
54
+ end
55
+ end
56
+ # Initialise @num and count upwards, if @num >= 2 reset to 1
57
+ # @num += 1 reset if @num >= 2
58
+ def ring_inc()
59
+ @num ||= 0
60
+ @num = 0 if @num >= 2
61
+ @num += 1
62
+ end
63
+
64
+ private :parse_gear, :type, :ring_inc
65
+
66
+ # A object representation of a peacie of gear.
67
+ class Gear
68
+ attr_reader :name, :ilevel, :slot, :url
69
+
70
+ def initialize(name, ilevel, slot, url)
71
+ @name = name
72
+ @ilevel = ilevel
73
+ @slot = slot
74
+ @url = url
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,35 @@
1
+ require 'xiv_lodestone/lodestone_helper'
2
+ require 'oj'
3
+
4
+ module XIVLodestone
5
+ class MountList
6
+ attr_reader :list
7
+
8
+ def initialize(mount_path)
9
+ @list = Array.new
10
+ parse_mount(mount_path)
11
+ end
12
+ # Uses gem Oj to dump MountList to JSON
13
+ def to_json()
14
+ Oj.dump(@list)
15
+ end
16
+ #### Private Methods ####
17
+ def parse_mount(mount_path)
18
+ mount_path.each do |mount|
19
+ @list.push(Mount.new(mount['title'],
20
+ mount.at_xpath('img')['src']))
21
+ end
22
+ end
23
+
24
+ private :parse_mount
25
+
26
+ class Mount
27
+ attr_reader :name, :icon_url
28
+
29
+ def initialize(name, icon_url)
30
+ @name = name.split.map(&:capitalize)*' '
31
+ @icon_url = icon_url
32
+ end
33
+ end
34
+ end
35
+ end
@@ -1,55 +1,134 @@
1
- require 'nokogiri'
2
- require 'open-uri'
3
-
4
- module XIVLodestone
5
- # RuntimeError if a character can't be found
6
- class CharacterNotFound < RuntimeError
7
- end
8
- # RuntimeError if more than one character is found
9
- class MoreThanOneCharacter < RuntimeError
10
- end
11
- # A class of helper methods
12
- class Helper
13
- # Find a character profile from a given name and
14
- # server. Returns a Nokogiri XML document of the
15
- # characters page.
16
- def self.open_url(name, server)
17
- page = Nokogiri::HTML(open_character_url(name, server))
18
- check_valid_url(page)
19
- id = page.xpath('//h4/a')[0]['href'].split(/\//).last
20
- Nokogiri::HTML(open_id_url(id))
21
- end
22
- # Find a characters profiles from a given id.
23
- # Returns a Nokogiri XML document of the characters
24
- # page.
25
- def self.open_id(id)
26
- Nokogiri::HTML(open_id_url(id))
27
- end
28
- # Checks string if two handed weapon type
29
- # returns true if two handed weapon type
30
- def self.is_2hand_weapon(name)
31
- (name =~ /(Arm|Arms|Grimoire|Primary Tool)/i) ? true : false
32
- end
33
- # Open a URL with the given name and server.
34
- # Returns a file stream.
35
- def self.open_character_url(name, server)
36
- open('http://na.finalfantasyxiv.com/lodestone/character/' \
37
- "?q=#{name}&worldname=#{server}")
38
- end
39
- # Open a URL with the given id.
40
- # Reutrn a file stream.
41
- def self.open_id_url(id)
42
- open("http://na.finalfantasyxiv.com/lodestone/character/#{id}")
43
- end
44
- # Validates a Nokogiri document for a character.
45
- # Throws a CharacterNotFound exception.
46
- # Throws a MoreThanOneCharacter exception.
47
- def self.check_valid_url(page)
48
- fail CharacterNotFound unless page.at_xpath('//h4/a')
49
- fail MoreThanOneCharacter if page.xpath('//h4/a').size > 1
50
- end
51
-
52
- private_class_method :open_character_url, :open_id_url
53
- private_class_method :check_valid_url
54
- end
55
- end
1
+ require 'nokogiri'
2
+ require 'open-uri'
3
+
4
+ module XIVLodestone
5
+ # RuntimeError if a character can't be found
6
+ class CharacterNotFound < RuntimeError
7
+ end
8
+ # RuntimeError if more than one character is found
9
+ class MoreThanOneCharacter < RuntimeError
10
+ end
11
+ # A class of helper methods
12
+ class Helper
13
+ # Validates arguments and calls corresponding method
14
+ # Invalid arguments will rase a ArgumentError
15
+ def self.process_args(args)
16
+ return Helper.open_id(args[:id]) if args.key?(:id)
17
+ return Helper.open_url(args[:name], "") if args.key?(:name)
18
+ return Helper.open_url(args[:name], args[:server]) if args.size == 2
19
+ fail ArgumentError, "Invalid arguments passed"
20
+ end
21
+ # Find a character profile from a given name and
22
+ # server. Returns a Nokogiri XML document of the
23
+ # characters page.
24
+ def self.open_url(name, server)
25
+ page = Nokogiri::HTML(open_character_url(name, server))
26
+ check_valid_url(page)
27
+ id = page.xpath('//h4/a')[0]['href'].split(/\//).last
28
+ Nokogiri::HTML(open_id_url(id))
29
+ end
30
+ # Find a characters profiles from a given id.
31
+ # Returns a Nokogiri XML document of the characters
32
+ # page.
33
+ def self.open_id(id)
34
+ Nokogiri::HTML(open_id_url(id))
35
+ end
36
+ # Checks string if two handed weapon type
37
+ # returns true if two handed weapon type
38
+ def self.is_2hand_weapon(name)
39
+ (name =~ /(Arm|Arms|Grimoire|Primary Tool)/i) ? true : false
40
+ end
41
+ # Replaces spaces wtih underscores, and downcases
42
+ # Returns a #String
43
+ def self.replace_downcase(string)
44
+ string.gsub(" ", "_").downcase
45
+ end
46
+ # Returns a #String of the character portrait
47
+ def self.get_server(page)
48
+ page.at_xpath('//h2/span').text.strip.gsub(/\(|\)/, "")
49
+ end
50
+ # Returns a #String of the character portrait
51
+ def self.get_portrait(page)
52
+ page.at_xpath('//div[@class="img_area bg_chara_264"]/img')['src']
53
+ end
54
+ # Returns a #String of the character name
55
+ def self.get_name(page)
56
+ page.at_xpath('//h2/a').text
57
+ end
58
+ # Returns a #String of character title
59
+ def self.get_title(page)
60
+ page.at_xpath('//h2/div').text
61
+ end
62
+ # Returns a #String of character introduction
63
+ def self.get_introduction(page)
64
+ page.at_xpath('//div[@class="area_inner_body txt_selfintroduction"]').text.strip!
65
+ end
66
+ # Returns a #Integer of the characters hp
67
+ def self.get_hp(page)
68
+ page.at_xpath('//li[@class="hp"]').text.to_i
69
+ end
70
+ # Returns a #Integer of the characters mp
71
+ def self.get_mp(page)
72
+ page.at_xpath('//li[@class="mp"]').text.to_i
73
+ end
74
+ # Returns a #Integer of the characters tp
75
+ def self.get_tp(page)
76
+ page.at_xpath('//li[@class="tp"]').text.to_i
77
+ end
78
+ # Returns a #String of the characters sex
79
+ # example "Male" or "Female"
80
+ def self.get_sex(page)
81
+ page.at_xpath('//div[@class="chara_profile_title"]').text.split(/\//).last =~ /♂/i ? "Male" : "Female"
82
+ end
83
+ # Returns a #String of the characters race
84
+ def self.get_race(page)
85
+ page.at_xpath('//div[@class="chara_profile_title"]').text.split(/\//).first.strip!
86
+ end
87
+ # Returns a #String of the characters clan
88
+ def self.get_clan(page)
89
+ page.at_xpath('//div[@class="chara_profile_title"]').text.split(/\//)[1].strip!
90
+ end
91
+ # Returns a #String with the nameday
92
+ def self.get_nameday(page)
93
+ page.at_xpath('(//div[@class="chara_profile_table"]/dl/dd)[1]').text
94
+ end
95
+ # Returns a #String with the guardian name
96
+ def self.get_guardian(page)
97
+ page.at_xpath('(//div[@class="chara_profile_table"]/dl/dd)[2]').text
98
+ end
99
+ # Returns a #String the city name
100
+ def self.get_city(page)
101
+ page.at_xpath('(//dd[@class="txt_name"])[1]').text
102
+ end
103
+ # Returns a #String with the grandcompany
104
+ def self.get_grand_company(page)
105
+ page.at_xpath('(//dd[@class="txt_name"])[2]').text
106
+ end
107
+ # Returns a #Array with the freecompany name and url
108
+ def self.get_free_company(page)
109
+ element = page.at_xpath('//dd[@class="txt_name"]/a')
110
+ [ element.text, "http://na.finalfantasyxiv.com#{element['href']}" ]
111
+ end
112
+ # Open a URL with the given name and server.
113
+ # Returns a file stream.
114
+ def self.open_character_url(name, server)
115
+ open('http://na.finalfantasyxiv.com/lodestone/character/' \
116
+ "?q=#{name}&worldname=#{server}")
117
+ end
118
+ # Open a URL with the given id.
119
+ # Reutrn a file stream.
120
+ def self.open_id_url(id)
121
+ open("http://na.finalfantasyxiv.com/lodestone/character/#{id}")
122
+ end
123
+ # Validates a Nokogiri document for a character.
124
+ # Throws a CharacterNotFound exception.
125
+ # Throws a MoreThanOneCharacter exception.
126
+ def self.check_valid_url(page)
127
+ fail CharacterNotFound unless page.at_xpath('//h4/a')
128
+ fail MoreThanOneCharacter if page.xpath('//h4/a').size > 1
129
+ end
130
+
131
+ private_class_method :open_character_url, :open_id_url
132
+ private_class_method :check_valid_url
133
+ end
134
+ end
@@ -1,4 +1,4 @@
1
- # Stores the current version number of the gem
2
- module XIVLodestone
3
- VERSION = '0.0.3'
4
- end
1
+ # Stores the current version number of the gem
2
+ module XIVLodestone
3
+ VERSION = '0.0.4'
4
+ end
data/lib/xiv_lodestone.rb CHANGED
@@ -1,8 +1,2 @@
1
- require 'xiv_lodestone/version'
2
- require 'xiv_lodestone/lodestone_helper'
3
- require 'xiv_lodestone/lodestone_character'
4
- require 'xiv_lodestone/lodestone_parser'
5
-
6
- # TODO
7
- module XIVLodestone
8
- end
1
+ require 'xiv_lodestone/version'
2
+ require 'xiv_lodestone/lodestone_character'
data/spec/spec_helper.rb CHANGED
@@ -1,12 +1,12 @@
1
- require 'codeclimate-test-reporter'
2
- CodeClimate::TestReporter.start
3
-
4
- RSpec.configure do |config|
5
- config.expect_with :rspec do |expectations|
6
- expectations.include_chain_clauses_in_custom_matcher_descriptions = true
7
- end
8
-
9
- config.mock_with :rspec do |mocks|
10
- mocks.verify_partial_doubles = true
11
- end
12
- end
1
+ require 'codeclimate-test-reporter'
2
+ CodeClimate::TestReporter.start
3
+
4
+ RSpec.configure do |config|
5
+ config.expect_with :rspec do |expectations|
6
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
7
+ end
8
+
9
+ config.mock_with :rspec do |mocks|
10
+ mocks.verify_partial_doubles = true
11
+ end
12
+ end
@@ -5,7 +5,7 @@ LOCAL_FILE = File.join(File.dirname(__FILE__), "resources/character.html")
5
5
  INVALID_FILE = File.join(File.dirname(__FILE__), "resources/invalid.html")
6
6
 
7
7
  describe XIVLodestone::Character do
8
- let(:character) { XIVLodestone::Character.new("Benpi Kancho", "Tonberry") }
8
+ let(:character) { XIVLodestone::Character.new(:name => "Benpi Kancho", :server => "Tonberry") }
9
9
 
10
10
  it 'Character profile found' do
11
11
  expect(character.nil?).to eql(false)
@@ -13,95 +13,68 @@ describe XIVLodestone::Character do
13
13
  end
14
14
 
15
15
  describe XIVLodestone::Helper do
16
+ let(:helper) { XIVLodestone::Helper }
17
+
16
18
  it 'Find character from name and server' do
17
- page = XIVLodestone::Helper.open_url("Benpi Kancho", "Tonberry")
18
- expect(page.xpath('//h2/a')[0].text).to eql("Benpi Kancho")
19
+ page = helper.open_url("Benpi Kancho", "Tonberry")
20
+ expect(page.xpath('//h2/a')[0].text).to eq("Benpi Kancho")
19
21
  end
20
22
 
21
23
  it 'Invalid character name' do
22
- expect { XIVLodestone::Helper.open_url("#$%#FG", "Tonberry") }.to raise_error(URI::InvalidURIError)
24
+ expect { helper.open_url("#$%#FG", "Tonberry") }.to raise_error(URI::InvalidURIError)
23
25
  end
24
26
 
25
27
  it 'Find multiple characters exception' do
26
- expect { XIVLodestone::Helper.open_url("Benpi", "") }.to raise_error(XIVLodestone::MoreThanOneCharacter)
28
+ expect { helper.open_url("Benpi", "") }.to raise_error(XIVLodestone::MoreThanOneCharacter)
27
29
  end
28
30
 
29
31
  it 'No character found exception' do
30
- expect { XIVLodestone::Helper.open_url("Yoloswaggings", "Tonberry") }.to raise_error(XIVLodestone::CharacterNotFound)
32
+ expect { helper.open_url("Yoloswaggings", "Tonberry") }.to raise_error(XIVLodestone::CharacterNotFound)
31
33
  end
32
34
 
33
35
  it 'Find character from id' do
34
- page = XIVLodestone::Helper.open_id("1549391")
36
+ page = helper.open_id("1549391")
35
37
  expect(page.xpath('//h2/a')[0].text).to eql("Benpi Kancho")
36
38
  end
37
- end
38
39
 
39
- describe XIVLodestone::Character do
40
- let(:character) { XIVLodestone::Character.new("Pocket Rocket", "Tonberry") }
41
-
42
- it 'Character methods check' do
43
- expect(character.city).to eql("Ul'dah")
44
- # TODO Add full test of API
40
+ it 'invalid character id' do
41
+ expect { helper.open_id("154") }.to raise_error(OpenURI::HTTPError)
45
42
  end
46
43
 
47
- it 'GearList class check' do
48
- list = XIVLodestone::GearList.new({:weapon => ["Fist", 110, "Weapon", "http://..."]})
49
- expect(list.weapon.name).to eql("Fist")
50
- expect(list.weapon.ilevel).to eql(110)
51
- expect(list.weapon.slot).to eql("Weapon")
52
- expect(list.weapon.url).to eql("http://...")
44
+ it 'invalid arguments' do
45
+ expect { helper.process_args(:server => "Tonberry")}. to raise_error(ArgumentError)
53
46
  end
54
47
 
55
- it 'DiscipleList class check' do
56
- list = XIVLodestone::DiscipleList.new({:rogue => ["Rogue", 1, 0, 300, "http://..."]})
57
- expect(list.rogue.name).to eql("Rogue")
58
- expect(list.rogue.level).to eql(1)
59
- expect(list.rogue.current_exp).to eql(0)
60
- expect(list.rogue.total_exp).to eql(300)
61
- expect(list.rogue.icon_url).to eql("http://...")
62
- expect(list.rogue.next_level).to eql(300)
48
+ it 'Should/Shouldnt be a 2hand weapon' do
49
+ expect(helper.is_2hand_weapon("Two-handed Conjurer's Arm")).to be
50
+ expect(helper.is_2hand_weapon("Dogs Brekkie")).not_to be
63
51
  end
64
- end
65
52
 
66
- describe XIVLodestone::Parser do
67
- let(:parser) { XIVLodestone::Parser.new(Nokogiri::HTML(File.open(LOCAL_FILE))) }
68
- let(:invalid) { XIVLodestone::Parser.new(Nokogiri::HTML(File.open(INVALID_FILE))) }
53
+ it 'replace_downcase case test' do
54
+ expect(helper.replace_downcase("HELLO WORLD")).to eq("hello_world")
55
+ expect(helper.replace_downcase("well_yea")).to eq("well_yea")
56
+ end
69
57
 
70
- it 'Nil initializer to parser' do
71
- expect { XIVLodestone::Parser.new(nil) }.to raise_error(XIVLodestone::Parser::InvalidDocument)
58
+ it 'sucessful call of get methods' do
59
+ valid = Nokogiri::HTML(open(LOCAL_FILE))
60
+ expect(helper.get_hp(valid)).to eq(4975)
61
+ expect(helper.get_mp(valid)).to eq(4819)
62
+ expect(helper.get_tp(valid)).to eq(1000)
63
+ expect(helper.get_sex(valid)).to eq("Male")
64
+ expect(helper.get_race(valid)).to eq("Miqo'te")
65
+ expect(helper.get_clan(valid)).to eq("Keeper of the Moon")
66
+ expect(helper.get_nameday(valid)).to eq("27th Sun of the 1st Astral Moon")
67
+ expect(helper.get_guardian(valid)).to eq("Oschon, the Wanderer")
68
+ expect(helper.get_city(valid)).to eq("Gridania")
69
+ expect(helper.get_grand_company(valid)).to eq("Immortal Flames/Second Flame Lieutenant")
70
+ expect(helper.get_free_company(valid)).to eq(["Nomad Moogles", "http://na.finalfantasyxiv.com/lodestone/freecompany/9233505136016403440/"])
72
71
  end
72
+ end
73
73
 
74
- it 'Invalid parse methods' do
75
- expect(invalid.get_hp()).to eql(nil)
76
- expect(invalid.get_mp()).to eql(nil)
77
- expect(invalid.get_tp()).to eql(nil)
78
- expect(invalid.get_sex()).to eql(nil)
79
- expect(invalid.get_race()).to eql(nil)
80
- expect(invalid.get_clan()).to eql(nil)
81
- expect(invalid.get_nameday()).to eql(nil)
82
- expect(invalid.get_guardian()).to eql(nil)
83
- expect(invalid.get_city()).to eql(nil)
84
- expect(invalid.get_grand_company()).to eql(nil)
85
- expect(invalid.get_classes()).to eql({})
86
- expect(invalid.get_attributes()).to eql({})
87
- expect(invalid.get_gear()).to eql({})
88
- end
89
-
90
- it 'Sucessful parse methods' do
91
- expect(parser.get_classes().count).to eql(20)
92
- expect(parser.get_attributes().count).to eql(34)
93
- expect(parser.get_gear().count).to eql (12)
94
- expect(parser.get_hp()).to eql(4975)
95
- expect(parser.get_mp()).to eql(4819)
96
- expect(parser.get_tp()).to eql(1000)
97
- expect(parser.get_sex()).to eql("Male")
98
- expect(parser.get_race()).to eql("Miqo'te")
99
- expect(parser.get_clan()).to eql("Keeper of the Moon")
100
- expect(parser.get_nameday()).to eql("27th Sun of the 1st Astral Moon")
101
- expect(parser.get_guardian()).to eql("Oschon, the Wanderer")
102
- expect(parser.get_city()).to eql("Gridania")
103
- expect(parser.get_grand_company()).to eql("Immortal Flames/Second Flame Lieutenant")
104
- expect(parser.get_free_company()).to eql(["Nomad Moogles",
105
- "http://na.finalfantasyxiv.com/lodestone/freecompany/9233505136016403440/"])
74
+ describe XIVLodestone::Character do
75
+ let(:character) { XIVLodestone::Character.new(:name => "Pocket Rocket", :server =>"Tonberry") }
76
+
77
+ it 'Character methods check' do
78
+ # TODO Add full test of API
106
79
  end
107
80
  end
@@ -21,6 +21,7 @@ Gem::Specification.new do |spec|
21
21
  spec.required_ruby_version = "~> 2.2"
22
22
 
23
23
  spec.add_dependency("nokogiri", "~> 1.6")
24
+ spec.add_dependency("oj", "~> 2.11")
24
25
 
25
26
  spec.add_development_dependency("bundler", "~> 1.7")
26
27
  spec.add_development_dependency("rspec", "~> 3.1")
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xiv_lodestone
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Benjamin Evenson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-05 00:00:00.000000000 Z
11
+ date: 2015-01-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: oj
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.11'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.11'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -84,8 +98,11 @@ files:
84
98
  - Rakefile
85
99
  - lib/xiv_lodestone.rb
86
100
  - lib/xiv_lodestone/lodestone_character.rb
101
+ - lib/xiv_lodestone/lodestone_character_attribute.rb
102
+ - lib/xiv_lodestone/lodestone_character_disciple.rb
103
+ - lib/xiv_lodestone/lodestone_character_gear.rb
104
+ - lib/xiv_lodestone/lodestone_character_mount.rb
87
105
  - lib/xiv_lodestone/lodestone_helper.rb
88
- - lib/xiv_lodestone/lodestone_parser.rb
89
106
  - lib/xiv_lodestone/version.rb
90
107
  - spec/resources/character.html
91
108
  - spec/resources/invalid.html
@@ -1,158 +0,0 @@
1
- require 'nokogiri'
2
-
3
- module XIVLodestone
4
- class Parser
5
- # An exception for a invalid Nokogiri page
6
- class InvalidDocument < Exception
7
- end
8
- # default constructor, initalises @page with a
9
- # Nokogiri document. Raises a InvalidDocument eception
10
- # if page is invalid
11
- def initialize(page)
12
- fail InvalidDocument, 'Invalid page' if page.nil?
13
- @page = page
14
- end
15
- # Returns a #Hash of the characters class levels
16
- # Example { :Gladitor => 10, ... }
17
- # If no classes found returns a empty #Hash
18
- def get_classes()
19
- class_list = Hash.new
20
- @page.xpath('//table[@class="class_list"]/tr/td').each_slice(3) do |td|
21
- # Not a valid class
22
- next if td[0].text.empty?
23
- exp = td[2].text.split(/\//)
24
-
25
- class_list[td[0].text.downcase.to_sym] = [td[0].text,
26
- td[1].text.to_i,
27
- exp[0].to_i,
28
- exp[1].to_i,
29
- td[0].at_css('img')['src']]
30
- end
31
- class_list
32
- end
33
- # Returns a #Hash of the character attributes
34
- # Example { :str => 243, ... }
35
- # If no attributes found returns a empty #Hash
36
- def get_attributes()
37
- stats = Hash.new
38
- @page.xpath('//div[starts-with(@class, "param_left_area_inner")]/ul/li').each_with_index do |li, index|
39
- if index < 6
40
- stats[replace_downcase(li['class']).to_sym] = li.text.to_i
41
- else
42
- ele = li.text.split(/(?<=\D)(?=\d)/)
43
- stats[replace_downcase(ele[0]).to_sym] = ele[1].to_i
44
- end
45
- end
46
- stats
47
- end
48
- # Returns a #Hash of the characters gear list
49
- # Example { :head => [ "item_name", "item_url" ], ... }
50
- # If no gear found returns a empty #Hash
51
- def get_gear()
52
- items = Hash.new
53
- @page.xpath("(//div[@class='item_detail_box'])[position() < 13]").each do |item|
54
- type = get_item_type(item.at_css('h3.category_name').text)
55
- items[type.to_sym] = [ item.css('h2').text,
56
- item.at_css('div.pt3.pb3').text.split(/ /).last.to_i,
57
- item.at_css('h3.category_name').text,
58
- "http://na.finalfantasyxiv.com#{item.css('a')[0]['href']}" ]
59
- end
60
- items
61
- end
62
- # Returns a #Integer of the characters hp
63
- # otherwise returns nil
64
- def get_hp()
65
- hp = @page.at_xpath('//li[@class="hp"]')
66
- hp.nil? ? nil : hp.text.to_i
67
- end
68
- # Returns a #Integer of the characters mp
69
- # otherwise returns nil
70
- def get_mp()
71
- mp = @page.at_xpath('//li[@class="mp"]')
72
- mp.nil? ? nil : mp.text.to_i
73
- end
74
- # Returns a #Integer of the characters tp
75
- # otherwise returns nil
76
- def get_tp()
77
- tp = @page.at_xpath('//li[@class="tp"]')
78
- tp.nil? ? nil : tp.text.to_i
79
- end
80
- # Returns a #String of the characters sex
81
- # example "Male" or "Female"
82
- # otherwise returns nil
83
- def get_sex()
84
- sex = @page.at_xpath('//div[@class="chara_profile_title"]')
85
- if sex.nil?
86
- nil
87
- else
88
- sex.text.split(/\//).last =~ /♂/i ? "Male" : "Female"
89
- end
90
- end
91
- # Returns a #String of the characters race
92
- # otherwise returns nil
93
- def get_race()
94
- race = @page.at_xpath('//div[@class="chara_profile_title"]')
95
- race.nil? ? nil : race.text.split(/\//).first.strip!
96
- end
97
- # Returns a #String of the characters clan
98
- # otherwise returns nil
99
- def get_clan()
100
- clan = @page.at_xpath('//div[@class="chara_profile_title"]')
101
- clan.nil? ? nil : clan.text.split(/\//)[1].strip!
102
- end
103
- # Returns a #String with the nameday
104
- # otherwise returns nil
105
- def get_nameday()
106
- nameday = @page.at_xpath('(//div[@class="chara_profile_table"]/dl/dd)[1]')
107
- nameday.nil? ? nil : nameday.text
108
- end
109
- # Returns a #String with the guardian name
110
- # otherwise returns nil
111
- def get_guardian()
112
- guardian = @page.at_xpath('(//div[@class="chara_profile_table"]/dl/dd)[2]')
113
- guardian.nil? ? nil : guardian.text
114
- end
115
- # Returns a #String the city name
116
- # otherwise returns nil
117
- def get_city()
118
- city = @page.at_xpath('(//dd[@class="txt_name"])[1]')
119
- city.nil? ? nil : city.text
120
- end
121
- # Returns a #String with the grandcompany
122
- # otherwise returns nil
123
- def get_grand_company()
124
- company = @page.at_xpath('(//dd[@class="txt_name"])[2]')
125
- company.nil? ? nil : company.text
126
- end
127
- # Returns a #Array with the freecompany name and url
128
- # otherwise returns nil
129
- def get_free_company()
130
- element = @page.at_xpath('//dd[@class="txt_name"]/a')
131
- element.nil? ? nil : [ element.text, "http://na.finalfantasyxiv.com#{element['href']}" ]
132
- end
133
- # Replaces spaces wtih underscores, and downcases
134
- # Returns a #String
135
- def replace_downcase(string)
136
- string.gsub(" ", "_").downcase
137
- end
138
- # Auto-increaments between 1 and 2
139
- def ring
140
- @num ||= 0
141
- @num = 0 if @num >= 2
142
- @num += 1
143
- end
144
- # Returns a string representing what item type it is
145
- def get_item_type(item_name)
146
- if item_name =~ /(Arm|Arms|Grimoire|Primary Tool)/i
147
- return "weapon"
148
- elsif item_name =~ /Shield/i
149
- return "shield"
150
- elsif item_name.eql?("Ring")
151
- return "ring#{ring}"
152
- else
153
- return item_name.downcase
154
- end
155
- end
156
- private :replace_downcase, :ring, :get_item_type
157
- end
158
- end