导入 Danbooru 图片到 Eagle

在danbooru网页上添加下载按钮直接导入Eagle,默认同时保存所有标签,若属于pool则会以pool名创建文件夹

  1. // ==UserScript==
  2. // @name Save Danbooru Images to Eagle
  3. // @name:zh 导入 Danbooru 图片到 Eagle
  4. // @name:zh-CN 导入 Danbooru 图片到 Eagle
  5.  
  6. // @description Save images from Danbooru to Eagle.
  7. // @description:zh 在danbooru网页上添加下载按钮直接导入Eagle,默认同时保存所有标签,若属于pool则会以pool名创建文件夹
  8. // @description:zh-CN 在danbooru网页上添加下载按钮直接导入Eagle,默认同时保存所有标签,若属于pool则会以pool名创建文件夹
  9.  
  10. // @author miracleXL
  11. // @namespace https://github.com/miracleXL
  12. // @homepageURL https://github.com/miracleXL/scripts-for-Eagle
  13. // @icon https://danbooru.donmai.us/favicon.ico
  14.  
  15. // @match danbooru.donmai.us/posts/*
  16. // @match safebooru.donmai.us/posts/*
  17. // @match danbooru.donmai.us/pools/*
  18. // @match safebooru.domai.us/pools/*
  19. // @connect danbooru.donmai.us
  20. // @connect safebooru.donmai.us
  21. // @connect localhost
  22. // @grant GM_xmlhttpRequest
  23.  
  24. // @version 0.1.3
  25.  
  26. // ==/UserScript==
  27.  
  28. (function() {
  29. 'use strict';
  30.  
  31. // Eagle API 服务器位置
  32. const EAGLE_SERVER_URL = "http://localhost:41595";
  33. const EAGLE_IMPORT_API_URL = `${EAGLE_SERVER_URL}/api/item/addFromURL`;
  34. const EAGLE_IMPORT_API_URLS = `${EAGLE_SERVER_URL}/api/item/addFromURLs`;
  35. const EAGLE_CREATE_FOLDER_API_URL = `${EAGLE_SERVER_URL}/api/folder/create`;
  36. const EAGLE_GET_FOLDERS_API_URL = `${EAGLE_SERVER_URL}/api/folder/list`;
  37.  
  38. // 是否保存标签(true/false)
  39. const saveTags = true;
  40.  
  41. let mode = document.URL.split("/")[3];
  42.  
  43. function addButton(){
  44. let button = document.createElement("button");
  45. button.className = "ui-button ui-widget ui-corner-all";
  46. if(mode === "posts"){
  47. button.innerText = "下载";
  48. let buttons_div = document.getElementsByClassName("fav-buttons")[0];
  49. buttons_div.firstElementChild.style.display = "inline";
  50. buttons_div.appendChild(button);
  51. //绑定下载事件
  52. button.addEventListener("click",async ()=>{
  53. let [data,pool] = getImageData();
  54. if(pool){
  55. let folderId = await getFolderId(pool);
  56. if(folderId){
  57. data.folderId = folderId;
  58. }
  59. }
  60. // console.log(data);
  61. download(data);
  62. })
  63. }
  64. else{
  65. button.innerText = "下载当前页全部";
  66. let buttonPos = document.getElementById("description");
  67. buttonPos.appendChild(button);
  68. //绑定下载事件
  69. button.addEventListener("click",async ()=>{
  70. let [data,pool] = getPoolData();
  71. if(pool){
  72. let folderId = await getFolderId(pool);
  73. if(folderId){
  74. data.folderId = folderId;
  75. }
  76. }
  77. // console.log(data);
  78. downloadAll(data);
  79. })
  80. }
  81. }
  82.  
  83. addButton();
  84.  
  85. function download(data){
  86. GM_xmlhttpRequest({
  87. url: EAGLE_IMPORT_API_URL,
  88. method: "POST",
  89. data: JSON.stringify(data),
  90. onload: function(response) {
  91. if(response.statusText !== "OK"){
  92. console.log(response);
  93. alert("下载失败!")
  94. }
  95. }
  96. });
  97. }
  98.  
  99. function downloadAll(data){
  100. GM_xmlhttpRequest({
  101. url: EAGLE_IMPORT_API_URLS,
  102. method: "POST",
  103. data: JSON.stringify(data),
  104. onload: function(response) {
  105. if(response.statusText !== "OK"){
  106. alert("请检查eagle是否打开!");
  107. console.log("下载失败!")
  108. }
  109. }
  110. });
  111. }
  112.  
  113. function getImageData(){
  114. let name = document.getElementById("original-artist-commentary");
  115. if(name){
  116. name = name.firstElementChild.textContent;
  117. }
  118. else{
  119. let pool = document.getElementsByClassName("pool-name")[0]
  120. if(pool){
  121. pool = pool.firstElementChild;
  122. var poolname = pool.textContent.replace("Pool: ","");
  123. name = pool + " " + pool.title;
  124. }
  125. else{
  126. name = document.title;
  127. }
  128. }
  129. let website = document.getElementById("post-info-source").firstElementChild?.href;
  130. let data = {
  131. "url": document.getElementById("post-option-view-original").firstElementChild.href,
  132. "name": name,
  133. "website": website ? website : document.URL,
  134. "tags": [],
  135. "headers": {
  136. "referer" : document.URL
  137. }
  138. };
  139. if(saveTags){
  140. for(let tag of document.getElementsByClassName("search-tag")){
  141. data.tags.push(tag.textContent);
  142. };
  143. }
  144. return [data,poolname];
  145. };
  146.  
  147. function getPoolData(){
  148. try{
  149. var name = document.getElementsByClassName("pool-category-series")[0].textContent;
  150. }catch(e){
  151. name = document.title;
  152. console.log(e);
  153. }
  154. let data = {
  155. "items":[]
  156. };
  157. let count = 0;
  158. for(let article of document.getElementsByTagName("article")){
  159. let item = {
  160. "url": article.getAttribute("data-file-url"),
  161. "name": name + "_" + count,
  162. "website": article.getAttribute("data-normalized-source"),
  163. "tags": saveTags ? article.getAttribute("data-tags").split(" ") : [],
  164. "headers": {
  165. "referer" : document.URL
  166. }
  167. };
  168. data.items.push(item);
  169. }
  170. return [data,name];
  171. }
  172.  
  173. // 获取文件夹id
  174. async function getFolderId(pool){
  175. let folders = await getFolders();
  176. let dlFolder;
  177. if(folders){
  178. for(let folder of folders){
  179. if(folder.name === pool){
  180. dlFolder = folder;
  181. }
  182. }
  183. if(dlFolder === undefined) dlFolder = await creatFolder(pool);
  184. }
  185. else{
  186. console.log("获取文件夹信息失败!");
  187. alert("下载失败!");
  188. return;
  189. }
  190. return dlFolder.id;
  191. }
  192.  
  193. // 获取文件夹
  194. function getFolders(){
  195. return new Promise((resolve, reject) => {
  196. GM_xmlhttpRequest({
  197. url: EAGLE_GET_FOLDERS_API_URL,
  198. method: "GET",
  199. redirect:'follow',
  200. onload: function(response) {
  201. if(response.status !== 200){
  202. reject();
  203. }
  204. resolve(JSON.parse(response.response).data);
  205. }
  206. });
  207. })
  208. }
  209.  
  210. // 创建文件夹
  211. function creatFolder(folderName){
  212. return new Promise((resolve, reject) => {
  213. GM_xmlhttpRequest({
  214. url: EAGLE_CREATE_FOLDER_API_URL,
  215. method: "POST",
  216. data: JSON.stringify({ folderName: folderName }),
  217. onload: function(response) {
  218. var result = JSON.parse(response.response);
  219. if (result.status === "success" && result.data && result.data.id) {
  220. return resolve(result.data);
  221. }
  222. else{
  223. return reject();
  224. }
  225. }
  226. })
  227. })
  228. }
  229.  
  230. })();