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.
1
GM_xmlhttpRequest({
2
url: EAGLE_IMPORT_API_URL,
3
method: "POST",
4
data: JSON.stringify({ items: images, folderId: pageInfo.folderId }),
5
onload: function(response) {}
6
});
Copied!
Full Code:
1
// ==UserScript==
2
// @name Save Pinterest images to Eagle
3
4
// @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.
5
6
// @author Augus
7
// @namespace https://eagle.cool/
8
// @homepageURL https://eagle.cool/
9
// @license MIT License
10
11
// @match https://www.pinterest.com/*
12
// @grant GM_xmlhttpRequest
13
// @run-at context-menu
14
15
// @date 06/16/2020
16
// @modified 06/16/2020
17
// @version 0.0.3
18
19
// ==/UserScript==
20
21
22
(function() {
23
24
if (location.href.indexOf("pinterest.com") === -1) {
25
alert("This script only works on pinterest.com.");
26
return;
27
}
28
29
// Eagle API URL
30
const EAGLE_SERVER_URL = "http://localhost:41595";
31
const EAGLE_IMPORT_API_URL = `${EAGLE_SERVER_URL}/api/item/addFromURLs`;
32
const EAGLE_CREATE_FOLDER_API_URL = `${EAGLE_SERVER_URL}/api/folder/create`;
33
34
// Pinterest Rules
35
const SELECTOR_IMAGE = "[data-grid-item] a img[srcset]";
36
const SELECTOR_LINK = "[data-grid-item] a";
37
const SELECTOR_SPINNER = `[aria-label="Board Pins grid"]`;
38
39
var startTime = Date.now();
40
var scrollInterval;
41
var lastScrollPos;
42
var retryCount = 0;
43
var scrollDelay = 500;
44
var retryThreshold = 4;
45
var pageInfo = {
46
imageCount: 0,
47
imageSet: {},
48
folderId: ""
49
};
50
51
// Create a folder
52
var createFolder = function(folderName, callback) {
53
GM_xmlhttpRequest({
54
url: EAGLE_CREATE_FOLDER_API_URL,
55
method: "POST",
56
data: JSON.stringify({ folderName: folderName }),
57
onload: function(response) {
58
try {
59
var result = JSON.parse(response.response);
60
if (result.status === "success" && result.data && result.data.id) {
61
callback(undefined, result.data);
62
} else {
63
callback(true);
64
}
65
} catch (err) {
66
callback(true);
67
}
68
}
69
});
70
};
71
72
var scarollToTop = function() {
73
window.scrollTo(0, 0);
74
lastScrollPos = window.scrollY;
75
};
76
77
var scarollToBottom = function() {
78
window.scrollTo(0, document.body.scrollHeight);
79
lastScrollPos = window.scrollY;
80
};
81
82
var getImgs = function() {
83
var imgs = [];
84
var imgElements = Array.from(document.querySelectorAll(SELECTOR_IMAGE));
85
86
imgElements = imgElements.filter(function(elem) {
87
var src = elem.src;
88
if (!pageInfo.imageSet[src]) {
89
pageInfo.imageSet[src] = true;
90
return true;
91
}
92
return false;
93
});
94
95
var getLink = function(img) {
96
var links = Array.from(document.querySelectorAll(SELECTOR_LINK));
97
for (var i = 0; i < links.length; i++) {
98
if (links[i].contains(img)) {
99
return absolutePath(links[i].href);
100
}
101
}
102
return "";
103
};
104
105
imgs = imgElements.map(function(elem, index) {
106
pageInfo.imageCount++;
107
return {
108
name: elem.alt || "",
109
url: getHighestResImg(elem) || elem.src,
110
website: getLink(elem),
111
modificationTime: startTime - pageInfo.imageCount
112
}
113
});
114
115
return imgs;
116
};
117
118
var fetchImages = function() {
119
var currentScrollPos = window.scrollY;
120
scarollToBottom();
121
122
if (lastScrollPos === currentScrollPos) {
123
if (!document.querySelector(SELECTOR_SPINNER)) {
124
retryCount++;
125
if (retryCount >= retryThreshold) {
126
clearInterval(scrollInterval);
127
alert(`Scan completed, a total of ${pageInfo.imageCount} images have been added to Eagle App.`);
128
}
129
}
130
}
131
else {
132
retryCount = 0;
133
var images = getImgs();
134
addImagesToEagle(images);
135
}
136
}
137
138
var addImagesToEagle = function(images) {
139
GM_xmlhttpRequest({
140
url: EAGLE_IMPORT_API_URL,
141
method: "POST",
142
data: JSON.stringify({ items: images, folderId: pageInfo.folderId }),
143
onload: function(response) {}
144
});
145
}
146
147
function absolutePath(href) {
148
if (href && href.indexOf(" ") > -1) {
149
href = href.trim().split(" ")[0];
150
}
151
var link = document.createElement("a");
152
link.href = href;
153
return link.href;
154
}
155
156
function getHighestResImg(element) {
157
if (element.getAttribute('srcset')) {
158
let highResImgUrl = '';
159
let maxRes = 0;
160
let imgWidth, urlWidthArr;
161
element.getAttribute('srcset').split(',').forEach((item) => {
162
urlWidthArr = item.trim().split(' ');
163
imgWidth = parseInt(urlWidthArr[1]);
164
if (imgWidth > maxRes) {
165
maxRes = imgWidth;
166
highResImgUrl = urlWidthArr[0];
167
}
168
169
});
170
return highResImgUrl;
171
} else {
172
return element.getAttribute('src');
173
}
174
}
175
176
scarollToTop();
177
178
var folderName = document.querySelector("h1") && document.querySelector("h1").innerText || "Pinterest";
179
createFolder(folderName, function(err, folder) {
180
if (folder) {
181
pageInfo.folderId = folder.id;
182
scrollInterval = setInterval(fetchImages, 1000);
183
} else {
184
alert("An error has occurred or the Eagle app is not open.");
185
}
186
});
187
188
})();
Copied!
Last modified 1yr ago
Copy link