stew 0.5.1 → 0.5.2

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/README.md CHANGED
@@ -56,17 +56,17 @@ steam_id.friends.each {|friend| puts friend.profile.nickname}
56
56
 
57
57
  ##### From an App id
58
58
  ```ruby
59
- app = Stew::StoreClient.new.create_app(220240)
59
+ app = Stew::Store::StoreClient.new.create_app(220240)
60
60
  ```
61
61
 
62
62
  ##### From a URL
63
63
  ```ruby
64
- app = Stew::StoreClient.new.create_app("http://store.steampowered.com/app/220240/")
64
+ app = Stew::Store::StoreClient.new.create_app("http://store.steampowered.com/app/220240/")
65
65
  ```
66
66
 
67
67
  ##### From a URL with a region
68
68
  ```ruby
69
- app = Stew::StoreClient.new.create_app("http://store.steampowered.com/app/220240/?cc=uk")
69
+ app = Stew::Store::StoreClient.new.create_app("http://store.steampowered.com/app/220240/?cc=uk")
70
70
  ```
71
71
 
72
72
  All the examples above will create a Stew::Store::App instance for the game Far Cry 3. You can then access data like so:
@@ -8,17 +8,20 @@ require 'money'
8
8
 
9
9
  require "stew/version"
10
10
 
11
- require 'stew/web_client'
12
- require 'stew/xml_client'
13
- require 'stew/community_client'
14
- require 'stew/store_client'
11
+ require 'stew/community/xml_client/xml_client'
12
+ require 'stew/community/xml_client/xml_client_response_profile'
13
+ require 'stew/community/xml_client/xml_client_response_games'
14
+ require 'stew/community/xml_client/xml_client_response_friends'
15
15
 
16
+ require 'stew/community/community_client'
16
17
  require 'stew/community/steam_id'
17
18
  require 'stew/community/profile'
18
19
  require 'stew/community/profile_friends'
19
20
  require 'stew/community/profile_game'
20
21
  require 'stew/community/profile_games'
21
22
 
23
+ require 'stew/store/web_client'
24
+ require 'stew/store/store_client'
22
25
  require 'stew/store/app'
23
26
  require 'stew/store/app_offers'
24
27
  require 'stew/store/app_offer'
@@ -28,10 +31,10 @@ module Stew
28
31
  Money.assume_from_symbol = true
29
32
 
30
33
  @config = {
31
- :default_community_client => CommunityClient,
32
- :default_store_client => StoreClient,
33
- :default_xml_client => XmlClient,
34
- :default_web_client => WebClient,
34
+ :default_community_client => Community::CommunityClient,
35
+ :default_store_client => Store::StoreClient,
36
+ :default_xml_client => Community::XmlClient,
37
+ :default_web_client => Store::WebClient,
35
38
  :default_region => :us
36
39
  }
37
40
 
@@ -0,0 +1,53 @@
1
+ module Stew
2
+ module Community
3
+ # Creation of all profile* objects.
4
+ # Uses a given or default XmlClient instance to communicate with the Steam API
5
+ # The main identifier for most methods is the 64-bit steam id
6
+ # @example Create a Profile
7
+ # Stew::CommunityClient.new.profile(76561197992917668) #=> Stew::Community::Profile
8
+ #
9
+ # @example Resolve a Steam Vanity name
10
+ # Stew::CommunityClient.steam_id_from_vanity_name('eekon20') #=> 76561197986383225
11
+ #
12
+ class CommunityClient
13
+ COMMUNITY_URL = 'http://steamcommunity.com'
14
+ DEFAULT_BASE_PATH = 'profiles'
15
+
16
+ # @deprecated Use CommunityClient.new.steam_id_from_vanity_name instead
17
+ def self.steam_id_from_vanity_name(vanity_name)
18
+ self.new.steam_id_from_vanity_name(vanity_name)
19
+ end
20
+
21
+ def initialize(opts = {})
22
+ @xml_client = opts[:client] || Stew.config[:default_xml_client].new(COMMUNITY_URL)
23
+ @base_path = opts[:base_path] || DEFAULT_BASE_PATH
24
+ end
25
+
26
+ def steam_id_from_vanity_name(vanity_name)
27
+ response = XmlClientResponseProfile.new(@xml_client.get("/id/#{vanity_name}"))
28
+ response.profile['steamID64'].to_i
29
+ end
30
+
31
+ def profile(steam_id)
32
+ response = XmlClientResponseProfile.new(@xml_client.get(path(steam_id)))
33
+ Community::Profile.new(response.profile)
34
+ end
35
+
36
+ def profile_games(steam_id)
37
+ response = XmlClientResponseGames.new(@xml_client.get(path(steam_id,'games')))
38
+ Community::ProfileGames.new(response.games)
39
+ end
40
+
41
+ def profile_friends(steam_id)
42
+ response = XmlClientResponseFriends.new(@xml_client.get(path(steam_id,'friends')))
43
+ Community::ProfileFriends.new(response.friends)
44
+ end
45
+
46
+ private
47
+
48
+ def path(steam_id,command=nil)
49
+ "/#{@base_path}/#{steam_id}/#{command}"
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,50 @@
1
+ module Stew
2
+ module Community
3
+ # Client for accessing the steam community XML api
4
+ class XmlClient
5
+ def initialize(uri)
6
+ @connection = XmlClient.connection(uri)
7
+ end
8
+
9
+ # The Steam community is notorious for responding with error 503
10
+ # Retries up to 10 times for the same request to compensate for this
11
+ def get(path)
12
+ 10.times do
13
+ response = request(path)
14
+ return XmlClient.parse_response(response.body) unless response.status == 503
15
+ sleep 0.5
16
+ end
17
+ raise ServiceUnavailableError
18
+ end
19
+
20
+ private
21
+
22
+ def request(path)
23
+ @connection.get path do |req|
24
+ req.params['xml'] = 1
25
+ end
26
+ end
27
+
28
+ def self.connection(uri)
29
+ Faraday.new uri do |conn|
30
+ conn.response :xml, :content_type => /\bxml$/
31
+ conn.request :retry
32
+ conn.use FaradayMiddleware::FollowRedirects
33
+ conn.adapter Faraday.default_adapter
34
+ end
35
+ end
36
+
37
+ def self.parse_response(response)
38
+ raise(ObjectNotFoundError) if response.is_a?(String)
39
+ raise(ObjectNotFoundError, response['response']['error']) if response.has_key?('response')
40
+ response
41
+ end
42
+
43
+ # Raised when the Steam community API fails to respond after 10 tries
44
+ class ServiceUnavailableError < StandardError; end
45
+
46
+ # Raised when the reply is malformatted or if nothing is found
47
+ class ObjectNotFoundError < StandardError; end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,20 @@
1
+ module Stew
2
+ module Community
3
+ # A friends response from the Xml Client
4
+ class XmlClientResponseFriends
5
+ def initialize(response)
6
+ @response = response
7
+ end
8
+
9
+ def friends
10
+ has_friends? ? @response['friendsList']['friends']['friend'] : []
11
+ end
12
+
13
+ private
14
+
15
+ def has_friends?
16
+ !@response['friendsList']['friends'].nil?
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,20 @@
1
+ module Stew
2
+ module Community
3
+ # A games response from the Xml Client
4
+ class XmlClientResponseGames
5
+ def initialize(response)
6
+ @response = response
7
+ end
8
+
9
+ def games
10
+ has_games? ? @response['gamesList']['games']['game'] : []
11
+ end
12
+
13
+ private
14
+
15
+ def has_games?
16
+ !@response['gamesList']['games'].nil?
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,14 @@
1
+ module Stew
2
+ module Community
3
+ # A profile response from the Xml Client
4
+ class XmlClientResponseProfile
5
+ def initialize(response)
6
+ @response = response
7
+ end
8
+
9
+ def profile
10
+ @response['profile']
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,41 @@
1
+ module Stew
2
+ module Store
3
+ # Creation of app objects from URLs or app_ids
4
+ #
5
+ # Can create apps for any steam region. When no region is given, it defaults to the default region in the configuration
6
+ #
7
+ # @example Creation of a Stew::Store::App from a URL
8
+ # Stew::StoreClient.new.create_app('http://store.steampowered.com/app/211420') #=> Stew::StoreClient::App
9
+ #
10
+ # @example Creation of a Stew::Store::App from an id
11
+ # Stew::StoreClient.new.create_app(211420) #=> Stew::StoreClient::App
12
+ #
13
+ # @example Creation of a Stew::Store::App from a URL with a different region
14
+ # Stew::StoreClient.new.create_app('http://store.steampowered.com/app/211420?cc=uk') #=> Stew::StoreClient::App
15
+ #
16
+ # @example Creation of a Stew::Store::App from an id and a region
17
+ # Stew::StoreClient.new.app(211420, :uk) #=> Stew::StoreClient::App
18
+ #
19
+ class StoreClient
20
+ STORE_URL = 'http://store.steampowered.com'
21
+
22
+ def initialize(opts = {})
23
+ @client = opts[:client] || Stew.config[:default_web_client].new(STORE_URL)
24
+ end
25
+
26
+ def create_app(data)
27
+ return app(data) if data.class == Fixnum
28
+ return app($1,$2) if data =~ /store.steampowered.com\/app\/([0-9]+)\/?\?cc=([a-zA-Z]{2})/
29
+ return app($1) if data =~ /store.steampowered.com\/app\/([0-9]+)/
30
+ raise AppIdNotFoundError
31
+ end
32
+
33
+ def app(app_id,region = Stew.config[:default_region])
34
+ Store::App.new(@client.get("/app/#{app_id}",:cc => region.to_sym))
35
+ end
36
+ end
37
+
38
+ # Error used when an app cannot be found
39
+ class AppIdNotFoundError < StandardError; end
40
+ end
41
+ end
@@ -0,0 +1,31 @@
1
+ module Stew
2
+ module Store
3
+ # Client wrapper for performing requests to the Steam Store
4
+ class WebClient
5
+ def initialize(uri)
6
+ @connection = WebClient.connection(uri)
7
+ end
8
+
9
+ def get(path, options={})
10
+ request(path, options).body
11
+ end
12
+
13
+ private
14
+
15
+ def request(path,options={})
16
+ @connection.get(path) do |request|
17
+ request.params = options
18
+ end
19
+ end
20
+
21
+ def self.connection(uri)
22
+ Faraday.new uri do |conn|
23
+ conn.headers[:cookie] = "birthtime=365842801"
24
+ conn.request :retry
25
+ conn.use FaradayMiddleware::FollowRedirects
26
+ conn.adapter Faraday.default_adapter
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -1,3 +1,3 @@
1
1
  module Stew
2
- VERSION = "0.5.1"
2
+ VERSION = "0.5.2"
3
3
  end
@@ -0,0 +1,5 @@
1
+ ---
2
+ friendsList:
3
+ steamID64: '76561197994486912'
4
+ steamID: dkmez
5
+ friends:
@@ -0,0 +1,5 @@
1
+ ---
2
+ gamesList:
3
+ steamID64: '76561197994486912'
4
+ steamID: dkmez
5
+ games:
@@ -4,7 +4,7 @@ require 'spec_helper'
4
4
 
5
5
  describe "Store", :vcr do
6
6
 
7
- let(:store_client){Stew::StoreClient.new}
7
+ let(:store_client){Stew::Store::StoreClient.new}
8
8
  subject{store_client.app(id)}
9
9
 
10
10
  describe "Creation of a store app with data" do
@@ -15,7 +15,7 @@ describe "Store", :vcr do
15
15
  end
16
16
 
17
17
  it "sets the score" do
18
- subject.score.should eq 85
18
+ subject.score.should be_a(Integer)
19
19
  end
20
20
 
21
21
  it "sets the release date" do
@@ -62,7 +62,7 @@ describe "Store", :vcr do
62
62
  end
63
63
 
64
64
  it "has a base price" do
65
- subject.price.should eq Money.parse("$59.99")
65
+ subject.price.currency.should eq Money.parse("$59.99").currency
66
66
  end
67
67
 
68
68
  describe "the basic offer" do
@@ -76,24 +76,8 @@ describe "Store", :vcr do
76
76
  offer.description.should be_nil
77
77
  end
78
78
 
79
- it "has the correct price" do
80
- offer.price.should eq Money.parse("$59.99")
81
- end
82
- end
83
-
84
- describe "the 4 pack" do
85
- let(:offer){subject.offers.entries[1]}
86
-
87
- it "has the correct name" do
88
- offer.name.should eq 'Borderlands 2 - 4-Pack'
89
- end
90
-
91
- it "has the correct description" do
92
- offer.description.should eq "Includes four copies of Borderlands 2 - Send the extra copies to your friends"
93
- end
94
-
95
- it "has the correct price" do
96
- offer.price.should eq Money.parse("$179.99")
79
+ it "has the correct currency" do
80
+ offer.price.currency.should eq Money.parse("$59.99").currency
97
81
  end
98
82
  end
99
83
  end
@@ -0,0 +1,118 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Stew::CommunityClient" do
4
+ let(:client){double('xml_client')}
5
+ subject{Stew::Community::CommunityClient.new({:client => client})}
6
+ let(:id){76561197992917668}
7
+
8
+ describe "#steam_id_from_vanity_name" do
9
+ let(:vanity_name){"foobar"}
10
+
11
+ it "calls steam_id_from_vanity_name on a new instance" do
12
+ Stew::Community::CommunityClient.any_instance.should_receive(:steam_id_from_vanity_name).with(vanity_name)
13
+ Stew::Community::CommunityClient.steam_id_from_vanity_name(vanity_name)
14
+ end
15
+ end
16
+
17
+
18
+ describe ".steam_id_from_vanity_name" do
19
+ let(:response){YAML.load_file("spec/fixtures/profiles/#{id}.yml")}
20
+ let(:name){"Somename"}
21
+
22
+ before :each do
23
+ client.should_receive(:get).with("/id/#{name}").and_return(response)
24
+ end
25
+
26
+ context "when the vanity name exists" do
27
+ it "returns the 64-bit id" do
28
+ subject.steam_id_from_vanity_name(name).should eq id
29
+ end
30
+ end
31
+ end
32
+
33
+ describe "setting the base path" do
34
+ context "when the base path is not set" do
35
+ let(:results){YAML.load_file("spec/fixtures/profiles/#{id}.yml")}
36
+
37
+ it "should perform requests to the 'profile'" do
38
+ client.should_receive(:get).with("/profiles/#{id}/").and_return(results)
39
+ subject.profile(id)
40
+ end
41
+ end
42
+
43
+ context "when the base path is set to 'id'" do
44
+ let(:results){YAML.load_file("spec/fixtures/profiles/#{id}.yml")}
45
+ subject{Stew::Community::CommunityClient.new({:client => client, :base_path => 'id'})}
46
+
47
+ it "should perform profile-requests to the 'id'" do
48
+ client.should_receive(:get).with("/id/#{id}/").and_return(results)
49
+ subject.profile(id)
50
+ end
51
+ end
52
+ end
53
+
54
+ describe ".profile" do
55
+ let(:results){YAML.load_file("spec/fixtures/profiles/#{id}.yml")}
56
+
57
+ it "sends the correct message to its client" do
58
+ client.should_receive(:get).with("/profiles/#{id}/").and_return(results)
59
+ subject.profile(id)
60
+ end
61
+
62
+ it "creates a profile object" do
63
+ client.stub(:get).with("/profiles/#{id}/").and_return(results)
64
+ Stew::Community::Profile.should_receive(:new).with(results['profile'])
65
+ subject.profile(id)
66
+ end
67
+ end
68
+
69
+ describe ".profile_games" do
70
+ let(:results){YAML.load_file("spec/fixtures/profiles/games/#{id}.yml")}
71
+
72
+ it "sends the correct message to its client" do
73
+ client.should_receive(:get).with("/profiles/#{id}/games").and_return(results)
74
+ subject.profile_games(id)
75
+ end
76
+
77
+ it "creates a ProfileGames object" do
78
+ client.stub(:get).with("/profiles/#{id}/games").and_return(results)
79
+ Stew::Community::ProfileGames.should_receive(:new).with(results['gamesList']['games']['game'])
80
+ subject.profile_games(id)
81
+ end
82
+
83
+ context "when the profile has no games" do
84
+ let(:id){76561197994486912}
85
+
86
+ it "creates an empty ProfileGames instance if the profile has no games" do
87
+ client.stub(:get).with("/profiles/#{id}/games").and_return(results)
88
+ profile_games = subject.profile_games(id)
89
+ profile_games.entries.count.should eq 0
90
+ end
91
+ end
92
+ end
93
+
94
+ describe ".profile_friends" do
95
+ let(:results){YAML.load_file("spec/fixtures/profiles/friends/#{id}.yml")}
96
+
97
+ it "sends the correct message to its client" do
98
+ client.should_receive(:get).with("/profiles/#{id}/friends").and_return(results)
99
+ subject.profile_friends(id)
100
+ end
101
+
102
+ it "creates a ProfileFriends object" do
103
+ client.stub(:get).with("/profiles/#{id}/friends").and_return(results)
104
+ Stew::Community::ProfileFriends.should_receive(:new).with(results['friendsList']['friends']['friend'])
105
+ subject.profile_friends(id)
106
+ end
107
+
108
+ context "when the profile has no friends" do
109
+ let(:id){76561197994486912}
110
+
111
+ it "creates an empty ProfileFriends instance if the profile has no friends" do
112
+ client.stub(:get).with("/profiles/#{id}/friends").and_return(results)
113
+ profile_friends = subject.profile_friends(id)
114
+ profile_friends.entries.count.should eq 0
115
+ end
116
+ end
117
+ end
118
+ end
@@ -56,7 +56,7 @@ describe "Stew::Community::SteamId" do
56
56
  end
57
57
 
58
58
  it "should create a community client with no options" do
59
- Stew::CommunityClient.should_receive(:new).with()
59
+ Stew::Community::CommunityClient.should_receive(:new).with()
60
60
  Stew::Community::SteamId.new(id)
61
61
  end
62
62
  end
@@ -69,7 +69,7 @@ describe "Stew::Community::SteamId" do
69
69
  end
70
70
 
71
71
  it "should create a community client with the base_path option set to 'id'" do
72
- Stew::CommunityClient.should_receive(:new).with({:base_path => 'id'})
72
+ Stew::Community::CommunityClient.should_receive(:new).with({:base_path => 'id'})
73
73
  Stew::Community::SteamId.new(id)
74
74
  end
75
75
  end
@@ -1,11 +1,11 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "Stew::XmlClient" do
3
+ describe "Stew::Community::XmlClient" do
4
4
  let(:uri){'http://steamcommunity.com'}
5
5
  let(:results){YAML.load_file("spec/fixtures/profiles/#{id}.yml")}
6
6
  let(:id){76561197992917668}
7
7
 
8
- subject{Stew::XmlClient.new(uri)}
8
+ subject{Stew::Community::XmlClient.new(uri)}
9
9
 
10
10
  describe "#get" do
11
11
  context "when no error is found in the reply" do
@@ -15,7 +15,7 @@ describe "Stew::XmlClient" do
15
15
  stub_request(:get, "http://steamcommunity.com/profiles/#{id}?xml=1").to_return(File.new("spec/fixtures/profiles/#{id}.txt"))
16
16
  end
17
17
 
18
- it "returns a hash containing the parsed data from the steam community servers" do
18
+ it "returns the response" do
19
19
  subject.get(path).should eq results
20
20
  end
21
21
  end
@@ -29,7 +29,7 @@ describe "Stew::XmlClient" do
29
29
  end
30
30
 
31
31
  it "throws an ObjectNotFound error" do
32
- expect{subject.get(path).should}.to raise_error(Stew::XmlClient::ObjectNotFoundError)
32
+ expect{subject.get(path).should}.to raise_error(Stew::Community::XmlClient::ObjectNotFoundError)
33
33
  end
34
34
  end
35
35
  end
@@ -1,10 +1,10 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "Stew::StoreClient" do
3
+ describe "Stew::Store::StoreClient" do
4
4
  let(:client){double('web_client')}
5
5
  let(:response){open("spec/fixtures/store/apps/#{id}.txt")}
6
6
  let(:region){:us}
7
- subject{Stew::StoreClient.new({:client => client})}
7
+ subject{Stew::Store::StoreClient.new({:client => client})}
8
8
 
9
9
  describe ".app" do
10
10
  let(:id) {211420}
@@ -51,7 +51,7 @@ describe "Stew::StoreClient" do
51
51
  let(:url){"sodijfsdf"}
52
52
 
53
53
  it "raises a Stew::Store::AppIdNotFoundError" do
54
- expect{subject.create_app(url)}.to raise_error(Stew::AppIdNotFoundError)
54
+ expect{subject.create_app(url)}.to raise_error(Stew::Store::AppIdNotFoundError)
55
55
  end
56
56
  end
57
57
  end
@@ -1,9 +1,9 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe "Stew::WebClient", :vcr do
3
+ describe "Stew::Store::WebClient", :vcr do
4
4
  let(:uri){'http://store.steampowered.com/'}
5
5
 
6
- subject{Stew::WebClient.new(uri)}
6
+ subject{Stew::Store::WebClient.new(uri)}
7
7
 
8
8
  describe ".get" do
9
9
  let(:id){216390}
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: stew
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.5.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-02-07 00:00:00.000000000 Z
12
+ date: 2013-02-11 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
@@ -299,25 +299,30 @@ files:
299
299
  - README.md
300
300
  - Rakefile
301
301
  - lib/stew.rb
302
+ - lib/stew/community/community_client.rb
302
303
  - lib/stew/community/profile.rb
303
304
  - lib/stew/community/profile_friends.rb
304
305
  - lib/stew/community/profile_game.rb
305
306
  - lib/stew/community/profile_games.rb
306
307
  - lib/stew/community/steam_id.rb
307
- - lib/stew/community_client.rb
308
+ - lib/stew/community/xml_client/xml_client.rb
309
+ - lib/stew/community/xml_client/xml_client_response_friends.rb
310
+ - lib/stew/community/xml_client/xml_client_response_games.rb
311
+ - lib/stew/community/xml_client/xml_client_response_profile.rb
308
312
  - lib/stew/store/app.rb
309
313
  - lib/stew/store/app_offer.rb
310
314
  - lib/stew/store/app_offer_sale.rb
311
315
  - lib/stew/store/app_offers.rb
312
- - lib/stew/store_client.rb
316
+ - lib/stew/store/store_client.rb
317
+ - lib/stew/store/web_client.rb
313
318
  - lib/stew/version.rb
314
- - lib/stew/web_client.rb
315
- - lib/stew/xml_client.rb
316
319
  - spec/fixtures/profiles/4d.txt
317
320
  - spec/fixtures/profiles/76561197992917668.txt
318
321
  - spec/fixtures/profiles/76561197992917668.yml
319
322
  - spec/fixtures/profiles/friends/76561197992917668.yml
323
+ - spec/fixtures/profiles/friends/76561197994486912.yml
320
324
  - spec/fixtures/profiles/games/76561197992917668.yml
325
+ - spec/fixtures/profiles/games/76561197994486912.yml
321
326
  - spec/fixtures/store/apps/16870.txt
322
327
  - spec/fixtures/store/apps/211400_offers_sale.txt
323
328
  - spec/fixtures/store/apps/211400_sale.txt
@@ -330,19 +335,19 @@ files:
330
335
  - spec/fixtures/store/apps/no_app.txt
331
336
  - spec/integration/community_integration_spec.rb
332
337
  - spec/integration/store_integration_spec.rb
338
+ - spec/lib/stew/community/community_client_spec.rb
333
339
  - spec/lib/stew/community/profile_friends_spec.rb
334
340
  - spec/lib/stew/community/profile_game_spec.rb
335
341
  - spec/lib/stew/community/profile_games_spec.rb
336
342
  - spec/lib/stew/community/profile_spec.rb
337
343
  - spec/lib/stew/community/steam_id_spec.rb
338
- - spec/lib/stew/community_client_spec.rb
344
+ - spec/lib/stew/community/xml_client/xml_client_spec.rb
339
345
  - spec/lib/stew/store/app_offer_sale_spec.rb
340
346
  - spec/lib/stew/store/app_offer_spec.rb
341
347
  - spec/lib/stew/store/app_offers_spec.rb
342
348
  - spec/lib/stew/store/app_spec.rb
343
- - spec/lib/stew/store_client_spec.rb
344
- - spec/lib/stew/web_client_spec.rb
345
- - spec/lib/stew/xml_client_spec.rb
349
+ - spec/lib/stew/store/store_client_spec.rb
350
+ - spec/lib/stew/store/web_client_spec.rb
346
351
  - spec/lib/stew_spec.rb
347
352
  - spec/spec_helper.rb
348
353
  - stew.gemspec
@@ -360,7 +365,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
360
365
  version: '0'
361
366
  segments:
362
367
  - 0
363
- hash: -4370496576353841969
368
+ hash: -5319004060931315
364
369
  required_rubygems_version: !ruby/object:Gem::Requirement
365
370
  none: false
366
371
  requirements:
@@ -369,7 +374,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
369
374
  version: '0'
370
375
  segments:
371
376
  - 0
372
- hash: -4370496576353841969
377
+ hash: -5319004060931315
373
378
  requirements: []
374
379
  rubyforge_project:
375
380
  rubygems_version: 1.8.24
@@ -381,7 +386,9 @@ test_files:
381
386
  - spec/fixtures/profiles/76561197992917668.txt
382
387
  - spec/fixtures/profiles/76561197992917668.yml
383
388
  - spec/fixtures/profiles/friends/76561197992917668.yml
389
+ - spec/fixtures/profiles/friends/76561197994486912.yml
384
390
  - spec/fixtures/profiles/games/76561197992917668.yml
391
+ - spec/fixtures/profiles/games/76561197994486912.yml
385
392
  - spec/fixtures/store/apps/16870.txt
386
393
  - spec/fixtures/store/apps/211400_offers_sale.txt
387
394
  - spec/fixtures/store/apps/211400_sale.txt
@@ -394,19 +401,19 @@ test_files:
394
401
  - spec/fixtures/store/apps/no_app.txt
395
402
  - spec/integration/community_integration_spec.rb
396
403
  - spec/integration/store_integration_spec.rb
404
+ - spec/lib/stew/community/community_client_spec.rb
397
405
  - spec/lib/stew/community/profile_friends_spec.rb
398
406
  - spec/lib/stew/community/profile_game_spec.rb
399
407
  - spec/lib/stew/community/profile_games_spec.rb
400
408
  - spec/lib/stew/community/profile_spec.rb
401
409
  - spec/lib/stew/community/steam_id_spec.rb
402
- - spec/lib/stew/community_client_spec.rb
410
+ - spec/lib/stew/community/xml_client/xml_client_spec.rb
403
411
  - spec/lib/stew/store/app_offer_sale_spec.rb
404
412
  - spec/lib/stew/store/app_offer_spec.rb
405
413
  - spec/lib/stew/store/app_offers_spec.rb
406
414
  - spec/lib/stew/store/app_spec.rb
407
- - spec/lib/stew/store_client_spec.rb
408
- - spec/lib/stew/web_client_spec.rb
409
- - spec/lib/stew/xml_client_spec.rb
415
+ - spec/lib/stew/store/store_client_spec.rb
416
+ - spec/lib/stew/store/web_client_spec.rb
410
417
  - spec/lib/stew_spec.rb
411
418
  - spec/spec_helper.rb
412
419
  has_rdoc:
@@ -1,42 +0,0 @@
1
- module Stew
2
- # Creation of all profile* objects.
3
- # Uses a given or default XmlClient instance to communicate with the Steam API
4
- # The main identifier for most methods is the 64-bit steam id
5
- # @example Create a Profile
6
- # Stew::CommunityClient.new.profile(76561197992917668) #=> Stew::Community::Profile
7
- #
8
- # @example Resolve a Steam Vanity name
9
- # Stew::CommunityClient.steam_id_from_vanity_name('eekon20') #=> 76561197986383225
10
- #
11
- class CommunityClient
12
- COMMUNITY_URL = 'http://steamcommunity.com'
13
- DEFAULT_BASE_PATH = 'profiles'
14
-
15
- def self.steam_id_from_vanity_name(vanity_name)
16
- Stew::XmlClient.new(COMMUNITY_URL).get("/id/#{vanity_name}")['profile']['steamID64'].to_i
17
- end
18
-
19
- def initialize(opts = {})
20
- @xml_client = opts[:client] || Stew.config[:default_xml_client].new(COMMUNITY_URL)
21
- @base_path = opts[:base_path] || DEFAULT_BASE_PATH
22
- end
23
-
24
- def profile(steam_id)
25
- Community::Profile.new @xml_client.get(path(steam_id))['profile']
26
- end
27
-
28
- def profile_games(steam_id)
29
- Community::ProfileGames.new @xml_client.get(path(steam_id,'games'))['gamesList']['games']['game']
30
- end
31
-
32
- def profile_friends(steam_id)
33
- Community::ProfileFriends.new @xml_client.get(path(steam_id,'friends'))['friendsList']['friends']['friend']
34
- end
35
-
36
- private
37
-
38
- def path(steam_id,command=nil)
39
- "/#{@base_path}/#{steam_id}/#{command}"
40
- end
41
- end
42
- end
@@ -1,39 +0,0 @@
1
- module Stew
2
- # Creation of app objects from URLs or app_ids
3
- #
4
- # Can create apps for any steam region. When no region is given, it defaults to the default region in the configuration
5
- #
6
- # @example Creation of a Stew::Store::App from a URL
7
- # Stew::StoreClient.new.create_app('http://store.steampowered.com/app/211420') #=> Stew::StoreClient::App
8
- #
9
- # @example Creation of a Stew::Store::App from an id
10
- # Stew::StoreClient.new.create_app(211420) #=> Stew::StoreClient::App
11
- #
12
- # @example Creation of a Stew::Store::App from a URL with a different region
13
- # Stew::StoreClient.new.create_app('http://store.steampowered.com/app/211420?cc=uk') #=> Stew::StoreClient::App
14
- #
15
- # @example Creation of a Stew::Store::App from an id and a region
16
- # Stew::StoreClient.new.app(211420, :uk) #=> Stew::StoreClient::App
17
- #
18
- class StoreClient
19
- STORE_URL = 'http://store.steampowered.com'
20
-
21
- def initialize(opts = {})
22
- @client = opts[:client] || Stew.config[:default_web_client].new(STORE_URL)
23
- end
24
-
25
- def create_app(data)
26
- return app(data) if data.class == Fixnum
27
- return app($1,$2) if data =~ /store.steampowered.com\/app\/([0-9]+)\/?\?cc=([a-zA-Z]{2})/
28
- return app($1) if data =~ /store.steampowered.com\/app\/([0-9]+)/
29
- raise AppIdNotFoundError
30
- end
31
-
32
- def app(app_id,region = Stew.config[:default_region])
33
- Store::App.new(@client.get("/app/#{app_id}",:cc => region.to_sym))
34
- end
35
- end
36
-
37
- # Error used when an app cannot be found
38
- class AppIdNotFoundError < StandardError; end
39
- end
@@ -1,30 +0,0 @@
1
- module Stew
2
-
3
- # Client wrapper for performing requests to the Steam Store
4
- class WebClient
5
- def initialize(uri)
6
- @connection = WebClient.connection(uri)
7
- end
8
-
9
- def get(path, options={})
10
- request(path, options).body
11
- end
12
-
13
- private
14
-
15
- def request(path,options={})
16
- @connection.get(path) do |request|
17
- request.params = options
18
- end
19
- end
20
-
21
- def self.connection(uri)
22
- Faraday.new uri do |conn|
23
- conn.headers[:cookie] = "birthtime=365842801"
24
- conn.request :retry
25
- conn.use FaradayMiddleware::FollowRedirects
26
- conn.adapter Faraday.default_adapter
27
- end
28
- end
29
- end
30
- end
@@ -1,49 +0,0 @@
1
- module Stew
2
-
3
- # Client for accessing the steam community XML api
4
- class XmlClient
5
- def initialize(uri)
6
- @connection = XmlClient.connection(uri)
7
- end
8
-
9
- # The Steam community is notorious for responding with error 503
10
- # Retries up to 10 times for the same request to compensate for this
11
- def get(path)
12
- 10.times do
13
- response = request(path)
14
- return XmlClient.parse_response(response.body) unless response.status == 503
15
- sleep 0.5
16
- end
17
- raise ServiceUnavailableError
18
- end
19
-
20
- private
21
-
22
- def request(path)
23
- @connection.get path do |req|
24
- req.params['xml'] = 1
25
- end
26
- end
27
-
28
- def self.connection(uri)
29
- Faraday.new uri do |conn|
30
- conn.response :xml, :content_type => /\bxml$/
31
- conn.request :retry
32
- conn.use FaradayMiddleware::FollowRedirects
33
- conn.adapter Faraday.default_adapter
34
- end
35
- end
36
-
37
- def self.parse_response(response)
38
- raise(ObjectNotFoundError) if response.is_a?(String)
39
- raise(ObjectNotFoundError, response['response']['error']) if response.has_key?('response')
40
- response
41
- end
42
-
43
- # Raised when the Steam community API fails to respond after 10 tries
44
- class ServiceUnavailableError < StandardError; end
45
-
46
- # Raised when the reply is malformatted or if nothing is found
47
- class ObjectNotFoundError < StandardError; end
48
- end
49
- end
@@ -1,88 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe "Stew::CommunityClient" do
4
- let(:client){double('xml_client')}
5
- subject{Stew::CommunityClient.new({:client => client})}
6
- let(:id){76561197992917668}
7
-
8
- describe "#steam_id_from_vanity_name" do
9
- let(:response){YAML.load_file("spec/fixtures/profiles/#{id}.yml")}
10
- let(:name){"Somename"}
11
-
12
- before :each do
13
- Stew::XmlClient.any_instance.should_receive(:get).with("/id/#{name}").and_return(response)
14
- end
15
-
16
- context "when the vanity name exists" do
17
- it "returns the 64-bit id" do
18
- Stew::CommunityClient.steam_id_from_vanity_name(name).should eq id
19
- end
20
- end
21
- end
22
-
23
- describe "setting the base path" do
24
- context "when the base path is not set" do
25
- let(:response){YAML.load_file("spec/fixtures/profiles/#{id}.yml")}
26
-
27
- it "should perform requests to the 'profile'" do
28
- client.should_receive(:get).with("/profiles/#{id}/").and_return(response)
29
- subject.profile(id)
30
- end
31
- end
32
-
33
- context "when the base path is set to 'id'" do
34
- let(:response){YAML.load_file("spec/fixtures/profiles/#{id}.yml")}
35
- subject{Stew::CommunityClient.new({:client => client, :base_path => 'id'})}
36
-
37
- it "should perform profile-requests to the 'id'" do
38
- client.should_receive(:get).with("/id/#{id}/").and_return(response)
39
- subject.profile(id)
40
- end
41
- end
42
- end
43
-
44
- describe ".profile" do
45
- let(:response){YAML.load_file("spec/fixtures/profiles/#{id}.yml")}
46
-
47
- it "sends the correct message to its client" do
48
- client.should_receive(:get).with("/profiles/#{id}/").and_return(response)
49
- subject.profile(id)
50
- end
51
-
52
- it "creates a profile object" do
53
- client.stub(:get).with("/profiles/#{id}/").and_return(response)
54
- Stew::Community::Profile.should_receive(:new).with(response['profile'])
55
- subject.profile(id)
56
- end
57
- end
58
-
59
- describe ".profile_games" do
60
- let(:response){YAML.load_file("spec/fixtures/profiles/games/#{id}.yml")}
61
-
62
- it "sends the correct message to its client" do
63
- client.should_receive(:get).with("/profiles/#{id}/games").and_return(response)
64
- subject.profile_games(id)
65
- end
66
-
67
- it "creates a ProfileGames object" do
68
- client.stub(:get).with("/profiles/#{id}/games").and_return(response)
69
- Stew::Community::ProfileGames.should_receive(:new).with(response['gamesList']['games']['game'])
70
- subject.profile_games(id)
71
- end
72
- end
73
-
74
- describe ".profile_friends" do
75
- let(:response){YAML.load_file("spec/fixtures/profiles/friends/#{id}.yml")}
76
-
77
- it "sends the correct message to its client" do
78
- client.should_receive(:get).with("/profiles/#{id}/friends").and_return(response)
79
- subject.profile_friends(id)
80
- end
81
-
82
- it "returns the value of the ['friendsList']['friends']['friend'] key from the response hash" do
83
- client.stub(:get).with("/profiles/#{id}/friends").and_return(response)
84
- Stew::Community::ProfileFriends.should_receive(:new).with(response['friendsList']['friends']['friend'])
85
- subject.profile_friends(id)
86
- end
87
- end
88
- end