File Coverage

blib/lib/WWW/Leech/Walker.pm
Criterion Covered Total %
statement 23 82 28.0
branch 0 20 0.0
condition 0 2 0.0
subroutine 7 12 58.3
pod 4 4 100.0
total 34 120 28.3


line stmt bran cond sub pod time code
1             package WWW::Leech::Walker;
2 1     1   13124 use strict;
  1         2  
  1         24  
3 1     1   393 use LWP;
  1         34671  
  1         32  
4 1     1   374 use URI::URL;
  1         2589  
  1         44  
5 1     1   375 use WWW::Leech::Parser;
  1         54483  
  1         45  
6              
7             BEGIN {
8 1     1   7 use Exporter ();
  1         2  
  1         17  
9 1     1   5 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
  1         2  
  1         66  
10 1     1   3 $VERSION = '0.01';
11 1         8 @ISA = qw(Exporter);
12 1         3 @EXPORT = qw();
13 1         5 @EXPORT_OK = qw();
14 1         453 %EXPORT_TAGS = ();
15             }
16              
17             sub new{
18 0     0 1   my $class = shift;
19 0           my $this = shift;
20              
21 0           $this->{'url'} = url $this->{'url'};
22 0   0       $this->{'state'} ||= {};
23            
24 0           $this->{'_stop_flag'} = undef;
25              
26 0           $this = bless $this, __PACKAGE__;
27              
28 0           $this->{'parser'} = new WWW::Leech::Parser($this->{'parser'});
29            
30 0           return $this;
31             }
32              
33             sub leech{
34 0     0 1   my $this = shift;
35 0           $this->{'_stop_flag'} = undef;
36              
37 0           my $current_url = $this->{'url'};
38              
39 0           while(1){
40              
41 0           $this->log("Getting links list: $current_url ");
42              
43             # get and parse link list
44 0           my $data = $this->_get($current_url);
45              
46 0           my $parse_result = $this->{'parser'}->parseList($data);
47              
48 0           my $links = [map { url($_, $this->{'url'})->abs } @{$parse_result->{'links'}}];
  0            
  0            
49              
50 0           $this->log("Links list length: ".scalar(@$links));
51              
52 0 0         if(scalar(@$links) == 0){
53 0           $this->log("No items links found, check your XPath: ".$this->{'parser'}->{'item:link'});
54              
55 0           $this->stop();
56 0           return;
57             }
58              
59             # filtering if required
60 0 0         if( $this->{'filter'} ){
61 0           $this->log("Filtering links");
62 0           $links = $this->{'filter'}->($links,$this);
63 0           $this->log("Filtered links list length: ".scalar(@$links));
64              
65 0 0         return if($this->{'_stop_flag'});
66             }
67              
68             # get and parse individual items
69 0           foreach(@$links){
70 0           $this->log("\tGetting item: $_ ");
71              
72 0           my $item = $this->{'parser'}->parse($this->_get($_));
73 0           $item->{'_url'} = $_->as_string;
74              
75 0           $this->{'processor'}->($item,$this);
76              
77 0 0         return if($this->{'_stop_flag'});
78             }
79              
80 0 0         if($parse_result->{'next_page'}){
81              
82 0           my $pnurl;
83              
84 0 0         if($this->{'next_page_link_post_process'}){
85 0           $pnurl = $this->{'next_page_link_post_process'}->($parse_result->{'next_page'}, $this, $current_url);
86             }
87              
88 0 0         if($pnurl){
89 0           $current_url = url($pnurl)->abs;
90             } else {
91 0           $current_url = url($parse_result->{'next_page'}, $this->{'url'})->abs;
92             }
93              
94 0 0         return if($this->{'_stop_flag'});
95              
96             } else {
97 0           $this->stop("No next page link found");
98 0           return;
99             }
100             }
101              
102            
103             }
104              
105             sub log{
106 0     0 1   my $this = shift;
107 0           my $message = shift;
108              
109 0 0         if($this->{'logger'}){
110 0           $this->{'logger'}->($message,$this);
111             }
112             }
113              
114             sub stop{
115 0     0 1   my $this = shift;
116 0           my $reason = shift;
117              
118 0           $this->{'_stop_flag'} = 1;
119 0           $this->log("\tWalker stopped.");
120 0 0         if($reason){
121 0           $this->log("\tReason: $reason.");
122             }
123             }
124              
125             sub _get{
126 0     0     my $this = shift;
127 0           my $url = shift;
128              
129 0           my $req = new HTTP::Request('GET',$url);
130 0           my $res = $this->{'ua'}->request($req);
131              
132 0           return $res->decoded_content();
133             }
134              
135              
136             1;
137              
138              
139             __END__