Desu Image Downloader

Download images with original filenames on desuarchive.org and add download button to direct image pages

当前为 2024-08-11 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Desu Image Downloader
  3. // @version 1.19
  4. // @description Download images with original filenames on desuarchive.org and add download button to direct image pages
  5. // @author Anonimas
  6. // @match https://desuarchive.org/*
  7. // @match https://desu-usergeneratedcontent.xyz/*
  8. // @grant GM_download
  9. // @grant GM_addStyle
  10. // @namespace https://greasyfork.org/users/1342214
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. GM_addStyle(`
  17. #download-button {
  18. position: fixed;
  19. bottom: 20px;
  20. right: 20px;
  21. background-color: rgba(0, 0, 0, 0.5);
  22. color: white;
  23. border: none;
  24. border-radius: 5px;
  25. padding: 10px 20px;
  26. cursor: pointer;
  27. font-size: 16px;
  28. transition: background-color 0.3s;
  29. text-decoration: none;
  30. font-family: Arial, sans-serif;
  31. }
  32. #download-button:hover {
  33. background-color: rgba(0, 0, 0, 0.7);
  34. }
  35. `);
  36.  
  37. function getFullFilename(element) {
  38. return element.getAttribute('title') || element.textContent.trim();
  39. }
  40.  
  41. function appendFilenameToUrl(url, filename) {
  42. return `${url}?filename=${encodeURIComponent(filename)}`;
  43. }
  44.  
  45. function downloadImage(imageUrl, originalFilename) {
  46. if (imageUrl && originalFilename) {
  47. GM_download({
  48. url: imageUrl,
  49. name: originalFilename,
  50. onload: () => {},
  51. onerror: (error) => console.error('Download error:', error)
  52. });
  53. }
  54. }
  55.  
  56. function handleImageClick(event) {
  57. event.preventDefault();
  58. const imageLink = event.target.closest('a[href*="//desu-usergeneratedcontent.xyz/"]');
  59. if (!imageLink) return;
  60.  
  61. const imageUrl = imageLink.href;
  62. let filenameElement = imageLink.closest('div.post_file, article.thread, article.post')?.querySelector('a.post_file_filename');
  63. if (!filenameElement) return;
  64.  
  65. const originalFilename = getFullFilename(filenameElement);
  66.  
  67. const newUrl = appendFilenameToUrl(imageUrl, originalFilename);
  68. window.open(newUrl, '_blank');
  69. }
  70.  
  71. function addDownloadButtonToImagePage() {
  72. if (window.location.hostname === 'desu-usergeneratedcontent.xyz') {
  73. const button = document.createElement('a');
  74. button.id = 'download-button';
  75. button.textContent = 'Download';
  76.  
  77. const imageUrl = window.location.href;
  78.  
  79. const urlParams = new URLSearchParams(window.location.search);
  80. const originalFilename = urlParams.get('filename') || extractFilenameFromUrl(imageUrl);
  81.  
  82. button.href = imageUrl;
  83. button.download = originalFilename;
  84.  
  85. document.body.appendChild(button);
  86. }
  87. }
  88.  
  89. function extractFilenameFromUrl(url) {
  90. return url.substring(url.lastIndexOf('/') + 1);
  91. }
  92.  
  93. if (window.location.hostname === 'desuarchive.org') {
  94. document.querySelectorAll('a.post_file_filename').forEach(link => {
  95. link.addEventListener('click', event => {
  96. event.preventDefault();
  97. const imageUrl = link.closest('a').href;
  98. const originalFilename = getFullFilename(link);
  99. downloadImage(imageUrl, originalFilename);
  100. });
  101. });
  102.  
  103. document.querySelectorAll('a[href*="//desu-usergeneratedcontent.xyz/"] i.icon-download-alt').forEach(button => {
  104. button.closest('a').addEventListener('click', event => {
  105. event.preventDefault();
  106. const imageUrl = button.closest('a').href;
  107. let filenameElement = button.closest('div.post_file, article.thread, article.post')?.querySelector('a.post_file_filename');
  108. if (!filenameElement) return;
  109.  
  110. const originalFilename = getFullFilename(filenameElement);
  111. downloadImage(imageUrl, originalFilename);
  112. });
  113. });
  114.  
  115. document.querySelectorAll('a[href*="//desu-usergeneratedcontent.xyz/"] img').forEach(image => {
  116. image.closest('a').addEventListener('click', handleImageClick);
  117. });
  118. }
  119.  
  120. addDownloadButtonToImagePage();
  121. })();