Aozora2Epub

 view release on metacpan or  search on metacpan

lib/Aozora2Epub/Epub.pm  view on Meta::CPAN

package Aozora2Epub::Epub;
use strict;
use warnings;
use utf8;
use File::ShareDir qw(dist_dir);
use Path::Tiny;
use Text::Xslate qw/mark_raw/;
use UUID qw/uuid/;
use HTTP::Date qw/time2isoz/;
use File::Find qw//;
use Archive::Zip qw( :ERROR_CODES :CONSTANTS );
use Aozora2Epub::CachedGet;
use Aozora2Epub::Gensym;
use base qw/Class::Accessor/;
__PACKAGE__->mk_accessors(qw/assets/);

our $VERSION = "0.05";

sub new {
    my $class = shift;

    my $tmpdir = ($ENV{EPUB_TMP_DIR} || Path::Tiny->tempdir);
    my $sharedir = path(dist_dir('Aozora2Epub'), 'basic');
    my $tx = Text::Xslate->new();
    return bless {
        tmpdir=>$tmpdir,
        sharedir=>$sharedir,
        xslate=>$tx,
        assets=>[],
    }, $class;
}

sub dest_file {
    my ($self, @path) = @_;
    my $dest = path($self->{tmpdir}, @path);
    my $dir = path($dest->dirname);
    $dir->is_dir or $dir->mkdir;
    return $dest;
}

sub copy {
    my ($self, $file) = @_;
    my $dest = $self->dest_file($file);
    path($self->{sharedir}, $file)->copy($dest);
}

sub slurp {
    my ($self, $file) = @_;
    return path($self->{sharedir}, $file)->slurp_utf8;
}

sub render_to {
    my ($self, $template, $to, $args) = @_;
    my $dest = $self->dest_file($to);
    my $text = $self->{xslate}->render_string($self->slurp($template), $args);
    $dest->spew_utf8($text);
}

sub render {
    my ($self, $template, $args) = @_;
    $self->render_to($template, $template, $args);
}

sub write_string {
    my ($self, $bin, $to) = @_;
    my $dest = $self->dest_file($to);
    $dest->spew({binmode => ":raw"}, $bin);
}

sub files_in_dir {
    my $dir = shift;
    my @files;
    File::Find::find(sub { push @files, $File::Find::name unless -d || /^\./ },
                     $dir);
    return \@files;
}

sub save {
    my ($self, $epub_path) = @_;

    my $zip_error;
    Archive::Zip::setErrorHandler( sub { $zip_error = shift } );
    my $zip = Archive::Zip->new();
    my $dir = $self->{tmpdir};
    my $files = files_in_dir($dir);
    for my $file (@$files) {
        my $relative_path = $file;
        $relative_path =~ s{^$dir/}{};
        $zip->addFile($file, $relative_path)
            or die "Error adding file $file to zip: not a readable plain file";
    }

    unless ($zip->writeToFileNamed($epub_path) == AZ_OK) {
        die 'Error writing zip file: ', $zip_error;
    }
}

sub add_gaiji {
    my ($self, $bin, $path) = @_;
    $self->write_string($bin, "EPUB/gaiji/$path");
    push @{$self->assets}, "gaiji/$path";
}

sub add_image {
    my ($self, $bin, $path) = @_;
    $self->write_string($bin, "EPUB/images/$path");
    push @{$self->assets}, "images/$path";
}

sub _add_name_to_array {
    my $array = shift;
    return [ map {
            {
                name => gensym,
                value => $_
            }



( run in 0.864 second using v1.01-cache-2.11-cpan-99c4e6809bf )