File Coverage

blib/lib/WWW/RobotRules/Parser.pm
Criterion Covered Total %
statement 45 55 81.8
branch 24 30 80.0
condition n/a
subroutine 7 8 87.5
pod 3 3 100.0
total 79 96 82.2


line stmt bran cond sub pod time code
1             # $Id: /mirror/perl/WWW-RobotRules-Parser/trunk/lib/WWW/RobotRules/Parser.pm 31629 2007-12-01T13:31:37.690053Z daisuke $
2             #
3             # Copyright (c) 2006-2007 Daisuke Maki
4             # A lot of this code is based on WWW::RobotRules.
5              
6             package WWW::RobotRules::Parser;
7 2     2   57062 use strict;
  2         4  
  2         138  
8 2     2   11 use warnings;
  2         4  
  2         57  
9 2     2   10 use vars qw($VERSION);
  2         7  
  2         104  
10 2     2   1983 use URI;
  2         15919  
  2         74  
11              
12             BEGIN
13             {
14 2     2   1109 $VERSION = '0.04001';
15             }
16              
17 6     6 1 4162 sub new { bless { }, shift }
18              
19             sub parse_uri
20             {
21 0     0 1 0 my $self = shift;
22 0         0 my $uri = shift;
23              
24 0         0 require LWP::UserAgent;
25 0         0 my $ua = LWP::UserAgent->new;
26 0         0 my $res = $ua->get($uri);
27              
28 0 0       0 if (! $res->is_success) {
29 0         0 require Carp;
30 0         0 Carp::croak("Failed to retrieve $uri: Got HTTP code " . $res->code);
31             }
32            
33 0         0 $self->parse($uri, $res->content);
34             }
35              
36             sub parse
37             {
38 6     6 1 27 my $self = shift;
39 6         11 my $robot_txt_uri = shift;
40 6         8 my $text = shift;
41              
42 6 50       35 $robot_txt_uri = URI->new($robot_txt_uri) if ($robot_txt_uri);
43              
44 6         11025 my %result;
45             # blank lines are significant, so turn CRLF into LF to avoid generating
46             # false ones
47 6         16 $text =~ s/\015\012/\012/g;
48              
49 6         7 my $ua_pattern;
50             # split at \012 or \015
51 6         52 for (split(/[\012\015]/, $text)) {
52             # Lines containing only a comment are discarded completely, and
53             # therefore do not indicate a record boundary
54 50 100       119 next if /^\s*\#/;
55              
56 39         47 s/\s*\#.*//; # Remove comments at end-of-line
57              
58 39 100       157 if (/^\s*User-Agent\s*:\s*(.*)/i) {
    100          
59 14         22 $ua_pattern = $1;
60 14         28 $ua_pattern =~ s/\s+$//;
61             } elsif (/^\s*Disallow\s*:\s*(.*)/i) {
62 19 50       36 if (! defined $ua_pattern) {
63 0         0 $ua_pattern = '*';
64             }
65              
66 19         30 my $disallow = $1;
67 19         22 $disallow =~ s/\s+$//;
68 19 100       45 if (length $disallow) {
69 16 50       163 if ($robot_txt_uri) {
70 16         104 my $ignore;
71 16         17 eval {
72 16         53 my $u = URI->new_abs($disallow, $robot_txt_uri);
73 16 100       7062 $ignore++ if $u->scheme ne $robot_txt_uri->scheme;
74 16 100       415 $ignore++ if lc($u->host) ne lc($robot_txt_uri->host);
75 15 100       548 $ignore++ if $u->port ne $robot_txt_uri->port;
76 15         603 $disallow = $u->path_query;
77 15 100       151 $disallow = "/" unless length $disallow;
78             };
79 16 100       40 next if $@;
80 15 100       33 next if $ignore;
81             }
82 11         17 push @{$result{$ua_pattern}}, $disallow;
  11         110  
83             }
84             }
85             }
86 6 50       49 return wantarray ? %result : \%result
87             }
88              
89             1;
90              
91             __END__