gamercard 0.0.1
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/.gitignore +17 -0
- data/.rspec +2 -0
- data/.rvmrc +1 -0
- data/Gemfile +12 -0
- data/Guardfile +10 -0
- data/LICENSE +22 -0
- data/README.md +134 -0
- data/Rakefile +2 -0
- data/gamercard.gemspec +26 -0
- data/lib/gamercard.rb +12 -0
- data/lib/gamercard/card_parser.rb +69 -0
- data/lib/gamercard/client.rb +45 -0
- data/lib/gamercard/configuration.rb +29 -0
- data/lib/gamercard/version.rb +3 -0
- data/spec/fixtures/fetch_laikal1.yml +215 -0
- data/spec/fixtures/laikal1.html +113 -0
- data/spec/gamercard/card_parser_spec.rb +122 -0
- data/spec/gamercard/client_spec.rb +73 -0
- data/spec/gamercard_spec.rb +18 -0
- data/spec/spec_helper.rb +21 -0
- metadata +148 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/.rvmrc
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
rvm use --create 1.9.3@gamercard_gem
|
data/Gemfile
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
# Specify your gem's dependencies in gamercard.gemspec
|
4
|
+
gemspec
|
5
|
+
|
6
|
+
# Guard & Devtools
|
7
|
+
gem 'guard', '~> 0.8.8'
|
8
|
+
# MacOS notifications:
|
9
|
+
gem 'rb-fsevent', :require => ('rb-fsevent' if RUBY_PLATFORM =~ /darwin/i)
|
10
|
+
gem 'growl', :require => ('growl' if RUBY_PLATFORM =~ /darwin/i)
|
11
|
+
gem 'guard-bundler'
|
12
|
+
gem 'guard-rspec'
|
data/Guardfile
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
guard 'bundler' do
|
2
|
+
watch('Gemfile')
|
3
|
+
watch(/^.+\.gemspec/)
|
4
|
+
end
|
5
|
+
|
6
|
+
guard 'rspec', :version => 2, :cli => '--color --format nested', :all_on_start => true, :all_after_pass => true do
|
7
|
+
watch('spec/spec_helper.rb') { "spec" }
|
8
|
+
watch(%r{^spec/.+_spec\.rb$})
|
9
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
10
|
+
end
|
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Matt Wilson
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,134 @@
|
|
1
|
+
# Gamercard
|
2
|
+
|
3
|
+
Retrieves and parses an Xbox Live Gamercard for a player, providing a hash of the relevant data about the player or the raw HTML.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'gamercard'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install gamercard
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
Returns a hash suitable for JSON serialization.
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
resp = Gamercard.get('laikal1')
|
25
|
+
pp resp
|
26
|
+
# =>
|
27
|
+
{"gamertag"=>"laikal1",
|
28
|
+
"link"=>"http://live.xbox.com/en-US/Profile?Gamertag=laikal1",
|
29
|
+
"gamerpic"=>"http://avatar.xboxlive.com/avatar/laikal1/avatarpic-l.png",
|
30
|
+
"gamerscore"=>49646,
|
31
|
+
"location"=>"Ann Arbor, MI",
|
32
|
+
"motto"=>"Complexify!",
|
33
|
+
"name"=>"Nyarlathotep (1 bucket)",
|
34
|
+
"bio"=>"Design is how it works.",
|
35
|
+
"reputation"=>4.25,
|
36
|
+
"recent_games"=>
|
37
|
+
[{"comparison_url"=>
|
38
|
+
"http://live.xbox.com/en-US/Activity/Details?titleId=1161890110&compareTo=laikal1",
|
39
|
+
"image"=>
|
40
|
+
"http://tiles.xbox.com/tiles/9a/SL/0mdsb2JhbA9ECgQNGwEfV1wmL2ljb24vMC84MDAwIAAAAAAAAP2kpOo=.jpg",
|
41
|
+
"title"=>"KoA: Reckoning",
|
42
|
+
"last_played"=>"3/29/2012",
|
43
|
+
"earned_gamerscore"=>10,
|
44
|
+
"available_gamerscore"=>1300,
|
45
|
+
"earned_achievements"=>1,
|
46
|
+
"available_achievements"=>61,
|
47
|
+
"percentage_complete"=>"1%"},
|
48
|
+
{"comparison_url"=>
|
49
|
+
"http://live.xbox.com/en-US/Activity/Details?titleId=1161890141&compareTo=laikal1",
|
50
|
+
"image"=>
|
51
|
+
"http://tiles.xbox.com/tiles/np/G2/12dsb2JhbA9ECgQNGwEfV1onL2ljb24vMC84MDAwIAAAAAAAAPiZkYE=.jpg",
|
52
|
+
"title"=>"Mass Effect 3",
|
53
|
+
"last_played"=>"3/28/2012",
|
54
|
+
"earned_gamerscore"=>1025,
|
55
|
+
"available_gamerscore"=>1050,
|
56
|
+
"earned_achievements"=>51,
|
57
|
+
"available_achievements"=>52,
|
58
|
+
"percentage_complete"=>"98%"},
|
59
|
+
{"comparison_url"=>
|
60
|
+
"http://live.xbox.com/en-US/Activity/Details?titleId=1161890083&compareTo=laikal1",
|
61
|
+
"image"=>
|
62
|
+
"http://tiles.xbox.com/tiles/WQ/nz/0Wdsb2JhbA9ECgQNGwEfV11QL2ljb24vMC84MDAwIAAAAAAAAP7cCUY=.jpg",
|
63
|
+
"title"=>"Syndicate",
|
64
|
+
"last_played"=>"3/11/2012",
|
65
|
+
"earned_gamerscore"=>530,
|
66
|
+
"available_gamerscore"=>1000,
|
67
|
+
"earned_achievements"=>33,
|
68
|
+
"available_achievements"=>50,
|
69
|
+
"percentage_complete"=>"66%"},
|
70
|
+
{"comparison_url"=>
|
71
|
+
"http://live.xbox.com/en-US/Activity/Details?titleId=1414793176&compareTo=laikal1",
|
72
|
+
"image"=>
|
73
|
+
"http://tiles.xbox.com/tiles/fc/qf/0Wdsb2JhbA9ECgUMGgQfWStbL2ljb24vMC84MDAwIAAAAAAAAP6wymI=.jpg",
|
74
|
+
"title"=>"BioShock",
|
75
|
+
"last_played"=>"2/25/2012",
|
76
|
+
"earned_gamerscore"=>1100,
|
77
|
+
"available_gamerscore"=>1100,
|
78
|
+
"earned_achievements"=>51,
|
79
|
+
"available_achievements"=>51,
|
80
|
+
"percentage_complete"=>"100%"},
|
81
|
+
{"comparison_url"=>
|
82
|
+
"http://live.xbox.com/en-US/Activity/Details?titleId=1112737766&compareTo=laikal1",
|
83
|
+
"image"=>
|
84
|
+
"http://tiles.xbox.com/tiles/qR/QI/1Gdsb2JhbA9ECgQKGgMfWSpVL2ljb24vMC84MDAwIAAAAAAAAPsnFLY=.jpg",
|
85
|
+
"title"=>"Skyrim",
|
86
|
+
"last_played"=>"2/14/2012",
|
87
|
+
"earned_gamerscore"=>910,
|
88
|
+
"available_gamerscore"=>1000,
|
89
|
+
"earned_achievements"=>47,
|
90
|
+
"available_achievements"=>50,
|
91
|
+
"percentage_complete"=>"94%"}]}
|
92
|
+
```
|
93
|
+
|
94
|
+
### Configuration
|
95
|
+
|
96
|
+
Gamercard uses [Faraday](https://github.com/technoweenie/faraday), so you can use any http backend that Faraday supports. It assumes [Typhoeus](https://github.com/dbalatero/typhoeus) by default. Tell Gamercard what http library you are using by:
|
97
|
+
|
98
|
+
```ruby
|
99
|
+
Gamercard.adapter = :excon # (or :typhoeus, w/e)
|
100
|
+
```
|
101
|
+
|
102
|
+
A block-style configurator is also available:
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
Gamercard.configure do |c|
|
106
|
+
c.adapter = :typhoeus
|
107
|
+
c.user_agent = "My Awesome Client"
|
108
|
+
end
|
109
|
+
```
|
110
|
+
|
111
|
+
## CHANGELOG
|
112
|
+
|
113
|
+
* v0.0.1 Hello World
|
114
|
+
* Returns all the basic gamercard data, sans status. Status can be had from a public site, though, so that is next!
|
115
|
+
|
116
|
+
## Thanks to
|
117
|
+
|
118
|
+
This project builds on work done by the following people and projects:
|
119
|
+
|
120
|
+
* [barisbalic](https://github.com/barisbalic)'s [gamertag](https://github.com/barisbalic/gamertag), which depends on unfortunately unreliable 3rd-party proxies to Microsoft's service. This gem provides less data, but scrapes it directly from http://live.xbox.com – Straight from the horse's mouth, if you will.
|
121
|
+
|
122
|
+
So: thanks a ton to him.
|
123
|
+
|
124
|
+
## Note on Patches/Pull Requests
|
125
|
+
|
126
|
+
* Fork the project.
|
127
|
+
* Make your feature addition or bug fix.
|
128
|
+
* Add tests for it. This is important so I don't break it in a future version unintentionally.
|
129
|
+
* Commit, do not mess with rakefile, version, or history. (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
|
130
|
+
* Send me a pull request. Bonus points for topic branches.
|
131
|
+
|
132
|
+
## Copyright
|
133
|
+
|
134
|
+
Copyright (c) 2011 Matt Wilson. See LICENSE for details.
|
data/Rakefile
ADDED
data/gamercard.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/gamercard/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.authors = ["Matt Wilson"]
|
6
|
+
s.email = ["mhw@hypomodern.com"]
|
7
|
+
s.description = %q{A Simple & Straightforward XBox Live Gamercard parser.}
|
8
|
+
s.summary = %q{A Simple & Straightforward XBox Live Gamercard parser.}
|
9
|
+
s.homepage = "https://github.com/hypomodern/gamercard"
|
10
|
+
|
11
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
12
|
+
s.files = `git ls-files`.split("\n")
|
13
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
14
|
+
s.name = "gamercard"
|
15
|
+
s.require_paths = ["lib"]
|
16
|
+
s.version = Gamercard::VERSION
|
17
|
+
|
18
|
+
s.add_development_dependency 'rake'
|
19
|
+
s.add_development_dependency 'rspec'
|
20
|
+
s.add_development_dependency 'typhoeus'
|
21
|
+
s.add_development_dependency 'vcr'
|
22
|
+
s.add_development_dependency 'fakeweb'
|
23
|
+
|
24
|
+
s.add_dependency 'nokogiri'
|
25
|
+
s.add_dependency 'faraday', '>= 0.8.0.rc2'
|
26
|
+
end
|
data/lib/gamercard.rb
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
require 'nokogiri'
|
2
|
+
|
3
|
+
module Gamercard
|
4
|
+
class CardParser
|
5
|
+
attr_accessor :raw_response
|
6
|
+
|
7
|
+
def initialize http_response
|
8
|
+
self.raw_response = http_response
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.parse http_response
|
12
|
+
new(http_response).parse
|
13
|
+
end
|
14
|
+
|
15
|
+
def parse
|
16
|
+
doc = Nokogiri::HTML(raw_response.body)
|
17
|
+
gamertag = doc.css("#Gamertag").first
|
18
|
+
{
|
19
|
+
'gamertag' => gamertag.content,
|
20
|
+
'link' => gamertag.attribute("href").value,
|
21
|
+
'gamerpic' => doc.css("#Gamerpic").first.attribute("src").value,
|
22
|
+
'gamerscore' => doc.css("#Gamerscore").first.content.to_i,
|
23
|
+
'location' => doc.css("#Location").first.content,
|
24
|
+
'motto' => doc.css("#Motto").first.content,
|
25
|
+
'name' => doc.css("#Name").first.content,
|
26
|
+
'bio' => doc.css("#Bio").first.content,
|
27
|
+
'reputation' => count_reputation(doc),
|
28
|
+
'recent_games' => summarize_games(doc)
|
29
|
+
}
|
30
|
+
end
|
31
|
+
|
32
|
+
def count_reputation doc
|
33
|
+
rep = doc.css('.RepContainer')
|
34
|
+
counts = {
|
35
|
+
1.0 => rep.css('.Full').size,
|
36
|
+
0.75 => rep.css('.ThreeQuarter').size,
|
37
|
+
0.5 => rep.css('.Half').size,
|
38
|
+
0.25 => rep.css('.Quarter').size
|
39
|
+
}
|
40
|
+
counts.inject(0) do |rep, (value, count)|
|
41
|
+
rep += count * value
|
42
|
+
rep
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def summarize_games doc
|
47
|
+
doc.css('#PlayedGames li').inject([]) do |array, game_node|
|
48
|
+
array.push summarize(game_node)
|
49
|
+
array
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def summarize game
|
54
|
+
link = game.css('a').first
|
55
|
+
{
|
56
|
+
'comparison_url' => link.attribute('href').value,
|
57
|
+
'image' => link.css('img').first.attribute('src').value,
|
58
|
+
'title' => link.css('.Title').first.content,
|
59
|
+
'last_played' => link.css('.LastPlayed').first.content,
|
60
|
+
'earned_gamerscore' => link.css('.EarnedGamerscore').first.content.to_i,
|
61
|
+
'available_gamerscore' => link.css('.AvailableGamerscore').first.content.to_i,
|
62
|
+
'earned_achievements' => link.css('.EarnedAchievements').first.content.to_i,
|
63
|
+
'available_achievements' => link.css('.AvailableAchievements').first.content.to_i,
|
64
|
+
'percentage_complete' => link.css('.PercentageComplete').first.content
|
65
|
+
}
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'faraday'
|
2
|
+
|
3
|
+
module Gamercard
|
4
|
+
class Client
|
5
|
+
attr_accessor :gamertag
|
6
|
+
|
7
|
+
GAMERCARD_SERVICE_URL = "http://gamercard.xbox.com"
|
8
|
+
|
9
|
+
def initialize gamertag
|
10
|
+
self.gamertag = gamertag
|
11
|
+
end
|
12
|
+
|
13
|
+
def fetch
|
14
|
+
response = fetch_with_redirect
|
15
|
+
if response.success?
|
16
|
+
parse response
|
17
|
+
else
|
18
|
+
response
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def fetch_with_redirect
|
23
|
+
resp = connection.get(build_url)
|
24
|
+
if resp.status == 302 && resp['location']
|
25
|
+
resp = connection.get(resp['location'])
|
26
|
+
end
|
27
|
+
resp
|
28
|
+
end
|
29
|
+
|
30
|
+
def connection
|
31
|
+
@connection ||= Faraday.new(:url => GAMERCARD_SERVICE_URL) do |b|
|
32
|
+
b.adapter Gamercard.adapter
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def build_url
|
37
|
+
"#{gamertag}.card"
|
38
|
+
end
|
39
|
+
|
40
|
+
def parse response
|
41
|
+
CardParser.parse response
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Gamercard
|
2
|
+
module Configuration
|
3
|
+
# Set a custom User-Agent string (default: Gamercard Gem #{version})
|
4
|
+
attr_accessor :user_agent
|
5
|
+
|
6
|
+
# Select a different http library for Faraday to use (default: Typhoeus)
|
7
|
+
attr_accessor :adapter
|
8
|
+
|
9
|
+
# Yield self to be able to configure Gamercard
|
10
|
+
#
|
11
|
+
# Example:
|
12
|
+
#
|
13
|
+
# Gamercard.configure do |c|
|
14
|
+
# c.user_agent = "MyCoolApp Gamercard Client v2.51"
|
15
|
+
# c.adapter = :excon
|
16
|
+
# end
|
17
|
+
def configure
|
18
|
+
yield self
|
19
|
+
end
|
20
|
+
|
21
|
+
def user_agent
|
22
|
+
@user_agent || "Gamercard Gem #{Gamercard::VERSION}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def adapter
|
26
|
+
@adapter || :typhoeus
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,215 @@
|
|
1
|
+
---
|
2
|
+
http_interactions:
|
3
|
+
- request:
|
4
|
+
method: get
|
5
|
+
uri: http://gamercard.xbox.com/laikal1.card
|
6
|
+
body:
|
7
|
+
encoding: US-ASCII
|
8
|
+
string: ''
|
9
|
+
headers: {}
|
10
|
+
response:
|
11
|
+
status:
|
12
|
+
code: 302
|
13
|
+
message:
|
14
|
+
headers:
|
15
|
+
!binary "Q2FjaGUtQ29udHJvbA==":
|
16
|
+
- !binary |-
|
17
|
+
cHJpdmF0ZQ==
|
18
|
+
!binary "TG9jYXRpb24=":
|
19
|
+
- !binary |-
|
20
|
+
aHR0cDovL2dhbWVyY2FyZC54Ym94LmNvbTo4MC9lbi1VUy9sYWlrYWwxLmNh
|
21
|
+
cmQ=
|
22
|
+
!binary "WC1Db250ZW50LVR5cGUtT3B0aW9ucw==":
|
23
|
+
- !binary |-
|
24
|
+
bm9zbmlmZg==
|
25
|
+
!binary "Q29udGVudC1MZW5ndGg=":
|
26
|
+
- !binary |-
|
27
|
+
MA==
|
28
|
+
!binary "RGF0ZQ==":
|
29
|
+
- !binary |-
|
30
|
+
U3VuLCAwMSBBcHIgMjAxMiAyMjo1MjowMCBHTVQ=
|
31
|
+
!binary "Q29ubmVjdGlvbg==":
|
32
|
+
- !binary |-
|
33
|
+
a2VlcC1hbGl2ZQ==
|
34
|
+
body:
|
35
|
+
encoding: ASCII-8BIT
|
36
|
+
string: !binary ""
|
37
|
+
http_version:
|
38
|
+
recorded_at: Sun, 01 Apr 2012 22:52:00 GMT
|
39
|
+
- request:
|
40
|
+
method: get
|
41
|
+
uri: http://gamercard.xbox.com/en-US/laikal1.card
|
42
|
+
body:
|
43
|
+
encoding: US-ASCII
|
44
|
+
string: ''
|
45
|
+
headers: {}
|
46
|
+
response:
|
47
|
+
status:
|
48
|
+
code: 200
|
49
|
+
message:
|
50
|
+
headers:
|
51
|
+
!binary "Q2FjaGUtQ29udHJvbA==":
|
52
|
+
- !binary |-
|
53
|
+
cHJpdmF0ZQ==
|
54
|
+
!binary "Q29udGVudC1UeXBl":
|
55
|
+
- !binary |-
|
56
|
+
dGV4dC9odG1sOyBjaGFyc2V0PXV0Zi04
|
57
|
+
!binary "WC1Db250ZW50LVR5cGUtT3B0aW9ucw==":
|
58
|
+
- !binary |-
|
59
|
+
bm9zbmlmZg==
|
60
|
+
!binary "VmFyeQ==":
|
61
|
+
- !binary |-
|
62
|
+
QWNjZXB0LUVuY29kaW5n
|
63
|
+
!binary "Q29udGVudC1FbmNvZGluZw==":
|
64
|
+
- !binary |-
|
65
|
+
Z3ppcA==
|
66
|
+
!binary "Q29udGVudC1MZW5ndGg=":
|
67
|
+
- !binary |-
|
68
|
+
MTIwNQ==
|
69
|
+
!binary "RGF0ZQ==":
|
70
|
+
- !binary |-
|
71
|
+
U3VuLCAwMSBBcHIgMjAxMiAyMjo1MjowMSBHTVQ=
|
72
|
+
!binary "Q29ubmVjdGlvbg==":
|
73
|
+
- !binary |-
|
74
|
+
a2VlcC1hbGl2ZQ==
|
75
|
+
body:
|
76
|
+
encoding: ASCII-8BIT
|
77
|
+
string: !binary |-
|
78
|
+
DQo8IURPQ1RZUEUgaHRtbCBQVUJMSUMgIi0vL1czQy8vRFREIFhIVE1MIDEu
|
79
|
+
MCBUcmFuc2l0aW9uYWwvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvVFIveGh0
|
80
|
+
bWwxL0RURC94aHRtbDEtdHJhbnNpdGlvbmFsLmR0ZCI+DQo8aHRtbCB4bWxu
|
81
|
+
cz0iaHR0cDovL3d3dy53My5vcmcvMTk5OS94aHRtbCIgbGFuZz0iZW5nIj4N
|
82
|
+
CiAgICA8aGVhZD4NCiAgICAgICAgPGxpbmsgcmVsPSJzdHlsZXNoZWV0IiB0
|
83
|
+
eXBlPSJ0ZXh0L2NzcyIgaHJlZj0iL0NvbnRlbnQvR2FtZXJjYXJkL2RlZmF1
|
84
|
+
bHQvZ2FtZXJjYXJkLmNzcyIgLz4NCiAgICAgICAgPG1ldGEgbmFtZT0icm9i
|
85
|
+
b3RzIiBjb250ZW50PSJub2luZGV4LG5vZm9sbG93IiAvPg0KICAgICAgICA8
|
86
|
+
bWV0YSBuYW1lPSJjYXRlZ29yeSIgY29udGVudD0iR2FtZXJjYXJkIiAvPg0K
|
87
|
+
ICAgICAgICA8YmFzZSB0YXJnZXQ9Il90b3AiIC8+DQogICAgICAgIDx0aXRs
|
88
|
+
ZT5sYWlrYWwxPC90aXRsZT4NCiAgICA8L2hlYWQ+DQogICAgPGJvZHk+DQog
|
89
|
+
ICAgICAgIDxkaXYgY2xhc3M9IlhiY0dhbWVyY2FyZCBHb2xkIE1hbGUgIj4N
|
90
|
+
CiAgICAgICAgICAgIA0KICAgICAgICAgICAgPGEgaWQ9IkdhbWVydGFnIiBo
|
91
|
+
cmVmPSJodHRwOi8vbGl2ZS54Ym94LmNvbS9lbi1VUy9Qcm9maWxlP0dhbWVy
|
92
|
+
dGFnPWxhaWthbDEiPmxhaWthbDE8L2E+DQogICAgICAgICAgICA8YSBocmVm
|
93
|
+
PSJodHRwOi8vbGl2ZS54Ym94LmNvbS9lbi1VUy9Qcm9maWxlP0dhbWVydGFn
|
94
|
+
PWxhaWthbDEiPg0KICAgICAgICAgICAgICAgIDxpbWcgaWQ9IkdhbWVycGlj
|
95
|
+
IiBzcmM9Imh0dHA6Ly9hdmF0YXIueGJveGxpdmUuY29tL2F2YXRhci9sYWlr
|
96
|
+
YWwxL2F2YXRhcnBpYy1sLnBuZyIgYWx0PSJsYWlrYWwxIiB0aXRsZT0ibGFp
|
97
|
+
a2FsMSIvPg0KICAgICAgICAgICAgPC9hPg0KICAgICAgICAgICAgPGRpdiBj
|
98
|
+
bGFzcz0iUmVwQ29udGFpbmVyIj4NCiAgICAgICAgICAgICAgICA8bGFiZWw+
|
99
|
+
UmVwPC9sYWJlbD4NCiAgICAgICAgICAgICAgICANCiAgICAgICAgICAgICAg
|
100
|
+
ICAgICAgPGRpdiBjbGFzcz0iU3RhciBGdWxsIj48L2Rpdj4NCiAgICAgICAg
|
101
|
+
ICAgICAgICAgICAgPGRpdiBjbGFzcz0iU3RhciBGdWxsIj48L2Rpdj4NCiAg
|
102
|
+
ICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz0iU3RhciBGdWxsIj48L2Rp
|
103
|
+
dj4NCiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz0iU3RhciBGdWxs
|
104
|
+
Ij48L2Rpdj48ZGl2IGNsYXNzPSJTdGFyIFF1YXJ0ZXIiPjwvZGl2Pg0KICAg
|
105
|
+
ICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICA8ZGl2IGNsYXNzPSJHYW1l
|
106
|
+
cnNjb3JlQ29udGFpbmVyIj4NCiAgICAgICAgICAgICAgICA8bGFiZWw+PC9s
|
107
|
+
YWJlbD4NCiAgICAgICAgICAgICAgICA8ZGl2IGlkPSJHYW1lcnNjb3JlIj40
|
108
|
+
OTY0NjwvZGl2Pg0KICAgICAgICAgICAgPC9kaXY+DQogICAgICAgICAgICA8
|
109
|
+
ZGl2IGlkPSJMb2NhdGlvbiI+QW5uIEFyYm9yLCBNSTwvZGl2Pg0KICAgICAg
|
110
|
+
ICAgICAgPGRpdiBpZD0iTW90dG8iPkNvbXBsZXhpZnkhPC9kaXY+DQogICAg
|
111
|
+
ICAgICAgICA8ZGl2IGlkPSJOYW1lIj5OeWFybGF0aG90ZXAgKDEgYnVja2V0
|
112
|
+
KTwvZGl2Pg0KICAgICAgICAgICAgPGRpdiBpZD0iQmlvIj5EZXNpZ24gaXMg
|
113
|
+
aG93IGl0IHdvcmtzLjwvZGl2Pg0KDQogICAgICAgICAgICANCiAgICAgICAg
|
114
|
+
ICAgIDxvbCBpZD0iUGxheWVkR2FtZXMiID4NCiAgICAgICAgICAgIA0KICAg
|
115
|
+
ICAgICAgICAgICAgIDxsaSA+DQogICAgICAgICAgICAgICAgICAgIA0KICAg
|
116
|
+
ICAgICAgICAgICAgICAgICA8YSBocmVmPSJodHRwOi8vbGl2ZS54Ym94LmNv
|
117
|
+
bS9lbi1VUy9BY3Rpdml0eS9EZXRhaWxzP3RpdGxlSWQ9MTE2MTg5MDExMCZh
|
118
|
+
bXA7Y29tcGFyZVRvPWxhaWthbDEiPg0KICAgICAgICAgICAgICAgICAgICAg
|
119
|
+
ICA8aW1nIHNyYz0iaHR0cDovL3RpbGVzLnhib3guY29tL3RpbGVzLzlhL1NM
|
120
|
+
LzBtZHNiMkpoYkE5RUNnUU5Hd0VmVjF3bUwybGpiMjR2TUM4NE1EQXdJQUFB
|
121
|
+
QUFBQUFQMmtwT289LmpwZyIgYWx0PSJLb0E6IFJlY2tvbmluZyIgdGl0bGU9
|
122
|
+
IktvQTogUmVja29uaW5nIiAvPg0KICAgICAgICAgICAgICAgICAgICAgICA8
|
123
|
+
c3BhbiBjbGFzcz0iVGl0bGUiPktvQTogUmVja29uaW5nPC9zcGFuPg0KICAg
|
124
|
+
ICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz0iTGFzdFBsYXllZCI+
|
125
|
+
My8yOS8yMDEyPC9zcGFuPg0KICAgICAgICAgICAgICAgICAgICAgICA8c3Bh
|
126
|
+
biBjbGFzcz0iRWFybmVkR2FtZXJzY29yZSI+MTA8L3NwYW4+DQogICAgICAg
|
127
|
+
ICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPSJBdmFpbGFibGVHYW1lcnNj
|
128
|
+
b3JlIj4xMzAwPC9zcGFuPg0KICAgICAgICAgICAgICAgICAgICAgICA8c3Bh
|
129
|
+
biBjbGFzcz0iRWFybmVkQWNoaWV2ZW1lbnRzIj4xPC9zcGFuPg0KICAgICAg
|
130
|
+
ICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz0iQXZhaWxhYmxlQWNoaWV2
|
131
|
+
ZW1lbnRzIj42MTwvc3Bhbj4NCiAgICAgICAgICAgICAgICAgICAgICAgPHNw
|
132
|
+
YW4gY2xhc3M9IlBlcmNlbnRhZ2VDb21wbGV0ZSI+MSU8L3NwYW4+DQogICAg
|
133
|
+
ICAgICAgICAgICAgICAgIDwvYT4NCiAgICAgICAgICAgICAgICA8L2xpPg0K
|
134
|
+
ICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgPGxpID4NCiAgICAgICAg
|
135
|
+
ICAgICAgICAgICAgDQogICAgICAgICAgICAgICAgICAgIDxhIGhyZWY9Imh0
|
136
|
+
dHA6Ly9saXZlLnhib3guY29tL2VuLVVTL0FjdGl2aXR5L0RldGFpbHM/dGl0
|
137
|
+
bGVJZD0xMTYxODkwMTQxJmFtcDtjb21wYXJlVG89bGFpa2FsMSI+DQogICAg
|
138
|
+
ICAgICAgICAgICAgICAgICAgIDxpbWcgc3JjPSJodHRwOi8vdGlsZXMueGJv
|
139
|
+
eC5jb20vdGlsZXMvbnAvRzIvMTJkc2IySmhiQTlFQ2dRTkd3RWZWMW9uTDJs
|
140
|
+
amIyNHZNQzg0TURBd0lBQUFBQUFBQVBpWmtZRT0uanBnIiBhbHQ9Ik1hc3Mg
|
141
|
+
RWZmZWN0IDMiIHRpdGxlPSJNYXNzIEVmZmVjdCAzIiAvPg0KICAgICAgICAg
|
142
|
+
ICAgICAgICAgICAgICA8c3BhbiBjbGFzcz0iVGl0bGUiPk1hc3MgRWZmZWN0
|
143
|
+
IDM8L3NwYW4+DQogICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNz
|
144
|
+
PSJMYXN0UGxheWVkIj4zLzI4LzIwMTI8L3NwYW4+DQogICAgICAgICAgICAg
|
145
|
+
ICAgICAgICAgIDxzcGFuIGNsYXNzPSJFYXJuZWRHYW1lcnNjb3JlIj4xMDI1
|
146
|
+
PC9zcGFuPg0KICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz0i
|
147
|
+
QXZhaWxhYmxlR2FtZXJzY29yZSI+MTA1MDwvc3Bhbj4NCiAgICAgICAgICAg
|
148
|
+
ICAgICAgICAgICAgPHNwYW4gY2xhc3M9IkVhcm5lZEFjaGlldmVtZW50cyI+
|
149
|
+
NTE8L3NwYW4+DQogICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNz
|
150
|
+
PSJBdmFpbGFibGVBY2hpZXZlbWVudHMiPjUyPC9zcGFuPg0KICAgICAgICAg
|
151
|
+
ICAgICAgICAgICAgICA8c3BhbiBjbGFzcz0iUGVyY2VudGFnZUNvbXBsZXRl
|
152
|
+
Ij45OCU8L3NwYW4+DQogICAgICAgICAgICAgICAgICAgIDwvYT4NCiAgICAg
|
153
|
+
ICAgICAgICAgICA8L2xpPg0KICAgICAgICAgICAgDQogICAgICAgICAgICAg
|
154
|
+
ICAgPGxpID4NCiAgICAgICAgICAgICAgICAgICAgDQogICAgICAgICAgICAg
|
155
|
+
ICAgICAgIDxhIGhyZWY9Imh0dHA6Ly9saXZlLnhib3guY29tL2VuLVVTL0Fj
|
156
|
+
dGl2aXR5L0RldGFpbHM/dGl0bGVJZD0xMTYxODkwMDgzJmFtcDtjb21wYXJl
|
157
|
+
VG89bGFpa2FsMSI+DQogICAgICAgICAgICAgICAgICAgICAgIDxpbWcgc3Jj
|
158
|
+
PSJodHRwOi8vdGlsZXMueGJveC5jb20vdGlsZXMvV1EvbnovMFdkc2IySmhi
|
159
|
+
QTlFQ2dRTkd3RWZWMTFRTDJsamIyNHZNQzg0TURBd0lBQUFBQUFBQVA3Y0NV
|
160
|
+
WT0uanBnIiBhbHQ9IlN5bmRpY2F0ZSIgdGl0bGU9IlN5bmRpY2F0ZSIgLz4N
|
161
|
+
CiAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9IlRpdGxlIj5T
|
162
|
+
eW5kaWNhdGU8L3NwYW4+DQogICAgICAgICAgICAgICAgICAgICAgIDxzcGFu
|
163
|
+
IGNsYXNzPSJMYXN0UGxheWVkIj4zLzExLzIwMTI8L3NwYW4+DQogICAgICAg
|
164
|
+
ICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPSJFYXJuZWRHYW1lcnNjb3Jl
|
165
|
+
Ij41MzA8L3NwYW4+DQogICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNs
|
166
|
+
YXNzPSJBdmFpbGFibGVHYW1lcnNjb3JlIj4xMDAwPC9zcGFuPg0KICAgICAg
|
167
|
+
ICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz0iRWFybmVkQWNoaWV2ZW1l
|
168
|
+
bnRzIj4zMzwvc3Bhbj4NCiAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4g
|
169
|
+
Y2xhc3M9IkF2YWlsYWJsZUFjaGlldmVtZW50cyI+NTA8L3NwYW4+DQogICAg
|
170
|
+
ICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNzPSJQZXJjZW50YWdlQ29t
|
171
|
+
cGxldGUiPjY2JTwvc3Bhbj4NCiAgICAgICAgICAgICAgICAgICAgPC9hPg0K
|
172
|
+
ICAgICAgICAgICAgICAgIDwvbGk+DQogICAgICAgICAgICANCiAgICAgICAg
|
173
|
+
ICAgICAgICA8bGkgY2xhc3M9IkNvbXBsZXRlIiA+DQogICAgICAgICAgICAg
|
174
|
+
ICAgICAgIA0KICAgICAgICAgICAgICAgICAgICA8YSBocmVmPSJodHRwOi8v
|
175
|
+
bGl2ZS54Ym94LmNvbS9lbi1VUy9BY3Rpdml0eS9EZXRhaWxzP3RpdGxlSWQ9
|
176
|
+
MTQxNDc5MzE3NiZhbXA7Y29tcGFyZVRvPWxhaWthbDEiPg0KICAgICAgICAg
|
177
|
+
ICAgICAgICAgICAgICA8aW1nIHNyYz0iaHR0cDovL3RpbGVzLnhib3guY29t
|
178
|
+
L3RpbGVzL2ZjL3FmLzBXZHNiMkpoYkE5RUNnVU1HZ1FmV1N0YkwybGpiMjR2
|
179
|
+
TUM4NE1EQXdJQUFBQUFBQUFQNnd5bUk9LmpwZyIgYWx0PSJCaW9TaG9jayIg
|
180
|
+
dGl0bGU9IkJpb1Nob2NrIiAvPg0KICAgICAgICAgICAgICAgICAgICAgICA8
|
181
|
+
c3BhbiBjbGFzcz0iVGl0bGUiPkJpb1Nob2NrPC9zcGFuPg0KICAgICAgICAg
|
182
|
+
ICAgICAgICAgICAgICA8c3BhbiBjbGFzcz0iTGFzdFBsYXllZCI+Mi8yNS8y
|
183
|
+
MDEyPC9zcGFuPg0KICAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFz
|
184
|
+
cz0iRWFybmVkR2FtZXJzY29yZSI+MTEwMDwvc3Bhbj4NCiAgICAgICAgICAg
|
185
|
+
ICAgICAgICAgICAgPHNwYW4gY2xhc3M9IkF2YWlsYWJsZUdhbWVyc2NvcmUi
|
186
|
+
PjExMDA8L3NwYW4+DQogICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNs
|
187
|
+
YXNzPSJFYXJuZWRBY2hpZXZlbWVudHMiPjUxPC9zcGFuPg0KICAgICAgICAg
|
188
|
+
ICAgICAgICAgICAgICA8c3BhbiBjbGFzcz0iQXZhaWxhYmxlQWNoaWV2ZW1l
|
189
|
+
bnRzIj41MTwvc3Bhbj4NCiAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4g
|
190
|
+
Y2xhc3M9IlBlcmNlbnRhZ2VDb21wbGV0ZSI+MTAwJTwvc3Bhbj4NCiAgICAg
|
191
|
+
ICAgICAgICAgICAgICAgPC9hPg0KICAgICAgICAgICAgICAgIDwvbGk+DQog
|
192
|
+
ICAgICAgICAgICANCiAgICAgICAgICAgICAgICA8bGkgPg0KICAgICAgICAg
|
193
|
+
ICAgICAgICAgICANCiAgICAgICAgICAgICAgICAgICAgPGEgaHJlZj0iaHR0
|
194
|
+
cDovL2xpdmUueGJveC5jb20vZW4tVVMvQWN0aXZpdHkvRGV0YWlscz90aXRs
|
195
|
+
ZUlkPTExMTI3Mzc3NjYmYW1wO2NvbXBhcmVUbz1sYWlrYWwxIj4NCiAgICAg
|
196
|
+
ICAgICAgICAgICAgICAgICAgPGltZyBzcmM9Imh0dHA6Ly90aWxlcy54Ym94
|
197
|
+
LmNvbS90aWxlcy9xUi9RSS8xR2RzYjJKaGJBOUVDZ1FLR2dNZldTcFZMMmxq
|
198
|
+
YjI0dk1DODRNREF3SUFBQUFBQUFBUHNuRkxZPS5qcGciIGFsdD0iU2t5cmlt
|
199
|
+
IiB0aXRsZT0iU2t5cmltIiAvPg0KICAgICAgICAgICAgICAgICAgICAgICA8
|
200
|
+
c3BhbiBjbGFzcz0iVGl0bGUiPlNreXJpbTwvc3Bhbj4NCiAgICAgICAgICAg
|
201
|
+
ICAgICAgICAgICAgPHNwYW4gY2xhc3M9Ikxhc3RQbGF5ZWQiPjIvMTQvMjAx
|
202
|
+
Mjwvc3Bhbj4NCiAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9
|
203
|
+
IkVhcm5lZEdhbWVyc2NvcmUiPjkxMDwvc3Bhbj4NCiAgICAgICAgICAgICAg
|
204
|
+
ICAgICAgICAgPHNwYW4gY2xhc3M9IkF2YWlsYWJsZUdhbWVyc2NvcmUiPjEw
|
205
|
+
MDA8L3NwYW4+DQogICAgICAgICAgICAgICAgICAgICAgIDxzcGFuIGNsYXNz
|
206
|
+
PSJFYXJuZWRBY2hpZXZlbWVudHMiPjQ3PC9zcGFuPg0KICAgICAgICAgICAg
|
207
|
+
ICAgICAgICAgICA8c3BhbiBjbGFzcz0iQXZhaWxhYmxlQWNoaWV2ZW1lbnRz
|
208
|
+
Ij41MDwvc3Bhbj4NCiAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xh
|
209
|
+
c3M9IlBlcmNlbnRhZ2VDb21wbGV0ZSI+OTQlPC9zcGFuPg0KICAgICAgICAg
|
210
|
+
ICAgICAgICAgICA8L2E+DQogICAgICAgICAgICAgICAgPC9saT4NCiAgICAg
|
211
|
+
ICAgICAgIA0KICAgICAgICAgICAgPC9vbD4NCiAgICAgICAgPC9kaXY+DQog
|
212
|
+
ICAgICAgIA0KICAgIDwvYm9keT4NCjwvaHRtbD4=
|
213
|
+
http_version:
|
214
|
+
recorded_at: Sun, 01 Apr 2012 22:52:01 GMT
|
215
|
+
recorded_with: VCR 2.0.0
|
@@ -0,0 +1,113 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
4
|
+
<html xmlns="http://www.w3.org/1999/xhtml" lang="eng">
|
5
|
+
<head>
|
6
|
+
<link rel="stylesheet" type="text/css" href="/Content/Gamercard/default/gamercard.css" />
|
7
|
+
<meta name="robots" content="noindex,nofollow" />
|
8
|
+
<meta name="category" content="Gamercard" />
|
9
|
+
<base target="_top" />
|
10
|
+
<title>laikal1</title>
|
11
|
+
</head>
|
12
|
+
<body>
|
13
|
+
<div class="XbcGamercard Gold Male ">
|
14
|
+
|
15
|
+
<a id="Gamertag" href="http://live.xbox.com/en-US/Profile?Gamertag=laikal1">laikal1</a>
|
16
|
+
<a href="http://live.xbox.com/en-US/Profile?Gamertag=laikal1">
|
17
|
+
<img id="Gamerpic" src="http://avatar.xboxlive.com/avatar/laikal1/avatarpic-l.png" alt="laikal1" title="laikal1"/>
|
18
|
+
</a>
|
19
|
+
<div class="RepContainer">
|
20
|
+
<label>Rep</label>
|
21
|
+
|
22
|
+
<div class="Star Full"></div>
|
23
|
+
<div class="Star Full"></div>
|
24
|
+
<div class="Star Full"></div>
|
25
|
+
<div class="Star Full"></div><div class="Star Quarter"></div>
|
26
|
+
</div>
|
27
|
+
<div class="GamerscoreContainer">
|
28
|
+
<label></label>
|
29
|
+
<div id="Gamerscore">49646</div>
|
30
|
+
</div>
|
31
|
+
<div id="Location">Ann Arbor, MI</div>
|
32
|
+
<div id="Motto">Complexify!</div>
|
33
|
+
<div id="Name">Nyarlathotep (1 bucket)</div>
|
34
|
+
<div id="Bio">Design is how it works.</div>
|
35
|
+
|
36
|
+
|
37
|
+
<ol id="PlayedGames" >
|
38
|
+
|
39
|
+
<li >
|
40
|
+
|
41
|
+
<a href="http://live.xbox.com/en-US/Activity/Details?titleId=1161890110&compareTo=laikal1">
|
42
|
+
<img src="http://tiles.xbox.com/tiles/9a/SL/0mdsb2JhbA9ECgQNGwEfV1wmL2ljb24vMC84MDAwIAAAAAAAAP2kpOo=.jpg" alt="KoA: Reckoning" title="KoA: Reckoning" />
|
43
|
+
<span class="Title">KoA: Reckoning</span>
|
44
|
+
<span class="LastPlayed">3/28/2012</span>
|
45
|
+
<span class="EarnedGamerscore">10</span>
|
46
|
+
<span class="AvailableGamerscore">1300</span>
|
47
|
+
<span class="EarnedAchievements">1</span>
|
48
|
+
<span class="AvailableAchievements">61</span>
|
49
|
+
<span class="PercentageComplete">1%</span>
|
50
|
+
</a>
|
51
|
+
</li>
|
52
|
+
|
53
|
+
<li >
|
54
|
+
|
55
|
+
<a href="http://live.xbox.com/en-US/Activity/Details?titleId=1161890141&compareTo=laikal1">
|
56
|
+
<img src="http://tiles.xbox.com/tiles/np/G2/12dsb2JhbA9ECgQNGwEfV1onL2ljb24vMC84MDAwIAAAAAAAAPiZkYE=.jpg" alt="Mass Effect 3" title="Mass Effect 3" />
|
57
|
+
<span class="Title">Mass Effect 3</span>
|
58
|
+
<span class="LastPlayed">3/27/2012</span>
|
59
|
+
<span class="EarnedGamerscore">1025</span>
|
60
|
+
<span class="AvailableGamerscore">1050</span>
|
61
|
+
<span class="EarnedAchievements">51</span>
|
62
|
+
<span class="AvailableAchievements">52</span>
|
63
|
+
<span class="PercentageComplete">98%</span>
|
64
|
+
</a>
|
65
|
+
</li>
|
66
|
+
|
67
|
+
<li >
|
68
|
+
|
69
|
+
<a href="http://live.xbox.com/en-US/Activity/Details?titleId=1161890083&compareTo=laikal1">
|
70
|
+
<img src="http://tiles.xbox.com/tiles/WQ/nz/0Wdsb2JhbA9ECgQNGwEfV11QL2ljb24vMC84MDAwIAAAAAAAAP7cCUY=.jpg" alt="Syndicate" title="Syndicate" />
|
71
|
+
<span class="Title">Syndicate</span>
|
72
|
+
<span class="LastPlayed">3/11/2012</span>
|
73
|
+
<span class="EarnedGamerscore">530</span>
|
74
|
+
<span class="AvailableGamerscore">1000</span>
|
75
|
+
<span class="EarnedAchievements">33</span>
|
76
|
+
<span class="AvailableAchievements">50</span>
|
77
|
+
<span class="PercentageComplete">66%</span>
|
78
|
+
</a>
|
79
|
+
</li>
|
80
|
+
|
81
|
+
<li class="Complete" >
|
82
|
+
|
83
|
+
<a href="http://live.xbox.com/en-US/Activity/Details?titleId=1414793176&compareTo=laikal1">
|
84
|
+
<img src="http://tiles.xbox.com/tiles/fc/qf/0Wdsb2JhbA9ECgUMGgQfWStbL2ljb24vMC84MDAwIAAAAAAAAP6wymI=.jpg" alt="BioShock" title="BioShock" />
|
85
|
+
<span class="Title">BioShock</span>
|
86
|
+
<span class="LastPlayed">2/24/2012</span>
|
87
|
+
<span class="EarnedGamerscore">1100</span>
|
88
|
+
<span class="AvailableGamerscore">1100</span>
|
89
|
+
<span class="EarnedAchievements">51</span>
|
90
|
+
<span class="AvailableAchievements">51</span>
|
91
|
+
<span class="PercentageComplete">100%</span>
|
92
|
+
</a>
|
93
|
+
</li>
|
94
|
+
|
95
|
+
<li >
|
96
|
+
|
97
|
+
<a href="http://live.xbox.com/en-US/Activity/Details?titleId=1112737766&compareTo=laikal1">
|
98
|
+
<img src="http://tiles.xbox.com/tiles/qR/QI/1Gdsb2JhbA9ECgQKGgMfWSpVL2ljb24vMC84MDAwIAAAAAAAAPsnFLY=.jpg" alt="Skyrim" title="Skyrim" />
|
99
|
+
<span class="Title">Skyrim</span>
|
100
|
+
<span class="LastPlayed">2/14/2012</span>
|
101
|
+
<span class="EarnedGamerscore">910</span>
|
102
|
+
<span class="AvailableGamerscore">1000</span>
|
103
|
+
<span class="EarnedAchievements">47</span>
|
104
|
+
<span class="AvailableAchievements">50</span>
|
105
|
+
<span class="PercentageComplete">94%</span>
|
106
|
+
</a>
|
107
|
+
</li>
|
108
|
+
|
109
|
+
</ol>
|
110
|
+
</div>
|
111
|
+
|
112
|
+
</body>
|
113
|
+
</html>
|
@@ -0,0 +1,122 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Gamercard
|
4
|
+
describe "CardParser" do
|
5
|
+
let(:mock_response) { mock(:body => File.read("spec/fixtures/laikal1.html")) }
|
6
|
+
let(:parser) { CardParser.new mock_response }
|
7
|
+
let(:doc) { Nokogiri::HTML(mock_response.body) }
|
8
|
+
|
9
|
+
def nokogirize html
|
10
|
+
Nokogiri::HTML(html)
|
11
|
+
end
|
12
|
+
|
13
|
+
describe ".parse" do
|
14
|
+
it "returns a hash representing a parsed gamercard" do
|
15
|
+
result = CardParser.parse mock_response
|
16
|
+
result['gamertag'].should == 'laikal1'
|
17
|
+
result['gamerpic'].should == 'http://avatar.xboxlive.com/avatar/laikal1/avatarpic-l.png'
|
18
|
+
result['gamerscore'].should == 49646
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
describe "attributes" do
|
23
|
+
it "takes one required parameter, viz the http response from the card service" do
|
24
|
+
parser = CardParser.new mock_response
|
25
|
+
parser.raw_response.should == mock_response
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe "#parse" do
|
30
|
+
it "chops the html up neatly" do
|
31
|
+
result = parser.parse
|
32
|
+
result['gamertag'].should == 'laikal1'
|
33
|
+
result['gamerpic'].should == 'http://avatar.xboxlive.com/avatar/laikal1/avatarpic-l.png'
|
34
|
+
result['gamerscore'].should == 49646
|
35
|
+
result['recent_games'].size.should == 5
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "#count_reputation" do
|
40
|
+
it "returns laikal1's rep as 4.25" do
|
41
|
+
count = parser.count_reputation(doc).should == 4.25
|
42
|
+
end
|
43
|
+
it "counts the number of Full, Half, ThreeQuarter, and Quarter .Star elements in the .RepContainer" do
|
44
|
+
doc1 = <<-DOC1
|
45
|
+
<div class="RepContainer">
|
46
|
+
<label>Rep</label>
|
47
|
+
<div class="Star Full"></div>
|
48
|
+
<div class="Star Full"></div>
|
49
|
+
<div class="Star Full"></div>
|
50
|
+
<div class="Star ThreeQuarter"></div>
|
51
|
+
<div class="Star Empty"></div>
|
52
|
+
</div>
|
53
|
+
DOC1
|
54
|
+
parser.count_reputation(nokogirize(doc1)).should == 3.75
|
55
|
+
|
56
|
+
doc2 = <<-DOC2
|
57
|
+
<div class="RepContainer">
|
58
|
+
<label>Rep</label>
|
59
|
+
<div class="Star Full"></div>
|
60
|
+
<div class="Star Full"></div>
|
61
|
+
<div class="Star Half"></div>
|
62
|
+
<div class="Star Empty"></div>
|
63
|
+
<div class="Star Empty"></div>
|
64
|
+
</div>
|
65
|
+
DOC2
|
66
|
+
parser.count_reputation(nokogirize(doc2)).should == 2.5
|
67
|
+
|
68
|
+
doc3 = <<-DOC3
|
69
|
+
<div class="RepContainer">
|
70
|
+
<label>Rep</label>
|
71
|
+
<div class="Star Full"></div>
|
72
|
+
<div class="Star Empty"></div>
|
73
|
+
<div class="Star Half"></div>
|
74
|
+
<div class="Star Quarter"></div>
|
75
|
+
<div class="Star Empty"></div>
|
76
|
+
</div>
|
77
|
+
DOC3
|
78
|
+
parser.count_reputation(nokogirize(doc3)).should == 1.75
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "#summarize_games" do
|
83
|
+
it "returns an array of game summaries" do
|
84
|
+
games = parser.summarize_games(doc)
|
85
|
+
games.should be_a_kind_of(Array)
|
86
|
+
games.size.should == 5
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe "#summarize" do
|
91
|
+
it "returns a hash of parsed values" do
|
92
|
+
game = <<-DOC
|
93
|
+
<li >
|
94
|
+
<a href="http://live.xbox.com/en-US/Activity/Details?titleId=1161890110&compareTo=laikal1">
|
95
|
+
<img src="http://tiles.xbox.com/tiles/9a/SL/0mdsb2JhbA9ECgQNGwEfV1wmL2ljb24vMC84MDAwIAAAAAAAAP2kpOo=.jpg" alt="KoA: Reckoning" title="KoA: Reckoning" />
|
96
|
+
<span class="Title">KoA: Reckoning</span>
|
97
|
+
<span class="LastPlayed">3/28/2012</span>
|
98
|
+
<span class="EarnedGamerscore">10</span>
|
99
|
+
<span class="AvailableGamerscore">1300</span>
|
100
|
+
<span class="EarnedAchievements">1</span>
|
101
|
+
<span class="AvailableAchievements">61</span>
|
102
|
+
<span class="PercentageComplete">1%</span>
|
103
|
+
</a>
|
104
|
+
</li>
|
105
|
+
DOC
|
106
|
+
result = parser.summarize(nokogirize(game))
|
107
|
+
result.should == {
|
108
|
+
"comparison_url" => "http://live.xbox.com/en-US/Activity/Details?titleId=1161890110&compareTo=laikal1",
|
109
|
+
"image" => "http://tiles.xbox.com/tiles/9a/SL/0mdsb2JhbA9ECgQNGwEfV1wmL2ljb24vMC84MDAwIAAAAAAAAP2kpOo=.jpg",
|
110
|
+
"title" => "KoA: Reckoning",
|
111
|
+
"last_played" => "3/28/2012",
|
112
|
+
"earned_gamerscore" => 10,
|
113
|
+
"available_gamerscore" => 1300,
|
114
|
+
"earned_achievements" => 1,
|
115
|
+
"available_achievements" => 61,
|
116
|
+
"percentage_complete" => "1%"
|
117
|
+
}
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module Gamercard
|
4
|
+
describe "Client" do
|
5
|
+
let(:client) { Client.new("laikal1") }
|
6
|
+
|
7
|
+
it "should be loaded correctly" do
|
8
|
+
lambda { Gamercard::Client }.should_not raise_error
|
9
|
+
end
|
10
|
+
|
11
|
+
it "takes the gamertag as the only input parameter" do
|
12
|
+
client.gamertag.should == "laikal1"
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "#fetch" do
|
16
|
+
it "should return a hash of useful values" do
|
17
|
+
VCR.use_cassette('fetch_laikal1', :record => :new_episodes) do
|
18
|
+
response = client.fetch
|
19
|
+
response['gamertag'].should == 'laikal1'
|
20
|
+
response['gamerpic'].should == 'http://avatar.xboxlive.com/avatar/laikal1/avatarpic-l.png'
|
21
|
+
response['gamerscore'].should == 49646
|
22
|
+
response['recent_games'].size.should == 5
|
23
|
+
end
|
24
|
+
end
|
25
|
+
it "should return the raw response if there is a problem with the response" do
|
26
|
+
client.stub!(:connection).and_return(
|
27
|
+
Faraday.new do |builder|
|
28
|
+
builder.adapter :test do |stub|
|
29
|
+
stub.get('laikal1.card') {[ 500, {}, 'Oh Noes! I blew it up!' ]}
|
30
|
+
end
|
31
|
+
end
|
32
|
+
)
|
33
|
+
VCR.turned_off do
|
34
|
+
response = client.fetch
|
35
|
+
response.status.should == 500
|
36
|
+
response.body.should == 'Oh Noes! I blew it up!'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "#fetch_with_redirect" do
|
42
|
+
it "follows the redirect like a boss" do
|
43
|
+
VCR.use_cassette('fetch_laikal1', :record => :new_episodes) do
|
44
|
+
response = client.fetch_with_redirect
|
45
|
+
response.status.should == 200
|
46
|
+
response.body[0, 16].should == "\r\n<!DOCTYPE html"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
describe "#connection" do
|
52
|
+
it "returns a Faraday connection, using the configured http library, to the gamercard url" do
|
53
|
+
conn = client.send(:connection)
|
54
|
+
conn.host.should == Client::GAMERCARD_SERVICE_URL.sub("http://", "")
|
55
|
+
conn.builder.handlers.should include(Faraday::Adapter::Typhoeus)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "#build_url" do
|
60
|
+
it "returns the portion of the URL that generates the card for the given gamertag" do
|
61
|
+
client.build_url.should == "laikal1.card"
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe "#parse" do
|
66
|
+
it "delegates to a CardParser object" do
|
67
|
+
CardParser.should_receive(:parse).with("foo").and_return({ "gamertag" => "laikal1" })
|
68
|
+
client.parse "foo"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Gamercard do
|
4
|
+
it "should be configurable" do
|
5
|
+
Gamercard.should respond_to(:configure)
|
6
|
+
end
|
7
|
+
|
8
|
+
it "has a sensible default for .adapter" do
|
9
|
+
Gamercard.adapter.should == :typhoeus
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#get" do
|
13
|
+
it "is a shortcut to Client#fetch" do
|
14
|
+
Gamercard::Client.should_receive(:new).and_return(mock(:fetch => "OK."))
|
15
|
+
Gamercard.get("foo").should == "OK."
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
|
4
|
+
require 'gamercard' # and any other gems you need
|
5
|
+
require 'vcr'
|
6
|
+
|
7
|
+
RSpec.configure do |c|
|
8
|
+
c.extend VCR::RSpec::Macros
|
9
|
+
end
|
10
|
+
|
11
|
+
VCR.configure do |c|
|
12
|
+
c.cassette_library_dir = 'spec/fixtures'
|
13
|
+
c.hook_into :faraday
|
14
|
+
end
|
15
|
+
|
16
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
17
|
+
RSpec.configure do |config|
|
18
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
19
|
+
# config.run_all_when_everything_filtered = true
|
20
|
+
# config.filter_run :focus
|
21
|
+
end
|
metadata
ADDED
@@ -0,0 +1,148 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gamercard
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Matt Wilson
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-04-02 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rake
|
16
|
+
requirement: &2152009940 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *2152009940
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: rspec
|
27
|
+
requirement: &2152009460 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *2152009460
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: typhoeus
|
38
|
+
requirement: &2152008860 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *2152008860
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: vcr
|
49
|
+
requirement: &2152008300 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *2152008300
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: fakeweb
|
60
|
+
requirement: &2152007700 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *2152007700
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: nokogiri
|
71
|
+
requirement: &2152007120 !ruby/object:Gem::Requirement
|
72
|
+
none: false
|
73
|
+
requirements:
|
74
|
+
- - ! '>='
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: *2152007120
|
80
|
+
- !ruby/object:Gem::Dependency
|
81
|
+
name: faraday
|
82
|
+
requirement: &2152006420 !ruby/object:Gem::Requirement
|
83
|
+
none: false
|
84
|
+
requirements:
|
85
|
+
- - ! '>='
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: 0.8.0.rc2
|
88
|
+
type: :runtime
|
89
|
+
prerelease: false
|
90
|
+
version_requirements: *2152006420
|
91
|
+
description: A Simple & Straightforward XBox Live Gamercard parser.
|
92
|
+
email:
|
93
|
+
- mhw@hypomodern.com
|
94
|
+
executables: []
|
95
|
+
extensions: []
|
96
|
+
extra_rdoc_files: []
|
97
|
+
files:
|
98
|
+
- .gitignore
|
99
|
+
- .rspec
|
100
|
+
- .rvmrc
|
101
|
+
- Gemfile
|
102
|
+
- Guardfile
|
103
|
+
- LICENSE
|
104
|
+
- README.md
|
105
|
+
- Rakefile
|
106
|
+
- gamercard.gemspec
|
107
|
+
- lib/gamercard.rb
|
108
|
+
- lib/gamercard/card_parser.rb
|
109
|
+
- lib/gamercard/client.rb
|
110
|
+
- lib/gamercard/configuration.rb
|
111
|
+
- lib/gamercard/version.rb
|
112
|
+
- spec/fixtures/fetch_laikal1.yml
|
113
|
+
- spec/fixtures/laikal1.html
|
114
|
+
- spec/gamercard/card_parser_spec.rb
|
115
|
+
- spec/gamercard/client_spec.rb
|
116
|
+
- spec/gamercard_spec.rb
|
117
|
+
- spec/spec_helper.rb
|
118
|
+
homepage: https://github.com/hypomodern/gamercard
|
119
|
+
licenses: []
|
120
|
+
post_install_message:
|
121
|
+
rdoc_options: []
|
122
|
+
require_paths:
|
123
|
+
- lib
|
124
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
125
|
+
none: false
|
126
|
+
requirements:
|
127
|
+
- - ! '>='
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: '0'
|
130
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
131
|
+
none: false
|
132
|
+
requirements:
|
133
|
+
- - ! '>='
|
134
|
+
- !ruby/object:Gem::Version
|
135
|
+
version: '0'
|
136
|
+
requirements: []
|
137
|
+
rubyforge_project:
|
138
|
+
rubygems_version: 1.8.17
|
139
|
+
signing_key:
|
140
|
+
specification_version: 3
|
141
|
+
summary: A Simple & Straightforward XBox Live Gamercard parser.
|
142
|
+
test_files:
|
143
|
+
- spec/fixtures/fetch_laikal1.yml
|
144
|
+
- spec/fixtures/laikal1.html
|
145
|
+
- spec/gamercard/card_parser_spec.rb
|
146
|
+
- spec/gamercard/client_spec.rb
|
147
|
+
- spec/gamercard_spec.rb
|
148
|
+
- spec/spec_helper.rb
|