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 )