From: Vincent Vanwaelscappel Date: Thu, 16 Sep 2021 16:11:57 +0000 (+0200) Subject: wip #4666 @2 X-Git-Url: http://git.cubedesigners.com/?a=commitdiff_plain;h=a9914c1feaf0f0db163e83ebe81ff5b9a0af61ce;p=fluidbook_tools.git wip #4666 @2 --- diff --git a/src/Compiler/Compiler.php b/src/Compiler/Compiler.php index 06478d3..928890b 100644 --- a/src/Compiler/Compiler.php +++ b/src/Compiler/Compiler.php @@ -5,6 +5,10 @@ namespace Fluidbook\Tools\Compiler; use Cubist\Util\Files\Files; use Cubist\Util\Files\VirtualDirectory; use Cubist\Util\PHP; +use Exception; +use Fluidbook\Tools\Jobs\ProcessFile; +use Fluidbook\Tools\Jobs\ProcessPage; +use Fluidbook\Tools\Search\SearchIndex; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldBeUnique; use Illuminate\Contracts\Queue\ShouldQueue; @@ -12,6 +16,7 @@ use Illuminate\Foundation\Bus\Dispatchable; use Illuminate\Queue\InteractsWithQueue; use Illuminate\Queue\Jobs\SyncJob; use Illuminate\Queue\SerializesModels; +use stdClass; class Compiler implements ShouldQueue, ShouldBeUnique { @@ -30,10 +35,26 @@ class Compiler implements ShouldQueue, ShouldBeUnique */ protected $config; - public function __construct() + /** + * @var Source[] + */ + protected $sources = []; + + /** + * @var SourcePage[] + */ + protected $pages = []; + + public function addSource($document, $start = 1, $pages = null) { + $source = new Source($document,$this, $start ); + $this->sources[] = $source; + foreach ($source->getRange() as $sourcePage) { + $this->pages[] = new SourcePage($source, $sourcePage); + } } + /** * Execute the job. * @@ -57,23 +78,193 @@ class Compiler implements ShouldQueue, ShouldBeUnique public function processPages($sync = false) { start_measure('Process Pages'); - $out = $this->getConvertPath(); - Files::mkdir($out); - $this->in->processPages($out, $this->getProcessFiles(), $sync); + foreach ($this->sources as $source) { + $source->getDocument()->processPages($this->getProcessFiles(), $source->getRange(), $sync); + } stop_measure('Process Pages'); } - public function getConvertPath() - { - return storage_path('fluidbook/convert/' . $this->in->getHash() . '/'); - } - public function getTexts() { start_measure('Process texts'); - $this->in->processTexts($this->getConvertPath()); + foreach ($this->sources as $source) { + $source->getDocument()->processTexts(); + } start_measure('Process texts'); } + /** + * @return ProcessFile[] + */ + public function getProcessFiles() + { + return [ + 'thumb' => new ProcessFile('jpg', 'thumb'), + 'back150' => new ProcessFile('jpg', 150, true, false), + 'text' => new ProcessFile('svg', 300, false, true), + ]; + } + + /** + * @param $name + * @param null|int $page + * @return ProcessFile + * @throws Exception + */ + public function getProcessFile($name, $page = null) + { + $files = $this->getProcessFiles(); + if (isset($files[$name])) { + $res = $files[$name]; + if (null !== $page) { + $sourcePage = $this->getSourceOfPage($page); + $res->setJob(new ProcessPage($sourcePage->getSource(), $sourcePage->getPage())); + } + return $res; + } + throw new Exception(sprintf('File %s does not exist', $name)); + } + + /** + * @param $page + * @return SourcePage + * @throws Exception + */ + public function getSourceOfPage($page) + { + if (isset($this->pages[$page - 1])) { + return $this->pages[$page - 1]; + } + throw new Exception(sprintf('There is no source for page %d', $page)); + } + + public function getLinks() + { + start_measure('Process links'); + foreach ($this->sources as $source) { + $source->getDocument()->processLinks(); + } + + start_measure('Process links'); + } + + /** + * @throws JsonException + */ + protected function compileFluidbook() + { + start_measure('Compile fluidbook'); + + $this->vdir = new VirtualDirectory($this->out); + $this->vdir->copyDirectory($this->stub, '/'); + + $this->compileContents(); + $this->compileSearch(); + $this->compileConfig(); + + $this->vdir->sync(true); + + stop_measure('Compile fluidbook'); + } + + public function compileContents() + { + for ($i = 1; $i <= $this->getPageCount(); $i++) { + + $this->vdir->copy($this->getProcessFile('back150', $i)->getPath(), 'data/background/150/p' . $i . '.jpg'); + $this->vdir->copy($this->getProcessFile('text', $i)->getPath(), 'data/contents/p' . $i . '.svg'); + $this->vdir->copy($this->getProcessFile('thumb', $i)->getPath(), 'data/thumbnails/p' . $i . '.jpg'); + } + } + + public function getPageCount() + { + $res = 0; + foreach ($this->sources as $source) { + $res += $source->getPages(); + } + return $res; + } + + public function compileLinks() + { + return []; + } + + /** + * @throws \JsonException + */ + public function compileSearch() + { + $index = new SearchIndex(); + + foreach ($this->pages as $i => $page) { + $index->addPage($i + 1, $page->getPage(), $page->getSource()->getDocument()->getConvertPath() . 'texts'); + } + + $this->vdir->file_put_contents('data/search.highlight.js', 'var HIGHLIGHTS=' . json_encode($index->compileHighlights(), JSON_THROW_ON_ERROR) . ';'); + $this->vdir->file_put_contents('data/search.index.js', 'var INDEX=' . json_encode($index->compileIndex(), JSON_THROW_ON_ERROR) . ';'); + } + + /** + * @throws JsonException + */ + public function compileConfig() + { + $settings = mb_substr(file_get_contents($this->stub . '/data/datas.js'), 13, -2); + $this->config = json_decode($settings, false, 512, JSON_THROW_ON_ERROR); + + $this->compileDimensions(); + $this->compilePageNumbers(); + $this->compileChapters(); + $this->config->links = $this->compileLinks(); + + $c = 'var SETTINGS=' . json_encode($this->config, JSON_THROW_ON_ERROR) . ';'; + $this->vdir->file_put_contents('data/datas.js', $c); + } + + protected function compileDimensions() + { + $width = round($this->in->getWidth(), 8); + $height = round($this->in->getHeight(), 8); + + $this->config->pageZoomFactor = 3; + $this->config->optimalWidth = 567; + $this->config->optimalHeight = 709; + $imagesize = getimagesize($this->getProcessFile('back150', 1)->getPath()); + $this->config->pdfZoomFactor = round(($imagesize[0] * 0.48) / $width, 12); + + $this->config->cssScale = $this->config->pageZoomFactor * min($this->config->optimalWidth / $width, $this->config->optimalHeight / $height); + $cssWidth = $width * $this->config->cssScale; + $cssHeight = $height * $this->config->cssScale; + + $this->config->pages = $this->in->getPages(); + $this->config->width = $cssWidth; + $this->config->height = $cssHeight; + + $this->config->multiply = $this->config->pdfZoomFactor * $this->config->cssScale; + + $this->config->pagesDimensions = []; + + $thumbDimensions = getimagesize($this->getProcessFile('thumb', 1)->getPath()); + $this->config->thumbWidth = $thumbDimensions[0]; + $this->config->thumbHeight = $thumbDimensions[1]; + + for ($i = 1; $i <= $this->in->getPages(); $i++) { + $this->config->pagesDimensions[$i] = [$this->config->width, $this->config->height]; + } + } + + protected function compilePageNumbers() + { + $this->config->numerotation = $this->in->getPageNumbers(); + } + + protected function compileChapters() + { + $this->config->chaptersPagesNumber = 'physical'; + $this->config->chapters = $this->in->getChapters(); + } + } diff --git a/src/Compiler/Source.php b/src/Compiler/Source.php new file mode 100644 index 0000000..3bbe2e8 --- /dev/null +++ b/src/Compiler/Source.php @@ -0,0 +1,64 @@ +document = $document; + $this->start = $start; + $this->pages = $pages ?? $this->document->getPages(); + } + + /** + * @return Document + */ + public function getDocument(): Document + { + return $this->document; + } + + /** + * @return int + */ + public function getPages(): int + { + return $this->pages; + } + + /** + * @return int + */ + public function getStart(): mixed + { + return $this->start; + } + + public function getEnd(): int + { + return $this->start + $this->pages - 1; + } + + public function getRange(): array + { + return range($this->getStart(), $this->getEnd()); + } +} diff --git a/src/Compiler/SourcePage.php b/src/Compiler/SourcePage.php new file mode 100644 index 0000000..990ba29 --- /dev/null +++ b/src/Compiler/SourcePage.php @@ -0,0 +1,40 @@ +source = $source; + $this->page = $page; + } + + /** + * @return int + */ + public function getPage(): int + { + return $this->page; + } + + /** + * @return Source + */ + public function getSource(): Source + { + return $this->source; + } +} diff --git a/src/Jobs/ProcessFile.php b/src/Jobs/ProcessFile.php index 8dfed35..f1147a2 100644 --- a/src/Jobs/ProcessFile.php +++ b/src/Jobs/ProcessFile.php @@ -120,7 +120,7 @@ class ProcessFile */ public function getOut() { - return $this->job->getOut(); + return $this->job->getSource()->getSource()->getDocument()->getConvertPath(); } diff --git a/src/Jobs/ProcessPage.php b/src/Jobs/ProcessPage.php index 89ec3a6..3effbfa 100644 --- a/src/Jobs/ProcessPage.php +++ b/src/Jobs/ProcessPage.php @@ -3,9 +3,8 @@ namespace Fluidbook\Tools\Jobs; use Cubist\Util\Files\Files; +use Fluidbook\Tools\Compiler\SourcePage; use Fluidbook\Tools\PDF\Document; -use Fluidbook\Tools\PDF\PDFTools; -use Fluidbook\Tools\SVG\SVGTools; use Illuminate\Bus\Queueable; use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Foundation\Bus\Dispatchable; @@ -18,46 +17,24 @@ class ProcessPage implements ShouldQueue { use Dispatchable, InteractsWithQueue, Queueable, SerializesModels; - /** - * @var Document - */ - protected $document; - - /** - * @var integer - */ - protected $page; - - /** - * @var string - */ - protected $out; - /** * @var ProcessFile[] */ protected $files = []; /** - * @param $document Document - * @param $page integer - * @param $out string - * @param ProcessFile[] $files + * @var SourcePage */ - public function __construct($document, $page, $out, $files = []) - { - $this->document = $document; - $this->page = $page; - $this->out = $out; - $this->files = $files; - } + protected $source; /** - * @param int $page + * @param $source SourcePage + * @param ProcessFile[] $files */ - public function setPage(int $page): void + public function __construct($source, $files = []) { - $this->page = $page; + $this->source = $source; + $this->files = $files; } /** @@ -65,34 +42,26 @@ class ProcessPage implements ShouldQueue */ public function getPage(): int { - return $this->page; - } - - /** - * @return string - */ - public function getOut(): string - { - return $this->out; + return $this->source->getPage(); } public function handle() { - start_measure('Process page ' . $this->page); + start_measure('Process page ' . $this->source->getPage()); foreach ($this->files as $file) { - $this->getFile($this->page, $file, false); + $this->getFile($file, false); } - stop_measure('Process page ' . $this->page); + stop_measure('Process page ' . $this->source->getPage()); } /** - * @param $page + * @p * @param $file ProcessFile * @param false $force * @return string */ - public function getFile($page, $file, $force = false) + public function getFile($file, $force = false) { $file->setJob($this); return $file->getPath($force); @@ -100,12 +69,12 @@ class ProcessPage implements ShouldQueue public function getResolutionRatio() { - return $this->document->getResolutionRatio(); + return $this->source->getSource()->getDocument()->getResolutionRatio(); } public function getMobileFirstRatio() { - return $this->document->getMobileFirstRatio(); + return $this->source->getSource()->getDocument()->getMobileFirstRatio(); } public function splitDoc() @@ -144,11 +113,19 @@ class ProcessPage implements ShouldQueue */ public function getPagesNumber() { - return $this->document->getPages(); + return $this->source->getSource()->getDocument()->getPages(); } public function getPDFInput() { - return $this->document->getPDFInput(); + return $this->source->getSource()->getDocument()->getPDFInput(); + } + + /** + * @return SourcePage + */ + public function getSource(): SourcePage + { + return $this->source; } } diff --git a/src/PDF/Document.php b/src/PDF/Document.php index 96d6691..07ac15f 100644 --- a/src/PDF/Document.php +++ b/src/PDF/Document.php @@ -58,6 +58,11 @@ class Document return $this->hash; } + public function getConvertPath() + { + return storage_path('fluidbook/convert/' . $this->getHash() . '/'); + } + public function getInfos($force = false) { if (!$force && $this->pages > 0) { @@ -134,14 +139,15 @@ class Document } /** - * @param $dest string + * @param ProcessFile[] $files + * @param array $pages + * @param bool $sync */ - public function processPages($dest, $files, $sync = false) + public function processPages($files, $pages, $sync = false) { start_measure('Process pages (doc)'); - - for ($i = 1; $i <= $this->getPages(); $i++) { - $this->processPage($i, $dest, $files, $sync); + foreach ($pages as $i) { + $this->processPage($i, $files, $sync); } stop_measure('Process pages (doc)'); } @@ -152,28 +158,25 @@ class Document * @param $files ProcessFile[] * @param false $sync */ - public function processPage($page, $dest, $files, $sync = false) + public function processPage($page, $files, $sync = false) { $dispatchFunction = $sync ? 'dispatchSync' : 'dispatch'; - ProcessPage::$dispatchFunction($this, $page, $dest, $files); + ProcessPage::$dispatchFunction($this, $page, $this->getConvertPath(), $files); } - public function processLinks($dest) + public function processLinks() { - PDFTools::extractLinks($this->getPDFInput(), $dest); + PDFTools::extractLinks($this->getPDFInput(), $this->getConvertPath()); } - public function processTexts($dest) + public function processTexts() { start_measure('Extract texts'); - PDFTools::extractTexts($this->getPDFInput(), $dest); + PDFTools::extractTexts($this->getPDFInput(), $this->getConvertPath()); stop_measure('Extract texts'); start_measure('Get highlights data'); - PDFTools::extractHighlightsData($this->getPDFInput(), $dest); + PDFTools::extractHighlightsData($this->getPDFInput(), $this->getConvertPath()); stop_measure('Get highlights data'); - start_measure('Compile search index'); - $this->compileSearchIndex($dest); - stop_measure('Compile search index'); } public function getPageNumbers() @@ -188,12 +191,6 @@ class Document return $this->chapters; } - public function compileSearchIndex($dest) - { - - } - - public function getResolutionRatio() { $a4surface = 500990; // en pt²