]> git.donarmstrong.com Git - infobot.git/blob - src/Net.pl
2050c9e8b65c5e0234b24a3faf7e4a3e1ca038c7
[infobot.git] / src / Net.pl
1 #
2 #   Net.pl: FTP//HTTP helper
3 #   Author: dms
4 #  Version: v0.1 (20000309)
5 #  Created: 20000309
6 #
7
8 use strict;
9
10 use vars qw(%ftp %param);
11
12 # Usage: &ftpGet($host,$dir,$file,[$lfile]);
13 sub ftpGet {
14     my ($host,$dir,$file,$lfile) = @_;
15     my $verbose_ftp     = 1;
16
17     return unless &loadPerlModule("Net::FTP");
18
19     &status("FTP: opening connection to $host.") if ($verbose_ftp);
20     my $ftp = Net::FTP->new($host,
21         'Timeout'       => 1*60,
22 ###     'BlockSize'     => 1024,        # ???
23     );
24
25     return if ($@);
26
27     # login.
28     if ($ftp->login()) {
29         &status("FTP: logged in successfully.") if ($verbose_ftp);
30     } else {
31         &status("FTP: login failed.");
32         $ftp->quit();
33         return 0;
34     }
35
36     # change directories.
37     if ($ftp->cwd($dir)) {
38         &status("FTP: changed dirs to $dir.") if ($verbose_ftp);
39     } else {
40         &status("FTP: cwd dir ($dir) does not exist.");
41         $ftp->quit();
42         return 0;
43     }
44
45     # get the size of the file.
46     my ($size, $lsize);
47     if ($size = $ftp->size($file)) {
48         &status("FTP: file size is $size") if ($verbose_ftp);
49         my $thisfile    = $file || $lfile;
50
51         if ( -f $thisfile) {
52             $lsize      = -s $thisfile;
53             if ($_ != $lsize) {
54                 &status("FTP: local size is $lsize; downloading.") if ($verbose_ftp);
55             } else {
56                 &status("FTP: same size; skipping.");
57                 system("touch $thisfile");      # lame hack.
58                 $ftp->quit();
59                 return 1;
60             }
61         }
62     } else {
63         &status("FTP: file does not exist.");
64         $ftp->quit();
65         return 0;
66     }
67
68     my $start_time      = &timeget();
69     if (defined $lfile) {
70         &status("FTP: getting $file as $lfile.") if ($verbose_ftp);
71         $ftp->get($file,$lfile);
72     } else {
73         &status("FTP: getting $file.") if ($verbose_ftp);
74         $ftp->get($file);
75     }
76
77     if (defined $lsize) {
78         &DEBUG("FTP: locsize => '$lsize'.");
79         if ($size != $lsize) {
80             &FIXME("FTP: downloaded file seems truncated.");
81         }
82     }
83
84     my $delta_time      = &timedelta($start_time);
85     if ($delta_time > 0 and $verbose_ftp) {
86         &status(sprintf("FTP: %.02f sec to complete.", $delta_time));
87         my ($rateunit,$rate) = ('B', $size / $delta_time);
88         if ($rate > 1024) {
89             $rate /= 1024;
90             $rateunit = 'kB';
91         }
92         &status(sprintf("FTP: %.01f ${rateunit}/sec.", $rate));
93     }
94
95     $ftp->quit();
96
97     return 1;
98 }
99
100 # Usage: &ftpList($host,$dir);
101 sub ftpList {
102     my ($host,$dir) = @_;
103     my $verbose_ftp = 1;
104
105     return unless &loadPerlModule("Net::FTP");
106
107     &status("FTP: opening connection to $host.") if ($verbose_ftp);
108     my $ftp = Net::FTP->new($host,'Timeout'=>60);
109
110     return if ($@);
111
112     # login.
113     if ($ftp->login()) {
114         &status("FTP: logged in successfully.") if ($verbose_ftp);
115     } else {
116         &status("FTP: login failed.");
117         $ftp->quit();
118         return;
119     }
120
121     # change directories.
122     if ($ftp->cwd($dir)) {
123         &status("FTP: changed dirs to $dir.") if ($verbose_ftp);
124     } else {
125         &status("FTP: cwd dir ($dir) does not exist.");
126         $ftp->quit();
127         return;
128     }
129
130     &status("FTP: doing ls.") if ($verbose_ftp);
131     foreach ($ftp->dir()) {
132         # modes d uid gid size month day time file.
133         if (/^(\S+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\d+) (\S{3})\s+(\d+) \d+:\d+ (.*)$/) {
134             # name = size.
135             $ftp{$8} = $5;
136         } else {
137             &DEBUG("FTP: UNKNOWN  => '$_'.");
138         }
139     }
140     &status("FTP: ls done. ". scalar(keys %ftp) ." entries.");
141     $ftp->quit();
142
143     return %ftp;
144 }
145
146 ### LWP.
147 # Usage: &getURL($url, [$post]);
148 # TODO: rename this to getHTTP
149 sub getURL {
150     my ($url,$post) = @_;
151     my ($ua,$res,$req);
152
153     return unless &loadPerlModule("LWP::UserAgent");
154
155     $ua = new LWP::UserAgent;
156     $ua->proxy('http', $param{'httpProxy'}) if &IsParam('httpProxy');
157
158     if (defined $post) {
159         $req = new HTTP::Request('POST',$url);
160         $req->content_type('application/x-www-form-urlencoded');
161         $req->content($post);
162     } else {
163         $req = new HTTP::Request('GET',$url);
164     }
165
166     &status("getURL: getting '$url'");
167     my $time = time();
168     $res = $ua->request($req);
169     my $size = length($res->content);
170     if ($size and time - $time) {
171         my $rate = int( $size/1000/(time - $time) );
172         &status("getURL: Done (took ".&Time2String(time - $time).", $rate k/sec)");
173     }
174
175     # return NULL upon error.
176     return unless ($res->is_success);
177
178     return(split '\n', $res->content);
179 }
180
181 sub getURLAsFile {
182     my ($url,$file) = @_;
183     my ($ua,$res,$req);
184     my $time = time();
185
186     unless (&loadPerlModule('LWP::UserAgent')) {
187         &::DEBUG('getURLAsFile: LWP::UserAgent not installed');
188         return;
189     }
190
191     $ua = new LWP::UserAgent;
192     $ua->proxy('http', $param{'httpProxy'}) if &IsParam('httpProxy');
193     $req = HTTP::Request->new('GET', $url);
194     &status("getURLAsFile: getting '$url' as '$file'");
195     $res = $ua->request($req, $file);
196
197     my $delta_time      = time() - $time;
198     if ($delta_time) {
199         my $size = -s $file || 0;
200         my $rate = int($size / $delta_time / 1024);
201         &status("getURLAsFile: Done. ($rate kB/sec)");
202     }
203
204     return $res;
205 }
206
207 1;