Skip to content

Instantly share code, notes, and snippets.

@leedo
Created November 29, 2012 02:43
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save leedo/4166438 to your computer and use it in GitHub Desktop.
Save leedo/4166438 to your computer and use it in GitHub Desktop.
#!/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;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment