nT-Exporter

Export content URLs from newTumbl blog

  1. // ==UserScript==
  2. // @name nT-Exporter
  3. // @namespace https://www.newtumbl.com/
  4. // @version 1.3
  5. // @description Export content URLs from newTumbl blog
  6. // @author ceodoe
  7. // @license GPLv3
  8. // @match https://*.newtumbl.com/
  9. // @match https://newtumbl.com/*
  10. // @icon https://www.google.com/s2/favicons?sz=64&domain=newtumbl.com
  11. // @grant none
  12. // @run-at document-end
  13. // ==/UserScript==
  14.  
  15. window.setTimeout(function() {
  16. let nav = document.querySelector("div.nav > ul");
  17. let dumpBtn = document.createElement("li");
  18. dumpBtn.innerText = "Export";
  19.  
  20. dumpBtn.onclick = function() {
  21. let urlArray = [];
  22. let outputString = "";
  23.  
  24. let imgs = document.querySelectorAll("img");
  25. let mediaRegex = new RegExp(/^https:\/\/dn[0-9]\.newtumbl\.com\/img\/[0-9]+\/[0-9]+\/[0-9]\/[0-9]+\/nT_[A-Za-z0-9_]+\.jpg|gif|mp4$/);
  26. let thumbnailRegex = new RegExp(/(_150|_300|_600)\.(jpg|gif|mp4)$/);
  27. let avatarRegex = new RegExp(/^https:\/\/dn[0-9]\.newtumbl\.com\/img\/[0-9]+\/0\/0\//);
  28.  
  29. for(let i = 0; i < imgs.length; i++) {
  30. // Ignore avatars
  31. if(!avatarRegex.test(imgs[i].src)) {
  32. if(mediaRegex.test(imgs[i].src)) {
  33. // Replace thumbnails with full version of the image
  34. if(thumbnailRegex.test(imgs[i].src)) {
  35. urlArray.push(imgs[i].src.replace(thumbnailRegex, ".$2"));
  36. } else {
  37. urlArray.push(imgs[i].src);
  38. }
  39. }
  40. }
  41. }
  42.  
  43. let vids = document.querySelectorAll("video > source");
  44. for(let i = 0; i < vids.length; i++) {
  45. if(mediaRegex.test(vids[i].src)) {
  46. // If video hasn't been played yet, there is a .jpg video thumbnail with the same filename
  47. // loaded on top of it, which will have been included in the imgs loop, so we remove it
  48.  
  49. let vidThumb = vids[i].src.slice(0, -3) + "jpg";
  50. if(urlArray.includes(vidThumb)) {
  51. urlArray.splice(urlArray.indexOf(vidThumb), 1);
  52. }
  53. urlArray.push(vids[i].src);
  54. }
  55. }
  56.  
  57. let urlSet = [...new Set(urlArray)];
  58.  
  59. if(urlSet.length > 0) {
  60. for(let i = 0; i < urlSet.length; i++) {
  61. outputString += urlSet[i] + "\n";
  62. }
  63. let filePrefix = "newTumbl";
  64. // Are we on....
  65. if(new RegExp(/^https:\/\/.+\.newtumbl\.com/).test(window.location.href)) {
  66. // A subdomain? Put blog url in prefix
  67. filePrefix = window.location.host.split(".")[0];
  68. } else if(new RegExp(/^https:\/\/newtumbl\.com\/search/).test(window.location.href)) {
  69. // On the search page? Put search term in prefix
  70. filePrefix = decodeURIComponent(window.location.hash.substring(3)).replace(" ", "-");
  71. } else if(new RegExp(/^https:\/\/newtumbl\.com\/blog\//).test(window.location.href)) {
  72. // On a /blog/ page? Put drafts or queue in prefix
  73. if(window.location.href.includes("/drafts")) {
  74. filePrefix = "drafts";
  75. } else if(window.location.href.includes("/queue")) {
  76. filePrefix = "queue";
  77. }
  78. } else if(new RegExp(/^https:\/\/newtumbl\.com\/feed/).test(window.location.href)) {
  79. // On the feed? Put feed in prefix
  80. filePrefix = "feed";
  81. } else if(new RegExp(/^https:\/\/newtumbl\.com\/dashboard/).test(window.location.href)) {
  82. // On the dashboard? Put dashboard in prefix
  83. filePrefix = "dashboard";
  84. }
  85.  
  86. let element = document.createElement('a');
  87. element.setAttribute("href", "data:text/plain;charset=utf-8," + encodeURIComponent(outputString));
  88. element.setAttribute("download", `${filePrefix}_${GM_info.script.name}-${Date.now()}.txt`);
  89. element.style.display = "none";
  90. document.body.appendChild(element);
  91. element.click();
  92. document.body.removeChild(element);
  93.  
  94. alert("Success! " + GM_info.script.name + " found " + urlSet.length + " unique media elements on this page, and saved their URLs to a text file. In order to download the actual media files, feed the downloaded text file into your favourite downloader, such as wget or JDownloader 2.");
  95. } else {
  96. alert("No posts found on the current page.");
  97. }
  98. };
  99.  
  100. nav.append(dumpBtn);
  101. }, 1500);