-
Bekerle, Patrizio authoredBekerle, Patrizio authored
utils.js 8.95 KiB
import {AnnotationFactory} from '@digital-blueprint/annotpdf/_bundles/pdfAnnotate.js';
import {html} from "lit-element";
//import {humanFileSize} from "@dbp-toolkit/common/i18next";
/**
* Finds an object in a JSON result by identifier
*
* @param identifier
* @param results
* @param identifierAttribute
*/
export const findObjectInApiResults = (identifier, results, identifierAttribute = "@id") => {
const members = results["hydra:member"];
if (members === undefined) {
return;
}
for (const object of members) {
if (object[identifierAttribute] === identifier) {
return object;
}
}
};
export const getPDFFileBase64Content = (file) => {
return file.contentUrl.replace(/data:\s*application\/pdf;\s*base64,/, "");
};
export const convertDataURIToBinary = (dataURI) => {
const BASE64_MARKER = ';base64,';
const base64Index = dataURI.indexOf(BASE64_MARKER) + BASE64_MARKER.length;
const base64 = dataURI.substring(base64Index);
const raw = window.atob(base64);
const rawLength = raw.length;
let array = new Uint8Array(rawLength);
for(let i = 0; i < rawLength; i++) {
array[i] = raw.charCodeAt(i);
}
return array;
};
export const getDataURIContentType = (dataURI) => {
const BASE64_MARKER = ';base64,';
const base64Index = dataURI.indexOf(BASE64_MARKER);
return dataURI.substring(5, base64Index);
};
export const baseName = (str) =>
{
let base = String(str).substring(str.lastIndexOf('/') + 1);
if (base.lastIndexOf(".") !== -1) {
base = base.substring(0, base.lastIndexOf("."));
}
return base;
};
export const fabricjs2pdfasPosition = (data) => {
let angle = -(data.angle - 360) % 360;
let bottom = data.bottom;
let left = data.left;
if (data.angle === 90) {
bottom += data.height;
left -= data.height;
} else if (data.angle === 180) {
bottom += data.height * 2;
} else if (data.angle === 270) {
bottom += data.height;
left += data.height;
}
return {
y: Math.round(bottom),
x: Math.round(left),
r: angle,
w: Math.round(data.width), // only width, no "height" allowed in PDF-AS
p: data.currentPage
};
};
/**
* Returns the content of the file
*
* @param {File} file The file to read
* @returns {string} The content
*/
export const readBinaryFileContent = async (file) => {
return new Promise((resolve, reject) => {
let reader = new FileReader();
reader.onload = () => {
resolve(reader.result);
};
reader.onerror = () => {
reject(reader.error);
};
reader.readAsBinaryString(file);
});
};
/**
* Returns the content of the file as array buffer
*
* @param {File} file The file to read
* @returns {string} The content
*/
export const readArrayBufferFileContent = async (file) => {
return new Promise((resolve, reject) => {
let reader = new FileReader();
reader.onload = () => {
resolve(reader.result);
};
reader.onerror = () => {
reject(reader.error);
};
reader.readAsArrayBuffer(file);
});
};
/**
* Given a PDF file returns the amount of signatures found in it.
*
* Note that this uses an heuristic, so the result can be wrong
* (improvements welcome).
*
* @param {File} file The PDF file object
* @returns {number} The amount of signatures found
*/
export const getPDFSignatureCount = async (file) => {
const sigRegex = new RegExp(
"/Type\\s*/Sig(.|\\s)*?/SubFilter\\s*(/ETSI\\.CAdES\\.detached|/adbe\\.pkcs7\\.detached)",
"g");
const content = await readBinaryFileContent(file);
let matches = 0;
while (sigRegex.exec(content) !== null) {
matches++;
}
return matches;
};
/**
* Adds an annotation to a PDF file
*
* @param file
* @param activityNameDE
* @param activityNameEN
* @param personName
* @param key
* @param value
* @returns {File} file given as parameter, but with annotations
*/
export const addKeyValuePdfAnnotation = async (file, activityNameDE, activityNameEN, personName, key, value) => {
key = key.trim();
value = value.trim();
// don't annotate if key or value are empty
if (key === '' || value === '') {
return file;
}
let annotationFactory = await getAnnotationFactoryFromFile(file);
annotationFactory = addKeyValuePdfAnnotationsToAnnotationFactory(annotationFactory, activityNameDE, activityNameEN,
personName, key, 'Name DE', 'Name EN', 'organizationNumber', value);
return writeAnnotationFactoryToFile(annotationFactory, file);
};
/**
* Returns a File from an AnnotationFactory
*
* @param annotationFactory
* @param file
* @returns {File} file given as parameter, but with annotations
*/
export const writeAnnotationFactoryToFile = (annotationFactory, file) => {
const blob = annotationFactory.write();
return new File([blob], file.name, { type: file.type });
};
/**
* Creates an AnnotationFactory from a File
*
* @param file
* @returns {AnnotationFactory} from given file
*/
export const getAnnotationFactoryFromFile = async (file) => {
const data = await readArrayBufferFileContent(file);
return new AnnotationFactory(data);
};
/**
* Adds a key/value annotation to a AnnotationFactory and returns the AnnotationFactory
*
* @param annotationFactory
* @param activityNameDE
* @param activityNameEN
* @param personName
* @param annotationType
* @param annotationTypeNameDE
* @param annotationTypeNameEN
* @param organizationNumber
* @param value
* @returns {AnnotationFactory} prepared to annotate
*/
export const addKeyValuePdfAnnotationsToAnnotationFactory = (annotationFactory, activityNameDE, activityNameEN, personName,
annotationType, annotationTypeNameDE, annotationTypeNameEN, organizationNumber, value) => {
annotationType = annotationType.trim();
annotationTypeNameDE = annotationTypeNameDE.trim();
annotationTypeNameEN = annotationTypeNameEN.trim();
organizationNumber = organizationNumber.trim();
value = value.trim();
// don't annotate if key or value are empty
if (annotationType === '' || organizationNumber === '' || value === '') {
return annotationFactory;
}
// add human readable annotation
let author = personName + ' via "' + activityNameDE + ' / ' + activityNameEN + '"';
let content = annotationTypeNameDE + ': ' + value +"\n" + annotationTypeNameEN + ': ' + value;
annotationFactory = addPdfAnnotationToAnnotationFactory(annotationFactory, author, content);
// add machine readable annotation
author = 'Maschinell aufgebracht, bitte nicht entfernen / Applied automatically, please do not remove';
content = 'dbp_annotation_' + annotationType + '_' + organizationNumber + '=' + value;
annotationFactory = addPdfAnnotationToAnnotationFactory(annotationFactory, author, content);
return annotationFactory;
};
export const addPdfAnnotationToAnnotationFactory = (annotationFactory, author, content) => {
author = author.trim();
content = content.trim();
// don't annotate if author of content are empty
if (author === '' || content === '') {
return annotationFactory;
}
const page = 0;
const rect = [0, 0, 0, 0];
// annotationFactory.checkRect(4, rect);
// Create single free text annotation with print flag and 0 font size
let annotation = Object.assign(annotationFactory.createBaseAnnotation(page, rect, content, author), {
annotation_flag: 4, // enable print to be PDF/A conform
color: {r: 1, g: 1, b: 1}, // white to (maybe) hide it better
opacity: 0.001, // we can't set to 0 because of "if (opacity) {"
defaultAppearance: "/Invalid_font 0 Tf" // font size 0 to (maybe) hide it better
});
annotation.type = "/FreeText";
annotationFactory.annotations.push(annotation);
return annotationFactory;
};
/**
* Returns an object with all annotations types or only the values for one type
*
* @param key
* @returns {object} describing the annotation type named key
*/
export const getAnnotationTypes = (key = null) => {
const types = {
'bbe3a371': {
'de': 'Geschäftszahl',
'en': 'Businessnumber',
},
'85a4eb4c': {
'de': 'Andere Zahl',
'en': 'Other number',
}
};
return key === null ? types : types[key] || {};
};
/**
* Returns the html for the annotation type select
*
* @param selectedKey
* @param lang
* * @returns {*[]} Array of html templates
*/
export const getAnnotationTypeSelectOptionsHtml = (selectedKey, lang) => {
const annotationTypes = getAnnotationTypes();
const keys = Object.keys(annotationTypes);
let results = [];
keys.forEach((key) => {
const name = annotationTypes[key][lang];
results.push(html`
<option value="${key}" .selected=${selectedKey === key}>${name}</option>
`);
});
return results;
};