backpack_tf 0.8.1 → 0.8.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -34,19 +34,19 @@ module BackpackTF
34
34
 
35
35
  def self.build_url_via action, query_options = {}
36
36
  case action
37
- when :get_prices, :prices
37
+ when :get_prices, :prices, :price
38
38
  version = 4
39
39
  interface_url = "/#{Price.interface}/v#{version}/?"
40
- when :get_currencies, :currencies
40
+ when :get_currencies, :currencies, :currency
41
41
  version = 1
42
42
  interface_url = "/#{Currency.interface}/v#{version}/?"
43
- when :get_special_items, :special_items
43
+ when :get_special_items, :special_items, :special_item, :specialitem
44
44
  version = 1
45
45
  interface_url = "/#{SpecialItem.interface}/v#{version}/?"
46
- when :get_users, :users
46
+ when :get_users, :users, :user
47
47
  version = 3
48
48
  interface_url = "/#{User.interface}/v#{version}/?"
49
- when :get_user_listings, :user_listing, :user_listings
49
+ when :get_user_listings, :user_listings, :user_listing, :userlisting
50
50
  version = 1
51
51
  interface_url = "/#{UserListing.interface}/v#{version}/?"
52
52
  else
@@ -19,11 +19,17 @@ module BackpackTF
19
19
  attr = JSON.parse(attr)
20
20
  end
21
21
 
22
- @defindex = attr['defindex'][0]
23
- @prices = gen_prices_hash(attr)
22
+ @defindex = process_defindex(attr['defindex'])
23
+ @prices = generate_prices_hash(attr)
24
24
  end
25
25
 
26
- def gen_prices_hash input_hash
26
+ def process_defindex arr
27
+ return nil if arr.length == 0
28
+ return arr[0] if arr.length == 1
29
+ arr
30
+ end
31
+
32
+ def generate_prices_hash input_hash
27
33
 
28
34
  raise TypeError, 'expecting a Hash object' unless input_hash.class == Hash
29
35
  unless input_hash.has_key? 'prices'
@@ -34,6 +40,7 @@ module BackpackTF
34
40
  prices = input_hash['prices']
35
41
 
36
42
  prices.inject({}) do |hash, (key, val)|
43
+
37
44
  quality = BackpackTF::ItemPrice.qualities[key.to_i]
38
45
  new_key = [quality.to_s]
39
46
 
@@ -43,31 +50,34 @@ module BackpackTF
43
50
  craftability = prices[key][tradability].keys.first
44
51
  new_key << craftability
45
52
 
46
- new_key = new_key.join('_')
53
+ new_key = new_key.join(ItemPrice::KEYNAME_DELIMITER)
47
54
 
48
55
  prefix = prices[key][tradability][craftability]
49
56
 
50
- if prefix.class == Array
51
- item_prices = prefix.first
57
+ if (prefix.length <= 1)
58
+ item_prices = prefix[0]
59
+ # patch for oddly-structured items, ie: Aqua Summer 2013 Cooler
60
+ item_prices = prefix.values.first if item_prices.nil?
61
+
52
62
  item_price_obj = ItemPrice.new(new_key, item_prices)
53
63
  hash[new_key] = item_price_obj
54
- elsif prefix.class == Hash
55
- if prefix.keys.length <= 1
56
- item_prices = prefix.values[0]
57
- item_price_obj = ItemPrice.new(new_key, item_prices)
58
- hash[new_key] = item_price_obj
59
- else
60
- prefix.keys.each do |prefix_key|
61
- temp_key = "#{new_key}_Effect ##{prefix_key.to_i}"
62
- item_prices = prefix[prefix_key]
63
- item_price_obj = ItemPrice.new(temp_key, item_prices, prefix_key)
64
- hash[new_key] = item_price_obj
65
- end
64
+ elsif key == '5' # item with 'Unusual' quality
65
+ prefix.keys.each do |prefix_key|
66
+ item_prices = prefix[prefix_key]
67
+ item_price_obj = ItemPrice.new(new_key, item_prices, prefix_key)
68
+ hash[item_price_obj.effect] = item_price_obj
69
+ end
70
+ else # a Crate
71
+ prefix.keys.each do |prefix_key|
72
+ temp_key = "#{new_key}_##{prefix_key.to_i}"
73
+ item_prices = prefix[prefix_key]
74
+ item_price_obj = ItemPrice.new(temp_key, item_prices, prefix_key)
75
+ hash[temp_key] = item_price_obj
66
76
  end
67
77
  end
68
-
69
78
  hash
70
79
  end
80
+
71
81
  end
72
82
 
73
83
  end
@@ -2,13 +2,14 @@ module BackpackTF
2
2
 
3
3
  class ItemPrice
4
4
 
5
+ KEYNAME_DELIMITER = '_'
6
+ PARTICLE_EFFECTS_KEY = 'attribute_controlled_attached_particles'
7
+ PARTICLE_EFFECTS_FILE = "./lib/backpack_tf/assets/#{PARTICLE_EFFECTS_KEY}.json"
8
+
5
9
  ###########################
6
10
  # Class Methods
7
11
  ###########################
8
12
 
9
- @@required_keys = ['currency', 'value', 'last_update', 'difference']
10
- def self.required_keys; @@required_keys; end
11
-
12
13
  # mapping official API quality integers to quality names
13
14
  # https://wiki.teamfortress.com/wiki/WebAPI/GetSchema#Result_Data
14
15
  @@qualities = [
@@ -29,11 +30,51 @@ module BackpackTF
29
30
  :"Collector's"
30
31
  ]
31
32
 
32
- def self.qualities; @@qualities; end
33
-
34
33
  @@tradabilities = [:Tradable, :'Non-Tradable']
35
34
  @@craftabilities = [:Craftable, :'Non-Craftable']
36
-
35
+ @@required_keys = ['currency', 'value', 'last_update', 'difference']
36
+
37
+ def self.qualities; @@qualities; end
38
+ def self.required_keys; @@required_keys; end
39
+
40
+ def self.quality_name_to_index q
41
+ @@qualities.index(q.to_sym) unless q.nil?
42
+ end
43
+
44
+ def self.hash_particle_effects
45
+
46
+ file = File.open(PARTICLE_EFFECTS_FILE).read
47
+ effects_arr = JSON.parse(file)[PARTICLE_EFFECTS_KEY]
48
+
49
+ effects_arr.inject({}) do |hash, pe|
50
+ id = pe['id']
51
+ name = pe['name']
52
+ hash[id] = name
53
+ hash
54
+ end
55
+
56
+ end
57
+
58
+ @@particle_effects = self.hash_particle_effects
59
+ def self.particle_effects; @@particle_effects; end
60
+
61
+ def self.ins_sp str
62
+ str = str.split('')
63
+ new_str = ''
64
+ str.each_with_index do |c, i|
65
+ if i == 0
66
+ new_str += c
67
+ else
68
+ unless c == c.upcase && str[i-1] == str[i-1].upcase
69
+ new_str += c
70
+ else
71
+ new_str += (' ' + c)
72
+ end
73
+ end
74
+ end
75
+ new_str
76
+ end
77
+
37
78
  ###########################
38
79
  # Instance Methods
39
80
  ###########################
@@ -56,24 +97,24 @@ module BackpackTF
56
97
  attr_reader :value_raw
57
98
  # @return [Float] The item's value in the lowest currency without rounding. Reques raw to be enabled and set to 2
58
99
  attr_reader :value_high_raw
59
- # @return [Fixnum] A timestamp of when the price was last updated
100
+ # @return [Fixnum] A timestamp of when the price was last updated
60
101
  attr_reader :last_update
61
- # @return [Fixnum] A relative difference between the former price and the current price. If 0, assume new price.
102
+ # @return [Fixnum] A relative difference between the former price and the current price. If 0, assume new price.
62
103
  attr_reader :difference
104
+ # @return [String] Result of @@particle_effects[@priceindex]
105
+ attr_reader :effect
63
106
 
64
107
  def initialize key, attr, priceindex = nil
65
108
  attr = JSON.parse(attr) unless attr.class == Hash
66
- unless self.class.required_keys.all? {|k| attr.keys.member? k }
67
- raise KeyError, "The passed-in hash is required to have at least these 4 keys: #{self.class.required_keys.join(', ')}"
68
- end
69
109
 
70
- key_split = key.split('_')
110
+ key = key.split(KEYNAME_DELIMITER)
111
+ key = process_key(key)
71
112
 
72
- @priceindex = priceindex
113
+ validate_attributes(attr)
73
114
 
74
- @quality = key_split[0].to_sym
75
- @tradability = key_split[1].to_sym
76
- @craftability = key_split[2].to_sym
115
+ @quality = key[0]
116
+ @tradability = key[1]
117
+ @craftability = key[2]
77
118
  @currency = attr['currency'].to_sym
78
119
  @value = attr['value']
79
120
  @value_high = attr['value_high']
@@ -81,6 +122,49 @@ module BackpackTF
81
122
  @value_high_raw = attr['value_high_raw']
82
123
  @last_update = attr['last_update']
83
124
  @difference = attr['difference']
125
+ @priceindex = priceindex
126
+ @effect = self.class.particle_effects[priceindex.to_i]
127
+ end
128
+
129
+ private
130
+ # requires the key to an Array with length of 3 or more
131
+ # converts each element to a Symbol object
132
+ # The 3 bits of info are subject to a NameError if any one of them is invalid
133
+ # @return [Array] an Array of Symbol objects
134
+ # @raises NameError, ArgumentError
135
+ def process_key key
136
+
137
+ unless key.length >= 3
138
+ raise ArgumentError, "This key must have a length of 3 or greater"
139
+ end
140
+
141
+ key.map! { |bit| bit.to_sym }
142
+
143
+ unless @@qualities.include? key[0]
144
+ raise NameError, 'Must include a valid Quality'
145
+ end
146
+ unless @@tradabilities.include? key[1]
147
+ raise NameError, 'Must include a valid Tradability'
148
+ end
149
+ unless @@craftabilities.include? key[2]
150
+ raise NameError, 'Must include a valid Craftability'
151
+ end
152
+
153
+ key
154
+ end
155
+
156
+ def validate_attributes attributes
157
+
158
+ raise TypeError unless attributes.class == Hash
159
+
160
+ unless @@required_keys.all? { |k| attributes.keys.member? k }
161
+ msg = "The passed-in hash is required to have at least these 4 keys: "
162
+ msg += "#{self.class.required_keys.join(', ')}"
163
+ raise KeyError, msg
164
+ end
165
+
166
+ attributes
167
+
84
168
  end
85
169
 
86
170
  end
@@ -32,6 +32,9 @@ module BackpackTF
32
32
  @responses
33
33
  end
34
34
 
35
+ def self.response
36
+ end
37
+
35
38
  # checks the data type of the keys of a Hash object
36
39
  # if the key is a String, then changes it to a Symbol
37
40
  # otherwise, leaves it as is
@@ -1,3 +1,3 @@
1
1
  module BackpackTF
2
- VERSION = "0.8.1"
2
+ VERSION = "0.8.4"
3
3
  end
@@ -100,6 +100,13 @@ module BackpackTF
100
100
  expect(Currency.currencies).to be_nil
101
101
  end
102
102
 
103
+ after :each do
104
+ Response.responses(:reset => :confirm)
105
+ expect(Response.responses).to be_empty
106
+ expect(Currency.response).to be_nil
107
+ expect(Currency.currencies).to be_nil
108
+ end
109
+
103
110
  let(:fetched_currencies) {
104
111
  bp.fetch(:currencies, {:compress => 1, :appid => 440})
105
112
  }
@@ -16,70 +16,57 @@ module BackpackTF
16
16
  Response.hash_keys_to_sym(fixture)
17
17
  }
18
18
 
19
- it 'responds to these methods' do
20
- expect(described_class).to respond_to :responses, :response, :currencies, :interface, :hash_keys_to_sym
21
- end
22
-
23
- it 'has these default attributes' do
19
+ it 'class has these default attributes' do
24
20
  expect(described_class.interface).to eq :IGetCurrencies
25
21
  end
26
22
 
27
- describe '::responses' do
28
-
29
- before :each do
30
- stub_http_response_with('currencies.json')
31
- opts = { :app_id => 440, :compress => 1 }
32
- fetched_currencies = bp.fetch(:currencies, opts)
33
- Response.responses(described_class.to_sym => fetched_currencies)
34
- end
35
-
36
- context 'access from Response class' do
37
- it 'Currency can be accessed by calling the key, Currency' do
38
- expect(Response.responses[:'BackpackTF::Currency']).to eq json_obj
39
- end
40
- end
41
-
42
- context 'access from Currency class' do
43
- it 'can access response information via the class method, ::response' do
44
- expect(described_class.response).to eq json_obj
45
- end
46
- end
47
-
48
- it 'is the same as calling Currency.response' do
49
- expect(Response.responses[:'BackpackTF::Currency']).to eq Currency.response
23
+ describe '::response' do
24
+ before :all do
25
+ expect(described_class.response).to be_nil
50
26
  end
51
- end
52
27
 
53
- describe '::response' do
54
28
  before :each do
55
29
  stub_http_response_with('currencies.json')
56
- opts = { :app_id => 440, :compress => 1 }
57
- fetched_currencies = bp.fetch(:currencies, opts)
58
- Response.responses(':BackpackTF::Currency' => fetched_currencies)
30
+ fetched_currencies = bp.fetch(:currencies)
31
+ bp.update(described_class, fetched_currencies)
59
32
  end
60
- it 'the response attribute should have these keys' do
61
- expect(described_class.response.keys).to match_array [:success, :current_time, :currencies, :name, :url]
33
+
34
+ after :all do
35
+ Response.responses(:reset => :confirm)
36
+ expect(Response.responses).to be_empty
37
+ expect(described_class.response).to be_nil
38
+ expect(described_class.currencies).to be_nil
62
39
  end
63
40
 
64
41
  it 'the keys of the response attribute should have these values' do
65
- expect(described_class.response[:success]).to eq 1
66
- expect(described_class.response[:message]).to eq nil
67
- expect(described_class.response[:current_time]).to eq 1430784460
68
- expect(described_class.response[:name]).to eq 'Team Fortress 2'
69
- expect(described_class.response[:url]).to eq 'http://backpack.tf'
42
+ response = described_class.response
43
+ expect(response[:success]).to eq 1
44
+ expect(response[:message]).to eq nil
45
+ expect(response[:current_time]).to eq 1430784460
46
+ expect(response[:name]).to eq 'Team Fortress 2'
47
+ expect(response[:url]).to eq 'http://backpack.tf'
70
48
  end
71
-
72
49
  end
73
50
 
74
51
  describe '::currencies' do
52
+ before :all do
53
+ expect(described_class.response).to be_nil
54
+ expect(described_class.currencies).to be_nil
55
+ end
56
+
75
57
  before :each do
76
58
  Response.responses(:reset => :confirm)
77
59
  expect(Response.responses).to be_empty
78
60
 
79
61
  stub_http_response_with('currencies.json')
80
- opts = { :app_id => 440, :compress => 1 }
81
- fetched_currencies = bp.fetch(:currencies, opts)
82
- Response.responses(:'BackpackTF::Currency' => fetched_currencies)
62
+ fetched_currencies = bp.fetch(:currencies)
63
+ bp.update(described_class, fetched_currencies)
64
+ end
65
+
66
+ after :all do
67
+ Response.responses(:reset => :confirm)
68
+ expect(Response.responses).to be_empty
69
+ described_class.class_eval { @currencies = nil }
83
70
  end
84
71
 
85
72
  it 'returns the fixture and sets to @@currencies variable' do
@@ -96,26 +83,43 @@ module BackpackTF
96
83
  end
97
84
  end
98
85
 
99
- describe 'instance of Currency' do
86
+ describe '#initialize' do
87
+
88
+ before :all do
89
+ expect(described_class.response).to be_nil
90
+ expect(described_class.currencies).to be_nil
91
+ end
100
92
 
101
- let (:metal) { described_class.new(:metal, Currency.currencies[:metal]) }
93
+ before :each do
94
+ bp.update(described_class, json_obj)
95
+ expect(described_class.currencies).not_to be_nil
96
+ end
102
97
 
103
- it 'should respond to these methods' do
104
- expect(metal).to respond_to(:quality, :priceindex, :single, :plural, :round, :craftable, :tradable, :defindex, :blanket)
98
+ after :all do
99
+ Response.responses(:reset => :confirm)
100
+ expect(Response.responses).to be_empty
101
+ described_class.class_eval { @currencies = nil }
105
102
  end
106
103
 
107
- it 'should have these values' do
108
- expect(metal.quality).to eq 6
109
- expect(metal.priceindex).to eq 0
110
- expect(metal.single).to eq 'ref'
111
- expect(metal.plural).to eq 'ref'
112
- expect(metal.round).to eq 2
113
- expect(metal.craftable).to eq :Craftable
114
- expect(metal.tradable).to eq :Tradable
115
- expect(metal.defindex).to eq 5002
116
- expect(metal.blanket).to eq 0
104
+ subject {
105
+ described_class.new(:metal, described_class.currencies[:metal])
106
+ }
107
+
108
+ it 'instance should respond to these methods' do
109
+ expect(subject).to respond_to(:quality, :priceindex, :single, :plural, :round, :craftable, :tradable, :defindex, :blanket)
117
110
  end
118
111
 
112
+ it 'instance should have these values' do
113
+ expect(subject.quality).to eq 6
114
+ expect(subject.priceindex).to eq 0
115
+ expect(subject.single).to eq 'ref'
116
+ expect(subject.plural).to eq 'ref'
117
+ expect(subject.round).to eq 2
118
+ expect(subject.craftable).to eq :Craftable
119
+ expect(subject.tradable).to eq :Tradable
120
+ expect(subject.defindex).to eq 5002
121
+ expect(subject.blanket).to eq 0
122
+ end
119
123
  end
120
124
 
121
125
  end