Using Eagle API with Tampermonkey

Sample: Developing a batch import plugin for Pinterest with Tampermonkey Script and Eagle API

CORS related issue

If you want to use Eagle API in webpages via script extensions like 'Tampermonkey', please call through GM_xmlhttprequest to circumvent security policies related to Cross-Origin Resource Sharing.

GM_xmlhttpRequest({
    url: EAGLE_IMPORT_API_URL,
    method: "POST",
    data: JSON.stringify({ items: images, folderId: pageInfo.folderId }),
    onload: function(response) {}
});

Full Code:

// ==UserScript==
// @name                Save Pinterest images to Eagle

// @description         Launch a script on Pinterest that automatically scrolls the page and converts all images on the page into large images (with links, names) to be added to the Eagle App.

// @author              Augus
// @namespace           https://eagle.cool/
// @homepageURL         https://eagle.cool/
// @license             MIT License

// @match               https://www.pinterest.com/*
// @grant               GM_xmlhttpRequest
// @run-at              context-menu

// @date                06/16/2020
// @modified            06/16/2020
// @version             0.0.3

// ==/UserScript==


(function() {

    if (location.href.indexOf("pinterest.com") === -1) {
        alert("This script only works on pinterest.com.");
        return;
    }

    // Eagle API URL
    const EAGLE_SERVER_URL = "http://localhost:41595";
    const EAGLE_IMPORT_API_URL = `${EAGLE_SERVER_URL}/api/item/addFromURLs`;
    const EAGLE_CREATE_FOLDER_API_URL = `${EAGLE_SERVER_URL}/api/folder/create`;

    // Pinterest Rules
    const SELECTOR_IMAGE = "[data-grid-item] a img[srcset]";
    const SELECTOR_LINK = "[data-grid-item] a";
    const SELECTOR_SPINNER = `[aria-label="Board Pins grid"]`;

    var startTime = Date.now();     
    var scrollInterval;             
    var lastScrollPos;              
    var retryCount = 0;             
    var scrollDelay = 500;          
    var retryThreshold = 4;         
    var pageInfo = {
        imageCount: 0,
        imageSet: {},
        folderId: ""
    };

    // Create a folder
    var createFolder = function(folderName, callback) {
        GM_xmlhttpRequest({
            url: EAGLE_CREATE_FOLDER_API_URL,
            method: "POST",
            data: JSON.stringify({ folderName: folderName }),
            onload: function(response) {
                try {
                    var result = JSON.parse(response.response);
                    if (result.status === "success" && result.data && result.data.id) {
                        callback(undefined, result.data);
                    } else {
                        callback(true);
                    }
                } catch (err) {
                    callback(true);
                }
            }
        });
    };

    var scarollToTop = function() {
        window.scrollTo(0, 0);
        lastScrollPos = window.scrollY;
    };

    var scarollToBottom = function() {
        window.scrollTo(0, document.body.scrollHeight);
        lastScrollPos = window.scrollY;
    };

    var getImgs = function() {
        var imgs = [];
        var imgElements = Array.from(document.querySelectorAll(SELECTOR_IMAGE));

        imgElements = imgElements.filter(function(elem) {
            var src = elem.src;
            if (!pageInfo.imageSet[src]) {
                pageInfo.imageSet[src] = true;
                return true;
            }
            return false;
        });

        var getLink = function(img) {
            var links = Array.from(document.querySelectorAll(SELECTOR_LINK));
            for (var i = 0; i < links.length; i++) {
                if (links[i].contains(img)) {
                    return absolutePath(links[i].href);
                }
            }
            return "";
        };

        imgs = imgElements.map(function(elem, index) {
            pageInfo.imageCount++;
            return {
                name: elem.alt || "",
                url: getHighestResImg(elem) || elem.src, 
                website: getLink(elem), 
                modificationTime: startTime - pageInfo.imageCount
            }
        });

        return imgs;
    };

    var fetchImages = function() {
        var currentScrollPos = window.scrollY;
        scarollToBottom();
        
        if (lastScrollPos === currentScrollPos) {
            if (!document.querySelector(SELECTOR_SPINNER)) {
                retryCount++;
                if (retryCount >= retryThreshold) {
                    clearInterval(scrollInterval);
                    alert(`Scan completed, a total of ${pageInfo.imageCount} images have been added to Eagle App.`);
                }
            }
        }
        else {
            retryCount = 0;
            var images = getImgs();
            addImagesToEagle(images);
        }
    }

    var addImagesToEagle = function(images) {
        GM_xmlhttpRequest({
            url: EAGLE_IMPORT_API_URL,
            method: "POST",
            data: JSON.stringify({ items: images, folderId: pageInfo.folderId }),
            onload: function(response) {}
        });
    }

    function absolutePath(href) {
        if (href && href.indexOf(" ") > -1) {
            href = href.trim().split(" ")[0];
        }
        var link = document.createElement("a");
        link.href = href;
        return link.href;
    }

    function getHighestResImg(element) {
        if (element.getAttribute('srcset')) {
            let highResImgUrl = '';
            let maxRes = 0;
            let imgWidth, urlWidthArr;
            element.getAttribute('srcset').split(',').forEach((item) => {
                urlWidthArr = item.trim().split(' ');
                imgWidth = parseInt(urlWidthArr[1]);
                if (imgWidth > maxRes) {
                    maxRes = imgWidth;
                    highResImgUrl = urlWidthArr[0];
                }

            });
            return highResImgUrl;
        } else {
            return element.getAttribute('src');
        }
    }

    scarollToTop();

    var folderName = document.querySelector("h1") && document.querySelector("h1").innerText || "Pinterest";
    createFolder(folderName, function(err, folder) {
        if (folder) {
            pageInfo.folderId = folder.id;
            scrollInterval = setInterval(fetchImages, 1000);
        } else {
            alert("An error has occurred or the Eagle app is not open.");
        }
    });

})();

Last updated