public
Created

  • Download Gist
multi-mirror.pl
Perl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
#!/usr/bin/env perl
 
use v5.12;
use AnyEvent::HTTP;
use HTML::Parser;
 
sub parse_mirrors {
my $body = shift;
my ($in_us, $in_head, $in_th);
my ($mirror, @mirrors);
my $p = HTML::Parser->new(api_version => 3,
start_h => [sub {
my ($tag, $attr, $text) = @_;
if ($tag eq "tr" and ($attr->{class} || "") eq "head") {
$in_head = 1;
$in_us = 0;
}
if ($tag eq "th" and $in_head) {
$in_th = 1;
}
if ($tag eq "a" and $in_us){
$mirror = $attr->{href};
}
}, "tagname,attr,text"],
text_h => [sub {
my $text = shift;
if ($in_th && ($text || "") =~ /United States/) {
$in_us = 1;
}
if ($mirror && $text eq "http") {
push @mirrors, $mirror;
}
}, "text"],
end_h => [sub {
my $tag = shift;
$in_th = 0 if $tag eq "th";
$in_head = 0 if $tag eq "tr";
$mirror = "" if $tag eq "a";
}, "tagname"],
);
$p->parse($body);
$p->eof;
@mirrors;
}
 
my $mirror_url = "https://launchpad.net/ubuntu/+cdmirrors";
my $file = "12.10/ubuntu-12.10-desktop-amd64.iso";
my $bytes = 0;
my $active = 0;
my $time = AE::now;
my $cv = AE::cv;
my $t;
 
$cv->begin;
 
say "fetching list of mirrors from $mirror_url";
 
http_get $mirror_url, sub {
my ($body, $headers) = @_;
 
my @mirrors = parse_mirrors $body;
say "found " . scalar(@mirrors) . " US mirrors";
say "beginning downloads, Ctrl+c to quit";
 
$t = AE::timer 3, 3, sub {
my $diff = AE::now - $time;
my $speed = int($bytes / $diff / 1000);
say "$active connections -- $speed KB/s";
$time = AE::now;
$bytes = 0;
};
 
for my $mirror (@mirrors) {
$cv->begin;
$active++;
http_get $mirror . $file,
on_body => sub {
my ($body, $headers) = @_;
$bytes += length $body;
},
sub {
$active--;
$cv->end;
};
}
 
$cv->end;
};
 
$cv->recv;

Please sign in to comment on this gist.

Something went wrong with that request. Please try again.