Derpibooru - Download All

Adds a download button that lets you download all images from the current search query

  1. // ==UserScript==
  2. // @name Derpibooru - Download All
  3. // @namespace Selbi
  4. // @include http*://*derpibooru.org/*
  5. // @version 2.0.1
  6. // @description Adds a download button that lets you download all images from the current search query
  7. // ==/UserScript==
  8.  
  9. const states = {
  10. ready: 0,
  11. fetching: 1,
  12. readyForDownload: 2,
  13. downloading: 3
  14. };
  15. var state = states.ready;
  16.  
  17. var imageLinks = [];
  18.  
  19. let randomImageButton = document.querySelector("section.block__header > div:last-child > a:first-child");
  20. let downloadButton = randomImageButton.cloneNode(true);
  21.  
  22. let dlButtonText = downloadButton.querySelector("span");
  23. let dlButtonClasses = downloadButton.querySelector("i");
  24. downloadButton.onclick = function() {
  25. if (state === states.ready) {
  26. let params = new URLSearchParams(window.location.search);
  27. let page = params.get("page");
  28. if (page != null && parseInt(page) > 1) {
  29. alert("Warning: You are not on page 1 of the gallery! Only images starting at this page will be downloaded.")
  30. }
  31. state = states.fetching;
  32. dlButtonClasses.classList = "fa fa-spinner fa-spin fa-pulse";
  33. fetchLinksForPage(document);
  34. state = states.readyForDownload;
  35. dlButtonClasses.classList = "fa fa-check";
  36. dlButtonText.innerHTML = "Download Ready! (" + imageLinks.length + ")";
  37. } else if (state === states.fetching) {
  38. alert("Please wait until all links have been fetched!");
  39. } else if (state === states.readyForDownload) {
  40. downloadImages(imageLinks);
  41. } else if (state === downloading) {
  42. alert("Download is currently in progress, please wait for its completion!")
  43. }
  44. };
  45.  
  46. downloadButton.href = "#";
  47. downloadButton.title = "Download All Images";
  48. dlButtonClasses.classList = "fa fa-download";
  49. dlButtonText.innerHTML = "Download All";
  50.  
  51. randomImageButton.before(downloadButton);
  52.  
  53. var parser = new DOMParser();
  54.  
  55. function fetchLinksForPage(page) {
  56. // Get images of current page
  57. let images = page.querySelectorAll(".image-container");
  58. for (img of images) {
  59. let dataUris = img.getAttribute("data-uris");
  60. let full = JSON.parse(dataUris)["full"];
  61. let download = full.replace("/view/", "/download/"); // god I hope this never breaks
  62. imageLinks.push(download);
  63. dlButtonText.innerHTML = "Fetching Links... (" + imageLinks.length + ")";
  64. }
  65. // Go to next page, if there is any
  66. let nextButton = page.querySelector(".js-next");
  67. if (nextButton != null) {
  68. let nextPageHref = nextButton.href;
  69.  
  70. let xhr = new XMLHttpRequest();
  71. xhr.open("GET", nextPageHref, false);
  72. xhr.send();
  73. let responseText = xhr.responseText;
  74. let responseDom = parser.parseFromString(responseText, 'text/html');
  75. fetchLinksForPage(responseDom);
  76. }
  77. }
  78.  
  79. function downloadImages(links) {
  80. for (link of links) {
  81. window.open(link, '_blank');
  82. }
  83. state = states.readyForDownload;
  84. }