format = $options['format']; } if (isset($options['debug'])) { $this->debug = $options['debug']; } if (isset($options['filename'])) { $this->realFilename = $options['filename']; } $this->queryId = $options['queryId']; $this->zipFilename = $this->queryId.'.zip'; $this->currStatusKey = $this->statusKey.'/'.$this->queryId; } /** * progress: 0-1, error -1 * message: string */ public function setStatus($progress, $message = '') { $this->logs[] = $message; $data = [ 'progress' => $progress, 'message' => $message, 'log' => $this->logs, 'content-type' => 'application/zip', ]; if ($this->downloadUrl) { $data['url'] = $this->downloadUrl; } Cache::put( $this->currStatusKey, $data, $this->statusExpiry ); $percent = (int) ($progress * 100); return "[{$percent}%]".$message; } public function getStatus() { return Cache::get($this->currStatusKey); } public function upload(string $type, $sections, $bookMeta) { $outputFilename = Str::uuid(); $m = new \Mustache_Engine([ 'entity_flags' => ENT_QUOTES, 'delimiters' => '[[ ]]', 'escape' => function ($value) { return $value; }, ]); $tex = []; $_format = 'md'; $tplFile = resource_path('mustache/'.$type.'/'.$_format.'/main.'.$_format); $tpl = file_get_contents($tplFile); $texContent = $m->render($tpl, $bookMeta); $tex[] = [ 'name' => 'main.'.$_format, 'content' => $texContent, ]; foreach ($sections as $key => $section) { $tplFile = resource_path('mustache/'.$type.'/'.$_format.'/section.'.$_format); $tpl = file_get_contents($tplFile); $texContent = $m->render($tpl, $section['body']); $tex[] = [ 'name' => $section['name'], 'content' => $texContent, ]; } Log::debug('footnote start'); // footnote $tplFile = resource_path('mustache/'.$_format.'/footnote.'.$_format); if ( isset($GLOBALS['note']) && is_array($GLOBALS['note']) && count($GLOBALS['note']) > 0 && file_exists($tplFile) ) { $tpl = file_get_contents($tplFile); $texContent = $m->render($tpl, ['footnote' => $GLOBALS['note']]); $tex[] = [ 'name' => 'footnote.'.$_format, 'content' => $texContent, ]; } Log::debug('footnote finished'); $this->setStatus(0.95, 'export content done. tex count='.count($tex)); Log::debug('export content done.', ['tex_count' => count($tex)]); // upload $fileDate = ''; switch ($this->format) { case 'tex': $data = Export::ToPdf($tex); if ($data['ok']) { $this->info($data['content-type']); $fileDate = $data['data']; } else { $this->error($data['code'].'-'.$data['message']); } break; default: $file = []; foreach ($tex as $key => $section) { $file[] = $section['content']; } $fileDate = implode('', $file); break; } $dir = "tmp/export/{$type}/".$this->format.'/'; $mdFilename = $dir.$outputFilename.'.md'; Storage::disk('local')->put($mdFilename, $fileDate); Log::debug('markdown saved', ['filename' => $mdFilename]); if ($this->format === 'markdown') { $filename = $mdFilename; } else { $filename = $dir.$outputFilename.'.'.$this->format; Log::debug('tmp saved', ['filename' => $filename]); $absoluteMdPath = Storage::disk('local')->path($mdFilename); $absoluteOutputPath = Storage::disk('local')->path($filename); // $command = "pandoc pandoc1.md --reference-doc tpl.docx -o pandoc1.docx"; $command = ['pandoc', $absoluteMdPath, '-o', $absoluteOutputPath]; if ($this->format === 'docx') { $tplFile = resource_path('template/docx/paper.docx'); array_push($command, '--reference-doc'); array_push($command, $tplFile); } Log::debug('pandoc start', ['command' => $command, 'format' => $this->format]); $process = new Process($command); $process->run(); if (! $process->isSuccessful()) { throw new ProcessFailedException($process); } echo $process->getOutput(); Log::debug('pandoc end', ['command' => $command]); } $zipDir = storage_path('app/export/zip'); if (! is_dir($zipDir)) { $res = mkdir($zipDir, 0755, true); if (! $res) { Log::error('mkdir fail path='.$zipDir); return 1; } } $zipFile = $zipDir.'/'.$outputFilename.'.zip'; Log::debug('export chapter start zip file='.$zipFile); // zip压缩包里面的文件名 $realFilename = $this->realFilename.'.'.$this->format; $fileContent = Storage::disk('local')->get($filename); $zipOk = Tools::zip($zipFile, [$realFilename => $fileContent]); if (! $zipOk) { Log::error('export chapter zip fail zip file='.$zipFile); $this->setStatus(0.99, 'export chapter zip fail'); $this->error('export chapter zip fail zip file='.$zipFile); // TODO 给客户端返回错误状态 return 1; } $this->setStatus(0.96, 'export chapter zip success'); $bucket = config('mint.attachments.bucket_name.temporary'); $tmpFile = $bucket.'/'.$this->zipFilename; Log::debug('upload start filename='.$tmpFile); $this->setStatus(0.97, 'upload start '); $zipData = file_get_contents($zipFile); Storage::put($tmpFile, $zipData); if (App::environment('local')) { $s3Link = Storage::url($tmpFile); } else { try { $s3Link = Storage::temporaryUrl($tmpFile, now()->addDays(7)); } catch (\Exception $e) { Log::error('export {Exception}', ['exception' => $e]); return false; } } $this->downloadUrl = $s3Link; $this->setStatus(1, 'export chapter done'); Log::debug('export chapter done, upload', ['filename' => $tmpFile, 'url' => $s3Link]); unlink($zipFile); return true; } }