wowget 0.2.3 → 0.3.0
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.
- data/lib/wowget/item.rb +60 -32
- data/lib/wowget/spell.rb +68 -46
- data/lib/wowget.rb +5 -1
- data/spec/item_spec.rb +18 -10
- data/spec/spell_spec.rb +8 -0
- metadata +2 -2
data/lib/wowget/item.rb
CHANGED
@@ -187,52 +187,80 @@ module Wowget
|
|
187
187
|
28 => 'Relic'
|
188
188
|
}
|
189
189
|
|
190
|
-
def
|
190
|
+
def self.find(query)
|
191
|
+
item_ids = []
|
192
|
+
items = []
|
191
193
|
|
192
194
|
if query.class == Fixnum
|
193
195
|
# easy — e.g. 12345
|
194
|
-
|
196
|
+
item_ids << query
|
195
197
|
elsif query.class == String
|
196
198
|
# try parsing a number, e.g. "12345"
|
197
199
|
item_id = id_from_string(query)
|
198
200
|
|
199
|
-
|
200
|
-
|
201
|
+
unless item_id.nil?
|
202
|
+
item_ids << item_id
|
203
|
+
else
|
204
|
+
# try searching for this item by name
|
201
205
|
item_redirect = Net::HTTP.get_response(URI.parse("http://www.wowhead.com/search?q=#{uri_escape(query)}"))["Location"]
|
202
206
|
if item_redirect
|
203
|
-
|
207
|
+
item_ids << item_redirect.match(/^\/item=([1-9][0-9]*)$/)[1].to_i
|
208
|
+
else
|
209
|
+
# try retrieving a list of items that match the supplied query
|
210
|
+
begin
|
211
|
+
# horrendously messy. fuck you very much, wowhead.
|
212
|
+
item_json = JSON Nokogiri::XML(open("http://www.wowhead.com/search?q=#{uri_escape(query)}")).inner_text.match(/new Listview\(\{template: 'item'.*, data: (\[.*\])\}\);$/)[1]
|
213
|
+
rescue
|
214
|
+
no_results = true
|
215
|
+
end
|
216
|
+
|
217
|
+
if no_results || item_json.length == 0
|
218
|
+
self.error = {:error => "no items found"}
|
219
|
+
else
|
220
|
+
item_json.each do |item|
|
221
|
+
item_ids << item["id"].to_i
|
222
|
+
end
|
223
|
+
end
|
204
224
|
end
|
205
225
|
end
|
226
|
+
elsif query.class == NilClass
|
227
|
+
item_ids << nil
|
206
228
|
end
|
207
229
|
|
208
|
-
if
|
209
|
-
|
210
|
-
|
211
|
-
self.error = {:error => "not found"}
|
212
|
-
else
|
213
|
-
item_json = JSON "{#{item_xml.css('wowhead item json').inner_text.strip.to_s}}"
|
214
|
-
item_equip_json = JSON "{#{item_xml.css('wowhead item jsonEquip').inner_text.strip.to_s}}"
|
215
|
-
self.id = item_id.to_i
|
216
|
-
self.name = item_xml.css('wowhead item name').inner_text.strip.to_s
|
217
|
-
self.level = item_xml.css('wowhead item level').inner_text.strip.to_i
|
218
|
-
self.quality_id = item_xml.css('wowhead item quality').attribute('id').content.to_i
|
219
|
-
self.category_id = item_xml.css('wowhead item class').attribute('id').content.to_i
|
220
|
-
self.subcategory_id = item_xml.css('wowhead item subclass').attribute('id').content.to_i
|
221
|
-
self.icon_id = item_xml.css('wowhead item icon').attribute('displayId').content.to_i
|
222
|
-
self.icon_name = item_xml.css('wowhead item icon').inner_text.strip.to_s
|
223
|
-
self.required_level = item_json['reqlevel']
|
224
|
-
self.inventory_slot_id = item_xml.css('wowhead item inventorySlot').attribute('id').content.to_i
|
225
|
-
self.buy_price = item_equip_json['buyprice'].to_i
|
226
|
-
self.sell_price = item_equip_json['sellprice'].to_i
|
227
|
-
|
228
|
-
if item_xml.css('wowhead item createdBy').length == 1
|
229
|
-
self.recipe_id = item_xml.css('wowhead item createdBy spell').attribute('id').content.to_i
|
230
|
-
end
|
230
|
+
if item_ids.length > 0
|
231
|
+
item_ids.each do |item_id|
|
232
|
+
items << Wowget::Item.new(item_id)
|
231
233
|
end
|
232
|
-
|
234
|
+
end
|
235
|
+
|
236
|
+
items.length == 1 ? items[0] : items
|
237
|
+
end
|
238
|
+
|
239
|
+
def initialize(item_id)
|
240
|
+
item_xml = Nokogiri::XML(open("http://www.wowhead.com/item=#{item_id}&xml"))
|
241
|
+
if item_id.nil?
|
233
242
|
self.error = {:error => "no item ID supplied"}
|
243
|
+
elsif item_xml.css('wowhead error').length == 1
|
244
|
+
self.error = {:error => "not found"}
|
234
245
|
else
|
235
|
-
|
246
|
+
item_json = JSON "{#{item_xml.css('wowhead item json').inner_text.strip.to_s}}"
|
247
|
+
item_equip_json = JSON "{#{item_xml.css('wowhead item jsonEquip').inner_text.strip.to_s}}"
|
248
|
+
self.id = item_id.to_i
|
249
|
+
self.name = item_xml.css('wowhead item name').inner_text.strip.to_s
|
250
|
+
self.level = item_xml.css('wowhead item level').inner_text.strip.to_i
|
251
|
+
self.quality_id = item_xml.css('wowhead item quality').attribute('id').content.to_i
|
252
|
+
self.category_id = item_xml.css('wowhead item class').attribute('id').content.to_i
|
253
|
+
self.subcategory_id = item_xml.css('wowhead item subclass').attribute('id').content.to_i
|
254
|
+
self.icon_id = item_xml.css('wowhead item icon').attribute('displayId').content.to_i
|
255
|
+
self.icon_name = item_xml.css('wowhead item icon').inner_text.strip.to_s
|
256
|
+
self.required_level = item_json['reqlevel']
|
257
|
+
self.inventory_slot_id = item_xml.css('wowhead item inventorySlot').attribute('id').content.to_i
|
258
|
+
self.buy_price = item_equip_json['buyprice'].to_i
|
259
|
+
self.sell_price = item_equip_json['sellprice'].to_i
|
260
|
+
|
261
|
+
if item_xml.css('wowhead item createdBy').length == 1
|
262
|
+
self.recipe_id = item_xml.css('wowhead item createdBy spell').attribute('id').content.to_i
|
263
|
+
end
|
236
264
|
end
|
237
265
|
end
|
238
266
|
|
@@ -268,11 +296,11 @@ module Wowget
|
|
268
296
|
|
269
297
|
private
|
270
298
|
|
271
|
-
def id_from_string(string)
|
299
|
+
def self.id_from_string(string)
|
272
300
|
string.to_i if string.match /^[1-9][0-9]*$/
|
273
301
|
end
|
274
302
|
|
275
|
-
def uri_escape(string)
|
303
|
+
def self.uri_escape(string)
|
276
304
|
URI.escape(string, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
|
277
305
|
end
|
278
306
|
|
data/lib/wowget/spell.rb
CHANGED
@@ -1,15 +1,20 @@
|
|
1
1
|
require 'open-uri'
|
2
2
|
require 'nokogiri'
|
3
|
+
require 'json'
|
3
4
|
|
4
5
|
module Wowget
|
5
6
|
class Spell
|
6
7
|
attr_accessor :id
|
7
8
|
attr_accessor :name
|
8
9
|
attr_accessor :item_id
|
10
|
+
attr_accessor :item_quantity_min
|
11
|
+
attr_accessor :item_quantity_max
|
9
12
|
attr_accessor :reagents
|
10
13
|
attr_accessor :profession
|
11
14
|
attr_accessor :profession_id
|
12
15
|
attr_accessor :skill
|
16
|
+
attr_accessor :skillup
|
17
|
+
attr_accessor :source_id
|
13
18
|
attr_accessor :error
|
14
19
|
|
15
20
|
def initialize(spell_id)
|
@@ -26,59 +31,76 @@ module Wowget
|
|
26
31
|
else
|
27
32
|
self.name = spell_xml.css('div.text h1').inner_text.strip.to_s
|
28
33
|
|
29
|
-
#
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
# profession
|
35
|
-
unless self.item_id.nil?
|
36
|
-
prof_markup = spell_xml.xpath("//script[contains(., 'Markup')]")
|
34
|
+
# retrieve recipe data
|
35
|
+
recipe = spell_xml.inner_text.match(/^new Listview\(\{template: 'spell', id: 'recipes', .*, data: (\[\{.*\}\])\}\);$/)
|
36
|
+
unless recipe.nil?
|
37
|
+
recipe_json = (JSON recipe[1])[0]
|
37
38
|
|
38
|
-
unless
|
39
|
-
|
40
|
-
self.
|
41
|
-
self.
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
when "Yes" then 11
|
53
|
-
when "No" then 12
|
54
|
-
when "Fishing" then 13
|
55
|
-
when "Herbalism" then 14
|
56
|
-
when "Inscription" then 15
|
57
|
-
when "Archaeology" then 16
|
39
|
+
unless recipe_json["creates"].nil?
|
40
|
+
# item produced and quantity
|
41
|
+
self.item_id = recipe_json["creates"][0]
|
42
|
+
self.item_quantity_min = recipe_json["creates"][1]
|
43
|
+
self.item_quantity_max = recipe_json["creates"][2]
|
44
|
+
|
45
|
+
# profession
|
46
|
+
unless recipe_json["skill"].nil?
|
47
|
+
profession = wowhead_profession(recipe_json["skill"][0])
|
48
|
+
self.profession = profession[:name]
|
49
|
+
self.profession_id = profession[:id]
|
50
|
+
self.skill = recipe_json["learnedat"]
|
51
|
+
self.skillup = recipe_json["nskillup"]
|
52
|
+
self.source_id = recipe_json["source"][0]
|
58
53
|
end
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
reagents.each do |r|
|
68
|
-
item_id = r.css("span a").attribute('href').content.match(/\/item=([0-9]+)/)[1].to_i
|
69
|
-
quantity_match = r.content.match(/\(([0-9]+)\)$/)
|
70
|
-
if quantity_match.nil?
|
71
|
-
quantity = 1
|
72
|
-
else
|
73
|
-
quantity = quantity_match[1].to_i
|
74
|
-
quantity += 1 if self.profession.nil? # see http://www.wowhead.com/spell=49244#comments:id=448843
|
75
|
-
end
|
76
|
-
self.reagents.push({:item => Wowget::Item.new(item_id), :quantity => quantity})
|
54
|
+
|
55
|
+
# reagents
|
56
|
+
self.reagents = []
|
57
|
+
recipe_json["reagents"].each do |reagent|
|
58
|
+
item_id = reagent[0]
|
59
|
+
quantity = self.profession_id.nil? ? reagent[1] + 1 : reagent[1]
|
60
|
+
self.reagents.push({:item => Wowget::Item.new(item_id), :quantity => quantity})
|
61
|
+
end
|
77
62
|
end
|
78
63
|
end
|
79
64
|
|
80
65
|
end
|
81
66
|
end
|
82
67
|
|
68
|
+
def source
|
69
|
+
case self.source_id
|
70
|
+
when 1 then "Crafted"
|
71
|
+
when 2 then "Drop"
|
72
|
+
when 3 then "PvP"
|
73
|
+
when 4 then "Quest"
|
74
|
+
when 5 then "Vendor"
|
75
|
+
when 6 then "Trainer"
|
76
|
+
when 7 then "Discovery"
|
77
|
+
when 8 then "Redemption"
|
78
|
+
when 9 then "Talent"
|
79
|
+
when 10 then "Starter"
|
80
|
+
when 11 then "Event"
|
81
|
+
when 12 then "Achievement"
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
def wowhead_profession(id)
|
88
|
+
case id
|
89
|
+
when 171 then {:name => "Alchemy", :id => 1}
|
90
|
+
when 164 then {:name => "Blacksmithing", :id => 2}
|
91
|
+
when 333 then {:name => "Enchanting", :id => 4}
|
92
|
+
when 202 then {:name => "Engineering", :id => 5}
|
93
|
+
when 182 then {:name => "Herbalism", :id => 14}
|
94
|
+
when 773 then {:name => "Inscription", :id => 15}
|
95
|
+
when 755 then {:name => "Jewelcrafting", :id => 7}
|
96
|
+
when 165 then {:name => "Leatherworking", :id => 8}
|
97
|
+
when 186 then {:name => "Mining", :id => 9}
|
98
|
+
when 197 then {:name => "Tailoring", :id => 10}
|
99
|
+
when 794 then {:name => "Archaeology", :id => 16}
|
100
|
+
when 185 then {:name => "Cooking", :id => 3}
|
101
|
+
when 129 then {:name => "First Aid", :id => 6}
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
83
105
|
end
|
84
106
|
end
|
data/lib/wowget.rb
CHANGED
data/spec/item_spec.rb
CHANGED
@@ -3,7 +3,7 @@ require_relative "../lib/wowget/item.rb"
|
|
3
3
|
describe Wowget::Item do
|
4
4
|
|
5
5
|
describe "With a valid ID" do
|
6
|
-
item = Wowget::Item.
|
6
|
+
item = Wowget::Item.find(4817)
|
7
7
|
|
8
8
|
it "should have an item name" do
|
9
9
|
item.name.should == "Blessed Claymore"
|
@@ -58,11 +58,11 @@ describe Wowget::Item do
|
|
58
58
|
end
|
59
59
|
|
60
60
|
it "should have a vendor sell price" do
|
61
|
-
item.sell_price.should == 2462
|
61
|
+
item.sell_price.should == 2462 and item.sell_price.class.should == Fixnum
|
62
62
|
end
|
63
63
|
|
64
64
|
it "should have a vendor buy price" do
|
65
|
-
item.buy_price.should == 12311
|
65
|
+
item.buy_price.should == 12311 and item.sell_price.class.should == Fixnum
|
66
66
|
end
|
67
67
|
|
68
68
|
it "should produce a colorised link" do
|
@@ -72,14 +72,14 @@ describe Wowget::Item do
|
|
72
72
|
end
|
73
73
|
|
74
74
|
describe "With an ID passed as a string" do
|
75
|
-
item = Wowget::Item.
|
75
|
+
item = Wowget::Item.find("4817")
|
76
76
|
it "should have an item name" do
|
77
77
|
item.name.should == "Blessed Claymore"
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
81
81
|
describe "With a recipe" do
|
82
|
-
item = Wowget::Item.
|
82
|
+
item = Wowget::Item.find(45559)
|
83
83
|
|
84
84
|
it "should have a recipe spell to create this item" do
|
85
85
|
item.recipe_id.should == 63188
|
@@ -87,25 +87,33 @@ describe Wowget::Item do
|
|
87
87
|
end
|
88
88
|
|
89
89
|
describe "With an invalid ID" do
|
90
|
-
item = Wowget::Item.
|
91
|
-
it "should return
|
90
|
+
item = Wowget::Item.find(-1000)
|
91
|
+
it "should return the error 'not found'" do
|
92
92
|
item.error.should == {:error => "not found"}
|
93
93
|
end
|
94
94
|
end
|
95
95
|
|
96
96
|
describe "With no item ID supplied" do
|
97
|
-
item = Wowget::Item.
|
98
|
-
it "should return
|
97
|
+
item = Wowget::Item.find(nil)
|
98
|
+
it "should return the error 'no item ID supplied'" do
|
99
99
|
item.error.should == {:error => "no item ID supplied"}
|
100
100
|
end
|
101
101
|
end
|
102
102
|
|
103
103
|
describe "When the name of an item is supplied" do
|
104
|
-
item = Wowget::Item.
|
104
|
+
item = Wowget::Item.find("Blessed Claymore")
|
105
105
|
|
106
106
|
it "should find the appropriate item" do
|
107
107
|
item.id.should == 4817
|
108
108
|
end
|
109
109
|
end
|
110
110
|
|
111
|
+
describe "When an item name with multiple matches is supplied" do
|
112
|
+
it "should return an array of items" do
|
113
|
+
items = Wowget::Item.find("Titansteel")
|
114
|
+
items.class.should == ::Array
|
115
|
+
items.length.should == 15
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
111
119
|
end
|
data/spec/spell_spec.rb
CHANGED
@@ -36,6 +36,10 @@ describe Wowget::Spell do
|
|
36
36
|
spell.item_id.should == 45559
|
37
37
|
end
|
38
38
|
|
39
|
+
it "should have a minimum and maximum number of items produced" do
|
40
|
+
spell.item_quantity_min.should == 1 and spell.item_quantity_max.should == 1
|
41
|
+
end
|
42
|
+
|
39
43
|
it "should have a list of reagents" do
|
40
44
|
spell.reagents.length.should == 2 and
|
41
45
|
spell.reagents.all? {|r| r[:item].class == Wowget::Item}.should == true and
|
@@ -50,6 +54,10 @@ describe Wowget::Spell do
|
|
50
54
|
spell.profession.should == 'Blacksmithing' and
|
51
55
|
spell.skill.should == 450
|
52
56
|
end
|
57
|
+
|
58
|
+
it "should have a source" do
|
59
|
+
spell.source.should == "Drop"
|
60
|
+
end
|
53
61
|
end
|
54
62
|
|
55
63
|
describe "Without a recipe" do
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: wowget
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: 0.3.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Ben Darlow
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-07-
|
13
|
+
date: 2011-07-12 00:00:00 +01:00
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|