xiv_lodestone 0.0.4 → 0.0.5
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 +4 -4
- data/CHANGELOG.md +13 -0
- data/LICENSE.txt +1 -1
- data/OUTLINE.md +37 -0
- data/README.md +45 -11
- data/lib/xiv_lodestone/lodestone_character.rb +17 -12
- data/lib/xiv_lodestone/lodestone_character_attribute.rb +5 -5
- data/lib/xiv_lodestone/lodestone_character_collectable.rb +29 -0
- data/lib/xiv_lodestone/lodestone_character_disciple.rb +11 -21
- data/lib/xiv_lodestone/lodestone_character_gear.rb +11 -19
- data/lib/xiv_lodestone/lodestone_helper.rb +42 -27
- data/lib/xiv_lodestone/lodestone_server.rb +34 -0
- data/lib/xiv_lodestone/version.rb +1 -1
- data/lib/xiv_lodestone.rb +1 -0
- data/spec/resources/status.html +2151 -0
- data/spec/spec_helper.rb +4 -0
- data/spec/xiv_lodestone_character_attribute_spec.rb +26 -0
- data/spec/xiv_lodestone_character_collectable_spec.rb +28 -0
- data/spec/xiv_lodestone_character_disciple_spec.rb +33 -0
- data/spec/xiv_lodestone_character_gear_spec.rb +37 -0
- data/spec/xiv_lodestone_helper_spec.rb +52 -0
- data/spec/xiv_lodestone_server_spec.rb +28 -0
- data/spec/xiv_lodestone_spec.rb +13 -72
- data/xiv_lodestone.gemspec +0 -1
- metadata +19 -17
- data/lib/xiv_lodestone/lodestone_character_mount.rb +0 -35
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 900f8547e08b2e76ee9b9392bb936fbc92c9b977
|
4
|
+
data.tar.gz: 12f1fe3b77ca3771923ca7b116b56d3d29a414a7
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2720c1bb7badfdbbe00d1cd2289f2b1a064c15aabf0bc9527f7f38ad81781e6e892789df9e50038d657fe93c53bf44749136104813fc96782bf555a27dc0f5b9
|
7
|
+
data.tar.gz: b37c89c1ae581c130cb57d697fa6a48d717798377757a080d91821e367909eb7aeea465723303783db078b2dd8a35a8992df2c4abc7046a828721f98a6a66c63
|
data/CHANGELOG.md
CHANGED
@@ -35,3 +35,16 @@ Features
|
|
35
35
|
Bugfixes
|
36
36
|
- Rewriting more comprehensive tests
|
37
37
|
- Change the way Character.new arguments work
|
38
|
+
- Cleaned up code structure to be more modular
|
39
|
+
|
40
|
+
## Alpha: 0.0.5 (2015-01-19)
|
41
|
+
Features
|
42
|
+
- Added server status
|
43
|
+
- Added job detection
|
44
|
+
|
45
|
+
Bugfixes
|
46
|
+
- Logic error in process_args
|
47
|
+
- Removed MoreThanOneCharacter exception(now picks the first character from result search)
|
48
|
+
- Now returns the first match if multiple characters
|
49
|
+
- cleaned up to_json method
|
50
|
+
- More bug fixes
|
data/LICENSE.txt
CHANGED
data/OUTLINE.md
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
Helper
|
2
|
+
- Opening URL - DONE
|
3
|
+
- Searching ID/Character - DONE
|
4
|
+
|
5
|
+
Character
|
6
|
+
- Profile - DONE
|
7
|
+
- Mounts - DONE
|
8
|
+
- Minions - DONE
|
9
|
+
- Gear - DONE
|
10
|
+
- Attributes - DONE
|
11
|
+
- Disciple - DONE
|
12
|
+
- Achievements
|
13
|
+
- Total Points
|
14
|
+
#### Leave Last ####
|
15
|
+
- Blog
|
16
|
+
- Following
|
17
|
+
- Friend
|
18
|
+
|
19
|
+
Free Company
|
20
|
+
- Profile
|
21
|
+
- Name
|
22
|
+
- Faction
|
23
|
+
- Tag
|
24
|
+
- Formed
|
25
|
+
- Active Members
|
26
|
+
- Rank
|
27
|
+
- Weekly Rank
|
28
|
+
- Monthly Rank
|
29
|
+
- Slogan
|
30
|
+
- Focus
|
31
|
+
- Seeking
|
32
|
+
- Active
|
33
|
+
- Recruitment
|
34
|
+
- Estate Profile
|
35
|
+
- Members
|
36
|
+
- Name
|
37
|
+
- Rank
|
data/README.md
CHANGED
@@ -9,6 +9,7 @@ submit a issue for bug or feature requests.
|
|
9
9
|
|
10
10
|
## Features
|
11
11
|
- Character Search (via ID number or Name and Server)
|
12
|
+
- To Json functionality
|
12
13
|
- Character profile
|
13
14
|
- name, server, portrait image url
|
14
15
|
- HP, MP, TP
|
@@ -16,14 +17,14 @@ submit a issue for bug or feature requests.
|
|
16
17
|
- Gear List - Shows item name, ilevel, slot, ffxiv db url, calculates total ilevel
|
17
18
|
- Disciple List(Classes) - Shows class name, level, current exp, total exp, icon url, calculates experience to next level
|
18
19
|
- All character attributes
|
20
|
+
- Mounts & Minions
|
21
|
+
- Server Status
|
22
|
+
- Job detection
|
19
23
|
|
20
24
|
## TODO
|
21
|
-
-
|
22
|
-
-
|
23
|
-
- To Json functionality
|
24
|
-
- Achievements, Blogs, Friends list, Mounts, Pets
|
25
|
+
- Multi-Language support(JP,NA,DE,FR)
|
26
|
+
- Achievements
|
25
27
|
- Free Company Search/Gather Member information
|
26
|
-
- Clean up smelly code 24/7
|
27
28
|
|
28
29
|
## Installation
|
29
30
|
|
@@ -48,14 +49,22 @@ directly taken from the lodestone naming conversation.
|
|
48
49
|
|
49
50
|
```ruby
|
50
51
|
require 'xiv_lodestone'
|
51
|
-
```
|
52
|
+
```
|
52
53
|
|
53
54
|
To parse a character
|
54
55
|
```ruby
|
55
|
-
character = XIVLodestone::Character("Benpi Kancho", "Tonberry")
|
56
|
-
character = XIVLodestone::Character("Benpi Kancho")
|
57
|
-
character = XIVLodestone::Character(1549391)
|
58
|
-
```
|
56
|
+
character = XIVLodestone::Character(name: "Benpi Kancho", :server: "Tonberry")
|
57
|
+
character = XIVLodestone::Character(name: "Benpi Kancho")
|
58
|
+
character = XIVLodestone::Character(id: 1549391)
|
59
|
+
```
|
60
|
+
|
61
|
+
Get server status
|
62
|
+
```ruby
|
63
|
+
status = XIVLodestone::ServerStatus.new
|
64
|
+
status.tonberry.name #=> Returns a string server name
|
65
|
+
status.tonberry.registration #=> Returns a string Open or Closed(Character registration)
|
66
|
+
status.tonberry.status #=> Retuns a string Online or Offline
|
67
|
+
```
|
59
68
|
|
60
69
|
Basic examples
|
61
70
|
|
@@ -77,6 +86,7 @@ character.nameday #=> character nameday #String
|
|
77
86
|
character.guardian #=> character guardian #String
|
78
87
|
character.city #=> character home city #String
|
79
88
|
character.grand_company #=> character grand company #String
|
89
|
+
character.job #=> characters current job
|
80
90
|
|
81
91
|
# Character Attributes
|
82
92
|
str, dex, vit, int, mnd, pie, fire, ice, wind, earth, lighting, water, accuracy,
|
@@ -86,6 +96,8 @@ piercing, slashing, heavy_resistance, bind_resistance, sleep_resistance,
|
|
86
96
|
stun_resistance, poison_resistance, blind_resistance, silence_resistance,
|
87
97
|
slow_resistance
|
88
98
|
|
99
|
+
character.attribute.str #=> character str #Integer
|
100
|
+
|
89
101
|
# Available Gear Slot
|
90
102
|
weapon, head, body, hands, belt, legs, feet, shield, necklace, earrings,
|
91
103
|
bracelets, ring1, ring2
|
@@ -109,7 +121,29 @@ character.disciple.rogue.current_exp # => current experience #Interger
|
|
109
121
|
character.disciple.rogue.total_exp # => total experience #Integer
|
110
122
|
character.disciple.rogue.icon_url # => class icon url #String
|
111
123
|
character.disciple.rogue.next_level # => experience to required to level #Integer
|
112
|
-
|
124
|
+
|
125
|
+
# Mounts & Minions
|
126
|
+
character.mounts.each do |mount|
|
127
|
+
puts mount.name
|
128
|
+
puts mount.icon_url
|
129
|
+
end
|
130
|
+
|
131
|
+
character.minions.each do |minion|
|
132
|
+
puts minion.name
|
133
|
+
puts minion.icon_url
|
134
|
+
end
|
135
|
+
|
136
|
+
character.minions #=> Returns a array of Minion
|
137
|
+
character.mounts #=> Returns a array of mounts
|
138
|
+
|
139
|
+
# To Json
|
140
|
+
character.to_json
|
141
|
+
character.mounts.to_json
|
142
|
+
character.minions.to_json
|
143
|
+
character.disciple.to_json
|
144
|
+
character.gear.to_json
|
145
|
+
character.attribute.to_json
|
146
|
+
```
|
113
147
|
|
114
148
|
## Contributing
|
115
149
|
|
@@ -2,7 +2,8 @@ require 'xiv_lodestone/lodestone_helper'
|
|
2
2
|
require 'xiv_lodestone/lodestone_character_gear'
|
3
3
|
require 'xiv_lodestone/lodestone_character_disciple'
|
4
4
|
require 'xiv_lodestone/lodestone_character_attribute'
|
5
|
-
require 'xiv_lodestone/
|
5
|
+
require 'xiv_lodestone/lodestone_character_collectable'
|
6
|
+
require 'json'
|
6
7
|
|
7
8
|
module XIVLodestone
|
8
9
|
# A Object that represents a FFXIV:ARR character,
|
@@ -12,34 +13,38 @@ module XIVLodestone
|
|
12
13
|
# 1. Character.new(:name => "CHARACTER_NAME", :server => "SERVER_NAME")
|
13
14
|
# 2. Character.new(:name => "CHARACTER_NAME")
|
14
15
|
# 3. Character.new(:id => ID_NUMBER)
|
15
|
-
def initialize(args =
|
16
|
-
@profile = Hash.new
|
16
|
+
def initialize(args = {})
|
17
|
+
@profile = Hash.new
|
17
18
|
initialise_profile(Helper.process_args(args))
|
18
19
|
end
|
19
20
|
# Returns a #String with characters first name
|
20
|
-
def first_name
|
21
|
+
def first_name
|
21
22
|
@profile[:name].split(/ /).first
|
22
23
|
end
|
23
24
|
# Returns a #String with characters last name
|
24
|
-
def last_name
|
25
|
+
def last_name
|
25
26
|
@profile[:name].split(/ /).last
|
26
27
|
end
|
27
28
|
# Returns a #Array of characters mounts
|
28
|
-
def mounts
|
29
|
+
def mounts
|
29
30
|
@mounts.list
|
30
31
|
end
|
31
32
|
# Returns a #Array of characters minions
|
32
|
-
def minions
|
33
|
+
def minions
|
33
34
|
@minions.list
|
34
35
|
end
|
36
|
+
# Returns the current character job
|
37
|
+
def job
|
38
|
+
@profile[:gear].soul_crystal.name.gsub("Soul of the ", "")
|
39
|
+
end
|
35
40
|
# Generates missing methods from @profile hash keys
|
36
41
|
def method_missing(method)
|
37
42
|
return @profile[method] if @profile.key?(method)
|
38
43
|
super
|
39
44
|
end
|
40
45
|
# Uses gem Oj to dump Character Object to JSON
|
41
|
-
def to_json
|
42
|
-
|
46
|
+
def to_json
|
47
|
+
@profile.to_json
|
43
48
|
end
|
44
49
|
#### Private Methods ####
|
45
50
|
# Initialises all characters information from lodestone
|
@@ -61,10 +66,10 @@ module XIVLodestone
|
|
61
66
|
@profile[:grand_company] = Helper.get_grand_company(page)
|
62
67
|
@profile[:free_company] = Helper.get_free_company(page)
|
63
68
|
@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() <
|
69
|
+
@profile[:gear] = GearList.new(page.xpath("(//div[@class='item_detail_box'])[position() < 14]"))
|
65
70
|
@profile[:attribute] = AttributeList.new(page.xpath('//div[starts-with(@class, "param_left_area_inner")]/ul/li'))
|
66
|
-
@mounts =
|
67
|
-
@minions =
|
71
|
+
@mounts = CollectableList.new(page.xpath('(//div[@class="minion_box clearfix"])[1]/a'))
|
72
|
+
@minions = CollectableList.new(page.xpath('(//div[@class="minion_box clearfix"])[2]/a'))
|
68
73
|
end
|
69
74
|
|
70
75
|
private :initialise_profile
|
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'xiv_lodestone/lodestone_helper'
|
2
|
-
require '
|
2
|
+
require 'json'
|
3
3
|
|
4
4
|
module XIVLodestone
|
5
5
|
# A Object that represents a set of atrributes from
|
@@ -8,17 +8,17 @@ module XIVLodestone
|
|
8
8
|
# names are based of names of attributes from lodestone website
|
9
9
|
class AttributeList
|
10
10
|
def initialize(attribute_path)
|
11
|
-
@attributes =
|
11
|
+
@attributes = {}
|
12
12
|
parse_attributes(attribute_path)
|
13
13
|
end
|
14
14
|
# Generate methods from each key in the @attribute hash
|
15
15
|
def method_missing(method)
|
16
|
-
return @attributes[method] if @attributes.key?(
|
16
|
+
return @attributes[method] if @attributes.key?(method)
|
17
17
|
super
|
18
18
|
end
|
19
|
-
#
|
19
|
+
# Converts t
|
20
20
|
def to_json()
|
21
|
-
|
21
|
+
@attributes.to_json
|
22
22
|
end
|
23
23
|
#### Private Methods ####
|
24
24
|
# Parsers attributes from a document into @attribute hash
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'xiv_lodestone/lodestone_helper'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module XIVLodestone
|
5
|
+
class CollectableList
|
6
|
+
attr_reader :list
|
7
|
+
|
8
|
+
Collectable = Struct.new(:name, :icon_url)
|
9
|
+
|
10
|
+
def initialize(collectable_path)
|
11
|
+
@list = []
|
12
|
+
parse_collectable(collectable_path)
|
13
|
+
end
|
14
|
+
# Uses gem Oj to dump MountList to JSON
|
15
|
+
def to_json()
|
16
|
+
@list.map { |obj| Hash[obj.each_pair.to_a] }.to_json
|
17
|
+
end
|
18
|
+
#### Private Methods ####
|
19
|
+
def parse_collectable(collectable_path)
|
20
|
+
collectable_path.each do |collectable|
|
21
|
+
@list.push(Collectable.new(
|
22
|
+
collectable['title'].split.map(&:capitalize)*' ',
|
23
|
+
collectable.at_xpath('img')['src']))
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
private :parse_collectable
|
28
|
+
end
|
29
|
+
end
|
@@ -1,18 +1,25 @@
|
|
1
1
|
require 'nokogiri'
|
2
|
-
require '
|
2
|
+
require 'json'
|
3
3
|
|
4
4
|
module XIVLodestone
|
5
5
|
# A object representation of disciples(classes)
|
6
6
|
# The initialiser takes a hash of Disciple, that layout follows
|
7
7
|
# { :rogue => ["Rogue", 1, 0, 300, "http://..."] }
|
8
8
|
class DiscipleList
|
9
|
+
# This strct representents a disciple
|
10
|
+
Disciple = Struct.new(:name, :level, :current_exp, :total_exp, :icon_url) do
|
11
|
+
def next_level
|
12
|
+
total_exp - current_exp
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
9
16
|
def initialize(disciple_path)
|
10
|
-
@disciple =
|
17
|
+
@disciple = {}
|
11
18
|
parse_disciple(disciple_path)
|
12
19
|
end
|
13
|
-
#
|
20
|
+
# Returns a json repsentation of all disciples
|
14
21
|
def to_json()
|
15
|
-
|
22
|
+
@disciple.to_json
|
16
23
|
end
|
17
24
|
# Generates missing methods using @disciple hash keys
|
18
25
|
def method_missing(method)
|
@@ -33,22 +40,5 @@ module XIVLodestone
|
|
33
40
|
end
|
34
41
|
|
35
42
|
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
43
|
end
|
54
44
|
end
|
@@ -1,13 +1,17 @@
|
|
1
1
|
require 'nokogiri'
|
2
|
-
require '
|
2
|
+
require 'json'
|
3
|
+
require 'xiv_lodestone/lodestone_helper'
|
3
4
|
|
4
5
|
module XIVLodestone
|
5
6
|
# A Object that represents a list of Gear pieces
|
6
7
|
# The initialiser takes a hash of items in the following layout
|
7
8
|
# { :weapon => ["Fist", 110, "Weapon", "http://...."], ... }
|
8
9
|
class GearList
|
10
|
+
# This struct representation a piece of gear.
|
11
|
+
Gear = Struct.new(:name, :ilevel, :slot, :url)
|
12
|
+
|
9
13
|
def initialize(gear_path)
|
10
|
-
@items =
|
14
|
+
@items = {}
|
11
15
|
parse_gear(gear_path)
|
12
16
|
end
|
13
17
|
# Calculates the total gear list ilevel
|
@@ -15,15 +19,15 @@ module XIVLodestone
|
|
15
19
|
# returns a #Integer
|
16
20
|
def ilevel()
|
17
21
|
ilevel = 0
|
18
|
-
ilevel = @items[:weapon].ilevel if
|
22
|
+
ilevel = @items[:weapon].ilevel if @items[:shield].nil?
|
19
23
|
@items.each_value do |value|
|
20
|
-
ilevel += value.ilevel
|
24
|
+
ilevel += value.ilevel unless value.name =~ /Soul of the/i
|
21
25
|
end
|
22
26
|
(ilevel/13).round
|
23
27
|
end
|
24
|
-
#
|
28
|
+
# Returns a JSON string of all items
|
25
29
|
def to_json()
|
26
|
-
|
30
|
+
@items.to_json
|
27
31
|
end
|
28
32
|
# Generates access methods for each item slot
|
29
33
|
def method_missing(method)
|
@@ -50,7 +54,7 @@ module XIVLodestone
|
|
50
54
|
elsif name.eql?("Ring")
|
51
55
|
return "ring#{ring_inc}"
|
52
56
|
else
|
53
|
-
return name
|
57
|
+
return Helper.replace_downcase(name)
|
54
58
|
end
|
55
59
|
end
|
56
60
|
# Initialise @num and count upwards, if @num >= 2 reset to 1
|
@@ -62,17 +66,5 @@ module XIVLodestone
|
|
62
66
|
end
|
63
67
|
|
64
68
|
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
69
|
end
|
78
70
|
end
|
@@ -5,26 +5,33 @@ module XIVLodestone
|
|
5
5
|
# RuntimeError if a character can't be found
|
6
6
|
class CharacterNotFound < RuntimeError
|
7
7
|
end
|
8
|
-
# RuntimeError if more than one character is found
|
9
|
-
class MoreThanOneCharacter < RuntimeError
|
10
|
-
end
|
11
8
|
# A class of helper methods
|
12
9
|
class Helper
|
13
10
|
# Validates arguments and calls corresponding method
|
14
11
|
# Invalid arguments will rase a ArgumentError
|
15
12
|
def self.process_args(args)
|
16
13
|
return Helper.open_id(args[:id]) if args.key?(:id)
|
17
|
-
return Helper.open_url(args[:name], "") if args.key?(:name)
|
18
14
|
return Helper.open_url(args[:name], args[:server]) if args.size == 2
|
15
|
+
return Helper.open_url(args[:name], "") if args.key?(:name)
|
19
16
|
fail ArgumentError, "Invalid arguments passed"
|
20
17
|
end
|
18
|
+
# Opens the FFXIV server status page
|
19
|
+
# returns a Nokogiri document
|
20
|
+
def self.open_server_status()
|
21
|
+
Nokogiri::HTML(open("http://na.finalfantasyxiv.com/lodestone/worldstatus/"))
|
22
|
+
end
|
23
|
+
# Opens the FFXIV registration page
|
24
|
+
# returns a Nokogiri document
|
25
|
+
def self.open_registration_status()
|
26
|
+
Nokogiri::HTML(open("http://na.finalfantasyxiv.com/lodestone/news/detail/80cd4583bf743600105b947d6906d0909189e479"))
|
27
|
+
end
|
21
28
|
# Find a character profile from a given name and
|
22
29
|
# server. Returns a Nokogiri XML document of the
|
23
30
|
# characters page.
|
24
31
|
def self.open_url(name, server)
|
25
32
|
page = Nokogiri::HTML(open_character_url(name, server))
|
26
33
|
check_valid_url(page)
|
27
|
-
id = page.
|
34
|
+
id = page.at_xpath('//h4/a')['href'].split(/\//).last
|
28
35
|
Nokogiri::HTML(open_id_url(id))
|
29
36
|
end
|
30
37
|
# Find a characters profiles from a given id.
|
@@ -33,11 +40,6 @@ module XIVLodestone
|
|
33
40
|
def self.open_id(id)
|
34
41
|
Nokogiri::HTML(open_id_url(id))
|
35
42
|
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
43
|
# Replaces spaces wtih underscores, and downcases
|
42
44
|
# Returns a #String
|
43
45
|
def self.replace_downcase(string)
|
@@ -45,69 +47,83 @@ module XIVLodestone
|
|
45
47
|
end
|
46
48
|
# Returns a #String of the character portrait
|
47
49
|
def self.get_server(page)
|
48
|
-
page.at_xpath('//h2/span')
|
50
|
+
server = page.at_xpath('//h2/span')
|
51
|
+
server ? server.text.strip.gsub(/\(|\)/, "") : ""
|
49
52
|
end
|
50
53
|
# Returns a #String of the character portrait
|
51
54
|
def self.get_portrait(page)
|
52
|
-
page.at_xpath('//div[@class="img_area bg_chara_264"]/img')
|
55
|
+
port = page.at_xpath('//div[@class="img_area bg_chara_264"]/img')
|
56
|
+
port ? port['src'] : ""
|
53
57
|
end
|
54
58
|
# Returns a #String of the character name
|
55
59
|
def self.get_name(page)
|
56
|
-
page.at_xpath('//h2/a')
|
60
|
+
name = page.at_xpath('//h2/a')
|
61
|
+
name ? name.text : ""
|
57
62
|
end
|
58
63
|
# Returns a #String of character title
|
59
64
|
def self.get_title(page)
|
60
|
-
page.at_xpath('//h2/div')
|
65
|
+
title = page.at_xpath('//h2/div')
|
66
|
+
title ? title.text : ""
|
61
67
|
end
|
62
68
|
# Returns a #String of character introduction
|
63
69
|
def self.get_introduction(page)
|
64
|
-
page.at_xpath('//div[@class="area_inner_body txt_selfintroduction"]')
|
70
|
+
intro = page.at_xpath('//div[@class="area_inner_body txt_selfintroduction"]')
|
71
|
+
intro ? intro.text.strip! : ""
|
65
72
|
end
|
66
73
|
# Returns a #Integer of the characters hp
|
67
74
|
def self.get_hp(page)
|
68
|
-
page.at_xpath('//li[@class="hp"]')
|
75
|
+
hp = page.at_xpath('//li[@class="hp"]')
|
76
|
+
hp ? hp.text.to_i : 0
|
69
77
|
end
|
70
78
|
# Returns a #Integer of the characters mp
|
71
79
|
def self.get_mp(page)
|
72
|
-
page.at_xpath('//li[@class="mp"]')
|
80
|
+
mp = page.at_xpath('//li[@class="mp"]')
|
81
|
+
mp ? mp.text.to_i : 0
|
73
82
|
end
|
74
83
|
# Returns a #Integer of the characters tp
|
75
84
|
def self.get_tp(page)
|
76
|
-
page.at_xpath('//li[@class="tp"]')
|
85
|
+
tp = page.at_xpath('//li[@class="tp"]')
|
86
|
+
tp ? tp.text.to_i : 0
|
77
87
|
end
|
78
88
|
# Returns a #String of the characters sex
|
79
89
|
# example "Male" or "Female"
|
80
90
|
def self.get_sex(page)
|
81
|
-
page.at_xpath('//div[@class="chara_profile_title"]').text.split(/\//).last =~ /♂/i ? "Male" : "Female"
|
91
|
+
sex = page.at_xpath('//div[@class="chara_profile_title"]').text.split(/\//).last =~ /♂/i ? "Male" : "Female"
|
82
92
|
end
|
83
93
|
# Returns a #String of the characters race
|
84
94
|
def self.get_race(page)
|
85
|
-
page.at_xpath('//div[@class="chara_profile_title"]')
|
95
|
+
race = page.at_xpath('//div[@class="chara_profile_title"]')
|
96
|
+
race ? race.text.split(/\//).first.strip! : ""
|
86
97
|
end
|
87
98
|
# Returns a #String of the characters clan
|
88
99
|
def self.get_clan(page)
|
89
|
-
page.at_xpath('//div[@class="chara_profile_title"]')
|
100
|
+
clan = page.at_xpath('//div[@class="chara_profile_title"]')
|
101
|
+
clan ? clan.text.split(/\//)[1].strip! : ""
|
90
102
|
end
|
91
103
|
# Returns a #String with the nameday
|
92
104
|
def self.get_nameday(page)
|
93
|
-
page.at_xpath('(//div[@class="chara_profile_table"]/dl/dd)[1]')
|
105
|
+
nameday = page.at_xpath('(//div[@class="chara_profile_table"]/dl/dd)[1]')
|
106
|
+
nameday ? nameday.text : ""
|
94
107
|
end
|
95
108
|
# Returns a #String with the guardian name
|
96
109
|
def self.get_guardian(page)
|
97
|
-
page.at_xpath('(//div[@class="chara_profile_table"]/dl/dd)[2]')
|
110
|
+
guardian = page.at_xpath('(//div[@class="chara_profile_table"]/dl/dd)[2]')
|
111
|
+
guardian ? guardian.text : ""
|
98
112
|
end
|
99
113
|
# Returns a #String the city name
|
100
114
|
def self.get_city(page)
|
101
|
-
page.at_xpath('(//dd[@class="txt_name"])[1]')
|
115
|
+
city = page.at_xpath('(//dd[@class="txt_name"])[1]')
|
116
|
+
city ? city.text : ""
|
102
117
|
end
|
103
118
|
# Returns a #String with the grandcompany
|
104
119
|
def self.get_grand_company(page)
|
105
|
-
page.at_xpath('(//dd[@class="txt_name"])[2]')
|
120
|
+
company = page.at_xpath('(//dd[@class="txt_name"])[2]')
|
121
|
+
company ? company.text : ""
|
106
122
|
end
|
107
123
|
# Returns a #Array with the freecompany name and url
|
108
124
|
def self.get_free_company(page)
|
109
125
|
element = page.at_xpath('//dd[@class="txt_name"]/a')
|
110
|
-
[ element.text, "http://na.finalfantasyxiv.com#{element['href']}" ]
|
126
|
+
element ? [ element.text, "http://na.finalfantasyxiv.com#{element['href']}" ] : [ "", "" ]
|
111
127
|
end
|
112
128
|
# Open a URL with the given name and server.
|
113
129
|
# Returns a file stream.
|
@@ -125,7 +141,6 @@ module XIVLodestone
|
|
125
141
|
# Throws a MoreThanOneCharacter exception.
|
126
142
|
def self.check_valid_url(page)
|
127
143
|
fail CharacterNotFound unless page.at_xpath('//h4/a')
|
128
|
-
fail MoreThanOneCharacter if page.xpath('//h4/a').size > 1
|
129
144
|
end
|
130
145
|
|
131
146
|
private_class_method :open_character_url, :open_id_url
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'xiv_lodestone/lodestone_helper'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
module XIVLodestone
|
5
|
+
# This is a basic class fetchs the server status from
|
6
|
+
# lodestone.
|
7
|
+
class ServerStatus
|
8
|
+
Server = Struct.new(:name, :status, :registration)
|
9
|
+
|
10
|
+
def initialize()
|
11
|
+
@list = {}
|
12
|
+
fetch_server_status(Helper.open_server_status)
|
13
|
+
end
|
14
|
+
# Generates methods from @server hash keys
|
15
|
+
def method_missing(method)
|
16
|
+
return @list[method] if @list.key?(method)
|
17
|
+
super
|
18
|
+
end
|
19
|
+
# Fills the @server hash with each servers status
|
20
|
+
def fetch_server_status(page)
|
21
|
+
rego = Helper.open_registration_status
|
22
|
+
page.xpath('//td').each_slice(2) do |elem|
|
23
|
+
@list[elem[0].text.strip.downcase.to_sym] = Server.new(
|
24
|
+
elem[0].text.strip,
|
25
|
+
elem[1].text.strip,
|
26
|
+
rego.css('div.area_inner_cont').text[/○ #{elem[0].text.strip}/] ? "Open" : "Closed")
|
27
|
+
end
|
28
|
+
end
|
29
|
+
# Returns a JSON string of server list
|
30
|
+
def to_json
|
31
|
+
@list.to_json
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/xiv_lodestone.rb
CHANGED