File Coverage

blib/lib/Slackware/Slackget/Network/Connection/FTP.pm
Criterion Covered Total %
statement 9 72 12.5
branch 0 44 0.0
condition 0 6 0.0
subroutine 3 11 27.2
pod 2 2 100.0
total 14 135 10.3


line stmt bran cond sub pod time code
1             package Slackware::Slackget::Network::Connection::FTP;
2              
3 2     2   5374 use warnings;
  2         2  
  2         57  
4 2     2   7 use strict;
  2         3  
  2         43  
5              
6             require Slackware::Slackget::Network::Connection ;
7 2     2   938 use Time::HiRes ;
  2         2263  
  2         6  
8             require Net::FTP ;
9             require File::Copy;
10             require Slackware::Slackget::File ;
11              
12             =head1 NAME
13              
14             Slackware::Slackget::Network::Connection::FTP - This class encapsulate Net::FTP
15              
16             =head1 VERSION
17              
18             Version 1.0.0
19              
20             =cut
21              
22             our $VERSION = '1.0.0';
23             our @ISA = qw() ;
24              
25             =head1 SYNOPSIS
26              
27             This class encapsulate Net::FTP, and provide some methods for the treatment of FTP requests.
28              
29             This class need the following extra CPAN modules :
30              
31             - Net::FTP
32             - Time::HiRes
33              
34             use Slackware::Slackget::Network::Connection::FTP;
35              
36             my $foo = Slackware::Slackget::Network::Connection::FTP->new();
37             ...
38              
39             =cut
40              
41             sub new
42             {
43 0     0 1   my ($class,$url,$config) = @_ ;
44 0           my $self = {};
45             # return undef if(!defined($config) && ref($config) ne 'Slackware::Slackget::Config');
46             # $self->{config} = $config ;
47 0 0         return undef unless (is_url($self,$url));
48 0           $self->{DATA}->{conn} = new Net::FTP ($url);
49 0           bless($self,$class);
50 0           $self->parse_url($url) ;
51 0           return $self;
52             }
53              
54             =head1 CONSTRUCTOR
55              
56             =head2 new
57              
58             This class is not designed to be instanciate alone or used alone. You have to use the Slackware::Slackget::Network::Connection.
59              
60             =head1 FUNCTIONS
61              
62             =head2 __test_server
63              
64             This method test the rapidity of the mirror, by making a new connection to the server and logging in. Be aware of the fact that after testing the connection you will have a new connection (if you were previously connected the previous connection is closed).
65              
66             my $time = $connection->test_server() ;
67              
68             =cut
69              
70             sub __test_server {
71 0     0     my $self = shift ;
72             # print "[debug http] protocol : $self->{DATA}->{protocol}\n";
73             # print "[debug http] host : $self->{DATA}->{host}\n";
74 0 0         if(defined($self->{DATA}->{conn}))
75             {
76 0           $self->{DATA}->{conn}->close ;
77 0           $self->{DATA}->{conn} = undef ;
78             }
79            
80             # print "[debug http] Testing a FTP server: $self->{DATA}->{host}\n";
81 0           my $start_time = Time::HiRes::time();
82             # print "[debug http] \$start_time : $start_time\n";
83 0 0         $self->{DATA}->{conn} = Net::FTP->new($self->{DATA}->{host}) or return undef;
84 0 0         $self->{DATA}->{conn}->login($self->{DATA}->{config}->{'network-parameters'}->{ftp}->{login},$self->{DATA}->{config}->{'network-parameters'}->{ftp}->{password}) or return undef;
85 0           my $stop_time = Time::HiRes::time();
86             # print "[debug http] \$stop_time: $stop_time\n";
87 0           return ($stop_time - $start_time);
88             }
89              
90             sub _connect
91             {
92 0     0     my $self = shift ;
93             # print "[_connect] test de config\n";
94             # print "[_connect] config param is $self->{DATA}->{config}\n";
95 0 0 0       return undef if(!defined($self->{DATA}->{config}) && ref($self->{DATA}->{config}) ne 'Slackware::Slackget::Config') ;
96             # print "[_connect] test de l'existence d'une connexion\n";
97 0 0         unless($self->{DATA}->{conn})
98             {
99             # print "[_connect] pas de connexion : cr�tion\n";
100 0 0         $self->{DATA}->{conn} = Net::FTP->new($self->{DATA}->{host}) or return undef;
101             # print "[_connect] login\n";
102 0 0         $self->{DATA}->{conn}->login($self->{DATA}->{config}->{'network-parameters'}->{ftp}->{login},$self->{DATA}->{config}->{'network-parameters'}->{ftp}->{password}) or return undef;
103             }
104             # print "[_connect] That's all folks\n";
105 0           return 1;
106             }
107              
108             =head2 _test_current_directory [PRIVATE]
109              
110             This private methos is used internally each time you require a transfert, for testing if the current directory is the 'path' parameter of the DATA section of the current Connection object.
111              
112             Do that by sending a PWD command to the server and compare the result with $connection->path.
113              
114             $ftp->cwd('/any/remote/directory/') unless($connection->_test_current_directory) ;
115              
116             Due to the fact that this method is private and internal the example is not really explicit, please look at the code for more informations.
117              
118             =cut
119              
120             sub _test_current_directory {
121 0     0     my $self = shift ;
122             # print "test de connexion\n";
123 0 0         $self->_connect or return undef;
124             # print "r�ertoire courant : ",$self->conn->pwd,"\n";
125             # print "path : $self->{DATA}->{path}\n";
126 0           my $tmp_path = $self->conn->pwd ;
127 0 0         if( $self->{DATA}->{path}=~/^$tmp_path\/*$/)
128             {
129 0           return 1;
130             }
131             else
132             {
133             # print "CHANGEMENT\n";
134 0 0         $self->conn->cwd($self->{DATA}->{path}) or return undef;
135 0           return 1;
136             }
137             }
138              
139             =head2 __get_file
140              
141             Download and return a given file.
142              
143             my $file = $connection->get_file('PACKAGES.TXT') ;
144              
145             Please note that the Net::FTP module doesn't support a method like that. So, this method is not an encapsulator like the one of HTTP.pm, and use Slackware::Slackget::File to return the content of the downloaded file.
146              
147             So you'd better to use fetch_file().
148              
149             =cut
150              
151             sub __get_file {
152 0     0     my ($self,$remote_file) = @_ ;
153 0 0         $remote_file = $self->file unless(defined($remote_file)) ;
154 0           srand (time ^ $$ ^ unpack "%L*", `ps axww | gzip`);
155 0           my $name = $remote_file.'-' ;
156 0           for(my $k=0;$k<=20;$k++){
157 0           $name .= (0..9,'a'..'f')[int(rand(15))];
158             }
159             # print "[Slackware::Slackget::Network::Connection::FTP] temp filename is '$name'\n";
160 0 0         $self->_test_current_directory or return undef;
161 0 0         $self->conn->get($remote_file,"/tmp/$name") or return undef;
162 0 0         my $file = new Slackware::Slackget::File ("/tmp/$name",'file-encoding' => $self->{DATA}->{config}->{'file-encoding'}) or return undef ;
163 0           return join "\n",$file->Get_file ;
164             # return get($self->protocol().'://'.$self->host().'/'.$self->path().'/'.$remote_file);
165             }
166              
167             =head2 __fetch_file
168              
169             Download and store a given file.
170              
171             $connection->fetch_file() ; # download the file $connection->file and store it at $config->{common}->{'update-directory'}/$connection->file, this way is not recommended
172             or
173             $connection->fetch_file($remote_file) ; # download the file $remote_file and store it at $config->{common}->{'update-directory'}/$connection->file, this way is not recommended
174             or
175             $connection->fetch_file('PACKAGES.TXT',"$config->{common}->{'update-directory'}/".$current_specialfilecontainer_object->id."/PACKAGES.TXT") ; # This is the recommended way.
176             # This is equivalent to : $connection->fetch_file($remote_file,$local_file) ;
177              
178             This method return a Slackware::Slackget::Status object with the following object declaration :
179              
180             my $status = Slackware::Slackget::Status->new(codes => {
181             0 => "All goes well.\n",
182             1 => "An error occured "
183             });
184              
185              
186             =cut
187              
188             sub __fetch_file {
189 0     0     my ($self,$remote_file,$local_file) = @_ ;
190 0 0         $remote_file = $self->file unless(defined($remote_file));
191 0 0         unless(defined($local_file)){
192 0 0 0       if(defined($self->{DATA}->{download_directory}) && -e $self->{DATA}->{download_directory}){
    0          
193 0           $remote_file=~ /([^\/]*)$/;
194 0           $local_file = $self->{DATA}->{download_directory}.'/'.$1 ;
195             }
196             elsif(defined($self->{DATA}->{config})){
197 0           $remote_file=~ /([^\/]*)$/;
198 0           $local_file = $self->{DATA}->{config}->{common}->{'update-directory'}.'/'.$1 ;
199             }
200             else{
201 0           warn "[Slackware::Slackget::Network::Connection::FTP] unable to determine the path to save $remote_file.\n";
202 0           return undef;
203             }
204             }
205             # print "[debug ftp] save the fetched file (",$remote_file,") to $local_file\n";
206 0 0         $self->_test_current_directory or return undef;
207 0           my $state = Slackware::Slackget::Status->new(codes => {
208             0 => "All goes well.\n",
209             1 => "An error occured, we recommend to change this server's host.\n"
210             });
211 0 0         if($self->conn->get($remote_file,$local_file.'.part'))
212             {
213 0           File::Copy::move( $local_file.'.part' , $local_file );
214 0           $state->current(0);
215             }
216             else
217             {
218 0           $state->current(1);
219             }
220 0           return $state;
221             }
222              
223             =head2 __fetch_all
224              
225             This method fetch all files declare in the "files" parameter of the constructor.
226              
227             $connection->fetch_all or die "Unable to fetch all files\n";
228              
229             This method save all files in the $config->{common}->{'update-directory'} directory (so you have to manage yourself the files deletion/replacement problems)
230              
231             =cut
232              
233             sub __fetch_all {
234 0     0     my $self = shift ;
235 0           foreach (@{$self->files}){
  0            
236 0 0         $self->fetch_file($_) or return undef;
237             }
238 0           return 1 ;
239             }
240              
241              
242             =head2 conn
243              
244             An accessor which return the current Net::FTP connection object
245              
246             =cut
247              
248             sub conn {
249 0     0 1   my $self = shift;
250 0           return $self->{DATA}->{conn};
251             }
252              
253             =head1 AUTHOR
254              
255             DUPUIS Arnaud, C<< <a.dupuis@infinityperl.org> >>
256              
257             =head1 BUGS
258              
259             Please report any bugs or feature requests to
260             C<bug-Slackware-Slackget@rt.cpan.org>, or through the web interface at
261             L<http://rt.cpan.org/NoAuth/ReportBug.html?Queue=Slackware-Slackget>.
262             I will be notified, and then you'll automatically be notified of progress on
263             your bug as I make changes.
264              
265             =head1 SUPPORT
266              
267             You can find documentation for this module with the perldoc command.
268              
269             perldoc Slackware::Slackget
270              
271              
272             You can also look for information at:
273              
274             =over 4
275              
276             =item * Infinity Perl website
277              
278             L<http://www.infinityperl.org>
279              
280             =item * slack-get specific website
281              
282             L<http://slackget.infinityperl.org>
283              
284             =item * RT: CPAN's request tracker
285              
286             L<http://rt.cpan.org/NoAuth/Bugs.html?Dist=Slackware-Slackget>
287              
288             =item * AnnoCPAN: Annotated CPAN documentation
289              
290             L<http://annocpan.org/dist/Slackware-Slackget>
291              
292             =item * CPAN Ratings
293              
294             L<http://cpanratings.perl.org/d/Slackware-Slackget>
295              
296             =item * Search CPAN
297              
298             L<http://search.cpan.org/dist/Slackware-Slackget>
299              
300             =back
301              
302             =head1 ACKNOWLEDGEMENTS
303              
304             Thanks to Bertrand Dupuis (yes my brother) for his contribution to the documentation.
305              
306             =head1 COPYRIGHT & LICENSE
307              
308             Copyright 2005 DUPUIS Arnaud, All Rights Reserved.
309              
310             This program is free software; you can redistribute it and/or modify it
311             under the same terms as Perl itself.
312              
313             =cut
314              
315             1; # End of Slackware::Slackget::Network::Connection::FTP