File Coverage

blib/lib/WWW/XBoxLive.pm
Criterion Covered Total %
statement 75 75 100.0
branch 8 10 80.0
condition 4 4 100.0
subroutine 12 12 100.0
pod 2 2 100.0
total 101 103 98.0


line stmt bran cond sub pod time code
1 2     2   418642 use strict;
  2         6  
  2         102  
2 2     2   12 use warnings;
  2         3  
  2         154  
3              
4             package WWW::XBoxLive;
5             {
6             $WWW::XBoxLive::VERSION = '1.123160';
7             }
8              
9             # ABSTRACT: Get XBox Live Gamercard information
10              
11 2     2   1658 use WWW::XBoxLive::Gamercard;
  2         6  
  2         19  
12 2     2   1171 use WWW::XBoxLive::Game;
  2         6  
  2         15  
13              
14 2     2   1753 use LWP::Simple ();
  2         98163  
  2         65  
15 2     2   2791 use HTML::TreeBuilder::XPath ();
  2         220086  
  2         104  
16              
17             # the gamercard url
18 2     2   28 use constant GAMERCARD_URL => 'http://gamercard.xbox.com/%s/%s.card';
  2         5  
  2         159  
19              
20             # if a user has this avatar, they are not a user
21 2         1636 use constant INVALID_AVATAR =>
22 2     2   12 'http://image.xboxlive.com//global/t.FFFE07D1/tile/0/20000';
  2         123  
23              
24              
25             sub new {
26 3     3 1 12555 my $class = shift;
27 3   100     23 my $args = shift || {};
28 3         6 my $self = {};
29              
30 3         7 bless( $self, $class );
31              
32 3   100     27 $self->{region} = $args->{region} || 'en-US';
33              
34 3         10 return $self;
35             }
36              
37              
38             sub get_gamercard {
39 1     1 1 850 my ( $this, $gamertag ) = @_;
40              
41             # get the html
42 1         35 my $html =
43             LWP::Simple::get( sprintf( GAMERCARD_URL, $this->{region}, $gamertag ) );
44              
45             # parse
46 1         231072 my $gamercard = $this->_parse_gamercard($html);
47              
48 1         7 return $gamercard;
49             }
50              
51             # parse the HTML
52             sub _parse_gamercard {
53 4     4   16083 my ( $this, $html ) = @_;
54              
55             # generate HTML tree
56 4         76 my $tree = HTML::TreeBuilder::XPath->new_from_content($html);
57              
58             # get the gamertag
59 4         80854 my $gamertag = _trimWhitespace( $tree->findvalue('//title') );
60              
61             # is valid? If not, then skip everything else
62 4         19 my $gamerpic = $tree->findvalue('//img[@id="Gamerpic"]/@src');
63 4 100       55600 if ( $gamerpic eq INVALID_AVATAR ) {
64 1         11 return WWW::XBoxLive::Gamercard->new(
65             gamertag => $gamertag,
66             is_valid => 0,
67             );
68             }
69              
70 3         18 my $bio = _trimWhitespace( $tree->findvalue('//div[@id="Bio"]') );
71 3         17 my $gamerscore =
72             _trimWhitespace( $tree->findvalue('//div[@id="Gamerscore"]') );
73 3         19 my $motto = _trimWhitespace( $tree->findvalue('//div[@id="Motto"]') );
74 3         34 my $location = _trimWhitespace( $tree->findvalue('//div[@id="Location"]') );
75 3         21 my $name = _trimWhitespace( $tree->findvalue('//div[@id="Name"]') );
76 3         18 my $profile_link = $tree->findvalue('//a[@id="Gamertag"]/@href');
77              
78             # guess account status
79 3         63847 my $account_status = 'unknown';
80 3 100       41 if ( $tree->exists('//body/div[@class=~ /Gold/]') ) {
    50          
81 2         16592 $account_status = 'gold';
82             }
83             elsif ( $tree->exists('//body/div[@class=~ /Silver/]') ) {
84 1         14257 $account_status = 'silver';
85             }
86              
87             # find gender
88 3         10 my $gender = 'unknown';
89 3 100       15 if ( $tree->exists('//body/div[@class=~ /Male/]') ) {
    50          
90 2         12553 $gender = 'male';
91             }
92             elsif ( $tree->exists('//body/div[@class=~ /Female/]') ) {
93 1         11950 $gender = 'female';
94             }
95              
96             # count the reputation stars
97 3         34 my @reputation_stars =
98             $tree->findnodes('//div[@class="RepContainer"]/div[@class="Star Full"]');
99 3         61185 my $reputation = scalar @reputation_stars;
100              
101             # games
102 3         8 my @recent_games;
103 3         6 my $i = 1;
104 3         31 while (
105             my $title = $tree->findvalue(
106             '//ol[@id="PlayedGames"]/li[' . $i . ']/a/span[@class="Title"]'
107             )
108             )
109             {
110 12         253252 my $last_played =
111             $tree->findvalue( '//ol[@id="PlayedGames"]/li['
112             . $i
113             . ']/a/span[@class="LastPlayed"]' );
114 12         278672 my $earned_gamerscore =
115             $tree->findvalue( '//ol[@id="PlayedGames"]/li['
116             . $i
117             . ']/a/span[@class="EarnedGamerscore"]' );
118 12         293737 my $available_gamerscore =
119             $tree->findvalue( '//ol[@id="PlayedGames"]/li['
120             . $i
121             . ']/a/span[@class="AvailableGamerscore"]' );
122 12         292276 my $earned_achievements =
123             $tree->findvalue( '//ol[@id="PlayedGames"]/li['
124             . $i
125             . ']/a/span[@class="EarnedAchievements"]' );
126 12         284353 my $available_achievements =
127             $tree->findvalue( '//ol[@id="PlayedGames"]/li['
128             . $i
129             . ']/a/span[@class="AvailableAchievements"]' );
130 12         277860 my $percentage_complete =
131             $tree->findvalue( '//ol[@id="PlayedGames"]/li['
132             . $i
133             . ']/a/span[@class="PercentageComplete"]' );
134              
135 12         268782 my $game = WWW::XBoxLive::Game->new(
136             available_achievements => $available_achievements,
137             available_gamerscore => $available_gamerscore,
138             earned_achievements => $earned_achievements,
139             earned_gamerscore => $earned_gamerscore,
140             last_played => $last_played,
141             percentage_complete => $percentage_complete,
142             title => $title,
143             );
144              
145 12         211 push @recent_games, $game;
146 12         102 $i++;
147             }
148              
149             # to ensure we do not have memory leaks
150 3         53942 $tree->delete;
151              
152             # create new gamercard
153 3         2753 my $gamercard = WWW::XBoxLive::Gamercard->new(
154             account_status => $account_status,
155             bio => $bio,
156             gamerscore => $gamerscore,
157             gamertag => $gamertag,
158             gender => $gender,
159             is_valid => 1,
160             location => $location,
161             motto => $motto,
162             name => $name,
163             profile_link => $profile_link,
164             recent_games => \@recent_games,
165             reputation => $reputation,
166             );
167              
168 3         195 return $gamercard;
169             }
170              
171             # trims whitespace from a string
172             sub _trimWhitespace {
173 19     19   302265 my $string = shift;
174 19         113 $string =~ s/^\s+//;
175 19         82 $string =~ s/\s+$//;
176 19         56 return $string;
177             }
178              
179             1;
180              
181              
182             __END__