File Coverage

blib/lib/Chess/FIDE.pm
Criterion Covered Total %
statement 126 130 96.9
branch 29 36 80.5
condition 1 3 33.3
subroutine 17 17 100.0
pod 1 6 16.6
total 174 192 90.6


line stmt bran cond sub pod time code
1             package Chess::FIDE;
2              
3 2     2   7628 use 5.008;
  2         7  
  2         325  
4 2     2   11 use strict;
  2         5  
  2         76  
5 2     2   10 use warnings FATAL => 'all';
  2         4  
  2         92  
6              
7 2     2   10 use Exporter;
  2         10  
  2         77  
8 2     2   11 use Carp;
  2         7  
  2         378  
9 2     2   7006 use LWP::UserAgent;
  2         135283  
  2         101  
10 2     2   2882 use IO::File;
  2         25289  
  2         343  
11 2     2   2534 use IO::String;
  2         5417  
  2         82  
12 2     2   4534 use Archive::Zip qw( :ERROR_CODES :CONSTANTS );
  2         153617  
  2         458  
13 2     2   1591 use Archive::Zip::MemberRead;
  2         2916  
  2         63  
14              
15 2     2   589 use Chess::FIDE::Player qw(@FIDE_field);
  2         4  
  2         3162  
16              
17             our @ISA = qw(Exporter);
18              
19             our $VERSION = '1.12';
20              
21             my $data_offsets = [
22             [qw(title 45)],
23             [qw(federation 49)],
24             [qw(rating 54)],
25             [qw(games 59)],
26             [qw(year 65)],
27             [qw(flags 70)],
28             ];
29              
30             our $DATA_URL = 'http://ratings.fide.com/download/players_list.zip';
31              
32             sub new ($;@) {
33              
34 4     4 0 5311646 my $self = shift;
35 4   33     13076 my $class = ref($self) || $self;
36 4         36 my %param = @_;
37              
38 4         11 my $fide = [];
39 4         11 my $line;
40              
41 4         13 bless $fide,$class;
42 4 100       8504 if ($param{-file}) {
    100          
43 1         11 my $fh = IO::File->new($param{-file},'r');
44 1 50       140 if (defined $fh) {
45 1         18 $fide->parseFile($fh);
46             }
47             else {
48 0         0 warn "$!: $param{-file}\n";
49 0         0 return {};
50             }
51             }
52             elsif ($param{-www}) {
53 2         3124 my $ua = LWP::UserAgent->new();
54 2 50       141667 $ua->proxy(['http'],$param{-proxy}) if $param{-proxy};
55 2         4094 my $response = $ua->get($DATA_URL);
56 2         19124976 my $webcontent;
57 2 100       1960 if ($response->is_success) {
58 1         25 $webcontent = $response->content();
59             }
60             else {
61 1         304 warn "Cannot download playerfile: Check your network connection\n";
62 1         80 return 0;
63             }
64 1 50       15260 my $fh = IO::String->new(\$webcontent) or die "BLAAAH\n";
65 1         109 my $zip = Archive::Zip->new();
66 1         63 my $status = $zip->readFromFileHandle($fh);
67 1 50       885 unless ($status == AZ_OK) {
68 0         0 warn "Problems unzipping the downloaded file";
69 0         0 return 0;
70             }
71 1         3 my $membername;
72 1         6 for $membername ($zip->memberNames()) {
73 1         29 my $fh2 = Archive::Zip::MemberRead->new($zip, $membername);
74 1 50       857 return 0 unless defined $fh2;
75 1         8 $fide->parseFile($fh2);
76             }
77 1         70117 $fh->close();
78             }
79             else {
80 1         48 warn "No source (-file or -www) given";
81             }
82 3         387605 return $fide;
83             }
84              
85             sub parseFile ($$) {
86              
87 2     2 0 85 my $fide = shift;
88 2         4 my $fh = shift;
89              
90 2         6 my $line;
91 2         60 while (defined($line = $fh->getline())) {
92 472438 100       44968736 next unless $line =~ /^\s*\d/;
93 472435         1018400 my $player = $fide->parseLine($line);
94 472435 50       1181521 push(@{$fide}, $player) if $player;
  472435         1957569  
95             }
96 2         10333 $fh->close();
97             }
98              
99             sub parseIdAndName ($$) {
100              
101 472435     472435 0 554032 my $self = shift;
102 472435         562525 my $id_and_name = shift;
103              
104 472435         3135019 my ($id, $givenname, $surname) =
105             ($id_and_name =~ /^\s*(\d+)\s+(.*?)\,?\s+(\S+|\S+\s+\S+)/);
106              
107 472435 100       1940141 if ($id_and_name =~ /\S\,\s*\S/) {
108 435336         585827 my $tmp = $surname;
109 435336         466612 $surname = $givenname;
110 435336         553372 $givenname = $tmp;
111             }
112 472435         766005 $givenname =~ s/^\s+//;
113 472435         715913 $givenname =~ s/\s+$//;
114 472435         681593 $surname =~ s/^\s+//;
115 472435         566795 $surname =~ s/\s+$//;
116 472435 100       1381039 my $name =
    100          
117             !$givenname ? $surname : !$surname ? $givenname : "$givenname $surname";
118              
119 472435         1510713 return ($id, $name, $givenname, $surname);
120             }
121              
122             sub parseRest ($$){
123              
124 472435     472435 0 524341 my $self = shift;
125 472435         606415 my $rest = shift;
126              
127 472435         667564 my %data = ();
128              
129 472435         707580 my $start_offset = $data_offsets->[0][1];
130 472435         473434 for my $i (0..$#{$data_offsets}) {
  472435         1100860  
131 2830331         4503921 my $offset = $data_offsets->[$i][1] - $start_offset;
132 2830331 100       2784785 my $d_offset = $i == $#{$data_offsets} ?
  2830331         6841417  
133             "" : $data_offsets->[$i+1][1] - $data_offsets->[$i][1];
134 2830331 100       5968054 last if $offset > length($rest);
135 2822667 100       3097228 if ($i == $#{$data_offsets}) {
  2822667         5011617  
136 464771         3734537 $data{$data_offsets->[$i][0]} = substr($rest, $offset);
137             }
138             else {
139 2357896         16927675 $data{$data_offsets->[$i][0]} = substr(
140             $rest, $offset,
141             $data_offsets->[$i+1][1] - $data_offsets->[$i][1]
142             );
143             }
144 2822667         29112021 $data{$data_offsets->[$i][0]} =~ s/\s//g;
145             }
146 472435         25766012 return %data;
147             }
148              
149             sub parseLine ($$) {
150              
151 472435     472435 0 608662 my $self = shift;
152 472435         638524 my $line = shift;
153              
154 472435         833026 chomp $line;
155 472435         2933633 $line =~ s/\s+$//;
156 472435         1359440 my $id_and_name = substr($line, 0, $data_offsets->[0][1] - 1);
157 472435         850522 my $rest = substr($line, $data_offsets->[0][1] - 1);
158 472435         920715 my ($id, $name, $givenname, $surname) = $self->parseIdAndName($id_and_name);
159 472435         1658618 my $player = Chess::FIDE::Player->new(
160             id => $id,
161             name => $name,
162             givenname => $givenname,
163             surname => $surname,
164             );
165 472435         1073058 my %rest = $self->parseRest($rest);
166 472435         1476769 for my $field (keys %rest) {
167 2822667         12159889 $player->$field($rest{$field});
168             }
169              
170 472435         2068492 return $player;
171             }
172              
173             sub fideSearch {
174              
175 2     2 1 1195 my $fide = shift;
176 2         6 my $criteria = shift;
177              
178 2         4 my $found = 0;
179 2         7 for my $field (@FIDE_field) {
180 3 100       71 if ($criteria =~ /^$field /) {
181 2         33 $criteria =~ s/^($field)/'$_->{'.$field.'}'/ge;
  2         10  
182 2         5 $found = 1;
183 2         3 last;
184             }
185             }
186 2 50       9 die "Invalid criteria supplied" unless $found;
187 2         4 my @player = grep(eval $criteria, @{$fide});
  2         363  
188 2         15 return @player;
189             }
190              
191             1;
192             __END__