Almascript - Alma Start Process List Helper

Show what isn't done and display uploaded files.

目前為 2019-08-05 提交的版本,檢視 最新版本

// ==UserScript==
// @name         Almascript - Alma Start Process List Helper
// @namespace    https://gf.qytechs.cn/en/users/8332-sreyemnayr
// @version      2019.8.5.1
// @description  Show what isn't done and display uploaded files.
// @author       Ryan Meyers
// @match        https://*.getalma.com/workflows/processes/*/review
// @require https://gf.qytechs.cn/scripts/388114-pdf-js/code/PDFjs.js?version=721820
// @require https://gf.qytechs.cn/scripts/388210-html2pdf-js/code/html2pdfjs.js?version=722443
// @require https://unpkg.com/[email protected]/dist/pdf-lib.min.js
// @require https://unpkg.com/[email protected]/dist/FileSaver.min.js
// @grant unsafeWindow
// ==/UserScript==

// Loaded via <script> tag, create shortcut to access PDF.js exports.
var pdfjsLib = window['pdfjs-dist/build/pdf'];

// The workerSrc property shall be specified.
pdfjsLib.GlobalWorkerOptions.workerSrc = '//gf.qytechs.cn/scripts/388115-pdf-js-worker/code/PDFjs%20Worker.js?version=721821';

function fetchAndUpdate(node) {
    const updateNode = node;

    fetch(node.href).then(function(response) { return response.text(); }).then(function(body) {
            //console.log(body);
            var parser = new DOMParser();
            var doc = parser.parseFromString(body, "text/html");
            var xpath = "//li[contains(@class,'task')][not(contains(@class,'task-complete'))]";
            var result = document.evaluate(xpath, doc, null, XPathResult.ANY_TYPE, null);
            //console.log(result);
            var node, nodes = [];
            while (node = result.iterateNext()) {
                //console.log(node.textContent.trim());
                var newNode = document.createElement('div');
                newNode.classList.add("pill");

                newNode.innerHTML = "<i class=\"far fa-times-circle\" style=\"color:#eb6841;\"></i>"+node.textContent.trim();

                updateNode.parentElement.parentElement.children[4].append(newNode);
            }

        });

}

function fetchHealthForm(node) {
    var updateNode = node;
    var pdfIcon = document.createElement('div');
    pdfIcon.classList.add('pure-button', 'pure-button-pdf', 'pure-button-large', 'image-icon-button');
    var iconElement = document.createElement('i');
    iconElement.classList.add('far','fa-images','fa-1x', 'pdfIcon');
    pdfIcon.append(iconElement);
    var studentName, processName = '';

    updateNode.parentElement.parentElement.children[0].append(pdfIcon);

    pdfIcon.onclick = async function() {
        iconElement.classList.add('lds-circle');

    fetch(node.href).then(function(response) { return response.text(); }).then(function(body) {
            //console.log(body);
            var parser = new DOMParser();
            var doc = parser.parseFromString(body, "text/html");
            var xpath = "//li[contains(@class,'task')]";
            var result = document.evaluate(xpath, doc, null, XPathResult.ANY_TYPE, null);
            //console.log(result);
            var node, nodes = [];
            var numFiles = 0;
            var filesDone = 0;
            while (node = result.iterateNext()) {

                var taskUri = node.dataset.href;
                var formUri = taskUri.replace("task-details","form");
                let headers = new Headers({
                    "Accept"       : "application/json",
                    "Content-Type" : "application/json",
                    "X-Requested-With": "XMLHttpRequest"
                });

                fetch(formUri, {method: "GET", headers: headers})
                    .then(function(response) {
                    return response.json();
                }).then(function(myJson) {
            //console.log(myJson);
            var jsonHTML = myJson.Message.html;
            jsonHTML = jsonHTML.replace(/form-section/g,"form-section-off");
            jsonHTML = jsonHTML.replace(/<ul class/g,"<ul style=\"display:none;\" class");
            //console.log(jsonHTML);
            //var files = jsonHTML.match(/<a href="(\/workflows\/processes\/.*\/get-file\?id=[a-zA-z0-9]*)">/g);
            var files = jsonHTML.match(/\/workflows\/processes\/.*\/get-file\?id=[a-zA-z0-9]*/g);
            if (files) {
                numFiles += files.length;
                iconElement.classList.add('lds-circle');
                for (var file of files) {
                    fetch(file).then(function(response) {


                        return response.blob(); }
                                     ).then(async function(blob) {

                        console.log(blob.type);
                        let reader = new FileReader();
                        reader.readAsArrayBuffer(blob);
                        reader.onload = async function() {
                            var newImg;

                        //blob.arrayBuffer().then(async function(myBuffer){
                            if (blob.type === "application/pdf") {
                                newImg = document.createElement('canvas');

                                var loadingTask = pdfjsLib.getDocument(file);
                                loadingTask.promise.then(function(pdf) {
                                    console.log('PDF loaded');

                                    // Fetch the first page
                                    var pageNumber = 1;
                                    pdf.getPage(pageNumber).then(function(page) {
                                        console.log('Page loaded');

                                        var scale = 0.25;
                                        var viewport = page.getViewport(scale);

                                        // Prepare canvas using PDF page dimensions
                                        var canvas = newImg;
                                        var context = canvas.getContext('2d');
                                        canvas.height = 230;
                                        canvas.width = 160;

                                        // Render PDF page into canvas context
                                        var renderContext = {
                                            canvasContext: context,
                                            viewport: viewport
                                        };
                                        var renderTask = page.render(renderContext);
                                        renderTask.promise.then(function () {
                                            console.log('Page rendered');
                                        });
                                    });
                                }, function (reason) {
                                    // PDF loading error
                                    console.error(reason);
                                });

                                //newImg = document.createElement('a');
                                //newImg.href = file;
                                //newImg.innerHTML = "Download";
                                updateNode.append(newImg);
                            }
                            else {
                                 newImg = document.createElement('img');
                                newImg.src = file;
                                newImg.width = 160;
                                updateNode.append(newImg);

                            }


                        };
                        filesDone += 1;
                        if (filesDone === numFiles ) {
                            iconElement.classList.remove('lds-circle');
                        }

                    });
                }
            }




        });
            }
    }).then(function() {

    });
}
}

function doIncomplete() {
    var xpath = "//tr[td[text()='Active (in progress)']]/td[2]/a";
    var result = document.evaluate(xpath, document, null, XPathResult.ANY_TYPE, null);
    var node, nodes = [];
    while (node = result.iterateNext()) {
        nodes.push(node);
        //console.log(node.href);
        fetchAndUpdate(node);
    }
}

function doComplete() {
    var node;
    for (node of document.getElementsByClassName("image-icon-button") ) {
        node.click();
    }
}

function doCompletePDFButtons() {
    var xpath = "//tr[td[text()='Active (complete)' or 'Complete']]/td[2]/a";
    var result = document.evaluate(xpath, document, null, XPathResult.ANY_TYPE, null);
    //var result = document.evaluate(xpath,document.cloneNode(true))
    var node, nodes = [];
    while (node = result.iterateNext()) {
        nodes.push(node);
        //console.log(node.href);

    }
    for (node of nodes) {

        generatePDF(node);
        fetchHealthForm(node);
    }
}


function generatePDF(node) {
    var updateNode = node;
    var pdfIcon = document.createElement('div');
    pdfIcon.classList.add('pure-button', 'pure-button-pdf', 'pure-button-large', 'pdf-icon-button');
    var iconElement = document.createElement('i');
    iconElement.classList.add('fas','fa-file-pdf','fa-1x', 'pdfIcon');
    pdfIcon.append(iconElement);
    var studentName, processName = '';

    updateNode.parentElement.parentElement.children[0].append(pdfIcon);

    pdfIcon.onclick = async function() {

    iconElement.classList.add('lds-circle');
    const bigPdf = await PDFLib.PDFDocument.create();
    var allHTML = [];

    fetch(node.href).then(function(response) { return response.text(); }).then(async function(body) {
            //console.log(body);
            var parser = new DOMParser();
            var doc = parser.parseFromString(body, "text/html");
            var xpath = "//li[contains(@class,'task')]";
            var result = document.evaluate(xpath, doc, null, XPathResult.ANY_TYPE, null);
            studentName = doc.getElementsByClassName("fn")[0].innerText;
            processName = doc.getElementById("page-header").innerText;


    var numDone = 0;
    var task;
    while (task = result.iterateNext()) {
                var taskUri = task.dataset.href;
                var formUri = taskUri.replace("task-details","form");
                let headers = new Headers({
                    "Accept"       : "application/json",
                    "Content-Type" : "application/json",
                    "X-Requested-With": "XMLHttpRequest"
                });

        var taskNum = parseInt(taskUri.match(/task=([0-9]+)/)[1]);
        console.log(taskNum);
        await fetch(formUri, {method: "GET", headers: headers})
            .then(function(response) {
            return response.json();
        })
            .then(function(myJson) {
            console.log(myJson);
            var jsonHTML = myJson.Message.html;
            jsonHTML = jsonHTML.replace(/form-section/g,"form-section-off");
            jsonHTML = jsonHTML.replace(/<ul class/g,"<ul style=\"display:none;\" class");
            console.log(jsonHTML);
            //var files = jsonHTML.match(/<a href="(\/workflows\/processes\/.*\/get-file\?id=[a-zA-z0-9]*)">/g);
            var files = jsonHTML.match(/\/workflows\/processes\/.*\/get-file\?id=[a-zA-z0-9]*/g);
            if (files) {

                for (var file of files) {
                    fetch(file).then(function(response) {

                        return response.blob(); }
                                     ).then(async function(blob) {
                        console.log(blob.type);
                        let reader = new FileReader();
                        reader.readAsArrayBuffer(blob);
                        reader.onload = async function() {

                        //blob.arrayBuffer().then(async function(myBuffer){
                            if (blob.type === "application/pdf") {
                        const pdf = await PDFLib.PDFDocument.load(reader.result);
                        console.log(pdf);
                        const numPages = pdf.getPages().length;

                        const copiedPages = await bigPdf.copyPages(pdf, Array.from(Array(numPages).keys()));
                        copiedPages.forEach((page) => {
                            bigPdf.addPage(page);
                        });
                            }
                            else if (blob.type === "image/jpeg") {

                                // Embed the JPG image bytes and PNG image bytes
                                const jpgImage = await bigPdf.embedJpg(reader.result)

                                // Get the width/height of the JPG image scaled down to 25% of its original size
                                const jpgDims = jpgImage.scale(.5)

                                // Add a blank page to the document
                                const page = bigPdf.addPage([jpgDims.width, jpgDims.height])

                                // Draw the JPG image in the center of the page
                                page.drawImage(jpgImage, {
                                    x: page.getWidth() / 2 - jpgDims.width / 2,
                                    y: page.getHeight() / 2 - jpgDims.height / 2,
                                    width: jpgDims.width,
                                    height: jpgDims.height,
                                });

                            }
                            else if (blob.type === "image/png") {

                                // Embed the JPG image bytes and PNG image bytes
                                const jpgImage = await bigPdf.embedPng(reader.result)

                                // Get the width/height of the JPG image scaled down to 25% of its original size
                                const jpgDims = jpgImage.scale(.5)

                                // Add a blank page to the document
                                const page = bigPdf.addPage([jpgDims.width, jpgDims.height])

                                // Draw the JPG image in the center of the page
                                page.drawImage(jpgImage, {
                                    x: page.getWidth() / 2 - jpgDims.width / 2,
                                    y: page.getHeight() / 2 - jpgDims.height / 2,
                                    width: jpgDims.width,
                                    height: jpgDims.height,
                                });

                            }
                        //bigPdf.addPage(pdf);

                        // console.log(pdf);

                        //var objectURL = URL.createObjectURL(myBlob);
                        //let reader = new FileReader();
                        //reader.readAsDataURL(myBlob);
                        //reader.onload = function() {
                        //    console.log(myBlob);
                        //allHTML += "<embed src=\""+reader.result+"\" width=\"850\" height=\"1100\" class=\"page-break\" type=\"application/pdf\">";
                        //numDone += 1;
                           // pdfButtonProgress.innerHTML = parseInt(100 * (numDone / (totalTasks + 3) )).toString() + "%";

                        //};

                        };

                    });
                }
            }
            console.log(files);
            var jsonHeader = myJson.Message.header;
            allHTML[taskNum] = "<h1>"+jsonHeader+"</h1>"+jsonHTML;
           // numDone += 1;
           // pdfButtonProgress.innerHTML = parseInt(100 * (numDone / (totalTasks + 3))).toString() + "%";

            // <a href="/workflows/processes/5d0a73db7b86eb6fe20f6092/5d1a18b97b86eb0a7532e0f9/5d1a18b97b86eb39037d417d/get-file?id=5d372340a814e42a0d1872e1">



        });
    }

    }).then(function() {

                html2pdf().set({
                                html2canvas:  { scale: 2 },
                                pagebreak: { before: '.page-break', avoid: ['div','h1','.form-section-offs'] }
                            }).from("<div style=\"padding:100px;\">"+allHTML.join(" ")+"</div>").output('datauristring').then(async function (pdfAsString) {
                                //pdfButtonProgress.innerHTML = parseInt(100 * (numDone / (totalTasks + 2))).toString() + "%";
                                const htmlPdf = await PDFLib.PDFDocument.load(pdfAsString);
                    //pdfButtonProgress.innerHTML = parseInt(100 * (numDone / (totalTasks + 1.5))).toString() + "%";
                                const numPages = bigPdf.getPages().length;
                                const copiedPages = await htmlPdf.copyPages(bigPdf, Array.from(Array(numPages).keys()));
                                //pdfButtonProgress.innerHTML = parseInt(100 * (numDone / (totalTasks + 1.2))).toString() + "%";
                                copiedPages.forEach((page) => {
                                    htmlPdf.addPage(page);
                                });
                                //pdfButtonProgress.innerHTML = parseInt(100 * (numDone / (totalTasks + 1))).toString() + "%";
                                //const pdfUrl = URL.createObjectURL(
                                //    new Blob([await htmlPdf.save()], { type: 'application/pdf' }),
                                //);

                    saveAs(new Blob([await htmlPdf.save()]), studentName+" - "+processName+".pdf");
                                //pdfButtonProgress.innerHTML = parseInt(100 * (numDone / totalTasks)).toString() + "%";
                                iconElement.classList.remove('lds-circle');
                                //pdfButtonText.innerHTML = "Saved";
                                //pdfButtonProgress.innerHTML = "";
                                //htmlPdf.save();
                            });
                    //saveAs(await htmlPdf.save(), "Form.pdf");
                                //window.open(pdfUrl, '_blank');
                                //htmlPdf.save();
                            // });
                // console.log(allHTML);

    });
}
}




(async function() {
    'use strict';
    var newStyle = document.createElement('style');
    newStyle.innerHTML = `
.pill {
background-color: #fff;
padding: .5em;
border-radius: 5px;
display: inline-block;
cursor: default;
margin-top: 1em;
font-size: 8pt;
}
.pure-button-pdf { color: #eb6841; background: #fff; padding: 0.1em;}
.pdfIcon { margin-left:2px; margin-right:2px;}
.lds-circle { display: inline-block; transform: translateZ(1px); }
.lds-circle { display: inline-block; animation: lds-circle 2.4s cubic-bezier(0, 0.2, 0.8, 1) infinite; }
@keyframes lds-circle {  0%, 100% { animation-timing-function: cubic-bezier(0.5, 0, 1, 0.5); } 0% { transform: rotateY(0deg); } 50% { transform: rotateY(1800deg); animation-timing-function: cubic-bezier(0, 0.5, 0.5, 1); } 100% { transform: rotateY(3600deg); } }
    `;
    document.getElementsByTagName('head')[0].append(newStyle);

    var showFormsButton = document.createElement('button');
    showFormsButton.onclick = doComplete;
    showFormsButton.innerHTML = "Show Thumbnails for All Uploads";
    document.getElementById('page-header').append(showFormsButton);




    doIncomplete();
    doCompletePDFButtons();

})();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址