add latex to pdf export function

- move file path sanitizing to endpoint main function
This commit is contained in:
Christian Staudte 2020-11-05 01:16:53 +01:00
parent 5f7db5f8ea
commit e9a86d3dec
Signed by: christian.staudte
GPG key ID: 88ED5070FE0D5F23
2 changed files with 103 additions and 10 deletions

View file

@ -18,10 +18,16 @@ length = 16
; %r - Vote Round
header = Ergebnis der Abstimmung %r am %t - %t
pgpkey = ID
; if rawpath is set, the raw JSON will be saved into the directory
rawpath = /path/to/json/dir
; path in which signed files will be stored
path = /path/to/dir
; path to PDF TeX template
pdf_tmpl = /path/to/file
; synccmd can be empty, if no synchronization command is needed. Placeholders:
; %f - filename
;synccmd = rclone %f Remote:dir

View file

@ -139,27 +139,36 @@ class AbstimmIDd {
return ['success' => false];
}
$sha256 = $this->create_text_file($body);
// if a raw JSON export is configured, write the data
if (strlen($this->cfg['export']['rawpath']) > 0) {
$filepath = "{$this->cfg['export']['rawpath']}/{$body->event_token}-{$body->vote_round}.json";
file_put_contents($filepath, json_encode($body));
}
return ['success' => true, 'sha256' => $sha256, 'signing_key' => $this->cfg['export']['pgpkey']];
// sanitize the inputs which will go to the filesystem path
$vote_round = (int)$body->vote_round;
$event_title = str_replace(' ', '_', addslashes($body->event_title));
$file_path = $this->cfg['export']['path'] . '/' . date('Y-m-d') .
"__{$event_title}__Abstimmung-$vote_round";
$sha256_txt = $this->create_text_file($body, "$file_path.txt");
$sha256_pdf = $this->create_pdf_file($body, "$file_path.pdf");
return [
'success' => true,
'sha256_txt' => $sha256_txt,
'sha256_pdf' => $sha256_pdf,
'signing_key' => $this->cfg['export']['pgpkey']];
}
/**
* Utility function to create a signed voting result text file
* @param mixed $body The complete JSON object from the API endpoint
* @param string $file_path The path and name of the output file
* @return string The SHA256 hash of the file created
*/
function create_text_file($body) : string {
// sanitize the inputs which will go to the shell
$vote_round = (int)$body->vote_round;
$event_title = str_replace(' ', '_', addslashes($body->event_title));
$file_path = $this->cfg['export']['path'] . '/' . date('Y-m-d') .
"__{$event_title}__Abstimmung-$vote_round.txt";
function create_text_file($body, string $file_path) : string {
// create the file's header
$header = str_replace('%t', $body->event_title, $this->cfg['export']['header']);
$header = str_replace('%d', date('d.m.Y'), $header);
@ -189,6 +198,84 @@ EOT;
return trim(shell_exec("/usr/bin/sha256sum $file_path | awk '{ print $1 }'"));
}
/**
* Utility function to create a signed voting result PDF file
* @param mixed $body The complete JSON object from the API endpoint
* @param string $file_path The path and name of the output file
* @return string The SHA256 hash of the file created
*/
function create_pdf_file($body, string $file_path) : string {
// get the maximum number of votes a single person did to determine the number of columns
$col_count = 0;
foreach ($body->votes as $vote)
if (count($vote->vote) > $col_count)
$col_count = count($vote->vote);
if ($col_count < 1 || $col_count > 5)
throw new Exception('Too many or no vote columns');
// build the table header variables
$table_col_count = str_repeat('|l', $col_count);
$table_col_headers = '';
for ($i = 0; $i < $col_count; $i++)
$table_col_headers .= ' & \textbf{Stimme '.($i+1).'}';
// build the table body with the votes
$table_body = '';
foreach ($body->votes as $vote) {
// start with the vote hash
$table_body .= " $vote->hash";
// continue with the existing votes
$cols_done = 0;
foreach ($vote->vote as $v){
$table_body .= " & $v";
$cols_done++;
}
// fill the empty columns, if any
for ($i = $cols_done; $i < $col_count; $i++)
$table_body .= ' &';
// end the line
$table_body .= " \\\\\n";
}
// read in the template file
if (($tmpl = file_get_contents($this->cfg['export']['pdf_tmpl'])) === false)
throw new Exception('PDF template not found');
// do the template variable replacements
$tmpl = str_replace('==EVENT_NAME==', $body->event_title, $tmpl);
$tmpl = str_replace('==VOTE_ROUND==', $body->vote_round, $tmpl);
$tmpl = str_replace('==COL_COUNT==', $table_col_count, $tmpl);
$tmpl = str_replace('==COL_HDRS==', $table_col_headers, $tmpl);
$tmpl = str_replace('==TABLE_BODY==', $table_body, $tmpl);
$fdir = pathinfo($file_path, PATHINFO_DIRNAME).'/'; // just the directory part
$fname = pathinfo($file_path, PATHINFO_FILENAME); // filename without extension
$ffull = $fdir.$fname;
// write the temporary tex file and convert it to pdf
if (file_put_contents("$ffull.tex", $tmpl) === false)
throw new Exception('Could not write tex file');
shell_exec("cd $fdir; /usr/bin/pdflatex $fname.tex");
// remove the temporary files
unlink("$ffull.tex");
unlink("$ffull.log");
unlink("$ffull.aux");
// TODO: sign the pdf file
shell_exec("");
// synchronize the file
$this->sync_command("$ffull.pdf");
// return the hash of the file
return trim(shell_exec("/usr/bin/sha256sum $file_path | awk '{ print $1 }'"));
}
/**
* Utility function to synchronize a specific file with a remote location,
* with a command specified in the config.ini file