Wykop Random Filename Uploader

Changes uploaded file names to random numbers on Wykop (supports both click upload and drag-drop, main editor and replies)

  1. // ==UserScript==
  2. // @name Wykop Random Filename Uploader
  3. // @namespace http://tampermonkey.net/
  4. // @icon https://i.imgur.com/micEWu9.png
  5. // @version 1.4
  6. // @description Changes uploaded file names to random numbers on Wykop (supports both click upload and drag-drop, main editor and replies)
  7. // @author stopbreathing
  8. // @match https://wykop.pl/*
  9. // @grant none
  10. // @license MIT
  11. // ==/UserScript==
  12.  
  13. (function() {
  14. 'use strict';
  15.  
  16. // Function to generate random number string
  17. function generateRandomNumber(length = 10) {
  18. let result = '';
  19. for(let i = 0; i < length; i++) {
  20. result += Math.floor(Math.random() * 10);
  21. }
  22. return result;
  23. }
  24.  
  25. // Function to create a new file with random name
  26. function createRandomNameFile(file) {
  27. const extension = file.name.split('.').pop();
  28. const newName = `${generateRandomNumber()}.${extension}`;
  29.  
  30. const newFile = new File([file], newName, {
  31. type: file.type,
  32. lastModified: new Date().getTime()
  33. });
  34.  
  35. console.log('File renamed from', file.name, 'to', newName);
  36. return newFile;
  37. }
  38.  
  39. // Function to handle file selection through input
  40. function handleFileSelection(event) {
  41. const input = event.target;
  42. if (!input.files || !input.files.length) return;
  43.  
  44. const file = input.files[0];
  45. const newFile = createRandomNameFile(file);
  46.  
  47. // Create new FileList
  48. const dataTransfer = new DataTransfer();
  49. dataTransfer.items.add(newFile);
  50. input.files = dataTransfer.files;
  51. }
  52.  
  53. // Function to handle drag events
  54. function handleDragOver(event) {
  55. event.preventDefault();
  56. event.stopPropagation();
  57. }
  58.  
  59. // Function to handle drop events
  60. function handleDrop(event) {
  61. // We need to prevent the default behavior initially
  62. event.preventDefault();
  63. event.stopPropagation();
  64.  
  65. const files = event.dataTransfer?.files;
  66. if (!files || !files.length) return;
  67.  
  68. // Create a new DataTransfer object with renamed files
  69. const newDataTransfer = new DataTransfer();
  70. for (const file of files) {
  71. const newFile = createRandomNameFile(file);
  72. newDataTransfer.items.add(newFile);
  73. }
  74.  
  75. // Create a new drop event with our renamed files
  76. const newDropEvent = new DragEvent('drop', {
  77. bubbles: true,
  78. cancelable: true,
  79. dataTransfer: newDataTransfer
  80. });
  81.  
  82. // Remove our event listeners temporarily
  83. const editorArea = event.target.closest('.editor');
  84. if (editorArea) {
  85. editorArea.removeEventListener('drop', handleDrop, true);
  86. editorArea.removeEventListener('dragover', handleDragOver, true);
  87.  
  88. // Dispatch the new event
  89. event.target.dispatchEvent(newDropEvent);
  90.  
  91. // Re-add our event listeners after a short delay
  92. setTimeout(() => {
  93. editorArea.addEventListener('drop', handleDrop, true);
  94. editorArea.addEventListener('dragover', handleDragOver, true);
  95. }, 100);
  96. }
  97. }
  98.  
  99. // Function to add visual indicator
  100. function addVisualIndicator(element, isDragDrop = false) {
  101. if (!element.querySelector('.random-filename-indicator')) {
  102. const indicator = document.createElement('div');
  103. indicator.className = 'random-filename-indicator';
  104. indicator.style.color = 'green';
  105. indicator.style.fontSize = '12px';
  106.  
  107. if (isDragDrop) {
  108. indicator.style.position = 'absolute';
  109. indicator.style.top = '0';
  110. indicator.style.right = '0';
  111. indicator.style.padding = '5px';
  112. indicator.textContent = 'Random filename active (drag & drop enabled)';
  113. element.style.position = 'relative';
  114. } else {
  115. indicator.textContent = 'Random filename active';
  116. }
  117.  
  118. element.appendChild(indicator);
  119. }
  120. }
  121.  
  122. // Function to observe DOM for file inputs and drag-drop zones
  123. function observeElements(mutations) {
  124. const addEventListeners = () => {
  125. // Handle file inputs
  126. const fileInputs = document.querySelectorAll('input[type="file"]');
  127. fileInputs.forEach(input => {
  128. if (!input.dataset.randomized) {
  129. input.dataset.randomized = 'true';
  130. input.addEventListener('change', handleFileSelection);
  131. addVisualIndicator(input.parentElement);
  132. }
  133. });
  134.  
  135. // Handle both main editor and reply editors
  136. const editorAreas = document.querySelectorAll('.editor.entry-editor, .editor.entry-comment-editor');
  137. editorAreas.forEach(editorArea => {
  138. if (!editorArea.dataset.randomizedDrop) {
  139. editorArea.dataset.randomizedDrop = 'true';
  140.  
  141. // Add drag and drop event listeners
  142. editorArea.addEventListener('dragover', handleDragOver, true);
  143. editorArea.addEventListener('drop', handleDrop, true);
  144.  
  145. // Add visual indicator
  146. addVisualIndicator(editorArea, true);
  147. }
  148. });
  149. };
  150.  
  151. // Initial check
  152. addEventListeners();
  153.  
  154. // Monitor for changes
  155. const observer = new MutationObserver((mutations) => {
  156. addEventListeners();
  157. });
  158.  
  159. observer.observe(document.body, {
  160. childList: true,
  161. subtree: true
  162. });
  163. }
  164.  
  165. // Start monitoring when document is ready
  166. if (document.readyState === 'loading') {
  167. document.addEventListener('DOMContentLoaded', observeElements);
  168. } else {
  169. observeElements();
  170. }
  171.  
  172. // Also monitor for dynamic changes
  173. const observer = new MutationObserver(observeElements);
  174. observer.observe(document.body, {
  175. childList: true,
  176. subtree: true
  177. });
  178. })();