3

特定の親フォルダーからファイルのグループを圧縮して*.epubファイルを作成するperlスクリプトを作成しています。プロセスは正常に機能し、Adobe Digital EditionでePubを開くことはできますが、ePubcheckerエラーが発生します。

Required MTA-INF/container.xml resource is missing

ファイルを手動で圧縮する場合(私はwinxpマシンを使用しています)、問題はありませんが、perlで作成されたファイルはエラーをスローします。関連するコードは次のとおりです。

#------------------------------------------------------------------------------- 
# name      :   createEpub
# purpose   :   create an epub from a given parent folder
# args      :   [0] parent folder [1] name of new zip file [2] log object
# example   :   &createEpub( $zipLoc, 'newzip', $log);
# notes     :   it is assumed that mimetype, meta-inf and oebs are all child folders
#               of the given parent folder
# author:   :   jw 2/4/13
#-------------------------------------------------------------------------------


sub createEpub(){
my ($parentFolder, $zipName, $log) = @_;
my $newZipLoc;
$parentFolder =~ s#\\#/#g;

    my $newZip = Archive::Zip->new();

    # add mimetype first with no compression
    my $mimetype = "$parentFolder/mimetype";
    my $mimetypeMember = $newZip->addFile( $mimetype, 'mimetype');
    $mimetypeMember->desiredCompressionMethod( COMPRESSION_STORED );

    ## add web-inf
    my $metaINF = $parentFolder . '/META-INF';
    &addFilesToZip( $metaINF, $parentFolder, $newZip, $log);

    ## add OEBPS
    my $oebps = $parentFolder . '/OEBPS';
    &addFilesToZip( $oebps, $parentFolder, $newZip, $log );

    # maybe break this out in its own func...ok for current epub script purposes
    $newZipLoc = $1 if $parentFolder =~ m/(.*)\//;
    $newZipLoc = $newZipLoc . '/' . $zipName;
    if( $newZipLoc !~ m/\.zip/){
        $newZipLoc = $newZipLoc . '.epub';
    }

    $log->info("writing new zip file to $newZipLoc");
    $newZip->writeToFileNamed( $newZipLoc );

    ## not sure if this is the write thing to do...returning actual file name, not zip     extract object
    return $newZipLoc;

}


sub addFilesToZip(){
my ($file, $origParent, $zip, $log) = @_;

    if( -d $file ){
        my @children = grep{ $_ !~ m/mimetype/} glob("$file/*") or warn "can't add     $file to zip! $!\n";
            foreach my $child( @children ){
                &addFilesToZip( $child, $origParent, $zip, $log);
            }
        } elsif (-f $file){
            my $memPath = $file; $memPath =~ s/\Q$origParent\E//;
            $log->info("adding member $memPath");
            my $newMember = $zip->addFile( $file, $memPath );

        }



}

結果のepubファイルをwinzipで開くと、container.xmlが確実に存在します。また、mimetypeが最初に圧縮されていないことを確認しました。ログからの抜粋は次のとおりです。

-------------------------------------------------------------------------
    creating zip file from recently unzipped files
-------------------------------------------------------------------------

[ok]:     adding member /META-INF/container.xml
[ok]:     adding member /META-INF/stylesheet.css.kindle
[ok]:     adding member /META-INF/toc.ncx.kindle
[ok]:     adding member /OEBPS/content.opf
[ok]:     adding member /OEBPS/coverpage.html

グーグルでは、Linuxシェルコマンドにわずかな変更が加えられているのを確認しましたが、archive::zipまたはwinに関連するものは何も表示されませんでした。

ありがとう、bp

4

1 に答える 1

3

ログから、絶対パスを使用してzipファイルにエントリを作成しているように見えます。

[ok]:     adding member /META-INF/container.xml

ePubファイルは相対パスである必要があると思います。zipファイルに書き込まれるパスから先頭の「/」を削除してみてください。thsのようなもの(未テスト)

    } elsif (-f $file){
        my $memPath = $file; $memPath =~ s/\Q$origParent\E//;
        # remove leading "/"
        $memPath =~ s#^/+##;
        $log->info("adding member $memPath");
        my $newMember = $zip->addFile( $file, $memPath );

    }
于 2013-02-05T11:41:07.380 に答える