File Coverage

blib/lib/Net/DownloadMirror.pm
Criterion Covered Total %
statement 71 153 46.4
branch 12 62 19.3
condition 9 22 40.9
subroutine 17 19 89.4
pod 9 10 90.0
total 118 266 44.3


line stmt bran cond sub pod time code
1             #*** DownloadMirror.pm ***#
2             # Copyright (C) 2006 - 2008 by Torsten Knorr
3             # create-soft@tiscali.de
4             # All rights reserved!
5             #------------------------------------------------
6 1     1   25789 use strict;
  1         3  
  1         55  
7             #------------------------------------------------
8             package Net::DownloadMirror::FileName;
9 1     1   1180 use Storable;
  1         4975  
  1         264  
10 3   33 3   8 sub TIESCALAR { my ($class, $obj) = @_; return(bless(\$obj, $class || ref($class))); }
  3         32  
11             sub STORE
12             {
13 6 100   6   42928 if(-f $_[1])
14             {
15 5         35 ${$_[0]}->{_last_modified} = retrieve($_[1]);
  5         731  
16             }
17             else
18             {
19 1         3 ${$_[0]}->{_last_modified} = {};
  1         3  
20 1         2 store(${$_[0]}->{_last_modified}, $_[1]);
  1         7  
21 1         366 warn("\nno information of the files last modified times\n");
22             }
23             }
24 3     3   887 sub FETCH { return(${$_[0]}->{_filename}); }
  3         20  
25             #-------------------------------------------------
26             package Net::DownloadMirror;
27             #------------------------------------------------
28 1     1   1065 use Net::MirrorDir 0.19;
  1         132366  
  1         30  
29 1     1   26 use File::Path;
  1         5  
  1         91  
30 1     1   7 use Storable;
  1         3  
  1         4182  
31             #------------------------------------------------
32             @Net::DownloadMirror::ISA = qw(Net::MirrorDir);
33             $Net::DownloadMirror::VERSION = '0.10';
34             #-------------------------------------------------
35             sub _Init
36             {
37 3     3   69434 my ($self, %arg) = @_;
38 3         25 tie($self->{_filename}, 'Net::DownloadMirror::FileName', $self);
39 3   50     39 $self->{_filename} = $arg{filename} || 'lastmodified_remote';
40 3   50     21 $self->{_delete} = $arg{delete} || 'disabled';
41 3         10 $self->{_current_modified} = {};
42 3         14 return 1;
43             }
44             #-------------------------------------------------
45             sub Download
46             {
47 0     0 0 0 my ($self) = @_;
48 0 0       0 return 0 unless($self->Connect());
49 0         0 my ($rh_lf, $rh_ld) = $self->ReadLocalDir();
50 0 0       0 if($self->{_debug})
51             {
52 0         0 print("local files : $_\n") for(sort keys %$rh_lf);
53 0         0 print("local dirs : $_\n") for(sort keys %$rh_ld);
54             }
55 0         0 my ($rh_rf, $rh_rd) = $self->ReadRemoteDir();
56 0 0       0 if($self->{_debug})
57             {
58 0         0 print("remote files : $_\n") for(sort keys %$rh_rf);
59 0         0 print("remote dirs : $_\n") for(sort keys %$rh_rd);
60             }
61 0         0 my $ra_rdnil = $self->RemoteNotInLocal($rh_ld, $rh_rd);
62 0 0       0 if($self->{_debug})
63             {
64 0         0 print("remote directories not in local: $_\n") for(@$ra_rdnil);
65             }
66 0         0 $self->MakeDirs($ra_rdnil);
67 0         0 my $ra_rfnil = $self->RemoteNotInLocal($rh_lf, $rh_rf);
68 0 0       0 if($self->{_debug})
69             {
70 0         0 print("remote files not in local : $_\n") for(@$ra_rfnil);
71             }
72 0         0 $self->StoreFiles($ra_rfnil);
73 0 0       0 if($self->{_delete} eq 'enable')
74             {
75 0         0 my $ra_lfnir = $self->LocalNotInRemote($rh_lf, $rh_rf);
76 0 0       0 if($self->{_debug})
77             {
78 0         0 print("local files not in remote: $_\n") for(@$ra_lfnir);
79             }
80 0         0 $self->DeleteFiles($ra_lfnir);
81 0         0 my $ra_ldnir = $self->LocalNotInRemote($rh_ld, $rh_rd);
82 0 0       0 if($self->{_debug})
83             {
84 0         0 print("local directories not in remote : $_\n") for(@$ra_ldnir);
85             }
86 0         0 $self->RemoveDirs($ra_ldnir);
87             }
88 0         0 delete(@{$rh_rf}{@$ra_rfnil});
  0         0  
89 0         0 my $ra_mrf = $self->CheckIfModified($rh_rf);
90 0 0       0 if($self->{_debug})
91             {
92 0         0 print("modified remote files : $_\n") for(@$ra_mrf);
93             }
94 0         0 $self->StoreFiles($ra_mrf);
95 0         0 $self->Quit();
96 0         0 return 1;
97             }
98             #-------------------------------------------------
99             sub CheckIfModified
100             {
101 1     1 1 4 my ($self, $rh_rf) = @_;
102 1 50       7 return [] unless($self->IsConnection());
103 0         0 my @mf;
104 0         0 my $changed = undef;
105 0         0 for my $rf (keys(%$rh_rf))
106             {
107 0 0       0 next unless($self->{_current_modified}{$rf} = $self->{_connection}->mdtm($rf));
108 0 0       0 if(defined($self->{_last_modified}{$rf}))
109             {
110 0 0       0 next if($self->{_last_modified}{$rf} eq $self->{_current_modified}{$rf});
111             }
112             else
113             {
114 0         0 $self->{_last_modified}{$rf} = $self->{_current_modified}{$rf};
115 0         0 $changed++;
116             }
117 0         0 push(@mf, $rf);
118             }
119 0 0       0 store($self->{_last_modified}, $self->{_filename}) if($changed);
120 0         0 return \@mf;
121             }
122             #-------------------------------------------------
123             sub UpdateLastModified
124             {
125 0     0 1 0 my ($self, $ra_rf) = @_;
126 0 0       0 return unless($self->IsConnection());
127 0         0 my $mt;
128 0         0 for(@$ra_rf)
129             {
130 0 0       0 next unless($mt = $self->{_connection}->mdtm($_));
131 0 0       0 next unless($mt =~ m/^\d+$/);
132 0         0 $self->{_last_modified}{$_} = $mt;
133             }
134 0         0 store($self->{_last_modified}, $self->{_filename});
135 0         0 return 1;
136             }
137             #-------------------------------------------------
138             sub StoreFiles
139             {
140 1     1 1 2 my ($self, $ra_rf) = @_;
141 1 50 33     10 return 0 unless(@$ra_rf && $self->IsConnection());
142 0         0 my $lf;
143 0         0 for my $rf (@$ra_rf)
144             {
145 0         0 $lf = $rf;
146 0         0 $lf =~ s!$self->{_regex_remotedir}!$self->{_localdir}!;
147 0 0       0 next unless($self->{_connection}->get($rf, $lf));
148 0   0     0 $self->{_last_modified}{$rf} =
149             $self->{_current_modified}{$rf}
150             || $self->{_connection}->mdtm($rf);
151             }
152 0         0 store($self->{_last_modified}, $self->{_filename});
153 0         0 return 1;
154             }
155             #-------------------------------------------------
156             sub MakeDirs
157             {
158 1     1 1 2 my ($self, $ra_rd) = @_;
159 1 50       7 return 0 unless(@$ra_rd);
160 0         0 my $ld;
161 0         0 for my $rd (@$ra_rd)
162             {
163 0         0 $ld = $rd;
164 0         0 $ld =~ s!$self->{_regex_remotedir}!$self->{_localdir}!;
165 0 0       0 mkpath($ld, $self->{_debug}) unless(-d $ld);
166             }
167 0         0 return 1;
168             }
169             #-------------------------------------------------
170             sub DeleteFiles
171             {
172 1     1 1 314 my ($self, $ra_lf) = @_;
173 1 50 33     20 return 0 unless(($self->{_delete} eq 'enable') && @$ra_lf);
174 0         0 my $rf;
175 0         0 for my $lf (@$ra_lf)
176             {
177 0         0 $rf = $lf;
178 0 0       0 next unless(-f $lf);
179 0 0       0 warn("can not unlink : $lf\n") unless(unlink($lf));
180 0         0 $rf =~ s!$self->{_regex_localdir}!$self->{_remotedir}!;
181 0 0       0 delete($self->{_last_modified}{$rf})
182             if(defined($self->{_last_modified}{$rf}));
183             }
184 0         0 store($self->{_last_modified}, $self->{_filename});
185 0         0 return 1;
186             }
187             #-------------------------------------------------
188             sub RemoveDirs
189             {
190 1     1 1 36 my ($self, $ra_ld) = @_;
191 1 50 33     198 return 0 unless(($self->{_delete} eq 'enable') && @$ra_ld);
192 0         0 for my $ld (@$ra_ld)
193             {
194 0 0       0 next unless(-d $ld);
195 0         0 rmtree($ld, $self->{_debug}, 1);
196             }
197 0         0 return 1;
198             }
199             #------------------------------------------------
200             sub CleanUp
201             {
202 1     1 1 505 my ($self, $ra_exists) = @_;
203 1         4 my %h_temp = ();
204 1         3 for my $key (@$ra_exists)
205             {
206 3 100 100     30 if(
207             defined($self->{_last_modified}{$key})
208             &&
209             ($self->{_last_modified}{$key} =~ m/^\d+$/)
210             )
211             {
212 1         4 $h_temp{$key} = delete($self->{_last_modified}{$key});
213             }
214 3 50       10 if($self->{_debug})
215             {
216 3         1224 print(
217             "key: $_ value: "
218             . (defined($self->{_last_modified}{$_}) ? $self->{_last_modified}{$_} : 'undef')
219             . " removed\n")
220 3 100       4 for(keys(%{$self->{_last_modified}}));
221             }
222             }
223 1         4 %{$self->{_last_modified}} = %h_temp;
  1         7  
224 1         7 store($self->{_last_modified}, $self->{_filename});
225 1         280 return 1;
226             }
227             #-------------------------------------------------
228             sub LtoR
229             {
230 1     1 1 946 my ($self, $ra_lp) = @_;
231 1         2 my $ra_rp = [];
232 1         2 my $rp;
233 1         40 for(@$ra_lp)
234             {
235 3         4 $rp = $_;
236 3         23 $rp =~ s!$self->{_regex_localdir}!$self->{_remotedir}!;
237 3         21 push(@$ra_rp, $rp);
238             }
239 1         5 return $ra_rp;
240             }
241             #-------------------------------------------------
242             sub RtoL
243             {
244 1     1 1 3588 my ($self, $ra_rp) = @_;
245 1         5 my $ra_lp = [];
246 1         2 my $lp;
247 1         27 for(@$ra_rp)
248             {
249 3         7 $lp = $_;
250 3         28 $lp =~ s!$self->{_regex_remotedir}!$self->{_localdir}!;
251 3         24 push(@$ra_lp, $lp);
252             }
253 1         5 return $ra_lp;
254             }
255             #-------------------------------------------------
256             1;
257             #------------------------------------------------
258             __END__