Skip to content
Snippets Groups Projects
Select Git revision
  • d7fcecb36d595511e964076f6263f2964f7e27cb
  • main default protected
  • demo protected
  • master
  • icon-set-mapping
  • production protected
  • revert-62666d1a
  • favorites-and-recent-files
  • lit2
  • wc-part
  • mark-downloaded-files
  • feature/annotpdf-test
  • fix-zip-upload
  • config-cleanup
  • wip
  • app-shell-update
16 results

utils.js

Blame
  • utils.js 8.37 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;
    };
    
    /**
     * 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 === '' || 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
        const organizationNumberContent = organizationNumber !== '' ? '_' + organizationNumber : '';
        author = 'Maschinell aufgebracht, bitte nicht entfernen / Applied automatically, please do not remove';
        content = 'dbp_annotation_' + annotationType + organizationNumberContent + '=' + 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': {
                'name': {
                    'de': 'Geschäftszahl',
                    'en': 'Businessnumber',
                },
                'hasOrganization': true,
            },
            '85a4eb4c': {
                'name': {
                    'de': 'Verwendungszweck',
                    'en': 'Intended use',
                },
                'hasOrganization': false,
            }
        };
    
        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].name[lang];
            results.push(html`
                <option value="${key}" .selected=${selectedKey === key}>${name}</option>
            `);
        });
    
        return results;
    };