// ==UserScript== // @name Telegram Media Downloader (Batch Support) // @name:en Telegram Media Downloader (Batch Support) // @name:zh-CN Telegram 受限图片视频下载器 (批量支持) // @name:zh-TW Telegram 受限圖片影片下載器 (批次支援) // @name:ru Telegram: загрузчик медиафайлов (пакетная загрузка) // @version 1.207 // @namespace https://github.com/Neet-Nestor/Telegram-Media-Downloader // @description Enhanced version with batch download support for restricted Telegram content // @description:en Download multiple images/videos at once from restricted Telegram channels // @description:ru Пакетная загрузка медиафайлов из закрытых Telegram-каналов // @description:zh-CN 批量下载禁止保存的Telegram频道内容 // @description:zh-TW 批次下載禁止儲存的 Telegram 頻道內容 // @author Nestor Qin + Modifications // @license GNU GPLv3 // @website https://github.com/Neet-Nestor/Telegram-Media-Downloader // @match https://web.telegram.org/* // @match https://webk.telegram.org/* // @match https://webz.telegram.org/* // @icon https://img.icons8.com/color/452/telegram-app--v5.png // @grant GM_download // @grant GM_xmlhttpRequest // @downloadURL https://update.greasyfork.cloud/scripts/531736/Telegram%20Media%20Downloader%20%28Batch%20Support%29.user.js // @updateURL https://update.greasyfork.cloud/scripts/531736/Telegram%20Media%20Downloader%20%28Batch%20Support%29.meta.js // ==/UserScript== (function() { 'use strict'; // Existing logger and constants remain unchanged const logger = { /* ... original logger code ... */ }; const contentRangeRegex = /^bytes (\d+)-(\d+)\/(\d+)$/; const REFRESH_DELAY = 500; const hashCode = s => { /* ... original hash code ... */ }; // Batch Download System const batchManager = { queue: new Map(), isProcessing: false, addToQueue: function(url, type, element) { this.queue.set(url, { type, element }); element.classList.add('tel-batch-selected'); }, removeFromQueue: function(url) { this.queue.delete(url); }, processQueue: async function() { this.isProcessing = true; const batchSize = this.queue.size; for (const [url, {type, element}] of this.queue) { try { await new Promise((resolve, reject) => { setTimeout(() => { try { switch(type) { case 'video': tel_download_video(url); break; case 'audio': tel_download_audio(url); break; case 'image': tel_download_image(url); break; } resolve(); } catch(e) { reject(e); } }, 1000); }); element.classList.remove('tel-batch-selected'); } catch(e) { logger.error(`Batch failed for ${url}: ${e.message}`); } } this.queue.clear(); this.isProcessing = false; } }; // Batch UI Elements const createBatchUI = () => { const existingButton = document.getElementById('tel-batch-download'); if (!existingButton) { const batchButton = document.createElement('button'); batchButton.id = 'tel-batch-download'; batchButton.textContent = `Batch Download (${batchManager.queue.size})`; Object.assign(batchButton.style, { position: 'fixed', bottom: '20px', right: '20px', zIndex: '99999', padding: '10px 20px', backgroundColor: '#0088cc', color: 'white', border: 'none', borderRadius: '5px', cursor: 'pointer' }); batchButton.addEventListener('click', () => { if (!batchManager.isProcessing && batchManager.queue.size > 0) { batchButton.textContent = 'Processing...'; batchManager.processQueue().finally(() => { batchButton.textContent = 'Batch Download (0)'; }); } }); document.body.appendChild(batchButton); } }; // Modified media injection with checkboxes const injectMediaElements = (mediaElements, mediaType) => { mediaElements.forEach(element => { if (element.querySelector('.tel-batch-checkbox')) return; const url = element.querySelector('video,img,audio')?.src; if (!url) return; const checkbox = document.createElement('input'); checkbox.type = 'checkbox'; checkbox.className = 'tel-batch-checkbox'; Object.assign(checkbox.style, { position: 'absolute', top: '5px', left: '5px', zIndex: '1000', width: '18px', height: '18px' }); checkbox.addEventListener('change', (e) => { if (e.target.checked) { batchManager.addToQueue(url, mediaType, element); } else { batchManager.removeFromQueue(url); } document.getElementById('tel-batch-download').textContent = `Batch Download (${batchManager.queue.size})`; }); element.style.position = 'relative'; element.appendChild(checkbox); }); }; // Modified interval handlers const createMediaHandlers = () => { // Original media detection code modified to include batch checkboxes setInterval(() => { // Video elements const videoElements = document.querySelectorAll('.VideoPlayer, video'); injectMediaElements(videoElements, 'video'); // Image elements const imageElements = document.querySelectorAll('img.PVZ8TOWS, img.media-photo'); injectMediaElements(imageElements, 'image'); // Audio elements const audioElements = document.querySelectorAll('audio-element, audio'); injectMediaElements(audioElements, 'audio'); createBatchUI(); }, REFRESH_DELAY); }; // Existing progress bar setup remains unchanged const setupProgressBar = () => { /* ... original progress bar code ... */ }; // Original download functions remain unchanged const tel_download_video = url => { /* ... original video download ... */ }; const tel_download_audio = url => { /* ... original audio download ... */ }; const tel_download_image = url => { /* ... original image download ... */ }; // Initialization (function init() { setupProgressBar(); createMediaHandlers(); logger.info('Batch download system initialized'); })(); })();