App-Fetchware
view release on metacpan or search on metacpan
lib/App/Fetchware.pm view on Meta::CPAN
my ($day, $month, $year) = split /-/, $fields[0];
# Ditch the ':' in the time.
$fields[1] =~ s/://;
# Some dirlistings use string months Aug, Jun, etc...
if (looks_like_number($month)) {
# Strip leading 0 if it exists by converting the
# string with the useless leading 0 into an integer.
# The %num_month hash lookup will add back a leading
# 0 if there was one. This stupid roundabout code is
# to ensure that there always is a leading 0 if the
# number is less than 10 to ensure that all of the
# numbers this hacky datetime parser outputs all
# have the same length so that the numbers can
# easily be compared with each other.
$month = sprintf("%u", $month);
push @filename_listing, [$filename,
"$year$num_month{$month}$day$fields[1]"];
# ...and some use numbers 8, 6, etc....
} else {
push @filename_listing, [$filename,
"$year$month{$month}$day$fields[1]"];
}
} else {
###BUGALERT### Add support for other http servers such as lighttpd, nginx,
#cherokee, starman?, AND use the Server: header to determine which algorithm to
#use.
die <<EOD;
App-Fetchware: run-time error. A hardcoded algorithm to parse HTML directory
listings has failed! Fetchware currently only supports parseing Apache HTML
directory listings. This is a huge limitation, but surprisingly pretty much
everyone who runs a mirror uses apache for http support. This is a bug so
please report it. Also, if you want to try a possible workaround, just use a ftp
mirror instead of a http one, because ftp directory listings are a easy to
parse. See perldoc App::Fetchware.
EOD
}
}
}
);
# Delete the $tree, so perl can garbage collect it.
$tree = $tree->delete;
return \@filename_listing;
}
} # end bare block for %month.
sub file_parse_filelist {
my $file_listing = shift;
for my $file (@$file_listing) {
my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, $atime,$mtime,$ctime,
$blksize,$blocks)
= stat($file) or die <<EOD;
App-Fetchware: Fetchware failed to stat() the file [$file] while trying to parse
your local [file://] lookup_url. The OS error was [$!]. This should not happen,
and is either a bug in fetchware or some sort of race condition.
EOD
# Replace scalar filename with a arrayref of the filename with its
# assocated timestamp for later processing for lookup().
#
# Use Path::Class's file() constructor & basename() method to strip out
# all unneeded directory information leaving just the file's name.
# Add all of the timestamp numbers together, so that only one numberical
# sort is needed instead of a descending list of numerical sorts.
$file = [file($file)->basename(), $mtime ];
}
return $file_listing;
}
sub lookup_by_timestamp {
my $file_listing = shift;
# Sort the timstamps to determine the latest one. The one with the higher
# numbers, and put $b before $a to put the "bigger", later versions before
# the "lower" older versions.
# Sort based on timestamp, which is $file_listing->[0..*][1][0..6].
# Note: the crazy || ors are to make perl sort each timestamp array first by
# year, then month, then day of the month, and so on.
my @sorted_listing = sort { $b->[1] <=> $a->[1] } @$file_listing;
return \@sorted_listing;
}
sub lookup_by_versionstring {
my $file_listing = shift;
# Implement versionstring algorithm.
my @versionstrings;
for (my $i = 0; $i <= $#{$file_listing}; $i++) {
# Split the filename on "Not a numbers", so remove all "not
# numbers", but keep a list of things that actually are numbers.
my @iversionstring = split(/\D+/, $file_listing->[$i][0]);
# Use grep to strip leading empty strings (eg: '').
@iversionstring = grep {$_ ne ''} @iversionstring;
if (@iversionstring == 0) {
# Let the usr know we're skipping this filename, but only if they
# really want to know (They turned on verbose output.).
vmsg <<EOM;
File [$file_listing->[$i][0]] has no version number in it. Ignoring.
EOM
# And also skip adding this @iversionstring to @versionstrings,
# because this @iversionstring is empty, and how do I sort an empty
# array? Return undef--nope causes "value undef in sort fatal errors
# and warnings." Return 0--nope causes a file with no version number
# at beginning of listing to stay at listing, and cause fetchware to
# fail picking the right version. Return -1--nope, because that's
( run in 2.137 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )