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;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\Jobs\SyncJob;
use Illuminate\Queue\SerializesModels;
+use stdClass;
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.
*
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();
+ }
+
}
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;
{
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;
}
/**
*/
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);
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()
*/
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;
}
}
return $this->hash;
}
+ public function getConvertPath()
+ {
+ return storage_path('fluidbook/convert/' . $this->getHash() . '/');
+ }
+
public function getInfos($force = false)
{
if (!$force && $this->pages > 0) {
}
/**
- * @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)');
}
* @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()
return $this->chapters;
}
- public function compileSearchIndex($dest)
- {
-
- }
-
-
public function getResolutionRatio()
{
$a4surface = 500990; // en pt²