wowr 0.2.2 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/README CHANGED
@@ -1,62 +1,29 @@
1
1
  Wowr
2
2
  ----
3
-
4
3
  Ruby Library for the World of Warcraft Armory
5
4
 
6
5
 
7
6
 
8
7
  Introduction
9
8
  ------------
10
-
11
9
  Wowr is an API for accessing data in the World of Warcraft Armory. Using the XML data provided by the armory, it allows developers to query World of Warcraft items, characters, guilds and arena teams. It is designed to support developers that wish to add WoW information to their Ruby-powered site, as well as larger guild or portal sites for many users.
12
10
 
13
11
 
14
12
 
15
13
  Usage
16
14
  -----
17
-
18
- When initialising the library, it is possible to set a number of parameters to be used as defaults in other API functions.
19
-
20
- # all parameters optional
21
- api = Wowr::API.new(:character_name => 'Foo',
22
- :guild_name => 'Bar',
23
- :realm => 'Baz',
24
- :locale => 'eu', # defaults to US www
25
- :lang => 'fr_fr', # remove for locale default language
26
- :caching => true # defaults to false)
27
-
28
- # Character requests
29
- my_char = api.get_character_sheet # gets character with API default values
30
- char_boo = api.get_character_sheet(:character_name => 'Boo')
31
- chars = api.search_characters(:search => 'Cake')
32
-
33
- # Guild requests
34
- guilds = api.search_guilds(:search => 'Cake')
35
- cake_guild = api.get_guild(:guild_name => 'Cake', :realm => 'Silver Hand')
36
-
37
- # Items
38
- items = api.search_items(:search => 'Cake')
39
- item_info = api.get_item_info(:item_id => 33924)
40
- item_tooltip = api.get_item_tooltip(:item_id => 33924)
41
-
42
- # Arena Teams
43
- arena_teams = api.search_arena_teams(:search => 'Lemon')
44
- arena_team = api.get_arena_team(:team_name => 'Lemon', :realm => 'Hakkar', :team_size => 5)
45
-
46
- This API is under development, and is one of my first API projects, so I would greatly appreciate any feedback about it's usefulness or any requests for features/changes. Feel free to drop me a line at benhumphreys[at]gmail
15
+ See example.rb
47
16
 
48
17
 
49
18
 
50
19
  Documentation
51
20
  -------------
52
-
53
21
  Please view the RubyDoc for more information on usage. http://wowr.rubyforge.org/doc/
54
22
 
55
23
 
56
24
 
57
25
  Installation
58
26
  ------------
59
-
60
27
  Wowr can be installed through RubyGems using the command below:
61
28
  gem install wowr
62
29
 
@@ -64,3 +31,8 @@ Alternatively, the latest version can be downloaded from SVN with:
64
31
  svn checkout http://wowr.rubyforge.org/svn/trunk/lib/
65
32
 
66
33
 
34
+
35
+ Author
36
+ ------
37
+ Ben Humphreys
38
+ benhumphreys[at]gmail.com
@@ -0,0 +1,31 @@
1
+ 0.3.0
2
+ * It is now possible to use shorter method calls
3
+ api.get_item_tooltip(29242)
4
+ api.get_item_tooltip(29242, :caching => false, :lang => 'fr_fr')
5
+
6
+ Old method calls using hashes are still supported
7
+ api.get_item_tooltip(:item_id => 29242)
8
+
9
+ api.get_character_sheet("Smith")
10
+
11
+ The same applies for searches, instead of
12
+ api.search_characters(:search => "cake")
13
+ it is now possible to write
14
+ api.search_characters("cake")
15
+
16
+ * A new request get_character has been created which gets the full character details provided by the character_sheet.xml, character_skills.xml and character_reputation.xml. It is still possible to use get_character_sheet, but this is deprecated
17
+
18
+ * A new method Wowr::API.get_item has been created, which provides the details from get_item_info and get_item_tooltip returned in one object.
19
+
20
+ * The API is now more strict and will throw exceptions if the correct parameters are not provided.
21
+
22
+ * For consistency, the get requests now throws exceptions whenever the item or character is not found. Search requests still return empty arrays if nothing is found, but will return an exception if empty search parameters are provided.
23
+
24
+ * Skill information is now in a hash my_char.skill_categories['weaponskills'].skills['maces']
25
+
26
+ * Reputation information is accessible by hash: my_char.rep['alliance'].factions['darnassus']
27
+
28
+ * More informative exception messages.
29
+
30
+ * Caching is now on by default.
31
+
@@ -1,114 +1,67 @@
1
+ #
1
2
  # Wowr - Ruby library for the World of Warcraft Armory
2
3
  # http://wowr.rubyforge.org/
3
-
4
- # written by Ben Humphreys
4
+ # Written by Ben Humphreys
5
5
  # http://benhumphreys.co.uk/
6
+ #
7
+ # Author:: Ben Humphreys
8
+ # May not be used for commercial applications
9
+ #
6
10
 
7
11
  begin
8
12
  require 'hpricot' # version 0.6
9
13
  rescue LoadError
10
14
  require 'rubygems'
11
- require 'hpricot' # version 0.6
15
+ require 'hpricot'
12
16
  end
13
17
  require 'net/http'
14
18
  require 'cgi'
15
- require 'fileutils' # for making directories :S
19
+ require 'fileutils'
16
20
 
17
- # TODO: what does this do?
18
21
  $:.unshift(File.dirname(__FILE__)) unless $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
19
-
20
- # require 'lib/wowr/exceptions.rb'
21
- # require 'lib/wowr/extensions.rb'
22
- # require 'lib/wowr/classes.rb'
22
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
23
23
 
24
24
  require 'wowr/exceptions.rb'
25
25
  require 'wowr/extensions.rb'
26
- require 'wowr/classes.rb'
27
26
 
27
+ require 'wowr/character.rb'
28
+ require 'wowr/guild.rb'
29
+ require 'wowr/item.rb'
30
+ require 'wowr/arena_team.rb'
28
31
 
29
32
  module Wowr
30
33
  class API
31
-
34
+ VERSION = '0.3.0'
35
+
32
36
  @@armory_url_base = 'wowarmory.com/'
33
- # @@eu_armory_url = 'http://eu.wowarmory.com/'
34
37
 
35
38
  @@search_url = 'search.xml'
36
39
 
37
- @@character_sheet_url = 'character-sheet.xml'
38
- @@character_talents_url = 'character-talents.xml'
39
- @@character_skills_url = 'character-skills.xml'
40
- @@character_reputation_url = 'character-reputation.xml'
40
+ @@character_sheet_url = 'character-sheet.xml'
41
+ @@character_talents_url = 'character-talents.xml'
42
+ @@character_skills_url = 'character-skills.xml'
43
+ @@character_reputation_url = 'character-reputation.xml'
41
44
 
42
- @@guild_info_url = 'guild-info.xml'
45
+ @@guild_info_url = 'guild-info.xml'
46
+
47
+ @@item_info_url = 'item-info.xml'
48
+ @@item_tooltip_url = 'item-tooltip.xml'
43
49
 
44
- @@item_info_url = 'item-info.xml'
45
- @@item_tooltip_url = 'item-tooltip.xml'
46
-
47
50
  @@arena_team_url = 'team-info.xml'
48
51
 
49
52
  @@max_connection_tries = 10
50
53
 
51
54
  @@cache_directory_path = 'cache/'
52
-
53
- # Tiny forum-used race/class icons
54
- # @@icon_url = 'http://wowbench.com/images/icons/32x32/'
55
- # http://forums.worldofwarcraft.com/images/icon/class/4.gif
56
- # http://forums.worldofwarcraft.com/images/icon/race/3-0.gif
57
- # http://forums.worldofwarcraft.com/images/icon/pvpranks/rank_default_0.gif
58
-
59
- # Spell stuff
60
- # http://armory.worldofwarcraft.com/images/icons/21x21/spell_nature_thorns.png
61
- # http://armory.worldofwarcraft.com/images/icons/21x21/ability_mount_mountainram.png
62
-
63
- # Part of the rails plugin stuff?
64
- # @@profession_icons = {
65
- # :alchemy => "Trade_Alchemy.png",
66
- # :blacksmithing => "Trade_BlackSmithing.png",
67
- # :engineering => "Trade_Engineering.png",
68
- # :enchanting => "Trade_Engraving.png",
69
- # :jewelcrafting => "INV_Hammer_21.png",
70
- # :herbalism => "Trade_Herbalism.png",
71
- # :leatherworking => "Trade_LeatherWorking.png",
72
- # :mining => "Trade_Mining.png",
73
- # :tailoring => "Trade_Tailoring.png",
74
- # :skinning => "INV_Weapon_ShortBlade_01.png"
75
- # }
76
-
77
- @@classes = {
78
- 1 => 'Warrior',
79
- 2 => 'Paladin',
80
- 3 => 'Hunter',
81
- 4 => 'Rogue',
82
- 5 => 'Priest',
83
- #6 => 'Gold Farmer', # there is no class 6
84
- 7 => 'Shaman',
85
- 8 => 'Mage',
86
- 9 => 'Warlock',
87
- #10 => 'Purveyor of Baked Goods', # there is no class 10
88
- 11 => 'Druid'
89
- }
90
55
 
91
- @@genders = {
92
- 0 => 'Male',
93
- 1 => 'Female'
94
- }
56
+ cattr_accessor :armory_url_base, :search_url,
57
+ :character_sheet_url, :character_talents_url, :character_skills_url, :character_reputation_url,
58
+ :guild_info_url,
59
+ :item_info_url, :item_tooltip_url,
60
+ :arena_team_url,
61
+ :max_connection_tries,
62
+ :cache_directory_path
95
63
 
96
- @@races = {
97
- 1 => 'Human',
98
- 1 => 'Orc',
99
- 3 => 'Dwarf',
100
- 4 => 'Night Elf',
101
- 5 => 'Undead',
102
- 6 => 'Tauren',
103
- 7 => 'Gnome',
104
- 8 => 'Troll',
105
- #9 => 'Pandaren', # there is no race 9
106
- 10 => 'Blood Elf',
107
- 11 => 'Draenei'
108
- }
109
-
110
64
  @@search_types = {
111
- #:all => 'all', # TODO: All is too complex at the moment, API doesn't return all results in one query
112
65
  :item => 'items',
113
66
  :character => 'characters',
114
67
  :guild => 'guilds',
@@ -116,68 +69,58 @@ module Wowr
116
69
  }
117
70
 
118
71
  @@arena_team_sizes = [2, 3, 5]
119
-
72
+
120
73
  attr_accessor :character_name, :guild_name, :realm, :locale, :lang, :caching, :debug
121
74
 
122
- # You can set up the API with an optional default guild and realm
123
- # These will be used in all your API requests unless you specify otherwise
124
- # For item requests, the locale will not matter in results, but may affect the speed of replies
125
- # Caching is off by default
126
- # TODO: are these nil declarations pointless?
127
- # :character_name => nil,
128
- # :guild_name => nil,
129
- # :realm => nil,
130
- # :locale => 'us',
131
- # :caching => false,
132
- # :debug => false
75
+
76
+ # Constructor
77
+ # Accepts an optional hash of parameters to create defaults for all API requests
78
+ # * options (Hash) - Hash used to set default values for all API requests
133
79
  def initialize(options = {})
134
80
  @character_name = options[:character_name]
135
81
  @guild_name = options[:guild_name]
136
82
  @realm = options[:realm]
137
- @locale = options[:locale] || :us
138
- @caching = options[:caching]
139
-
140
- if (options[:lang].nil?)
141
- @lang = 'default'
142
- else
143
- @lang = options[:lang]
144
- end
145
-
146
- @debug = options[:debug]
83
+ @locale = options[:locale] || 'us'
84
+ @caching = options[:caching] == nil ? true : false
85
+ @lang = options[:lang].nil? ? 'default' : options[:lang]
86
+ @debug = options[:debug] || false
147
87
  end
148
88
 
149
89
 
150
- # def self.test
151
- # puts @debug
152
- # puts @caching
153
- # puts @locale
154
- # end
155
-
156
-
157
90
  # General-purpose search
158
- # All specific searches are wrappers around this method.
159
- # Caching is disabled for searching
160
- def search(options = {:search => nil, :type => nil})
91
+ # All specific searches are wrappers around this method. Best to use those instead.
92
+ # Returns an array of results of the type requested (Wowr::Classes::SearchCharacter etc.) or an empty array.
93
+ # Searches across all realms.
94
+ # Caching is disabled for searching.
95
+ # * string (String) Search string
96
+ # * options (Hash) Optional hash of arguments identical to those used in the API constructor (realm, debug, cache etc.)
97
+ def search(string, options = {})
98
+ if (string.is_a?(Hash))
99
+ options = string
100
+ else
101
+ options.merge!(:search => string)
102
+ end
103
+
161
104
  options = merge_defaults(options)
162
105
 
163
- if @@search_types.include? options[:type]
164
- raise Wowr::Exceptions::InvalidSearchType.new
106
+ if options[:search].nil? || options[:search].empty?
107
+ raise Wowr::Exceptions::NoSearchString.new
165
108
  end
166
109
 
167
- if options[:search].nil?
168
- raise Wowr::Exceptions::NoSearchString.new
110
+ if !@@search_types.has_value?(options[:type])
111
+ raise Wowr::Exceptions::InvalidSearchType.new(options[:type])
169
112
  end
170
113
 
171
114
  options.merge!(:caching => false)
172
-
115
+ options.delete(:realm) # all searches are across realms
116
+
173
117
  xml = get_xml(@@search_url, options)
174
118
 
175
119
  results = []
176
-
120
+
177
121
  if (xml) && (xml%'armorySearch') && (xml%'armorySearch'%'searchResults')
178
122
  case options[:type]
179
123
 
180
- # TODO: Filter stuff
181
124
  when @@search_types[:item]
182
125
  (xml%'armorySearch'%'searchResults'%'items'/:item).each do |item|
183
126
  results << Wowr::Classes::SearchItem.new(item)
@@ -185,17 +128,17 @@ module Wowr
185
128
 
186
129
  when @@search_types[:character]
187
130
  (xml%'armorySearch'%'searchResults'%'characters'/:character).each do |char|
188
- results << Wowr::Classes::Character.new(char)
131
+ results << Wowr::Classes::SearchCharacter.new(char, self)
189
132
  end
190
133
 
191
134
  when @@search_types[:guild]
192
135
  (xml%'armorySearch'%'searchResults'%'guilds'/:guild).each do |guild|
193
- results << Wowr::Classes::Guild.new(guild)
136
+ results << Wowr::Classes::SearchGuild.new(guild)
194
137
  end
195
138
 
196
139
  when @@search_types[:arena_team]
197
140
  (xml%'armorySearch'%'searchResults'%'arenaTeams'/:arenaTeam).each do |team|
198
- results << Wowr::Classes::ArenaTeam.new(team)
141
+ results << Wowr::Classes::SearchArenaTeam.new(team)
199
142
  end
200
143
  end
201
144
  end
@@ -204,159 +147,322 @@ module Wowr
204
147
  end
205
148
 
206
149
 
207
-
208
150
  # Characters
209
- # Note searches go across all realms by default
210
- # Caching is disabled for searching
211
- def search_characters(options = {:name => nil})
151
+ # Returns an array of results of Wowr::Classes::SearchCharacter or an empty array.
152
+ # Searches across all realms.
153
+ # Caching is disabled for searching.
154
+ # Parameters
155
+ # * name (String) Name of the character to search for
156
+ # * options (Hash) Optional hash of arguments identical to those used in the API constructor (realm, debug, cache etc.)
157
+ def search_characters(name, options = {})
158
+ if (name.is_a?(Hash))
159
+ options = name
160
+ else
161
+ options.merge!(:search => name)
162
+ end
163
+
212
164
  options.merge!(:type => @@search_types[:character])
213
165
  return search(options)
214
166
  end
215
167
 
216
- def get_character_sheet(options = {})
217
-
218
- options = {:character_name => @character_name}.merge(options) if (!@character_name.nil?)
168
+
169
+ # Get the full details of a character.
170
+ # Requires realm.
171
+ # * name (String) Name of the character to get, defaults to that specified in constructor
172
+ # * options (Hash) Optional hash of arguments identical to those used in the API constructor (realm, debug, cache etc.)
173
+ def get_character(name = @character_name, options = {})
174
+ if (name.is_a?(Hash))
175
+ options = name
176
+ else
177
+ options.merge!(:character_name => name)
178
+
179
+ # TODO check
180
+ options = {:character_name => @character_name}.merge(options) if (!@character_name.nil?)
181
+ end
219
182
 
220
183
  options = merge_defaults(options)
221
-
222
- xml = get_xml(@@character_sheet_url, options)
223
-
224
- # resist_types = ['arcane', 'fire', 'frost', 'holy', 'nature', 'shadow']
225
- # @resistances = {}
226
- # resist_types.each do |res|
227
- # @resistances[res] = Wowr::Classes::Resistance.new(xml%'resistances'%res)
228
- # end
229
- # puts @resistances.to_yaml
230
- return Wowr::Classes::CharacterSheet.new(xml)
184
+
185
+ if options[:character_name].nil? || options[:chracter_name] == ""
186
+ raise Wowr::Exceptions::CharacterNameNotSet.new
187
+ elsif options[:realm].nil? || options[:realm] == ""
188
+ raise Wowr::Exceptions::RealmNotSet.new
189
+ end
190
+
191
+ character_sheet = get_xml(@@character_sheet_url, options)
192
+ character_skills = get_xml(@@character_skills_url, options)
193
+ character_reputation = get_xml(@@character_reputation_url, options)
194
+
195
+ if true
196
+ return Wowr::Classes::FullCharacter.new(character_sheet,
197
+ character_skills,
198
+ character_reputation,
199
+ self)
200
+ else
201
+ raise Wowr::Excceptions::CharacterNotFound.new(options[:character_name])
202
+ end
231
203
  end
232
204
 
233
205
 
206
+ # DEPRECATED
207
+ # See get_character
208
+ def get_character_sheet(name = @character_name, options = {})
209
+ return get_character(name, options)
210
+ end
211
+
212
+ # TODO
213
+ # def get_character_skills
214
+ #
215
+ # end
216
+ #
217
+ # def get_character_reputation
218
+ #
219
+ # end
220
+
234
221
 
235
- # Guilds
236
- # Note searches go across all realms by default
237
- # Caching is disabled for searching
238
- def search_guilds(options = {:search => nil})
239
- options.merge!(:type => @@search_types[:guild],
240
- :caching => false)
222
+ # Find all guilds with the given string, return array of Wowr::Classes::SearchGuild.
223
+ # Searches across all realms.
224
+ # Caching is disabled for searching.
225
+ # * name (String) Name of the guild to search for
226
+ # * options (Hash) Optional hash of arguments identical to those used in the API constructor (realm, debug, cache etc.)
227
+ def search_guilds(name, options = {})
228
+ if (name.is_a?(Hash))
229
+ options = name
230
+ else
231
+ options.merge!(:search => name)
232
+ end
233
+ options.delete(:realm)
241
234
 
235
+ options.merge!(:type => @@search_types[:guild])
242
236
  return search(options)
243
237
  end
244
238
 
245
- def get_guild(options = {})
246
- # overwrite default with parameters, but only if the defaults aren't blank
247
- options = {:guild_name => @guild_name}.merge(options) if (!@guild_name.nil?)
239
+
240
+ # Get the guild details.
241
+ # Guild name is optional, assuming it's set in the api constructor.
242
+ # Requires realm.
243
+ # * name (String) Name of the guild to retrieve, defaults to that specified in constructor
244
+ # * options (Hash) Optional hash of arguments identical to those used in the API constructor (realm, debug, cache etc.)
245
+ def get_guild(name = @guild_name, options = {})
246
+ if (name.is_a?(Hash))
247
+ options = name
248
+ else
249
+ options.merge!(:guild_name => name)
250
+ end
248
251
 
249
252
  options = merge_defaults(options)
250
253
 
254
+ if options[:guild_name].nil? || options[:guild_name] == ""
255
+ raise Wowr::Exceptions::GuildNameNotSet.new
256
+ elsif options[:realm].nil? || options[:realm].empty?
257
+ raise Wowr::Exceptions::RealmNotSet.new
258
+ end
259
+
251
260
  xml = get_xml(@@guild_info_url, options)
252
- return Wowr::Classes::Guild.new(xml)
261
+
262
+ if (xml%'guildKey') && !(xml%'guildInfo').children.empty?
263
+ return Wowr::Classes::FullGuild.new(xml)
264
+ else
265
+ raise Wowr::Exceptions::GuildNotFound.new(options[:guild_name])
266
+ end
253
267
  end
254
268
 
255
269
 
256
- # Items
257
- # Items are not realm-specific
258
- # Caching is disabled for searching
259
- def search_items(options = {:search => nil})
270
+ # Search for items with the specified name.
271
+ # Returns an array of Wowr::Classes::SearchItem.
272
+ # Searches across all realms.
273
+ # Caching is disabled for searching.
274
+ # * name (String) Name of the item
275
+ # * options (Hash) Optional hash of arguments identical to those used in the API constructor (realm, debug, cache etc.)
276
+ def search_items(name, options = {})
277
+ if (name.is_a?(Hash))
278
+ options = name
279
+ else
280
+ options.merge!(:search => name)
281
+ end
282
+
260
283
  options.merge!(:type => @@search_types[:item])
261
284
  return search(options)
262
285
  end
263
286
 
264
- # TODO: Is not finding the item an exception or just return nil?
265
- #def get_item(options = {:item_id => nil, :locale => @locale})
287
+
288
+ # Get the full item details (Wowr::Classes::FullItem) with the given id.
289
+ # Composite of Wowr::Classes::ItemInfo and Wowr::Classes::ItemTooltip data.
290
+ # Item requests are identical across realms.
291
+ # * id (Fixnum) ID of the item
292
+ # * options (Hash) Optional hash of arguments identical to those used in the API constructor (realm, debug, cache etc.)
293
+ def get_item(id, options = {})
294
+ if (id.is_a?(Hash))
295
+ options = id
296
+ else
297
+ options.merge!(:item_id => id)
298
+ end
299
+
300
+ options = merge_defaults(options)
301
+ options.delete(:realm)
266
302
 
267
- #return Wowr::Classes::ItemTooltip.new(xml%'itemTooltip')
268
- #end
303
+ info = get_xml(@@item_info_url, options)
304
+ tooltip = get_xml(@@item_tooltip_url, options)
305
+
306
+ if (info%'itemInfo'%'item') && !tooltip.nil?
307
+ return Wowr::Classes::FullItem.new(info%'itemInfo'%'item', tooltip%'itemTooltip', self)
308
+ else
309
+ raise Wowr::Exceptions::ItemNotFound.new(options[:item_id])
310
+ end
311
+ end
269
312
 
270
- def get_item_info(options = {:item_id => nil})
313
+
314
+ # Get the basic item information Wowr::Classes::ItemInfo.
315
+ # Item requests are identical across realms.
316
+ # * id (Fixnum) ID of the item
317
+ # * options (Hash) Optional hash of arguments identical to those used in the API constructor (realm, debug, cache etc.)
318
+ def get_item_info(id, options = {})
319
+ if (id.is_a?(Hash))
320
+ options = id
321
+ else
322
+ options.merge!(:item_id => id)
323
+ end
324
+
271
325
  options = merge_defaults(options)
326
+ options.delete(:realm)
272
327
 
273
328
  xml = get_xml(@@item_info_url, options)
329
+
274
330
  if (xml%'itemInfo'%'item')
275
- return Wowr::Classes::ItemInfo.new(xml%'itemInfo'%'item')
331
+ return Wowr::Classes::ItemInfo.new(xml%'itemInfo'%'item', self)
276
332
  else
277
- return nil
333
+ raise Wowr::Exceptions::ItemNotFound.new(options[:item_id])
278
334
  end
279
335
  end
280
336
 
281
- def get_item_tooltip(options = {:item_id => nil})
337
+
338
+ # Get full item details including stats Wowr::Classes::ItemTooltip.
339
+ # Item requests are identical across realms.
340
+ # * id (Fixnum) ID of the item
341
+ # * options (Hash) Optional hash of arguments identical to those used in the API constructor (realm, debug, cache etc.)
342
+ def get_item_tooltip(id, options = {})
343
+ if (id.is_a?(Hash))
344
+ options = id
345
+ else
346
+ options.merge!(:item_id => id)
347
+ end
348
+
282
349
  options = merge_defaults(options)
350
+ options.delete(:realm)
283
351
 
284
352
  xml = get_xml(@@item_tooltip_url, options)
285
353
 
286
- # tooltip returns empty document when not found
287
- if xml.nil?
288
- return nil
289
- #raise Wowr::Exceptions::ItemNotFound.new("Item not found with id: #{options[:item_id]}")
354
+ if !xml.nil?
355
+ return Wowr::Classes::ItemTooltip.new(xml%'itemTooltip')
356
+ else
357
+ raise Wowr::Exceptions::ItemNotFound.new(options[:item_id])
290
358
  end
291
- return Wowr::Classes::ItemTooltip.new(xml%'itemTooltip')
292
359
  end
293
360
 
294
361
 
295
-
296
- # Arena Teams
297
- # Caching is disabled for searching
298
- def search_arena_teams(options = {})
362
+ # Search for arena teams with the given name of any size.
363
+ # Returns an array of Wowr::Classes::SearchArenaTeam
364
+ # Searches across all realms.
365
+ # Caching is disabled for searching.
366
+ # * name (String) Name of the arena team to seach for
367
+ # * options (Hash) Optional hash of arguments identical to those used in the API constructor (realm, debug, cache etc.)
368
+ def search_arena_teams(name, options = {})
369
+ if (name.is_a?(Hash))
370
+ options = name
371
+ else
372
+ options.merge!(:search => name)
373
+ end
374
+
299
375
  options.merge!(:type => @@search_types[:arena_team])
300
376
  return search(options)
301
377
  end
302
378
 
303
- def get_arena_team(options = {})
379
+
380
+ # Get the arena team of the given name and size, on the specified realm.
381
+ # Returns Wowr::Classes::FullArenaTeam
382
+ # Requires realm.
383
+ # * name (String) Team arena name
384
+ # * size (Fixnum) Must be 2, 3 or 5
385
+ # * options (Hash) Optional hash of arguments identical to those used in the API constructor (realm, debug, cache etc.)
386
+ def get_arena_team(name, size = nil, options = {})
387
+ if name.is_a?(Hash)
388
+ options = name
389
+ elsif size.is_a?(Hash)
390
+ options = size
391
+ options.merge!(:team_name => name)
392
+ else
393
+ options.merge!(:team_name => name, :team_size => size)
394
+ end
395
+
304
396
  options = merge_defaults(options)
397
+
398
+ if options[:team_name].nil? || options[:team_name].empty?
399
+ raise Wowr::Exceptions::ArenaTeamNameNotSet.new
400
+ end
401
+
402
+ if options[:realm].nil? || options[:realm].empty?
403
+ raise Wowr::Exceptions::RealmNotSet.new
404
+ end
305
405
 
306
406
  if !@@arena_team_sizes.include?(options[:team_size])
307
407
  raise Wowr::Exceptions::InvalidArenaTeamSize.new("Arena teams size must be: #{@@arena_team_sizes.inspect}")
308
408
  end
309
409
 
310
410
  xml = get_xml(@@arena_team_url, options)
311
- return Wowr::Classes::ArenaTeam.new(xml%'arenaTeam')
411
+
412
+ if !(xml%'arenaTeam').children.empty?
413
+ return Wowr::Classes::ArenaTeam.new(xml%'arenaTeam')
414
+ else
415
+ raise Wowr::Exceptions::ArenaTeamNotFound.new(options[:team_name])
416
+ end
312
417
  end
313
418
 
314
- # this is more of a rails-plugin thing
315
- # def icon(icon_url)
316
- # @@icon_url + icon_url
317
- # end
318
-
319
419
 
320
- # Clear the cache, optional filename
420
+ # Clear the cache, optional directory name.
421
+ # * cache_path (String) Relative path of the cache directory to be deleted
321
422
  def clear_cache(cache_path = @@cache_directory_path)
322
423
  begin
323
424
  FileUtils.remove_dir(cache_path)
324
425
  rescue Exception => e
325
-
426
+
326
427
  end
327
428
  end
328
429
 
329
430
 
431
+ # Return the base url for the armory, e.g. http://eu.wowarmory.com/
432
+ # * locale (String) The locale, defaults to that specified in the API constructor
433
+ def base_url(locale = @locale)
434
+ if locale == 'us'
435
+ 'http://www.' + @@armory_url_base
436
+ else
437
+ 'http://' + locale + '.' + @@armory_url_base
438
+ end
439
+ end
330
440
 
441
+
442
+ protected
443
+
444
+ # Merge the defaults specified in the constructor with those supplied,
445
+ # overriding any defaults with those supplied
331
446
  def merge_defaults(options = {})
332
- # defaults[:name] = @charater_name if @charater_name
333
- # defaults[:name] = @charater_name if @charater_name
334
447
  defaults = {}
448
+ # defaults[:character_name] = @charater_name if @charater_name
449
+ # defaults[:guild_name] = @guild_name if @guild_name
335
450
  defaults[:realm] = @realm if @realm
336
451
  defaults[:locale] = @locale if @locale
337
452
  defaults[:lang] = @lang if @lang
338
453
  defaults[:caching] = @caching if @caching
339
454
  defaults[:debug] = @debug if @debug
340
-
341
- # defaults = {:realm => @realm,
342
- # :locale => @locale,
343
- # :lang => @lang,
344
- # :caching => @caching,
345
- # :debug => @debug}
346
455
 
347
456
  # overwrite defaults with any given options
348
457
  defaults.merge!(options)
349
458
  end
350
459
 
351
-
352
- protected
353
-
354
- # TODO: pretty damn hacky
460
+ # Return an Hpricot document for the given URL
461
+ # TODO: Tidy up?
355
462
  def get_xml(url, options = {})
356
- # puts options.to_yaml
357
463
 
358
464
  # better way of doing this?
359
- # Map custom keys to the HTTP request values
465
+ # Map custom keys to the HTTP request values
360
466
  reqs = {
361
467
  :character_name => 'n',
362
468
  :realm => 'r',
@@ -370,122 +476,72 @@ module Wowr
370
476
 
371
477
  params = []
372
478
  options.each do |key, value|
373
- if reqs[key]
374
- params << "#{reqs[key]}=#{u(value)}"
375
- end
376
- end
377
-
378
- if params.size > 0
379
- query = '?' + params.join('&')
479
+ params << "#{reqs[key]}=#{u(value)}" if reqs[key]
380
480
  end
381
481
 
382
- # locale = options[:locale] || @locale
482
+ query = '?' + params.join('&') if params.size > 0
383
483
 
384
484
  base = self.base_url(options[:locale])
385
485
  full_query = base + url + query
386
486
 
387
- if options[:debug]
388
- puts full_query
389
- end
487
+ puts full_query if options[:debug]
390
488
 
391
489
  if options[:caching]
392
490
  response = get_cache(full_query, options)
393
491
  else
394
- response = http_request(full_query)
492
+ response = http_request(full_query, options)
395
493
  end
396
-
397
- if options[:debug]
398
- # puts response
399
- end
400
-
494
+
401
495
  doc = Hpricot.XML(response)
402
- begin
403
- errors = doc.search("*[@errCode]")
404
- #errors.to_yaml
405
- if errors.size > 0
406
- errors.each do |error|
407
- raise Wowr::Exceptions::raise_me(error[:errCode])
408
- end
409
- # elsif (doc%'page').nil?
410
- # puts full_query
411
- # puts response
412
- # raise Wowr::Exceptions::EmptyPage
413
- else
414
- return (doc%'page')
496
+ errors = doc.search("*[@errCode]")
497
+ if errors.size > 0
498
+ errors.each do |error|
499
+ raise Wowr::Exceptions::raise_me(error[:errCode], options)
415
500
  end
416
- rescue Exception => e
417
- $stderr.puts "Fatal error ((#{e.to_s})): Couldn't search the XML document."
418
- $stderr.puts doc
419
- exit 1
501
+ elsif (doc%'page').nil?
502
+ raise Wowr::Exceptions::EmptyPage
503
+ else
504
+ return (doc%'page')
420
505
  end
421
-
422
506
  end
423
507
 
424
- # TODO Rename
508
+ # Perform an HTTP request and return the contents of the document
425
509
  def http_request(url, options = {})
426
-
427
- req = Net::HTTP::Get.new(url)#, headers)
428
- req["user-agent"] = "Mozilla/5.0 Gecko/20070219 Firefox/2.0.0.2"
510
+ req = Net::HTTP::Get.new(url)
511
+ req["user-agent"] = "Mozilla/5.0 Gecko/20070219 Firefox/2.0.0.2" # ensure returns XML
429
512
  req["cookie"] = "cookieMenu=all; cookieLangId=" + options[:lang] + "; cookies=true;"
430
513
 
431
514
  uri = URI.parse(url)
432
515
 
433
516
  http = Net::HTTP.new(uri.host, uri.port)
434
-
517
+
435
518
  begin
436
-
437
519
  http.start do
438
520
  res = http.request req
439
- response = res.body
521
+ # response = res.body
522
+
523
+ tries = 0
524
+ response = case res
525
+ when Net::HTTPSuccess, Net::HTTPRedirection
526
+ res.body
527
+ else
528
+ tries += 1
529
+ if tries > @@max_connection_tries
530
+ raise Wowr::Exceptions::NetworkTimeout.new('Timed out')
531
+ else
532
+ retry
533
+ end
534
+ end
440
535
  end
441
536
  rescue
442
537
  raise Wowr::Exceptions::ServerDoesNotExist.new('Specified server at ' + url + ' does not exist.');
443
538
  end
444
-
445
- # tries = 0
446
- # response = case res
447
- # when Net::HTTPSuccess, Net::HTTPRedirection
448
- # res.body
449
- # else
450
- # tries += 1
451
- # if tries > @@max_connection_tries
452
- # raise Wowr::Exceptions::NetworkTimeout.new('Timed out')
453
- # else
454
- # retry
455
- # end
456
- # end
457
-
458
-
459
- #response = res.body
460
-
461
- # while
462
- # tries += 1
463
- # if tries > @@max_connection_tries
464
- # raise Wowr::Exceptions::NetworkTimeout.new('Timed out')
465
- # else
466
- # retry
467
- # end
468
- # end
469
- #
470
- # begin
471
- # res = Net::HTTP.new(uri.host, uri.port).start {|http| http.request(req) }
472
- # rescue Timeout::Error => e
473
- # retry
474
- # #raise Wowr::Exceptions::NetworkTimeout.new('Timed out')
475
- # end
476
- #
477
- # tries = 0
478
- # response = case res
479
- # when Net::HTTPSuccess, Net::HTTPRedirection
480
- # res.body
481
- # else
482
- #
483
- # end
484
539
  end
485
540
 
486
541
 
542
+ # Translate the specified URL to the cache location, and return the file
543
+ # If the cache does not exist, get the contents using http_request and create it
487
544
  def get_cache(url, options = {})
488
-
489
545
  path = @@cache_directory_path + options[:lang] + '/' + url_to_filename(url)
490
546
 
491
547
  # file doesn't exist, make it
@@ -494,25 +550,19 @@ module Wowr
494
550
  puts 'Cache doesn\'t exist, making: ' + path
495
551
  end
496
552
 
553
+ # make sure dir exists
497
554
  FileUtils.mkdir_p(localised_cache_path(options[:lang])) unless File.directory?(localised_cache_path(options[:lang]))
498
555
 
499
- # TODO: Hacky
500
- # FileUtils.mkdir_p(@@cache_directory_path + 'us/') unless File.directory?(@@cache_directory_path + 'us/')
501
- # FileUtils.mkdir_p(@@cache_directory_path + 'eu/') unless File.directory?(@@cache_directory_path + 'eu/')
502
-
503
556
  xml_content = http_request(url, options)
504
557
 
505
558
  # write the cache
506
559
  file = File.open(path, File::WRONLY|File::TRUNC|File::CREAT)
507
- #file = File.open(path, 'w')
508
560
  file.write(xml_content)
509
561
  file.close
510
562
 
511
563
  # file exists, return the contents
512
564
  else
513
- if options[:debug]
514
- puts 'Cache already exists, read: ' + path
515
- end
565
+ puts 'Cache already exists, read: ' + path if options[:debug]
516
566
 
517
567
  file = File.open(path, 'r')
518
568
  xml_content = file.read
@@ -523,41 +573,21 @@ module Wowr
523
573
 
524
574
 
525
575
 
526
- # :nodoc:
527
- # remove http://
576
+ # remove http://*.wowarmory.com/ leaving just xml file part and request parameters
528
577
  # Kind of assuming incoming URL is the same as the current locale
529
- def url_to_filename(url)
530
- path = url[7..-1]
531
-
532
-
533
- path = url.gsub(base_url, '')
534
- # if (url.include?(@@armory_url))
535
- # path = 'us/' + url.gsub(@@eu_armory_url, '')
536
- # elsif (url.include?(@@eu_armory_url))
537
- # path = 'eu/' + url.gsub(@@eu_armory_url, '')
538
- # end
539
- #
540
- return path
578
+ def url_to_filename(url) #:nodoc:
579
+ return url.gsub(base_url, '')
541
580
  end
542
581
 
543
582
 
544
- def localised_cache_path(lang = @lang)
545
- @@cache_directory_path + lang
546
- end
547
-
548
583
 
549
- # :nodoc:
550
- def base_url(locale = @locale)
551
- if locale == :us
552
- 'http://www.' + @@armory_url_base
553
- else
554
- 'http://' + locale + '.' + @@armory_url_base
555
- end
584
+ def localised_cache_path(lang = @lang) #:nodoc:
585
+ return @@cache_directory_path + lang
556
586
  end
557
587
 
558
588
 
559
- # :nodoc:
560
- def u(str)
589
+
590
+ def u(str) #:nodoc:
561
591
  if str.instance_of?(String)
562
592
  return CGI.escape(str)
563
593
  else