App-DistSync

 view release on metacpan or  search on metacpan

lib/App/DistSync.pm  view on Meta::CPAN

    return 1;
}
sub sync { # Synchronization. Main proccess
    my $self = shift;
    my $status = 0; # Статус операции для META

    # Создаем список исключений на базе прочитанного ранее SKIP + системные файлы
    my @skip_keys = @{(SKIPFILES)};
    push @skip_keys, keys %{($self->{maniskip})} if ref($self->{maniskip}) eq 'HASH';
    my %skips; for (@skip_keys) {$skips{$_} = _qrreconstruct($_)}
    #debug(Data::Dumper::Dumper(\%skips)) && return 0;

    # Удяляем файлы перечисленные в .DEL
    debug("Deleting of declared files");
    my $dellist = $self->{manidel};
    my $expire = _expire(0);
    if ($dellist && ref($dellist) eq 'HASH') {
        foreach (values %$dellist) {
            my $dt = _expire($_->[0] || 0);
            $_ = [$dt];
            $expire = $dt if $dt > $expire;
        }
        #debug(Data::Dumper::Dumper($dellist));
    }
    $expire = _expire(EXPIRE) unless $expire > 0;
    debug(sprintf("Expires at %s", scalar(localtime(time + $expire))));
    my $delfile = $self->{file_manidel};
    my $deltime = $self->{mtime_manidel};
    if ($deltime && (time - $deltime) > $expire) {

        # Удаляем файлы физически, если они есть физически и их нет в SKIP файле!
        foreach my $k (keys %$dellist) {
            if (_skipcheck(\%skips, $k)) { # Файл есть в списке исклюений

lib/App/DistSync.pm  view on Meta::CPAN

            my $fetch_lock = fetch($url, MANILOCK, $self->{file_manitemp});
            if ($fetch_lock->{status}) {
                if ($self->_check_lock($self->{file_manitemp})) {
                    $self->{uri} = $url;
                    debug("> [SKIPPED] Current resource SHOULD NOT update itself");
                } else {
                    debug("> [SKIPPED] Remote resource is in a state of updating. Please wait");
                }
                next;
            }
            #debug(Data::Dumper::Dumper($fetch_data));

            # Получение удаленного META и анализ его на status = 1. Иначе, пропуск данного ресурса
            debug(sprintf("Fetching %s file", METAFILE));
            my $fetch_meta = fetch($url, METAFILE, $self->{file_manitemp});
            if ($fetch_meta->{status}) {
                my $remote_meta = read_yaml($self->{file_manitemp});
                if ($remote_meta && ((ref($remote_meta) eq 'ARRAY') || ref($remote_meta) eq 'YAML::Tiny')) {
                    $remote_meta = $remote_meta->[0] || {};
                } elsif ($remote_meta && ref($remote_meta) eq 'HASH') {
                    # OK
                } else {
                    #debug(Data::Dumper::Dumper(ref($remote_meta),$remote_meta));
                    debug("> [SKIPPED] Remote resource is unreadable. Please contact the administrator of this resource");
                    next;
                }
                #debug(Data::Dumper::Dumper($remote_meta));
                if ($remote_meta && $remote_meta->{status}) {
                    my $remote_uri  = $remote_meta->{uri} || 'localhost';
                    my $remote_date = $fetch_meta->{mtime} || 0;
                    my $remote_ok = (time - $remote_date) > _expire(FREEZE) ? 0 : 1;
                    debug(sprintf("REMOTE RESOURCE:"
                        ."\n\tResource:\t%s"
                        ."\n\tDate:\t\t%s"
                        ."\n\tModified:\t%s"
                        ."\n\tStatus:\t\t%s",
                            $remote_uri,

lib/App/DistSync.pm  view on Meta::CPAN


                # Два списка объединяются во временную структуру
                foreach my $k (keys(%$local_manifest), keys(%$remote_manifest)) {
                    if ($mtmp{$k}) {
                        my $mt_l = $local_manifest->{$k}[0] || 0;
                        my $mt_r = $remote_manifest->{$k}[0] || 0;
                        $mtmp{$k}++ if $mt_l && $mt_r && $mt_l == $mt_r;
                    } else {
                        $mtmp{$k} = 1
                    }
                    #debug(Data::Dumper::Dumper($mt_l,$mt_r));
                }

                # Полуаем разницумоих и удаленных файлов
                # [<] Есть строка в левом файле
                # [>] есть строка в правом файле
                # [{] Более "свежий" в левом файле
                # [}] Более "свежий" в првом файле
                # [~] Отличаются размеры файлов в строке. Просто вывод информации об этом,
                #     т.к. более приоритетными являются даты модификации и наличие.
                #

lib/App/DistSync.pm  view on Meta::CPAN

                    } else {
                        debug(sprintf("> [!] %s", $k));
                    }
                }
                $status = 1; # Удалось связаться с ресурсом, значит он доступен
            } else {
                debug(sprintf("> [MISSING] File %s not fetched. Status code: %s",
                        MANIFEST,
                        $fetch_mani->{code} || 'UNDEFINED',
                    ));
                #debug(Data::Dumper::Dumper($fetch_mani));
                next;
            }

            # Пробегаемся по MIRRORS удаленным файлам и добавляем его к общему списку на обновление
            debug(sprintf("Fetching %s file", MIRRORS));
            my $fetch_mirr = fetch($url, MIRRORS, $self->{file_manitemp});
            if ($fetch_mirr->{status} && ((-z $self->{file_mirrors}) || $fetch_mirr->{mtime} > $self->{mtime_mirrors})) {
                # Читаем файл в отдельную структуру
                my $remote_mirr = maniread($self->{file_manitemp});
                # Добаляем файл на скачку, если там есть два или более зеркал

lib/App/DistSync.pm  view on Meta::CPAN

        } continue {
            fdelete($self->{file_manitemp});
        }
    } else {
        carp(sprintf("File %s is empty", MIRRORS));
        $status = 1; # Факт невозможности получить зеркала не является признаком того что ресурс
                     # отработал с ошибками
    }

    # Удаляем принудительно файлы полученного списка
    #debug(Data::Dumper::Dumper(\%delete_list));
    debug("Deleting files");
    foreach my $k (keys %delete_list) {
        my $f = File::Spec->canonpath(File::Spec->catfile($self->{dir}, $k));
        if (-e $f) {
            fdelete($f);
            debug(sprintf("> [DELETED] %s", $k));
        } else {
            debug(sprintf("> [MISSING] %s (%s)", $k, $f));
        }
    }

    # Проходим по sync_list и скачиваем файлы, но которых НЕТ в списке на удаление
    debug("Downloading files");
    #debug(Data::Dumper::Dumper(\%sync_list));
    my $total = 0;
    my $cnt = 0;
    my $all = scalar(keys %sync_list);
    foreach my $k (sort {lc $a cmp lc $b} keys %sync_list) {$cnt++;
        debug(sprintf("%03d/%03d %s", $cnt, $all, $k));
        my $list = $sync_list{$k};
        if ($list && ref($list) eq 'ARRAY') {
            my $mt_l = $self->{manifest}{$k}[0] || 0;
            my $dwldd = 0;
            my $skipped = 0;

lib/App/DistSync.pm  view on Meta::CPAN

                        mode => 0777,
                        error => \$mkerr,
                });
                if ($mkerr && (ref($mkerr) eq 'ARRAY') && @$mkerr) {
                    foreach my $e (@$mkerr) {
                        next unless $e && ref($e) eq 'HASH';
                        while (my ($_k, $_v) = each %$e) {
                            carp(sprintf("%s: %s", $_k, $_v));
                        }
                    }
                    #debug(Data::Dumper::Dumper($mkerr));
                }
                #debug(sprintf("--> %s >>> %s", $src, $dst));
                #debug(sprintf("--> %s >>> %s", $dst, $dir));

                # Переносим файлы по назначению
                fdelete($dst);
                unless (mv($src, $dst)) {
                    debug(sprintf("\t[ ERROR ] Can't move file %s to %s", $src, $dst));
                    carp($!);
                }

lib/App/DistSync.pm  view on Meta::CPAN

    # Формируем новый MANIFEST
    debug("Creating new manifest");
    my $new_manifest = manifind($self->{dir});

    # Отбираем файлы исключая исключения
    foreach my $k (keys %$new_manifest) {
        my $nskip = _skipcheck(\%skips, $k);
        delete $new_manifest->{$k} if $nskip;
        debug(sprintf("> [%s] %s", $nskip ? "SKIPPED" : " ADDED ", $k));
    }
    #debug(Data::Dumper::Dumper($new_manifest));

    # Пишем сам файл
    debug("Saving manifest to file ".MANIFEST);
    return 0 unless maniwrite($self->{file_manifest}, $new_manifest);

    # Формируем новый META
    debug("Creating new META file");
    my $new_meta = {
            last_start  => $self->{stamp},
            last_finish => time,



( run in 0.485 second using v1.01-cache-2.11-cpan-4d50c553e7e )