From 2fb4be0e5548b662085b56a4eedbfc0d5622d153 Mon Sep 17 00:00:00 2001 From: Paolo Date: Thu, 14 Oct 2021 11:34:27 +0200 Subject: [PATCH] - Added new config entry DOCSBOX_ENABLED to config/global.config-default.inc.php - Added new library application/libraries/DocsboxLib.php to manage document conversion using docsbox - Added new config file application/config/docsbox.php - Integrated DocsboxLib into include/dokument_export.class.php --- application/config/docsbox.php | 7 + application/libraries/DocsboxLib.php | 297 +++++++++++++++++++++++++++ config/global.config-default.inc.php | 3 + include/Docsbox.php | 112 ---------- include/dokument_export.class.php | 101 +++++---- 5 files changed, 372 insertions(+), 148 deletions(-) create mode 100644 application/config/docsbox.php create mode 100644 application/libraries/DocsboxLib.php delete mode 100644 include/Docsbox.php diff --git a/application/config/docsbox.php b/application/config/docsbox.php new file mode 100644 index 000000000..ca64698f9 --- /dev/null +++ b/application/config/docsbox.php @@ -0,0 +1,7 @@ +attach(array('file' => $inputFileName)) + ->expectsJson() + ->send(); + + // Checks that: + // - the response is not empty + // - the reponse body has the property id + // - the property id is a valid string + // - the reponse body has the property status + // - docsbox queued the conversion of the posted file + if (is_object($postFileResponse) + && isset($postFileResponse->body) + && isset($postFileResponse->body->id) + && $postFileResponse->body->id != '' && $postFileResponse->body->id != null + && isset($postFileResponse->body->status) + && $postFileResponse->body->status == self::STATUS_QUEUED) + { + $queueId = $postFileResponse->body->id; + } + else + { + // If docsbox refused to convert the posted file + if (isset($postFileResponse->body->status) + && $postFileResponse->body->status != self::STATUS_QUEUED) + { + error_log( + 'Docsbox did not queue the posted file. Returned status: '. + $postFileResponse->body->status + ); + } + else // any other generic error + { + error_log( + 'An error occurred while posting to docsbox. Response: '. + print_r($postFileResponse, 1) + ); + } + } + } + catch(\Httpful\Exception\ConnectionErrorException $cee) // Httpful exception + { + error_log($cee->getMessage()); + } + catch (Exception $e) // any other exception + { + error_log($e->getMessage()); + } + + return $queueId; + } + + /** + * Check the status of the file convertion identified by the given queue element id + * A URL is returned with the path where it is possible to download the converted file + * If an error occurred then a null value is returned + */ + private static function _checkConvertion($queueId) + { + $resultUrl = null; + $startConvertionsTime = time(); // time when the file conversion has started + + // Until a timeout has occurred + while (time() - $startConvertionsTime <= DOCSBOX_CONVERSION_TIMEOUT) + { + sleep(DOCSBOX_WAITING_SLEEP_TIME); // takes a nap on every round + + try + { + // Calls the docsbox server to check the status of the + // file conversion using the provided queue id + // it expects a response in JSON format + $getStatusResponse = \Httpful\Request::get(DOCSBOX_SERVER.DOCSBOX_PATH_API.$queueId) + ->expectsJson() + ->send(); + + // Checks that: + // - the response is not empty + // - the reponse body has the property id + // - the property id is a valid string + // - the reponse body has the property status + // - docsbox is working the conversion of the posted file + if (is_object($getStatusResponse) + && isset($getStatusResponse->body->id) + && $getStatusResponse->body->id != '' && $getStatusResponse->body->id != null + && isset($getStatusResponse->body->status)) + { + // Checks that docsbox has finished working on the file conversion + // and that there is a valid resultUrl property + if ($getStatusResponse->body->status == self::STATUS_FINISHED + && isset($getStatusResponse->body->result_url) + && $getStatusResponse->body->result_url != '' + && $getStatusResponse->body->result_url != null) + { + $resultUrl = $getStatusResponse->body->result_url; + break; + } + // Just started or still working on it + elseif ($getStatusResponse->body->status == self::STATUS_WORKING + || $getStatusResponse->body->status == self::STATUS_STARTED) + { + // go on! + } + else // any other status is abnormal + { + error_log( + 'Not valid status for queue element: '.$queueId.'. Response: '. + print_r($getStatusResponse, 1) + ); + break; // interrupt the loop on error + } + } + else // if the response from the docsbox server is not valid + { + error_log( + 'An error occurred while checking the docsbox activity. Response: '. + print_r($getStatusResponse, 1) + ); + break; // interrupt the loop on error + } + } + catch(\Httpful\Exception\ConnectionErrorException $cee) // Httpful exception + { + error_log($cee->getMessage()); + break; // interrupt the loop on error + } + catch (Exception $e) // any other exception + { + error_log($e->getMessage()); + break; // interrupt the loop on error + } + } + + return $resultUrl; + } + + /** + * Download the converted file using the provided URL, unzip it, and renames it into the provided file name + */ + private static function _downloadFile($resultUrl, $outputFileName) + { + $downloaded = false; // pessimistic assumption + + try + { + // Download the file + $getFileResponse = \Httpful\Request::get(DOCSBOX_SERVER.$resultUrl)->send(); + + // If the downloaded file content is valid and not empty + if (isset($getFileResponse->body) + && $getFileResponse->body != null + && $getFileResponse->body != '') + { + // Output directory where to unzip the downloaded zip file + $outputDirectory = dirname($outputFileName); + // The path and name of the downloaded zip file + $temporaryDownloadedZip = sys_get_temp_dir().'/'.basename($resultUrl); + + // Write the file content into a temporary directory and file + if (file_put_contents($temporaryDownloadedZip, $getFileResponse->body) != false) + { + $zipArchive = new ZipArchive; + + // Open and extract the dowloaded zip file into the directory of the output file + if ($zipArchive->open($temporaryDownloadedZip) === true + && $zipArchive->extractTo($outputDirectory) === true + && $zipArchive->close() === true) + { + // Opened, extracted and closed! + + // Rename the extracted file to the given output file name + if (rename($outputDirectory.'/'.self::OUTPUT_FILENAME, $outputFileName)) + { + $downloaded = true; + } + else + { + error_log( + 'An error occurred while renaming the extracted file: '. + $outputDirectory.'/'.self::OUTPUT_FILENAME.' into: '. + $outputFileName + ); + } + } + else + { + error_log( + 'An error occurred while working the dowloaded zip file: '. + $temporaryDownloadedZip + ); + } + } + else // if an error occurred while writing + { + error_log( + 'An error occurred while writing the file content to: '. + $temporaryDownloadedZip + ); + } + } + else // if the downloaded file is not valid + { + error_log( + 'An error occurred while downloading the file from the docsbox server: '. + print_r($getFileResponse, 1) + ); + } + } + catch(\Httpful\Exception\ConnectionErrorException $cee) + { + error_log($cee->getMessage()); + } + catch (Exception $e) + { + error_log($e->getMessage()); + } + + return $downloaded; + } +} + diff --git a/config/global.config-default.inc.php b/config/global.config-default.inc.php index b31447994..f4909ba5c 100644 --- a/config/global.config-default.inc.php +++ b/config/global.config-default.inc.php @@ -310,4 +310,7 @@ define ('ZAHLUNGSBESTAETIGUNG_ANZEIGEN_FUER_LEHRGAENGE', true); // Gibt an, ob im CIS die Zahlungsreferenz angezeigt wird define ('ZAHLUNGSBESTAETIGUNG_ZAHLUNGSREFERENZ_ANZEIGEN', false); + +define('DOCSBOX_ENABLED', false); + ?> diff --git a/include/Docsbox.php b/include/Docsbox.php deleted file mode 100644 index 08b04f71b..000000000 --- a/include/Docsbox.php +++ /dev/null @@ -1,112 +0,0 @@ -attach(array('file' => $inputFileName)) - ->expectsJson() - ->send(); - - var_dump($response);exit; - } - catch(\Httpful\Exception\ConnectionErrorException $cee) - { - // Error - } - catch (Exception $e) - { - // Error - } - - if (is_object($response) && isset($response->id) && isset($response->status)) - { - $status = null; - $result_url = null; - - while ($status == null) - { - try - { - $response = \Httpful\Request::get('http://docconverter.technikum-wien.at/api/v1/'.$response->id) - ->expectsJson() - ->send(); - - var_dump($response); - } - catch(\Httpful\Exception\ConnectionErrorException $cee) - { - // Error - } - catch (Exception $e) - { - // Error - } - - if (is_object($response) && isset($response->id) && isset($response->status)) - { - if ($response->status == 'finished' && isset($response->result_url)) - { - $status = $response->status; - $result_url = $response->result_url; - } - else - { - // Error - } - } - else - { - // Error - } - } - - try - { - $response = \Httpful\Request::get($result_url)->send(); - - var_dump($response); - } - catch(\Httpful\Exception\ConnectionErrorException $cee) - { - // Error - } - catch (Exception $e) - { - // Error - } - - var_dump($response);exit; - } - else - { - // Error - } - } -} - diff --git a/include/dokument_export.class.php b/include/dokument_export.class.php index 30af55ac6..c6c609ce9 100644 --- a/include/dokument_export.class.php +++ b/include/dokument_export.class.php @@ -37,6 +37,7 @@ class dokument_export private $images=array(); private $sourceDir; public $errormsg; + private $unoconv_version; private $sign; private $sign_user; private $sign_profile; @@ -49,6 +50,25 @@ class dokument_export if(!isset($vorlage)) return; + if (defined('DOCSBOX_ENABLED') && DOCSBOX_ENABLED === true) + { + // Use docsbox!! + } + else + { + exec('unoconv --version',$ret_arr); + if(isset($ret_arr[0])) + { + $hlp = explode(' ',$ret_arr[0]); + if(isset($hlp[1])) + $this->unoconv_version = $hlp[1]; + else + die('Could not get Unoconv Version'); + } + else + die('Unoconv not found'); + } + //Vorlage aus der Datenbank holen $this->vorlage = new vorlage(); if(!$this->vorlage->getAktuelleVorlage($oe_kurzbz, $vorlage, $version)) @@ -263,32 +283,36 @@ class dokument_export { case 'pdf': case 'doc': + $ret = 0; $this->temp_filename = $this->temp_folder . '/out.' . $this->outputformat; - // Unoconv Version 0.6 hat eine Bug wodurch die Berechtigungen des PDF/Doc nicht korrekt gesetzt - // werden. Deshalb wird dies hier speziell behandelt. - // Die 2. Variante hat den Vorteil dass hier eine bessere Fehlerbehandlung moeglich ist - //if($this->unoconv_version=='0.6') - // $command = 'unoconv -e IsSkipEmptyPages=false -f ' . $this->outputformat . ' %2$s > %1$s'; - //else - // $command = 'unoconv -e IsSkipEmptyPages=false -f ' . $this->outputformat . ' --output %s %s 2>&1'; + // If it is set to use docsbox + if (defined('DOCSBOX_ENABLED') && DOCSBOX_ENABLED === true) + { + require_once(dirname(__FILE__).'/../application/libraries/DocsboxLib.php'); - //$command = sprintf($command, $this->temp_filename, $tempname_zip); + $ret = DocsboxLib::convert($tempname_zip, $this->temp_filename); + } + else // otherwise use unoconv + { + // Unoconv Version 0.6 hat eine Bug wodurch die Berechtigungen des PDF/Doc nicht korrekt gesetzt + // werden. Deshalb wird dies hier speziell behandelt. + // Die 2. Variante hat den Vorteil dass hier eine bessere Fehlerbehandlung moeglich ist + if ($this->unoconv_version == '0.6') + $command = 'unoconv -e IsSkipEmptyPages=false -f ' . $this->outputformat . ' %2$s > %1$s'; + else + $command = 'unoconv -e IsSkipEmptyPages=false -f ' . $this->outputformat . ' --output %s %s 2>&1'; - //exec($command, $out, $ret); + $command = sprintf($command, $this->temp_filename, $tempname_zip); - require_once('Docsbox.php'); + exec($command, $out, $ret); + } - var_dump($tempname_zip); - var_dump($this->temp_filename); - - Docsbox::convert($tempname_zip, $this->temp_filename); - - //if($ret!=0) - //{ - // $this->errormsg = 'Dokumentenkonvertierung ist derzeit nicht möglich. Bitte versuchen Sie es in einer Minute erneut oder kontaktieren Sie einen Administrator'; - // return false; - //} + if ($ret != 0) + { + $this->errormsg = 'Dokumentenkonvertierung ist derzeit nicht möglich. Bitte versuchen Sie es in einer Minute erneut oder kontaktieren Sie einen Administrator'; + return false; + } break; case 'odt': default: @@ -449,26 +473,31 @@ class dokument_export */ public function convert($inFile, $outFile, $format = "pdf") { - //require_once('Docsbox.php'); + $ret = 0; - //var_dump($inFile); - //var_dump($outFile); + // If it is set to use DOCSBOX + if (defined('DOCSBOX_ENABLED') && DOCSBOX_ENABLED === true) + { + require_once(dirname(__FILE__).'/../application/libraries/DocsboxLib.php'); - //Docsbox::convert(); + $ret = DocsboxLib::convert($inFile, $outFile); + } + else // fallback to unoconv + { + if($this->unoconv_version=='0.6') + $command = 'unoconv -f %1$s %3$s > %2$s'; + else + $command = 'unoconv -f %s --output %s %s 2>&1'; + $command = sprintf($command, $format, $outFile, $inFile); - //if($this->unoconv_version=='0.6') - // $command = 'unoconv -f %1$s %3$s > %2$s'; - //else - // $command = 'unoconv -f %s --output %s %s 2>&1'; - //$command = sprintf($command, $format, $outFile, $inFile); + exec($command, $out, $ret); + } - //exec($command, $out, $ret); - - //if($ret!=0) - //{ - // $this->errormsg = 'Dokumentenkonvertierung ist derzeit nicht möglich. Bitte versuchen Sie es in einer Minute erneut oder kontaktieren Sie einen Administrator'; - // return false; - //} + if ($ret != 0) + { + $this->errormsg = 'Dokumentenkonvertierung ist derzeit nicht möglich. Bitte versuchen Sie es in einer Minute erneut oder kontaktieren Sie einen Administrator'; + return false; + } return true; }