App-DistSync
view release on metacpan or search on metacpan
lib/App/DistSync.pm view on Meta::CPAN
debug(" Resource URL : %s", $remote_url);
debug(" Date : %s", $remote_meta->{date} // 'UNKNOWN');
debug(" Modified : %s", $remote_datef);
debug(" Hostname : %s", $remote_meta->{hostname} // '');
debug(" Directory : %s", $remote_meta->{directory} // '');
debug(" Project : %s v%s",
$remote_meta->{project} || ref($self), $remote_meta->{version} // '0.01');
debug(" Script : %s", $remote_meta->{script} // '');
debug(" Status : %s", $remote_ok ? "OK" : "EXPIRED");
debug(" Time : %d sec", $remote_meta->{'time'} || 0);
}
unless ($remote_ok) {
debug("> [SKIPPED] Remote resource is expired. Last updated: %s", $remote_datef);
next
}
} else {
debug("> [SKIPPED] Remote resource is broken. Please contact the administrator of this resource");
next;
}
} else {
printf STDERR "Can't download \"%s\": %s\n", $fetch_meta->{url}, $fetch_meta->{message};
}
}
# Downloading the MANIFEST file
{
debug("Fetching %s", MANIFEST);
my $fetch_mani = $self->fetch($url, MANIFEST, $self->{file_manitemp});
if ($fetch_mani->{status}) {
my $remote_manifest = maniread($self->{file_manitemp}) // {};
my %mtmp; # {file => count} Temporary work structure
# Two manifest lists - local and remote - are merged into a temporary structure
# {file => [epoch, size, wday, month, day, time, year]}
foreach my $k (keys(%$manifest), keys(%$remote_manifest)) {
unless (exists $mtmp{$k}) {
$mtmp{$k} = 1;
next;
}
my $mt_l = $manifest->{$k}[0] || 0; # Modified time (local, left)
my $mt_r = $remote_manifest->{$k}[0] || 0; # Modified time (remote, right)
$mtmp{$k}++ if $mt_l && $mt_r && $mt_l == $mt_r; # =2 if the files are identical
}
#debug(Data::Dumper::Dumper(\%mtmp));
# Getting the difference between the lists of local and remote files
#
# [=] The files do not differ; they are identical in both lists
# [<] The file exists in the local (left) file list
# [>] The file exists in the remote (right) file list
# [{] The "newer" file is the one in the local list
# [}] The "newer" file is the one in the remote list
# [~] The file sizes differ between the lists. This is only reported as information,
# since modification times and file presence have higher priority than sizes
# [!] A conflict situation. An almost impossible edge case
#
# The comparison works as follows:
# We iterate through the entries of the manifest structures (the left and right lists)
# and analyze where the counter value is 1 and where it is 2.
# A value of 1 means that the file exists in only one of the file lists - but in which one?
# If it's the left list, the line is marked with "<", as described in the legend above;
# if it's the right list, the line is marked with ">".
my $lim = _expire(LIMIT); # 1 min
foreach my $k (keys %mtmp) {
next unless $mtmp{$k}; # Skip broken records
next unless $mtmp{$k} == 1; # Files are NOT idential
if ($manifest->{$k} && $remote_manifest->{$k}) { # Both sides: left and right
my $mt_l = $manifest->{$k}[0] || 0;
my $mt_r = $remote_manifest->{$k}[0] || 0;
if (($mt_l > $mt_r) && ($mt_l - $mt_r) > $lim) {
# Skip! The left (local) file is more than one minute newer than the right one
# debug("# [{] %s", $k) if $self->verbose;
} if (($mt_l < $mt_r) && ($mt_r - $mt_l) > $lim) {
# The right (remote) file is more than one minute newer than the left one
debug("# [}] %s (LOCAL [%s] < REMOTE [%s])", $k,
scalar(localtime($mt_l)), scalar(localtime($mt_r))) if $self->verbose;
# Add to sync list for downloading
unless (_skipcheck(\%skips, $k)) {
my $ar = $sync_list{$k} //= [];
push @$ar, {
url => $url,
mtime => $remote_manifest->{$k}[0],
size => $remote_manifest->{$k}[1],
};
}
} else {
# Skip! Files are idential
#debug("# [=] %s", $k) if $self->verbose;
}
} elsif ($manifest->{$k}) { # Left side
# Skip! No download requiered
# debug("# [<] %s", $k) if $self->verbose;
} elsif ($remote_manifest->{$k}) { # Right (remote) side
# Download required
debug("# [>] %s", $k) if $self->verbose;
unless (_skipcheck(\%skips, $k)) {
my $ar = $sync_list{$k} //= [];
push @$ar, {
url => $url,
mtime => $remote_manifest->{$k}[0],
size => $remote_manifest->{$k}[1],
};
}
} else {
debug(sprintf("# [!] %s", $k)) if $self->verbose;
}
}
# Ok
$status = 1;
} else {
debug("> [SKIPPED] Can't download \"%s\"", $fetch_mani->{url});
printf STDERR "Can't download \"%s\": %s\n", $fetch_mani->{url}, $fetch_mani->{message};
next;
}
}
# Download the MIRRORS file and add it to the sync list if it is up to date
{
debug("Fetching %s", MIRRORS);
my $fetch_mirr = $self->fetch($url, MIRRORS, $self->{file_manitemp});
( run in 2.717 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )