parlor.trickss / Xplor Album Download

// ==UserScript==
// @name         Xplor Album Download
// @namespace    https://openuserjs.org/users/parlor.trickss
// @author       parlortricks
// @description  Download all the photos of your child from the selected observation
// @homepageURL  https://openuserjs.org/scripts/parlor.trickss/Xplor_Album_Download
// @updateURL    https://openuserjs.org/install/parlor.trickss/Xplor_Album_Download.user.js
// @icon         data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAALcUExURQAAAOWirPecQ/ejUtl1hNl6iduKlvWaqvJ7kOh+kPJ3jfFxiMxebslSY+Zzh/u/U+Vrcfu6Rvu8S/WQQMlSVu9Zc+1JZu5QbPu0N+Faafu0N8BCVPqxL8FFVvWINPqwLPWJNddSZ/qyMr45TPWKNu1KZvqyMPWINPCBNfqxLr89UL89UPqyML89T78+Ub89TO1FYut6U/WHMr48T789UMBAUt9NYu1FYvCBNu1FYt9LYvGMPb4+UN9OZvigNL48TvWGMfSGMO1CYPSFL706Tb05TPSELfquJ705Su1HZPquJ/SDLL04S748T95IYL06TfSDLb04S/qtJL04S8Q8UOxAXvSDLOw+XMQ7TstMQ705S+1BX+w+XexAXt5IYOw/Xu1EXL04Suw/XfqtI/qtI95HYN5IYfqtI/SCK+w+XOw+XdhFXew/Xbw3St5IX/qsIPqsIfmlJOw+XLw3SfSBKrw3SfqsIPqsIdxGXr43S+x2LvSBKfSAKfqrH/qrHhivvRmWpByvuh+ZqCO0wiavsyuSly2jsjCtuziRkDikszymtT+uoUSQiUS/y06PhFaukWLJ03TP2Hate3mLbH2Lan2tdoqtbIzL2piIW5vS4aSoWaiHUq6HT7Lc67Xe7bXl67s1SLw2Sb04R72sSb86RsE4TMI+RMQ5TsQ9SMTk88VCQ8ZDQsc6UMg7UMs8U8uEP8w8U8xMP88+Vc9OPdDq+dM/V9NUO9OsOdZBWddaOdhbONpeNttDXdtJV9vv+txEXt1EXt5GXd/x++GrMOJXUuJoM+NqMeRtP+Tz/OT29+VsMeX2+OhsReiBL+lwQ+pzLup0QOt0Lew7Wux4Pu1AWO5IU+5/OfCAKvCINPJoQvJvPvJ9KfJ+KfKMLPN+KfN/KfSAKPSBKPSCKPSEJ/SVLPT7/PWrIfeTK/eiJPerIPicIvigIfmiIPmiI/mpH/qqHvqrHv3+//7//////2jCoCYAAAB/dFJOUwAAAAABAQEBAwQEBQcICAgKCg0OEhobHiMlJis0NTU3ODo6PT5BQURHSE1PUFNaXWBkZWdnZ2dpa21vdHZ2e32ChIWOkpOYmp6foaWoqKqrq6+vsLCyv8THx8jIyszNztHS0tPW2Nrd3+Dg5+jp6urt7/Dx8/T09fb5+fn9/f5FKeZpAAAB0ElEQVQYGX3BY2McURQG4Le2bdu2bdu2zdS23VOmTZ1ujUxqY+qmTU/t5jT5A507Nx86O7v7PPAvS9WWAyZ3hh+pK/Y0DCMseBx8SlVtpKEcIYIvRQbJp2uGYRwnIrilaTRTRP48CQ8loglwydxPtLchRNQH3nKNEpHvX0R+fYg4TdQYXgpOEjmzcnbQ0i0fmfn63lJwyjtR5Oq81bc/71ywli1T08Mh62gR2bA8Oubv5R2zjjFzazik7S+W9atioq94PIs3MXN+ODQVZc/cu7c8noNztjF3hENx0dYs3Lh985JlL3h6TsRKXKBuh+69x4j2Y+uK+YvW3WduCC1ppSGm5bVoP9+zNjgdbBm7mcrT36J8u/mQtWm5Ycs01LS9EuXlpQORrJWFLVkPU/sqIlGPLu47z1odaFVMc3ivTn3HPhORqHthwfsj2FYvHrQmpTPAkqimiDwwDtMdttWOCy/Z2854bhylc6y8qQwfyoSH0klWHh8qCbeUA0/RiUhmfndhNzWAW42zu1oUHs98I4SI2sElybAp1ROiULMupLSBS5722aDkIKU+XOIgVleylIB/tYhoRAr4V4yIyiGAfEStEiCAotQ8OQKpUD4+/vMPgOo2WK6n8O4AAAAASUVORK5CYII=
// @match        https://home.myxplor.com/*
// @require      https://code.jquery.com/jquery-latest.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/dayjs/1.8.29/dayjs.min.js
// @require      https://gitcdn.xyz/repo/BrockA/2625891/raw/waitForKeyElements.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/jszip/3.5.0/jszip.min.js
// @require      https://gitcdn.xyz/repo/eligrey/FileSaver.js/master/dist/FileSaver.js
// @require      https://raw.githubusercontent.com/Viglino/iconicss/master/iconicss.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/tooltipster/3.3.0/js/jquery.tooltipster.min.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.10.2/underscore.min.js
// @require      https://cdnjs.cloudflare.com/ajax/libs/underscore.string/3.3.5/underscore.string.min.js
// @resource     xplorCSS https://gitlab.com/ParlorTricks/xplor-album-download/-/raw/master/css/xplor-css.css
// @resource     iconicCSS https://rawgit.com/Viglino/iconicss/master/dist/iconicss.min.css
// @resource     tooltipsterCSS https://cdnjs.cloudflare.com/ajax/libs/tooltipster/3.3.0/css/tooltipster.min.css
// @run-at       document-end
// @grant        GM_addStyle
// @grant        GM_xmlhttpRequest
// @grant        GM_getResourceText
// @license      MIT
// @copyright    2020, parlortricks
// @version      2.2.3
// ==/UserScript==

var debug = false;
var author = "parlortricks";
var version = "2.2.3";
var homepage = "https://openuserjs.org/scripts/parlor.trickss/Xplor_Album_Download";
var cssNames = [
    "xplorCSS",
    "iconicCSS",
    "tooltipsterCSS",
];
var albumTitle;
var albumSummary;

function addResourceCSS(cssNames, debug) {
    for (var x in cssNames) {
        if (debug) { console.time(cssNames[x]) };
        var thetext = GM_getResourceText(cssNames[x]);
        if (debug) { console.timeEnd(cssNames[x]) };
        GM_addStyle(thetext);
    }
}

function xplorMain() {
    if (debug) { console.log("We are good to go, let's begin work!."); };
    function createDownloadButton() {
        if (debug) { console.log('Creating download button.') };
        return $('<button/>', {
            text: 'Download Album',
            id: 'btn_download',
            class: 'btn_download tooltip',
            title: 'Click here to download all the images in the observation as a zip',
            click: generateZIP
        });
    }

    function generateZIP() {
        if (debug) { console.log('Generating zip file.') };
        var imageURLS = [];
        var zip = new JSZip();
        var count = 0;
        var now = dayjs().format('YYYYMMDD_Hm')
        var albumTitleFile = albumTitle.split(' ').join('_');
        var zipFilename = now + '_' + albumTitleFile + '.zip';
        var images = document.querySelectorAll('li.slide div.sc-AxjAm.jSAKjm > img.sc-AxirZ.kNABon');

        images.forEach(function (entry) {
            imageURLS.push(entry.getAttribute('src'));
        });

        imageURLS = _.uniq(imageURLS);

        imageURLS.forEach(function (url, i) {
            var filename = now + '_' + albumTitleFile + '_' + i.toString() + '.jpg';
            GM_xmlhttpRequest({
                method: "GET",
                url: url,
                responseType: 'arraybuffer',
                onload: function (res) {
                    zip.file(filename, res.response, {
                        binary: true
                    });
                    count++;
                    if (count == imageURLS.length) {
                        zip.file(now + '_' + albumTitleFile + '_' + 'description.txt', albumSummary)
                        zip.generateAsync({
                            type: 'blob',
                            compression: "DEFLATE",
                            compressionOptions: {
                                level: 9
                            },
                            comment: albumTitle
                        }).then(function (content) {
                            if (debug) { console.log('Sendning zip file to user.') };
                            saveAs(content, zipFilename);
                        });
                    };
                }
            });
        });
    }

    albumTitle = document.querySelector('div.sc-AxiKw.dCEARj div.sc-AxhCb.iWRbdJ').innerText;
    albumSummary = document.querySelector('div.sc-AxiKw.dzOGUS.sc-fzomME.hhnKZs div.sc-AxhCb.dyobGx').innerText;

    $("div.sc-AxhCb.iWRbdJ").append("<br />");
    $("div.sc-AxhCb.iWRbdJ").append(createDownloadButton());
    $("#btn_download").prepend('<span class="icss-stack icss-tada x1"><i class="icss-download"></i></span>')
    $("span.icss-stack.icss-tada.x1").css("margin-right", "5px");
    $('.tooltip').tooltipster();
}

// Main function launched when window.load is finished with all resources
$(window).load(function () {
    console.log('Xplor Album Download' + ' ' + version);
    console.log('Created by ' + author);
    console.log('Homepage: ' + homepage);

    if (debug) { console.time('total'); console.log('Injecting CSS.') };

    addResourceCSS(cssNames, debug);
    if (debug) { console.timeEnd('total') };

    if (debug) { console.log('Waiting for key elements to arrive.'); };
    waitForKeyElements(
        'div.carousel-root.sc-fznAgC.YNyPI', xplorMain
    );
})