Fixing description generation

+ Removing existing description from TOC (Calibre use it if present)
master
Julien Rosset 1 year ago
parent 35496b5c8e
commit 7efd79fc3e

@ -1,4 +1,5 @@
<?php /** @noinspection HtmlUnknownTarget */ <?php
/** @noinspection HtmlUnknownTarget */
namespace jrosset; namespace jrosset;
@ -41,16 +42,16 @@ class Main {
self::TWIG_TEMPLATE_METADATA_DESCRIPTION => <<<'TWIG' self::TWIG_TEMPLATE_METADATA_DESCRIPTION => <<<'TWIG'
<div> <div>
<p>{{ description }}</p> <p>{{ description }}</p>
<p><b>Chapters:</b> {{ chapters ?? 1 }}</p> <p><strong>Chapters:</strong> {{ chapters ?? 1 }}</p>
<p><b>Word count:</b> {{ words }}</p> <p><strong>Word count:</strong> {{ words }}</p>
<p><b>Published:</b> {{ publishDate }}</p> <p><strong>Published:</strong> {{ publishDate }}</p>
<p><b>Last update:</b> {{ lastUpdateDate ?? publishDate }}</p> <p><strong>Last update:</strong> {{ lastUpdateDate ?? publishDate }}</p>
<p><b>Status:</b> {{ status }}</p> <p><strong>Status:</strong> {{ status }}</p>
<p><b>Rated:</b> {{ rated }}</p> <p><strong>Rated:</strong> {{ rated }}</p>
<p><b>Genre:</b> {{ genre }}</p> <p><strong>Genre:</strong> {{ genre }}</p>
<p><b>Pairings:</b> {{ characters }}</p> <p><strong>Pairings:</strong> {{ characters }}</p>
<p><b>Source link:</b><a href="{{ url }}"><span style="color: #6cb4ee">{{ url }}</span></a></p> <p><strong>Source link:</strong><a href="{{ url|default('#') }}"><span style="color: #6cb4ee">{{ url|default(' ') }}</span></a></p>
<p><b>Exported by:</b> {{ exportedBy }})</p> <p><strong>Exported by:</strong> {{ exportedBy }}</p>
</div> </div>
TWIG TWIG
, ,
@ -260,7 +261,7 @@ EOF
/** /**
* Execute the command * Execute the command
* *
* @param InputInterface $input The command line input * @param InputInterface $input The command line input
* @param OutputInterface $output The command line output * @param OutputInterface $output The command line output
* *
* @return int The command exit status code * @return int The command exit status code
@ -318,7 +319,7 @@ EOF
/** /**
* Process a file * Process a file
* *
* @param SplFileInfo $file The file * @param SplFileInfo $file The file
* @param OutputInterface $output The command line output * @param OutputInterface $output The command line output
* *
* @return void * @return void
@ -386,7 +387,7 @@ EOF
//endregion //endregion
//region Meta "container" file: root file path //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); $output->writeln('Processing meta "container": ' . $metaContainerPath, OutputInterface::VERBOSITY_VERBOSE);
//region Read and parse //region Read and parse
@ -476,11 +477,72 @@ EOF
return; return;
} }
//endregion //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('<error>Unable to delete existing temporary TOC file (' . $rootFilePathTemp . '): ' . (new LastErrorException())->getMessage() . '</error>');
$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('<error>Failed to write temporary TOC file (' . $rootFilePathTemp . '): ' . (new LastErrorException())->getMessage() . '</error>');
$fileArchive->close();
return;
}
//endregion
//region Replace TOC file in ZIP
if (($rootFileIndex = $fileArchive->locateName($rootFilePath)) === false) {
$output->writeln('<error>Unable to locate TOC file index: ' . $rootFilePath . '</error>');
$fileArchive->close();
return;
}
/** @noinspection PhpVoidFunctionResultUsedInspection */
if (!$fileArchive->replaceFile(
$rootFilePathTemp,
$rootFileIndex,
flags: ZipArchive::FL_ENC_UTF_8
)) {
$output->writeln('<error>Unable to replace TOC file: ' . $fileArchive->getStatusString() . '</error>');
$fileArchive->close();
return;
}
//endregion
}
//endregion
//endregion
unset($rootFileXPath); unset($rootFileXPath);
//endregion //endregion
//region TOC file: first page content //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); $output->writeln('Processing TOC file: ' . $tocFilePath, OutputInterface::VERBOSITY_VERBOSE);
//region Read and parse //region Read and parse
@ -554,10 +616,10 @@ EOF
unset($tocFileXPath); unset($tocFileXPath);
//endregion //endregion
//region Read the first page //region Read the first page
$firstPagePath = dirname($tocFilePath) . DIRECTORY_SEPARATOR . $firstPagePath; $firstPagePath = dirname($tocFilePath) . '/' . $firstPagePath;
$output->writeln('Read first page: ' . $firstPagePath, OutputInterface::VERBOSITY_VERBOSE); $output->writeln('Read first page: ' . $firstPagePath, OutputInterface::VERBOSITY_VERBOSE);
if (($firstPageStream = $fileArchive->getStream($firstPagePath)) === false) { if (($firstPageStream = $fileArchive->getStream($firstPagePath)) === false) {
$output->writeln('<error>Failed to open first page: ' . $fileArchive->getStatusString() . '</error>'); $output->writeln('<error>Failed to open first page (' . $firstPagePath . '): ' . $fileArchive->getStatusString() . '</error>');
$fileArchive->close(); $fileArchive->close();
return; return;
} }
@ -688,7 +750,7 @@ EOF
case 'status': case 'status':
$metadata->status = match (mb_strtolower($match['value'])) { $metadata->status = match (mb_strtolower($match['value'])) {
'completed' => 'complete', 'completed' => 'complete',
default => $match['value'], default => $match['value'],
}; };
break; break;
@ -757,8 +819,8 @@ EOF
/** @noinspection HttpUrlsUsage */ /** @noinspection HttpUrlsUsage */
$opfMetadata->setAttributeNS(self::DOM_NAMESPACE_ATTRIBUTE, 'xmlns:opf', self::OPF_NAMESPACE_OPF); $opfMetadata->setAttributeNS(self::DOM_NAMESPACE_ATTRIBUTE, 'xmlns:opf', self::OPF_NAMESPACE_OPF);
$title = $opf->createElementNS(self::OPF_NAMESPACE_DC, 'dc:publisher', $metadata->publisher); $publisher = $opf->createElementNS(self::OPF_NAMESPACE_DC, 'dc:publisher', $metadata->publisher);
$opfMetadata->appendChild($title); $opfMetadata->appendChild($publisher);
if (isset($metadata->title)) { if (isset($metadata->title)) {
$title = $opf->createElementNS(self::OPF_NAMESPACE_DC, 'dc:title', $metadata->title); $title = $opf->createElementNS(self::OPF_NAMESPACE_DC, 'dc:title', $metadata->title);
@ -836,10 +898,10 @@ EOF
foreach ($errors as $error) { foreach ($errors as $error) {
$levelName = match ($error->level) { $levelName = match ($error->level) {
LIBXML_ERR_WARNING => 'Warning', LIBXML_ERR_WARNING => 'Warning',
LIBXML_ERR_ERROR => 'Error', LIBXML_ERR_ERROR => 'Error',
LIBXML_ERR_FATAL => 'Fatal', LIBXML_ERR_FATAL => 'Fatal',
LIBXML_ERR_NONE => 'None', LIBXML_ERR_NONE => 'None',
default => 'Unknown (' . $error->level . ')' default => 'Unknown (' . $error->level . ')'
}; };
$output->writeln( $output->writeln(
'<error>' . $levelName . ' #' . $error->code . ': ' . $error->message . ' (line: ' . $error->line . ', column: ' . $error->column . ')</error>', '<error>' . $levelName . ' #' . $error->code . ': ' . $error->message . ' (line: ' . $error->line . ', column: ' . $error->column . ')</error>',

Loading…
Cancel
Save