Skip to content

Commit

Permalink
organisation: processing is carried out entirely on the javascript si…
Browse files Browse the repository at this point in the history
…de with the pdf-lib js library and not at all on the server side
  • Loading branch information
wincelau committed Nov 9, 2023
1 parent 081832d commit 410f1c1
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 63 deletions.
43 changes: 0 additions & 43 deletions app.php
Original file line number Diff line number Diff line change
Expand Up @@ -353,54 +353,11 @@ function($f3) {
if (!$f3->get('disableOrganization')) {
$f3->route('GET /organization',
function($f3) {
$f3->set('maxSize', min(array(convertPHPSizeToBytes(ini_get('post_max_size')), convertPHPSizeToBytes(ini_get('upload_max_filesize')))));

$f3->set('activeTab', 'organize');
echo View::instance()->render('organization.html.php');
}
);

$f3->route('POST /organize',
function($f3) {
$filenames = array();
$tmpfile = tempnam($f3->get('UPLOADS'), 'pdfsignature_organize');
unlink($tmpfile);
$pages = explode(',', preg_replace('/[^A-Z0-9a-z,]+/', '', $f3->get('POST.pages')));

$files = Web::instance()->receive(function($file,$formFieldName){
if(strpos(Web::instance()->mime($file['tmp_name'], true), 'application/pdf') !== 0) {
$f3->error(403);
}

return true;
}, false, function($fileBaseName, $formFieldName) use ($tmpfile, &$filenames) {
$filenames[] = str_replace('.pdf', '', $fileBaseName);

return basename($tmpfile).uniqid().".pdf";
});

if(!count($files)) {
$f3->error(403);
}

$pdfs = array();
foreach(array_keys($files) as $i => $file) {
$pdfs[] = chr(65 + $i)."=".$file;
}

shell_exec(sprintf("pdftk %s cat %s output %s", implode(" ", $pdfs), implode(" ", $pages), $tmpfile.'_final.pdf'));

Web::instance()->send($tmpfile."_final.pdf", null, 0, TRUE, implode('_', $filenames));

if($f3->get('DEBUG')) {
return;
}

array_map('unlink', glob($tmpfile."*"));
}
);
}

$f3->route('GET /metadata',
function($f3) {
$f3->set('activeTab','metadata');
Expand Down
72 changes: 55 additions & 17 deletions public/js/organization.js
Original file line number Diff line number Diff line change
Expand Up @@ -209,12 +209,12 @@ var loadPDF = async function(pdfBlob, filename, pdfIndex) {
e.stopPropagation();
let container = this.parentNode;
let pageValue = container.querySelector('.checkbox-page').value;
let orientation = degreesToOrientation(container.querySelector('.input-rotate').value);
let orientation = container.querySelector('.input-rotate').value;
if(orientation) {
pageValue = pageValue + "-" + orientation;
}
document.querySelector('#input_pages').value = pageValue;
document.querySelector('#form_pdf').submit();
save();
});
canvasContainer.querySelector('.btn-rotate').addEventListener('click', function(e) {
e.stopPropagation();
Expand Down Expand Up @@ -304,11 +304,16 @@ var getFilesStats = function() {
return files;
}

const getLetter = function(i) {

return String.fromCharCode(96 + i+1).toUpperCase();
}

var updateListePDF = function() {
document.querySelector('#list_pdf').innerHTML = "";
let nbFiles = document.querySelector('#input_pdf').files.length;
for (var i = 0; i < nbFiles; i++) {
let pdfLetter = String.fromCharCode(96 + i+1).toUpperCase();
let pdfLetter = getLetter(i);
const pdfFile = document.querySelector('#input_pdf').files.item(i);
document.querySelector('#list_pdf').insertAdjacentHTML('beforeend', '<li id="file_' + pdfLetter + '" class="list-group-item small ps-2 pe-5" title="'+decodeURI(pdfFile.name)+'" style="text-overflow: ellipsis; white-space: nowrap; overflow: hidden;"><i class="bi bi-files"></i><span class="ms-2">'+decodeURI(pdfFile.name)+'</span> <input class="form-check-input float-end position-absolute file-list-checkbox" type="checkbox" /> </li>');
let fileItem = document.querySelector('#file_' + pdfLetter);
Expand Down Expand Up @@ -537,22 +542,9 @@ var updateGlobalState = function() {
}
}

var degreesToOrientation = function(degrees) {
if(degrees == 90) { return "east"; }
if(degrees == 180) { return "south"; }
if(degrees == 270) { return "west"; }

return null;
}

var uploadAndLoadPDF = async function(input_upload) {
const cache = await caches.open('pdf');
for (let i = 0; i < input_upload.files.length; i++) {
if(input_upload.files[i].size > maxSize) {

alert("Le PDF ne doit pas dépasser " + Math.round(maxSize/1024/1024) + " Mo");
break;
}
let filename = input_upload.files[i].name;
let response = new Response(input_upload.files[i], { "status" : 200, "statusText" : "OK" });
let urlPdf = '/pdf/'+filename;
Expand All @@ -563,9 +555,51 @@ var uploadAndLoadPDF = async function(input_upload) {
}
}

const DL = function (d,f) {
let a = document.createElement("a"),
u = URL.createObjectURL(d);
a.download = f,
a.href = u,
a.click(),
setTimeout(() => URL.revokeObjectURL(u))
}

const save = async function () {
const PDFDocument = window['PDFLib'].PDFDocument
const Rotation = window['PDFLib'].Rotation

const pdf = await PDFDocument.create();
let filename = "";
let pdfFiles = [];
for (let i = 0; i < document.querySelector('#input_pdf').files.length; i++) {
if(filename) {
filename += '_';
}
filename += document.querySelector('#input_pdf').files.item(i).name.replace(/\.pdf$/, '');
pdfFiles[getLetter(i)] = await PDFDocument.load(await document.querySelector('#input_pdf').files.item(i).arrayBuffer());
}

const pages = document.querySelector('#input_pages').value.split(',');
console.log(pages);
for(let i in pages) {
const page = pages[i].split('-')[0];
const rotation = pages[i].split('-')[1];
let pdfFile = pdfFiles[page.substr(0,1)];
const [pdfPage] = await pdf.copyPages(pdfFile, [parseInt(page.substr(1)) - 1]);
if(rotation) {
pdfPage.setRotation(window['PDFLib'].degrees(parseInt(rotation)));
}
pdf.addPage(pdfPage);
}

const newPDF = new Blob([await pdf.save()], {type: "application/pdf"});
DL(newPDF, filename+".pdf");
}

var createEventsListener = function() {
document.getElementById('save-select_mobile').addEventListener('click', function(event) {
document.getElementById('save-select').click();
event.preventDefault();
});
document.getElementById('save-select').addEventListener('click', function(event) {
let buttonSave = document.getElementById('save');
Expand All @@ -574,6 +608,7 @@ var createEventsListener = function() {
buttonSave.disabled = false;
}
buttonSave.click();
event.preventDefault();
buttonSave.disabled = true;
});
document.getElementById('save').addEventListener('click', function(event) {
Expand All @@ -591,7 +626,7 @@ var createEventsListener = function() {
if(checkbox.checked) {
pageValue = checkbox.value;
}
let orientation = degreesToOrientation(inputRotate.value);
let orientation = inputRotate.value;
if(pageValue && orientation) {
pageValue = pageValue + "-" + orientation;
}
Expand All @@ -600,9 +635,12 @@ var createEventsListener = function() {
}
});
document.querySelector('#input_pages').value = order.join(',');
save();
event.preventDefault();
});
document.getElementById('save_mobile').addEventListener('click', function(event) {
document.getElementById('save').click();
event.preventDefault();
});
document.getElementById('input_pdf_upload_2').addEventListener('change', async function(event) {
await uploadAndLoadPDF(this);
Expand Down
6 changes: 3 additions & 3 deletions templates/organization.html.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@
<p class="fw-light mb-3 subtitle text-dark text-nowrap" style="overflow: hidden; text-overflow: ellipsis;"><?php echo _("Merge, sort, rotate, delete, extract pages"); ?></p>
<div class="col-md-6 col-lg-5 col-xl-4 col-xxl-3 mx-auto">
<div class="col-12">
<label class="form-label mt-3" for="input_pdf_upload"><?php echo _("Choose a PDF"); ?> <small class="opacity-75" style="cursor: help" title="<?php echo _("The PDF must not exceed "); ?> <?php echo round($maxSize / 1024 / 1024) ?> <?php echo _("Mb"); ?>"><i class="bi bi-info-circle"></i></small></label>
<label class="form-label mt-3" for="input_pdf_upload"><?php echo _("Choose a PDF"); ?></label>
<input id="input_pdf_upload" placeholder="<?php echo _("Choose a PDF"); ?>" class="form-control form-control-lg" type="file" accept=".pdf,application/pdf" multiple="true" />
<p class="mt-2 small fw-light text-dark"><?php echo _("The PDF will be processed by the server without being retained or stored"); ?></p>
<?php if($PDF_DEMO_LINK): ?>
<p class="mt-2 small fw-light text-dark">&nbsp;</p>
<a class="btn btn-sm btn-link opacity-75" href="#<?php echo $PDF_DEMO_LINK ?>"><?php echo _("Test with a demo PDF"); ?></a>
<?php endif; ?>
</div>
Expand Down Expand Up @@ -133,7 +133,6 @@
<script src="<?php echo $REVERSE_PROXY_URL; ?>/vendor/bootstrap.bundle.min.js?5.1.3"></script>
<script src="<?php echo $REVERSE_PROXY_URL; ?>/vendor/pdf.js?legacy"></script>
<script>
var maxSize = <?php echo $maxSize ?>;
var trad = <?php echo json_encode([
'Select this page' => _('Select this page'),
'Delete this page' => _('Delete this page'),
Expand All @@ -146,5 +145,6 @@
]); ?>;
</script>
<script src="<?php echo $REVERSE_PROXY_URL; ?>/js/organization.js?<?php echo ($COMMIT) ? $COMMIT : filemtime($ROOT."/public/js/organization.js") ?>"></script>
<script src="<?php echo $REVERSE_PROXY_URL; ?>/vendor/pdf-lib.min.js?1.17.1"></script>
</body>
</html>

0 comments on commit 410f1c1

Please sign in to comment.