sub sync_aria2 { -x "/usr/bin/aria2c" or die N("aria2 is missing\n"); my $options = shift; $options = { dir => $options } if !ref $options; #- force download to be done in cachedir to avoid polluting cwd. (my $cwd) = getcwd() =~ /(.*)/; chdir $options->{dir}; my ($buf, $total, $file) = ('', undef, undef); my $aria2c_command = join(" ", map { "'$_'" } "/usr/bin/aria2c", "--timeout", $CONNECT_TIMEOUT, "--max-tries=1", #- aria2 will always retry, even when 404, therefore disable it "--allow-overwrite=true", "--auto-file-renaming=false", ($options->{limit_rate} ? "--max-download-limit=$options->{limit_rate}" : ()), ($options->{resume} ? "--continue" : ()), ($options->{retry} ? "--max-tries=$options->{retry}" : ()), (defined $options->{'aria2-options'} ? split /\s+/, $options->{'aria2-options'} : ()), '-d', $options->{dir}, ($options->{metalink} ? "-M" : ()), @_); $options->{debug} and $options->{debug}($aria2c_command); my $aria2_pid = open (my $aria2, "$aria2c_command |"); local $/ = \1; #- read input by only one char, this is slow but very nice (and it works!). local $_; while(<$aria2>) { $buf .= $_; if ($_ eq "\r" || $_ eq "\n") { if ($options->{callback}) { unless (defined $file) { $file = shift @_; propagate_sync_callback($options, 'start', $file); } if ($buf =~ /\[\#\d*\s+\S+:([\d\.]+)\w*.([\d\.]+)\w*\S+\s+\S+\s*([\d\.]).+/) { my ($total, $percent, $speed, $eta) = ($2, $3, $4, $6); #- $1 = currently downloaded size, $5 = connections if (propagate_sync_callback($options, 'progress', $file, $percent, $total, $eta, $speed) eq 'canceled') { kill 15, $aria2_pid; close $aria2; return; } } if ($_ eq "\n") { propagate_sync_callback($options, 'end', $file); ($total, $file) = (undef, undef); } } else { $options->{quiet} or print STDERR $buf; } $buf = ''; } } chdir $cwd; close $aria2 or _error('aria2'); }