Daizu

 view release on metacpan or  search on metacpan

lib/Daizu/Publish.pm  view on Meta::CPAN

sub publish_urls
{
    my ($cms, $file, $generator, $method, $urls) = @_;

    eval { _publish_urls_work($cms, $file, $generator, $method, $urls) };

    if ($@) {
        # Clean up any temp files left behind.
        for my $url_info (@$urls) {
            my $filename = $url_info->{_tmp_filename};
            next unless defined $filename;
            warn "Cleaning up unfinished temp file '$filename'.\n";
            unlink $filename
                or warn "Error deleting temp file '$filename': $!\n";
            delete $url_info->{_tmp_filename};
        }

        die $@;
    }
}

# This is called in an eval{} so that any half-published temp files can
# be cleaned up if it breaks.
sub _publish_urls_work
{
    my ($cms, $file, $generator, $method, $urls) = @_;

    for my $url_info (@$urls) {
        my $out_url = $url_info->{url} = URI->new($url_info->{url});

        my $full_filename = _url_output_filename($cms, $out_url, 1);
        my $tmp_filename = "$full_filename.daizutmp";
        open my $fh, '>', $tmp_filename
            or die "Error opening output file '$tmp_filename': $!\n";
        binmode $fh
            or die "Error setting binmode on output file '$tmp_filename': $!\n";
        assert(!defined $url_info->{fh}) if DEBUG;
        $url_info->{fh} = $fh;
        $url_info->{_full_filename} = $full_filename;
        $url_info->{_tmp_filename} = $tmp_filename;
    }

    $generator->$method($file, $urls);

    # Close the output files explicitly, so that any errors encountered while
    # flushing buffers are correctly reported.  Also make them executable
    # if the original file in Subversion is (for CGI scripts).
    for my $url_info (@$urls) {
        my $filename = $url_info->{_full_filename};
        my $tmpfile = $url_info->{_tmp_filename};

        if (defined $url_info->{fh}) {
            close $url_info->{fh}
                or die "Error closing output file '$tmpfile': $!\n";
        }
        delete $url_info->{fh};

        if ($file->property('svn:executable')) {
            my $umask = umask;
            if (defined $umask) {
                chmod +(0777 & ~$umask), $tmpfile
                    or die "Error making '$tmpfile' executable: $!\n";
            }
        }

        if (!-f $filename || _file_hash($tmpfile) ne _file_hash($filename) ||
            -x $tmpfile ne -x $filename)
        {
            # Move the temp file into place, possibly overrwritting an older
            # published version.
            rename $tmpfile, $filename
                or die "Error moving file '$tmpfile' into place: $!\n";
        }
        else {
            # The new version of the file is identical to an older one which
            # is still present in the document root, so we might as well just
            # delete the temp file.  This wil mean that the timestamp of the
            # live version won't get fiddled with when no real changes have
            # been made, and it will save rsync from having to do a comparison.
            unlink $tmpfile
                or die "Error deleting temp file '$tmpfile': $!\n";
        }
    }
}

sub _url_output_filename
{
    my ($cms, $url, $create_dir) = @_;

    my ($config, $docroot, $path, $filename) = $cms->output_config($url);
    die "No output path defined for URL '$url'\n"
        unless defined $docroot;

    mkpath(file($docroot, $path)->stringify)
        if $create_dir;

    return file($docroot, $path, $filename);
}

# Return a SHA1 digest of a file's content (a file on the filesystem, not one
# in a database working copy).
sub _file_hash
{
    my ($filename) = @_;

    open my $fh, '<', $filename
        or die "Error opening file '$filename' for digesting: $!\n";
    binmode $fh
        or die "Error binmoding file '$filename' for digesting: $!\n";
    my $digest = Digest::SHA1->new;
    $digest->addfile($fh);

    return $digest->digest;
}

=item publish_redirect_map($cms, $wc_id, $config)

TODO

TODO - redirect and gone maps should be published in the same way as
URL content, with the file first written to a different filename, then



( run in 1.837 second using v1.01-cache-2.11-cpan-cdf2f3d4e48 )