// @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.
// @namespace https://eagle.cool/
// @homepageURL https://eagle.cool/
// @match https://www.pinterest.com/*
// @grant GM_xmlhttpRequest
if (location.href.indexOf("pinterest.com") === -1) {
alert("This script only works on pinterest.com.");
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`;
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 createFolder = function(folderName, callback) {
url: EAGLE_CREATE_FOLDER_API_URL,
data: JSON.stringify({ folderName: folderName }),
onload: function(response) {
var result = JSON.parse(response.response);
if (result.status === "success" && result.data && result.data.id) {
callback(undefined, result.data);
var scarollToTop = function() {
lastScrollPos = window.scrollY;
var scarollToBottom = function() {
window.scrollTo(0, document.body.scrollHeight);
lastScrollPos = window.scrollY;
var getImgs = function() {
var imgElements = Array.from(document.querySelectorAll(SELECTOR_IMAGE));
imgElements = imgElements.filter(function(elem) {
if (!pageInfo.imageSet[src]) {
pageInfo.imageSet[src] = true;
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);
imgs = imgElements.map(function(elem, index) {
url: getHighestResImg(elem) || elem.src,
modificationTime: startTime - pageInfo.imageCount
var fetchImages = function() {
var currentScrollPos = window.scrollY;
if (lastScrollPos === currentScrollPos) {
if (!document.querySelector(SELECTOR_SPINNER)) {
if (retryCount >= retryThreshold) {
clearInterval(scrollInterval);
alert(`Scan completed, a total of ${pageInfo.imageCount} images have been added to Eagle App.`);
addImagesToEagle(images);
var addImagesToEagle = function(images) {
url: EAGLE_IMPORT_API_URL,
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");
function getHighestResImg(element) {
if (element.getAttribute('srcset')) {
let imgWidth, urlWidthArr;
element.getAttribute('srcset').split(',').forEach((item) => {
urlWidthArr = item.trim().split(' ');
imgWidth = parseInt(urlWidthArr[1]);
highResImgUrl = urlWidthArr[0];
return element.getAttribute('src');
var folderName = document.querySelector("h1") && document.querySelector("h1").innerText || "Pinterest";
createFolder(folderName, function(err, folder) {
pageInfo.folderId = folder.id;
scrollInterval = setInterval(fetchImages, 1000);
alert("An error has occurred or the Eagle app is not open.");