backpack_tf 0.8.1 → 0.8.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.
@@ -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