ExportDownload.php 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174
  1. <?php
  2. namespace App\Tools;
  3. use Illuminate\Support\Str;
  4. use Illuminate\Support\Facades\Log;
  5. use Illuminate\Support\Facades\Storage;
  6. use App\Tools\RedisClusters;
  7. use App\Tools\Export;
  8. class ExportDownload
  9. {
  10. protected $exportStatusKey = 'export/status';
  11. protected $exportStatusExpiry = 3600;
  12. protected $currExportStatusKey = '';
  13. protected $realFilename = 'filename';
  14. protected $format = 'tex';
  15. protected $debug = false;
  16. protected $zipFilename = 'file';
  17. /**
  18. * Create a new command instance.
  19. *
  20. * @return void
  21. */
  22. public function __construct($options)
  23. {
  24. if(isset($options['format'])){
  25. $this->format = $options['format'];
  26. }
  27. if(isset($options['debug'])){
  28. $this->debug = $options['debug'];
  29. }
  30. if(isset($options['filename'])){
  31. $this->zipFilename = $options['filename'];
  32. }
  33. if(isset($options['real_filename'])){
  34. $this->realFilename = $options['real_filename'];
  35. }
  36. $this->currExportStatusKey = $this->exportStatusKey . '/' . $this->zipFilename;
  37. }
  38. /**
  39. * progress: 0-1, error -1
  40. * message: string
  41. */
  42. public function setStatus($progress,$message=''){
  43. $data = [
  44. 'progress'=>$progress,
  45. 'message'=>$message,
  46. 'content-type'=>'application/zip',
  47. ];
  48. if($this->realFilename){
  49. $data['filename'] = $this->realFilename;
  50. }
  51. RedisClusters::put($this->currExportStatusKey,
  52. $data,
  53. $this->exportStatusExpiry);
  54. $percent = (int)($progress * 100);
  55. return "[{$percent}%]".$message;
  56. }
  57. public function getStatus($filename){
  58. return RedisClusters::get($this->exportStatusKey.'/'.$filename);
  59. }
  60. public function upload(string $type,$sections,$bookMeta){
  61. $m = new \Mustache_Engine(array('entity_flags'=>ENT_QUOTES,
  62. 'delimiters' => '[[ ]]',
  63. 'escape'=>function ($value){
  64. return $value;
  65. }));
  66. $tex = array();
  67. $tplFile = resource_path("mustache/".$type.'/'.$this->format."/main.".$this->format);
  68. $tpl = file_get_contents($tplFile);
  69. $texContent = $m->render($tpl,$bookMeta);
  70. $tex[] = ['name'=>'main.'.$this->format,
  71. 'content'=>$texContent
  72. ];
  73. foreach ($sections as $key => $section) {
  74. $tplFile = resource_path("mustache/".$type.'/'.$this->format."/section.".$this->format);
  75. $tpl = file_get_contents($tplFile);
  76. $texContent = $m->render($tpl,$section['body']);
  77. $tex[] = ['name'=>$section['name'],
  78. 'content'=>$texContent
  79. ];
  80. }
  81. Log::debug('footnote start');
  82. //footnote
  83. $tplFile = resource_path("mustache/".$this->format."/footnote.".$this->format);
  84. if(isset($GLOBALS['note']) &&
  85. is_array($GLOBALS['note']) &&
  86. count($GLOBALS['note'])>0 &&
  87. file_exists($tplFile)){
  88. $tpl = file_get_contents($tplFile);
  89. $texContent = $m->render($tpl,['footnote'=>$GLOBALS['note']]);
  90. $tex[] = ['name'=>'footnote.'.$this->format,
  91. 'content'=>$texContent
  92. ];
  93. }
  94. if($this->debug){
  95. $dir = "export/{$type}/".$this->format."/".$this->zipFilename."/";
  96. foreach ($tex as $key => $section) {
  97. Storage::disk('local')->put($dir.$section['name'], $section['content']);
  98. }
  99. }
  100. Log::debug('footnote finished');
  101. $this->setStatus(0.95,'export content done.');
  102. //upload
  103. $fileDate = '';
  104. switch ($this->format) {
  105. case 'tex':
  106. $data = Export::ToPdf($tex);
  107. if($data['ok']){
  108. $this->info($data['content-type']);
  109. $fileDate = $data['data'];
  110. }else{
  111. $this->error($data['code'].'-'.$data['message']);
  112. }
  113. break;
  114. case 'html':
  115. $file = array();
  116. foreach ($tex as $key => $section) {
  117. $file[] = $section['content'];
  118. }
  119. $fileDate = implode('',$file);
  120. break;
  121. }
  122. $zipDir = storage_path('app/export/zip');
  123. if(!is_dir($zipDir)){
  124. $res = mkdir($zipDir,0755,true);
  125. if(!$res){
  126. Log::error('mkdir fail path='.$zipDir);
  127. return 1;
  128. }
  129. }
  130. $zipFile = $zipDir.'/'.Str::uuid().'.zip';
  131. Log::debug('export chapter start zip file='.$zipFile);
  132. //zip压缩包里面的文件名
  133. $realFilename = $this->realFilename.".".$this->format;
  134. $zipOk = \App\Tools\Tools::zip($zipFile,[$realFilename=>$fileDate]);
  135. if(!$zipOk){
  136. Log::error('export chapter zip fail zip file='.$zipFile);
  137. $this->setStatus(0.99,'export chapter zip fail');
  138. $this->error('export chapter zip fail zip file='.$zipFile);
  139. //TODO 给客户端返回错误状态
  140. return 1;
  141. }
  142. $this->setStatus(0.96,'export chapter zip success');
  143. $bucket = config('mint.attachments.bucket_name.temporary');
  144. $tmpFile = $bucket.'/'. $this->zipFilename ;
  145. Log::debug('upload start filename='.$tmpFile);
  146. $this->setStatus(0.97,'upload start ');
  147. $zipData = file_get_contents($zipFile);
  148. Storage::put($tmpFile, $zipData);
  149. $this->setStatus(1,'export chapter done');
  150. Log::debug('export chapter done, upload filename='.$tmpFile);
  151. unlink($zipFile);
  152. return true;
  153. }
  154. }