From 7efd79fc3ebc69413709e063fe1cb22c1ea565d4 Mon Sep 17 00:00:00 2001 From: Julien Rosset Date: Wed, 10 Jul 2024 11:02:02 +0200 Subject: [PATCH] Fixing description generation + Removing existing description from TOC (Calibre use it if present) --- src/Main.php | 110 ++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 86 insertions(+), 24 deletions(-) diff --git a/src/Main.php b/src/Main.php index 216fbb2..0119ba4 100644 --- a/src/Main.php +++ b/src/Main.php @@ -1,4 +1,5 @@ - <<<'TWIG'

{{ description }}

-

Chapters: {{ chapters ?? 1 }}

-

Word count: {{ words }}

-

Published: {{ publishDate }}

-

Last update: {{ lastUpdateDate ?? publishDate }}

-

Status: {{ status }}

-

Rated: {{ rated }}

-

Genre: {{ genre }}

-

Pairings: {{ characters }}

-

Source link:{{ url }}

-

Exported by: {{ exportedBy }})

+

Chapters: {{ chapters ?? 1 }}

+

Word count: {{ words }}

+

Published: {{ publishDate }}

+

Last update: {{ lastUpdateDate ?? publishDate }}

+

Status: {{ status }}

+

Rated: {{ rated }}

+

Genre: {{ genre }}

+

Pairings: {{ characters }}

+

Source link:{{ url|default(' ') }}

+

Exported by: {{ exportedBy }}

TWIG , @@ -260,7 +261,7 @@ EOF /** * Execute the command * - * @param InputInterface $input The command line input + * @param InputInterface $input The command line input * @param OutputInterface $output The command line output * * @return int The command exit status code @@ -318,7 +319,7 @@ EOF /** * Process a file * - * @param SplFileInfo $file The file + * @param SplFileInfo $file The file * @param OutputInterface $output The command line output * * @return void @@ -386,7 +387,7 @@ EOF //endregion //region Meta "container" file: root file path - $metaContainerPath = 'META-INF' . DIRECTORY_SEPARATOR . 'container.xml'; + $metaContainerPath = 'META-INF/container.xml'; $output->writeln('Processing meta "container": ' . $metaContainerPath, OutputInterface::VERBOSITY_VERBOSE); //region Read and parse @@ -476,11 +477,72 @@ EOF return; } //endregion + //region Delete description if present + //region Deletion form DOM + $rootFileDirty = false; + /** @noinspection HttpUrlsUsage */ + $rootFileXPath->registerNamespace('dc', 'http://purl.org/dc/elements/1.1/'); + if (($descriptionNodeList = $rootFileXPath->query('/r:package/r:metadata/dc:description')) !== false && $descriptionNodeList->count() > 0) { + $output->writeln($descriptionNodeList->count() . ' descriptions found → removing', OutputInterface::VERBOSITY_VERBOSE); + /** @var DOMNode $descriptionNode */ + foreach ($descriptionNodeList as $descriptionNode) { + $descriptionNode->parentNode->removeChild($descriptionNode); + $rootFileDirty = true; + } + } + else { + $output->writeln('no descriptions found', OutputInterface::VERBOSITY_VERBOSE); + } + //endregion + //region Overwrite root file in ZIP + if ($rootFileDirty) { + //region Get temporary TOC file + $rootFilePathTemp = sys_get_temp_dir() . DIRECTORY_SEPARATOR . basename($rootFilePath); + $output->writeln('Temporary TOC file path: ' . $rootFilePathTemp, OutputInterface::VERBOSITY_VERBOSE); + + if (file_exists($rootFilePathTemp)) { + if (!unlink($rootFilePathTemp)) { + $output->writeln('Unable to delete existing temporary TOC file (' . $rootFilePathTemp . '): ' . (new LastErrorException())->getMessage() . ''); + $fileArchive->close(); + return; + } + } + //endregion + //region Write temporary TOC file + $rootFileDocument = $rootFileXPath->document; + $rootFileDocument->formatOutput = true; + if (file_put_contents($rootFilePathTemp, $rootFileDocument->saveXML()) === false) { + $output->writeln('Failed to write temporary TOC file (' . $rootFilePathTemp . '): ' . (new LastErrorException())->getMessage() . ''); + $fileArchive->close(); + return; + } + //endregion + //region Replace TOC file in ZIP + if (($rootFileIndex = $fileArchive->locateName($rootFilePath)) === false) { + $output->writeln('Unable to locate TOC file index: ' . $rootFilePath . ''); + $fileArchive->close(); + return; + } + + /** @noinspection PhpVoidFunctionResultUsedInspection */ + if (!$fileArchive->replaceFile( + $rootFilePathTemp, + $rootFileIndex, + flags: ZipArchive::FL_ENC_UTF_8 + )) { + $output->writeln('Unable to replace TOC file: ' . $fileArchive->getStatusString() . ''); + $fileArchive->close(); + return; + } + //endregion + } + //endregion + //endregion unset($rootFileXPath); //endregion //region TOC file: first page content - $tocFilePath = dirname($rootFilePath) . DIRECTORY_SEPARATOR . $tocFilePath; + $tocFilePath = dirname($rootFilePath) . '/' . $tocFilePath; $output->writeln('Processing TOC file: ' . $tocFilePath, OutputInterface::VERBOSITY_VERBOSE); //region Read and parse @@ -554,10 +616,10 @@ EOF unset($tocFileXPath); //endregion //region Read the first page - $firstPagePath = dirname($tocFilePath) . DIRECTORY_SEPARATOR . $firstPagePath; + $firstPagePath = dirname($tocFilePath) . '/' . $firstPagePath; $output->writeln('Read first page: ' . $firstPagePath, OutputInterface::VERBOSITY_VERBOSE); if (($firstPageStream = $fileArchive->getStream($firstPagePath)) === false) { - $output->writeln('Failed to open first page: ' . $fileArchive->getStatusString() . ''); + $output->writeln('Failed to open first page (' . $firstPagePath . '): ' . $fileArchive->getStatusString() . ''); $fileArchive->close(); return; } @@ -688,7 +750,7 @@ EOF case 'status': $metadata->status = match (mb_strtolower($match['value'])) { 'completed' => 'complete', - default => $match['value'], + default => $match['value'], }; break; @@ -757,8 +819,8 @@ EOF /** @noinspection HttpUrlsUsage */ $opfMetadata->setAttributeNS(self::DOM_NAMESPACE_ATTRIBUTE, 'xmlns:opf', self::OPF_NAMESPACE_OPF); - $title = $opf->createElementNS(self::OPF_NAMESPACE_DC, 'dc:publisher', $metadata->publisher); - $opfMetadata->appendChild($title); + $publisher = $opf->createElementNS(self::OPF_NAMESPACE_DC, 'dc:publisher', $metadata->publisher); + $opfMetadata->appendChild($publisher); if (isset($metadata->title)) { $title = $opf->createElementNS(self::OPF_NAMESPACE_DC, 'dc:title', $metadata->title); @@ -836,10 +898,10 @@ EOF foreach ($errors as $error) { $levelName = match ($error->level) { LIBXML_ERR_WARNING => 'Warning', - LIBXML_ERR_ERROR => 'Error', - LIBXML_ERR_FATAL => 'Fatal', - LIBXML_ERR_NONE => 'None', - default => 'Unknown (' . $error->level . ')' + LIBXML_ERR_ERROR => 'Error', + LIBXML_ERR_FATAL => 'Fatal', + LIBXML_ERR_NONE => 'None', + default => 'Unknown (' . $error->level . ')' }; $output->writeln( '' . $levelName . ' #' . $error->code . ': ' . $error->message . ' (line: ' . $error->line . ', column: ' . $error->column . ')',