Bunkr Name Saver

Сохраняет названия всех медиа в файл media.txt (фикс для новой структуры имен)

  1. // ==UserScript==
  2. // @name Bunkr Name Saver
  3. // @namespace https://github.com/darhanger
  4. // @version 1.3
  5. // @description Сохраняет названия всех медиа в файл media.txt (фикс для новой структуры имен)
  6. // @author DarhangeR
  7. // @include *://bunkr*/a/*
  8. // @icon https://www.google.com/s2/favicons?sz=64&domain=bunkr.is
  9. // @license MIT
  10. // @grant none
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. const NAME_SELECTOR = '.theName';
  17.  
  18. function getBrowserLanguage() {
  19. return (navigator.language || navigator.userLanguage).split('-')[0];
  20. }
  21.  
  22. function logMessage(messageRu, messageEn) {
  23. console.log(getBrowserLanguage() === 'ru' ? messageRu : messageEn);
  24. }
  25.  
  26. function collectMediaNames() {
  27. return Array.from(document.querySelectorAll(NAME_SELECTOR)).map(nameElement => {
  28. let fileName = nameElement.textContent
  29. .trim()
  30. .replace(/[\\/:*?"<>|]/g, '')
  31. .replace(/\s+/g, ' ');
  32.  
  33. if (!fileName.includes('.')) {
  34. const parentLink = nameElement.closest('[href]');
  35. if (parentLink) {
  36. const url = new URL(parentLink.href);
  37. const extension = url.pathname.split('.').pop();
  38. fileName += `.${extension}`;
  39. }
  40. }
  41.  
  42. return fileName;
  43. });
  44. }
  45.  
  46. function downloadMediaTxt() {
  47. const mediaNames = collectMediaNames();
  48.  
  49. if (!mediaNames.length) {
  50. logMessage("❌ Медиа-файлы не найдены!", "❌ No media files found!");
  51. return;
  52. }
  53.  
  54. const text = mediaNames.join('\n');
  55. const blob = new Blob([text], { type: 'text/plain' });
  56. const url = URL.createObjectURL(blob);
  57.  
  58. const a = document.createElement('a');
  59. a.href = url;
  60. a.download = 'media.txt';
  61. document.body.appendChild(a);
  62. a.click();
  63.  
  64. setTimeout(() => {
  65. document.body.removeChild(a);
  66. URL.revokeObjectURL(url);
  67. }, 100);
  68. }
  69.  
  70. function getOrCreateButtonsRow() {
  71. const headerBlock = document.querySelector(
  72. 'main.cont.py-6.grid.auto-rows-max.gap-6 > div.flex.items-center.flex-wrap.gap-4'
  73. );
  74. if (!headerBlock) return null;
  75.  
  76. const next = headerBlock.nextElementSibling;
  77. if (next && next.dataset.bunkrButtonsRow === '1') {
  78. return next;
  79. }
  80.  
  81. const wrapper = document.createElement('div');
  82. wrapper.dataset.bunkrButtonsRow = '1';
  83. wrapper.style.display = 'flex';
  84. wrapper.style.justifyContent = 'flex-end';
  85. wrapper.style.marginTop = '0px';
  86. wrapper.style.gap = '8px';
  87.  
  88. headerBlock.insertAdjacentElement('afterend', wrapper);
  89. return wrapper;
  90. }
  91.  
  92. function createDownloadButton() {
  93. const wrapper = getOrCreateButtonsRow();
  94. if (!wrapper) return;
  95.  
  96. const btn = document.createElement('button');
  97. btn.innerText = '💾 Save Media List';
  98. btn.className = 'btn btn-sm rounded-md font-semibold';
  99. btn.style.width = "140px";
  100. btn.style.padding = "4px 8px";
  101. btn.style.background = "#1B2533";
  102. btn.style.color = "#fff";
  103. btn.style.border = "none";
  104. btn.style.cursor = "pointer";
  105. btn.style.fontSize = "12px";
  106. btn.style.borderRadius = "6px";
  107.  
  108. btn.addEventListener('click', () => {
  109. logMessage("⏳ Собираем названия...", "⏳ Collecting names...");
  110. setTimeout(downloadMediaTxt, 500);
  111. });
  112.  
  113. wrapper.appendChild(btn);
  114. }
  115.  
  116. logMessage("Bunkr Media Saver 1.3 запущен!", "Bunkr Media Saver 1.3 started!");
  117. createDownloadButton();
  118. })();

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址