backpack_tf 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +10 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +41 -0
- data/TODO.md +15 -0
- data/backpack_tf.gemspec +19 -0
- data/lib/backpack_tf/client.rb +102 -0
- data/lib/backpack_tf/currencies.rb +62 -0
- data/lib/backpack_tf/item.rb +19 -0
- data/lib/backpack_tf/item_price.rb +63 -0
- data/lib/backpack_tf/prices.rb +70 -0
- data/lib/backpack_tf/response.rb +59 -0
- data/lib/backpack_tf.rb +15 -0
- data/readme.md +56 -0
- data/spec/backpack_tf/client_spec.rb +75 -0
- data/spec/backpack_tf/currencies_spec.rb +68 -0
- data/spec/backpack_tf/item_spec.rb +27 -0
- data/spec/backpack_tf/prices_spec.rb +59 -0
- data/spec/backpack_tf/response_spec.rb +36 -0
- data/spec/fixtures/currencies.json +1 -0
- data/spec/fixtures/item.json +1 -0
- data/spec/fixtures/prices.json +1 -0
- data/spec/spec_helper.rb +29 -0
- metadata +24 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5b3f89b16c6ef3907403d7a9caab7457e740bd02
|
4
|
+
data.tar.gz: e41e8dbf4ba4bc3db93a40197cac519e22d3b106
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 29b1583190c592fcba721473e9800d1b9ed2d7b80a2d841917469513ef9db6e73a66ae3ac6c1e044718024f6e04f2192b1440d6da26234075c3a4deff332566e
|
7
|
+
data.tar.gz: 83f26e2dafd51d449cf205d6244a0575afe9e882a017dec8b8e86b88fb7ab30257c2d40d2ed6d983995c00fc63683ba7409eec4b0ea20f4a10527c966822cb39
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
addressable (2.3.8)
|
5
|
+
crack (0.4.2)
|
6
|
+
safe_yaml (~> 1.0.0)
|
7
|
+
diff-lcs (1.2.5)
|
8
|
+
httparty (0.13.3)
|
9
|
+
json (~> 1.8)
|
10
|
+
multi_xml (>= 0.5.2)
|
11
|
+
json (1.8.2)
|
12
|
+
multi_xml (0.5.5)
|
13
|
+
redis (3.2.1)
|
14
|
+
rspec (3.2.0)
|
15
|
+
rspec-core (~> 3.2.0)
|
16
|
+
rspec-expectations (~> 3.2.0)
|
17
|
+
rspec-mocks (~> 3.2.0)
|
18
|
+
rspec-core (3.2.3)
|
19
|
+
rspec-support (~> 3.2.0)
|
20
|
+
rspec-expectations (3.2.1)
|
21
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
22
|
+
rspec-support (~> 3.2.0)
|
23
|
+
rspec-mocks (3.2.1)
|
24
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
25
|
+
rspec-support (~> 3.2.0)
|
26
|
+
rspec-support (3.2.2)
|
27
|
+
safe_yaml (1.0.4)
|
28
|
+
vcr (2.9.3)
|
29
|
+
webmock (1.21.0)
|
30
|
+
addressable (>= 2.3.6)
|
31
|
+
crack (>= 0.3.2)
|
32
|
+
|
33
|
+
PLATFORMS
|
34
|
+
ruby
|
35
|
+
|
36
|
+
DEPENDENCIES
|
37
|
+
httparty
|
38
|
+
redis
|
39
|
+
rspec
|
40
|
+
vcr
|
41
|
+
webmock
|
data/TODO.md
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
##TODO list
|
2
|
+
|
3
|
+
#####testing:
|
4
|
+
* a mock backpack.tf service
|
5
|
+
* stubs & archived cache data
|
6
|
+
|
7
|
+
#####documentation:
|
8
|
+
* better documentation on all classes, modules, methods, attributes, etc
|
9
|
+
* support for YARD or RDOC
|
10
|
+
|
11
|
+
#####caching:
|
12
|
+
* options to cache data and force a refresh
|
13
|
+
|
14
|
+
#####formats:
|
15
|
+
* the API outputs 3 formats: JSON (default), JSONP and VDF. Currently, the gem supports JSON input only. Support for JSONP & VDF is needed.
|
data/backpack_tf.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'backpack_tf'
|
3
|
+
s.version = '0.2.1'
|
4
|
+
s.date = '2015-05-01'
|
5
|
+
s.summary = 'a wrapper for the backpack.tf API'
|
6
|
+
s.author = 'Rafael Espinoza'
|
7
|
+
s.email = 'rafael@rafaelespinoza.com'
|
8
|
+
s.homepage = 'https://github.com/NerdDiffer/backpack_tf'
|
9
|
+
s.license = 'MIT'
|
10
|
+
s.description = s.summary
|
11
|
+
|
12
|
+
s.require_paths = ['lib']
|
13
|
+
s.files = `git ls-files`.split("\n")
|
14
|
+
|
15
|
+
s.add_runtime_dependency 'httparty', '~>0.13', '>=0.13.3'
|
16
|
+
|
17
|
+
s.add_development_dependency 'rspec', '~>3.2', '>=3.2.0'
|
18
|
+
s.add_development_dependency 'webmock', '~>1.21', '>=1.21.0'
|
19
|
+
end
|
@@ -0,0 +1,102 @@
|
|
1
|
+
module BackpackTF
|
2
|
+
|
3
|
+
class Client
|
4
|
+
|
5
|
+
include HTTParty
|
6
|
+
|
7
|
+
###########################
|
8
|
+
# Class Methods
|
9
|
+
###########################
|
10
|
+
|
11
|
+
# store your API key as an environment variable
|
12
|
+
# `export <env_var>='<your api key>'`
|
13
|
+
@@env_var = 'BPTF_API_KEY'
|
14
|
+
def self.env_var; @@env_var; end
|
15
|
+
|
16
|
+
def self.api_key key = nil
|
17
|
+
default = key || ENV[@@env_var]
|
18
|
+
|
19
|
+
if default.nil?
|
20
|
+
msg = "Assign your API key to an environment variable.\n"
|
21
|
+
msg << "ex: `export #{@@env_var}=value`"
|
22
|
+
raise KeyError, msg
|
23
|
+
elsif default.class == String && (default.length != 24 || !!default[/\H/])
|
24
|
+
msg = "The key should be a hexadecimal number, 24-digits long"
|
25
|
+
raise ArgumentError, msg
|
26
|
+
else
|
27
|
+
default
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
base_uri 'http://backpack.tf/api'
|
32
|
+
default_timeout 5
|
33
|
+
default_params(:key => api_key)
|
34
|
+
|
35
|
+
def self.build_url_via action, query_options = {}
|
36
|
+
case action
|
37
|
+
when :get_prices
|
38
|
+
version = 4
|
39
|
+
interface_url = "/#{Prices.interface}/v#{version}/?"
|
40
|
+
when :get_currencies
|
41
|
+
version = 1
|
42
|
+
interface_url = "/#{Currencies.interface}/v#{version}/?"
|
43
|
+
when :get_special_items
|
44
|
+
version = 1
|
45
|
+
interface_url = "/IGetSpecialItems/v#{version}/?"
|
46
|
+
when :get_users
|
47
|
+
version = 3
|
48
|
+
interface_url = "/IGetUsers/v#{version}/?"
|
49
|
+
when :get_user_listings
|
50
|
+
version = 1
|
51
|
+
interface_url = "/IGetUserListings/v#{version}/?"
|
52
|
+
else
|
53
|
+
raise ArgumentError, 'pass in valid action as a Symbol object'
|
54
|
+
end
|
55
|
+
|
56
|
+
base_uri + interface_url + extract_query_string(query_options)
|
57
|
+
end
|
58
|
+
|
59
|
+
def self.extract_query_string options = {}
|
60
|
+
options.each_pair.map do |key, val|
|
61
|
+
unless val.class == Array
|
62
|
+
"#{key}=#{val}"
|
63
|
+
else
|
64
|
+
"#{key}=#{val.join(',')}"
|
65
|
+
end
|
66
|
+
end.join('&')
|
67
|
+
end
|
68
|
+
|
69
|
+
###########################
|
70
|
+
# Instance Methods
|
71
|
+
###########################
|
72
|
+
attr_reader :db
|
73
|
+
|
74
|
+
def initialize
|
75
|
+
@db = nil
|
76
|
+
end
|
77
|
+
|
78
|
+
def get_data action, query_options = {}
|
79
|
+
handle_timeouts do
|
80
|
+
url = self.class.build_url_via(action, query_options)
|
81
|
+
self.class.get(url)#['response']
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
private
|
86
|
+
|
87
|
+
# HTTParty raises an errors after time limit defined by ::default_timeout
|
88
|
+
# * if it cannot connect to server, then it raises Net::OpenTimeout
|
89
|
+
# * if it cannot read response from server, then it raises Net::ReadTimeout
|
90
|
+
# if one of those happen, then an empty hash is returned
|
91
|
+
def handle_timeouts
|
92
|
+
begin
|
93
|
+
yield
|
94
|
+
rescue Net::OpenTimeout, Net::ReadTimeout
|
95
|
+
{}
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
module BackpackTF
|
2
|
+
|
3
|
+
# ruby representations of a JSON response to
|
4
|
+
# `IGetCurrencies`['response']
|
5
|
+
class Currencies
|
6
|
+
|
7
|
+
###########################
|
8
|
+
# Class Methods
|
9
|
+
###########################
|
10
|
+
|
11
|
+
include BackpackTF::Response
|
12
|
+
|
13
|
+
@interface = :IGetCurrencies
|
14
|
+
|
15
|
+
def self.currencies
|
16
|
+
@@currencies = hash_keys_to_sym(@response[:currencies])
|
17
|
+
end
|
18
|
+
|
19
|
+
###########################
|
20
|
+
# Instance Methods
|
21
|
+
###########################
|
22
|
+
|
23
|
+
# @return [Fixnum] the quality index of the currency
|
24
|
+
attr_reader :quality
|
25
|
+
# @return [Fixnum] the internal priceindex of the currency
|
26
|
+
attr_reader :priceindex
|
27
|
+
# @return [String] the single form of noun that is used in the suffix
|
28
|
+
attr_reader :single
|
29
|
+
# @return [String] the plural form of noun that is used in the suffix
|
30
|
+
attr_reader :plural
|
31
|
+
# @return [Fixnum] the number of decimal places the price should be rounded to
|
32
|
+
attr_reader :round
|
33
|
+
# @return [Symbol] either :Craftable or :Non-Craftable to signify currency's craftability
|
34
|
+
attr_reader :craftable
|
35
|
+
# @return [Symbol] either :Tradable or :Non-Tradable to signify currency's tradability
|
36
|
+
attr_reader :tradable
|
37
|
+
# @return [Fixnum] the definition index of the currency
|
38
|
+
attr_reader :defindex
|
39
|
+
# TODO: what does the :blanket attribute mean?
|
40
|
+
# it is set to 0 by default. However, it is set to 1 for :hat.
|
41
|
+
# :hat also has an extra property & value :blanket_name => 'Random Craft Hat'
|
42
|
+
# @return [Fixnum]
|
43
|
+
attr_reader :blanket
|
44
|
+
|
45
|
+
def initialize name, attr
|
46
|
+
attr = check_attr_keys(attr)
|
47
|
+
|
48
|
+
@name = name.to_s
|
49
|
+
@quality = attr[:quality]
|
50
|
+
@priceindex = attr[:priceindex]
|
51
|
+
@single = attr[:single]
|
52
|
+
@plural = attr[:plural]
|
53
|
+
@round = attr[:round]
|
54
|
+
@craftable = attr[:craftable].to_sym
|
55
|
+
@tradable = attr[:tradable].to_sym
|
56
|
+
@defindex = attr[:defindex]
|
57
|
+
@blanket = attr[:blanket]
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module BackpackTF
|
2
|
+
|
3
|
+
class Item
|
4
|
+
|
5
|
+
# @return [String] the name of item
|
6
|
+
attr_reader :item_name
|
7
|
+
# @return [Fixnum] the index on which you can link this item to Team Fortress 2's Item Schema
|
8
|
+
attr_reader :defindex
|
9
|
+
# @return [Hash<Fixnum, ItemPrice>] a hash object
|
10
|
+
attr_reader :prices
|
11
|
+
|
12
|
+
def initialize item_name, attr
|
13
|
+
@item_name = item_name
|
14
|
+
@defindex = attr['defindex'][0]
|
15
|
+
@prices = nil
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module BackpackTF
|
2
|
+
|
3
|
+
class ItemPrice
|
4
|
+
|
5
|
+
attr_reader :quality, :tradability, :craftability, :priceindex,
|
6
|
+
:currency, :value, :value_high, :value_raw, :value_high_raw,
|
7
|
+
:last_update, :difference
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
end
|
11
|
+
|
12
|
+
# mapping official API quality integers to quality names
|
13
|
+
# https://wiki.teamfortress.com/wiki/WebAPI/GetSchema#Result_Data
|
14
|
+
@@qualities = [
|
15
|
+
'Normal',
|
16
|
+
'Genuine',
|
17
|
+
nil,
|
18
|
+
'Vintage',
|
19
|
+
nil,
|
20
|
+
'Unusual',
|
21
|
+
'Unique',
|
22
|
+
'Community',
|
23
|
+
'Valve',
|
24
|
+
'Self-Made',
|
25
|
+
nil,
|
26
|
+
'Strange',
|
27
|
+
nil,
|
28
|
+
'Haunted',
|
29
|
+
"Collector's"
|
30
|
+
]
|
31
|
+
|
32
|
+
@@tradabilities = [:Tradable, :Untradable]
|
33
|
+
@@craftabilities = [:Craftable, :Uncraftable]
|
34
|
+
|
35
|
+
# returns JSON data for the item
|
36
|
+
# does not return data for items with a special particle effect
|
37
|
+
def self.get_item_price quality, item_name
|
38
|
+
item = find_item_by_name(item_name)
|
39
|
+
ind = @@qualities.find_index(quality)
|
40
|
+
|
41
|
+
prefix = item['prices'][ind.to_s]['Tradable']
|
42
|
+
if prefix.nil?
|
43
|
+
raise(ArgumentError, "The item, #{quality} #{item_name}, is not Tradable")
|
44
|
+
end
|
45
|
+
prefix = prefix['Craftable']
|
46
|
+
if prefix.nil?
|
47
|
+
raise(ArgumentError, "The item, #{quality} #{item_name}, is not Craftable")
|
48
|
+
end
|
49
|
+
|
50
|
+
# oddly, there are cases (such as the "Lugermorph"), where the
|
51
|
+
# type of the object at this point in the JSON data (saved to the `prefix` variable)
|
52
|
+
# is a Hash object rather than an Array object.
|
53
|
+
# That makes the PriceIndex key a String, "0", rather than a Fixnum, 0.
|
54
|
+
if prefix[0].nil?
|
55
|
+
prefix[0.to_s]
|
56
|
+
else
|
57
|
+
prefix[0]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
module BackpackTF
|
2
|
+
|
3
|
+
# ruby representations of a JSON response to
|
4
|
+
# `IGetPrices`['response']
|
5
|
+
class Prices
|
6
|
+
|
7
|
+
include BackpackTF::Response
|
8
|
+
|
9
|
+
@interface = :IGetPrices
|
10
|
+
|
11
|
+
def self.items
|
12
|
+
@@items = @response[:items]
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.defindex_to_item_name defindex
|
16
|
+
items = get_items_hash
|
17
|
+
keys = items.keys#.shuffle
|
18
|
+
|
19
|
+
i = 0
|
20
|
+
while i < keys.length
|
21
|
+
current_defindex = items[keys[i]]['defindex']
|
22
|
+
if(current_defindex[0] == defindex)
|
23
|
+
return keys[i]
|
24
|
+
end
|
25
|
+
i += 1
|
26
|
+
end
|
27
|
+
raise KeyError, "item with a defindex of #{defindex} was not found"
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.get_name_of_random_item
|
31
|
+
items = get_items_hash
|
32
|
+
items.keys.sample
|
33
|
+
end
|
34
|
+
|
35
|
+
# returns JSON representation of pricing for the item
|
36
|
+
def self.find_item_by_name item_name
|
37
|
+
items = get_items_hash
|
38
|
+
if items[item_name].nil?
|
39
|
+
raise KeyError, "item with the name #{item_name} was not found"
|
40
|
+
else
|
41
|
+
items[item_name]
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# @param [String] item_name, the item name (according to item_name of item's schema)
|
46
|
+
# @param [Symbol] type, checking to see if item is of this type
|
47
|
+
# @return [Boolean] `true` if the item is the type
|
48
|
+
def self.is_item_of_type? item_name, type = :weapon
|
49
|
+
item = find_item_by_name(item_name)
|
50
|
+
defindex = item['defindex'][0]
|
51
|
+
tf2_item = Trade.tf2_item_schema.items[defindex]
|
52
|
+
|
53
|
+
case type
|
54
|
+
when :cosmetic
|
55
|
+
tf2_item[:item_class] == 'tf_wearable'
|
56
|
+
else
|
57
|
+
tf2_item[:item_slot] == 'primary' ||
|
58
|
+
tf2_item[:item_slot] == 'secondary' ||
|
59
|
+
tf2_item[:item_slot] == 'melee'
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def initialize
|
64
|
+
msg = "This class is meant to receive the JSON response from the #{self.class.interface} interface. It holds a Hash array of prices of items, but not is meant to be instantiated. See the Item class if you are interested in an item. However, information on items should be stored in the @items property of #{self.class}"
|
65
|
+
raise RuntimeError, msg
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
module BackpackTF
|
2
|
+
module Response
|
3
|
+
|
4
|
+
def self.included(other)
|
5
|
+
puts "#{self} included in (#{other})"
|
6
|
+
other.extend(ClassMethods)
|
7
|
+
super
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
|
12
|
+
@response = nil
|
13
|
+
def interface; @interface; end
|
14
|
+
|
15
|
+
def response force_update = false
|
16
|
+
# if force is true, set value of @response to results of ::fetch
|
17
|
+
# otherwise, use a `nil guard` to return @response
|
18
|
+
# if the value is already set, then it returns value of @response
|
19
|
+
# if the value is not set, then it runs ::fetch
|
20
|
+
force_update ?
|
21
|
+
@response = fetch :
|
22
|
+
@response ||= fetch
|
23
|
+
end
|
24
|
+
|
25
|
+
def fetch client_stuff
|
26
|
+
@response = hash_keys_to_sym(client_stuff)
|
27
|
+
end
|
28
|
+
|
29
|
+
# checks the data type of the keys of a Hash object
|
30
|
+
# if the key is a String, then changes it to a Symbol
|
31
|
+
# otherwise, leaves it as is
|
32
|
+
def hash_keys_to_sym hash
|
33
|
+
hash.each_pair.inject({}) do |new_hash, (key, val)|
|
34
|
+
unless key.class == String
|
35
|
+
new_hash[key] = val
|
36
|
+
else
|
37
|
+
new_hash[key.to_sym] = val
|
38
|
+
end
|
39
|
+
new_hash
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
############################
|
45
|
+
# PRIVATE INSTANCE METHODS
|
46
|
+
############################
|
47
|
+
private
|
48
|
+
def check_attr_keys attr
|
49
|
+
raise TypeError, 'pass in a Hash object' unless attr.class == Hash
|
50
|
+
|
51
|
+
unless attr.keys.all? { |k| k.class == String }
|
52
|
+
raise TypeError, 'all keys must be String object'
|
53
|
+
end
|
54
|
+
|
55
|
+
self.class.hash_keys_to_sym(attr)
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
end
|
data/lib/backpack_tf.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
require 'byebug'
|
3
|
+
|
4
|
+
# namespace for classes & modules inside of the wrapper for the BackpackTF API
|
5
|
+
module BackpackTF
|
6
|
+
|
7
|
+
end
|
8
|
+
|
9
|
+
# IMPORTANT! require the Response module before any other class or module
|
10
|
+
require 'backpack_tf/response'
|
11
|
+
require 'backpack_tf/client'
|
12
|
+
require 'backpack_tf/currencies'
|
13
|
+
require 'backpack_tf/item'
|
14
|
+
require 'backpack_tf/item_price'
|
15
|
+
require 'backpack_tf/prices'
|
data/readme.md
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
#backpack_tf
|
2
|
+
Backpack.tf is a website for the in-game economies of Team Fortress 2 and Dota 2. This gem is a wrapper for the backpack.tf [API](http://backpack.tf/api). The goal is to capture the results and turn them into Ruby objects for use in your application.
|
3
|
+
|
4
|
+
It is in the very early stages of development. See the [TODO](TODO.md) list if you are interested in contributing.
|
5
|
+
|
6
|
+
###Installation
|
7
|
+
Install it as a gem:
|
8
|
+
`gem install backpack_tf`
|
9
|
+
|
10
|
+
Or add it to your project's Gemfile:
|
11
|
+
`gem 'backpack_tf'`
|
12
|
+
|
13
|
+
###Usage
|
14
|
+
* [Register an API key](http://backpack.tf/api). You'll need to log in with your Steam account if you haven't already done so.
|
15
|
+
* Assign your key to an environment variable through your terminal:
|
16
|
+
`export BPTF_API_KEY='SECRET_KEY'`
|
17
|
+
* Load the gem into your project:
|
18
|
+
`require 'backpack_tf'`
|
19
|
+
|
20
|
+
##Interfaces
|
21
|
+
|
22
|
+
####IGetPrices
|
23
|
+
* Get pricing data for all priced items
|
24
|
+
* [official doc](http://backpack.tf/api/prices)
|
25
|
+
|
26
|
+
API responses from this interfaces are captured in the `Prices` class. The `Prices` class is not meant to be instantiated. One of the class attributes is `@@items`, a Hash object. Information on any particular item, ie: 'Kritzkrieg', is captured in an instance of the `Item` class. Furthermore, there may be several prices for the same item, ie: a Kritzkrieg with the Unique quality has a different price than a Kritzkrieg with a Vintage quality. Each price is an instance of the `ItemPrice` class, and is stored in the `@prices` hash of that item.
|
27
|
+
|
28
|
+
######a visual
|
29
|
+
* `Prices` class
|
30
|
+
* `@@items` hash of `Price` class.
|
31
|
+
* `Item` object (ie: 'Beast From Below')
|
32
|
+
* `Item` object (ie: 'Taunt: Rock, Paper Scissors')
|
33
|
+
* `Item` object (ie: 'Kritzkrieg')
|
34
|
+
* `@prices` hash of an `Item` object
|
35
|
+
* `ItemPrices` object (ie: price for Unique Kritzkrieg)
|
36
|
+
* `ItemPrices` object (ie: price for Collector's Kritzkrieg)
|
37
|
+
* `ItemPrices` object (ie: price for Vintage Kritzkrieg)
|
38
|
+
|
39
|
+
####IGetCurrencies
|
40
|
+
* Get internal currency data for a given game
|
41
|
+
* [official doc](http://backpack.tf/api/currencies)
|
42
|
+
|
43
|
+
API responses from this interface are captured in the `Currencies` class. Similar the `Prices` class, it has a set of class methods, and attributes to describe the API response. Unlike, the `Prices` class, this one can be instantiated. There are currently 4 currencies available through the API. Each one is an instance of `Currencies` and is held in the `@@currencies` hash of the `Currencies` class.
|
44
|
+
|
45
|
+
####IGetSpecialItems *(not yet implemented)*
|
46
|
+
* Get internal backpack.tf item placeholders for a given game.
|
47
|
+
* [official doc](http://backpack.tf/api/special)
|
48
|
+
|
49
|
+
####IGetUsers *(not yet implemented)*
|
50
|
+
* Get profile info for a list of 64-bit Steam IDs.
|
51
|
+
* Does not require an API key
|
52
|
+
* [official doc](http://backpack.tf/api/users)
|
53
|
+
|
54
|
+
####IGetUserListings *(not yet implemented)*
|
55
|
+
* Get classified listings for a given user
|
56
|
+
* [official doc](http://backpack.tf/api/classifieds)
|
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module BackpackTF
|
4
|
+
describe 'Client' do
|
5
|
+
context 'The Client class' do
|
6
|
+
|
7
|
+
it 'has these default options' do
|
8
|
+
ans = { base_uri: 'http://backpack.tf/api', timeout: 5 }
|
9
|
+
ans[:default_params] = { key: ENV[Client.env_var] }
|
10
|
+
expect(Client.default_options).to eq ans
|
11
|
+
end
|
12
|
+
|
13
|
+
describe '::api_key' do
|
14
|
+
it 'Raises ArgumentError, if key is not a hexadecimal string' do
|
15
|
+
fake_key = 'abcdefghijklmnopqrstuvwx'
|
16
|
+
expect{Client.api_key(fake_key)}.to raise_error ArgumentError
|
17
|
+
end
|
18
|
+
it 'Raises ArgumentError, if key is not 24 digits long' do
|
19
|
+
fake_key = 'abcdef0987654321'
|
20
|
+
expect{Client.api_key(fake_key)}.to raise_error ArgumentError
|
21
|
+
end
|
22
|
+
it 'lets an otherwise theoretically-valid key, pass through' do
|
23
|
+
key = generate_fake_api_key
|
24
|
+
expect(Client.api_key(key)).to eq key
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe '::extract_query_string' do
|
29
|
+
it 'produces a query parameter string' do
|
30
|
+
opts = {:key => Client.api_key, :appid => 440, :format => 'json', :compress => 1, :raw => 2}
|
31
|
+
ans = "key=#{Client.api_key}&appid=440&format=json&compress=1&raw=2"
|
32
|
+
expect(Client.extract_query_string(opts)).to eq ans
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe '::build_url_via' do
|
37
|
+
it 'returns correct destination url when asking for pricing data' do
|
38
|
+
opts = {:key => Client.api_key, :compress => 1}
|
39
|
+
expect(Client.build_url_via(:get_prices, opts)).to eq "http://backpack.tf/api/IGetPrices/v4/?key=#{Client.api_key}&compress=1"
|
40
|
+
end
|
41
|
+
it 'raises an error when asking for any unexpected interface' do
|
42
|
+
expect{Client.build_url_via(:foo)}.to raise_error ArgumentError
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
context 'Instances of Client' do
|
48
|
+
let(:bp) { Client.new }
|
49
|
+
|
50
|
+
describe '#get_data' do
|
51
|
+
|
52
|
+
it 'returns results from archived json file' do
|
53
|
+
stub_http_response_with('currencies.json')
|
54
|
+
opts = { :key => Client.api_key, :compress => 1, :appid => 440 }
|
55
|
+
currencies = bp.get_data(:get_currencies, opts)
|
56
|
+
|
57
|
+
expect(currencies['response']).to have_key('success')
|
58
|
+
expect(currencies['response']).to have_key('currencies')
|
59
|
+
expect(currencies['response']).to have_key('name')
|
60
|
+
expect(currencies['response']).to have_key('url')
|
61
|
+
expect(currencies['response']).to have_key('current_time')
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'client requests are returned as ruby Hash objects' do
|
65
|
+
stub_http_response_with('prices.json')
|
66
|
+
opts = {:app_id => 440, :compress => 1}
|
67
|
+
expect(bp.get_data(:get_prices, opts)).to be_instance_of Hash
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|