// ==UserScript== // @name RED Cover Inspector // @namespace https://greasyfork.org/users/321857-anakunda // @version 1.002 // @description Adds simple cover sticker if needs updating for unsupported host / big size / small resolution // @author Anakunda // @copyright 2020, Anakunda (https://greasyfork.org/users/321857-anakunda) // @license GPL-3.0-or-later // @match https://redacted.ch/torrents.php?id=* // @connect * // @grant GM_xmlhttpRequest // @grant GM_getValue // @grant GM_setValue // @downloadURL none // ==/UserScript== function getRemoteFileSize(url) { return new Promise(function(resolve, reject) { var imageSize, abort = GM_xmlhttpRequest({ method: 'GET', url: url, responseType: 'arraybuffer', onreadystatechange: function(response) { if (imageSize || response.readyState < XMLHttpRequest.HEADERS_RECEIVED || !/^(?:Content-Length):\s*(\d+)\b/im.test(response.responseHeaders)) return; if (!(imageSize = parseInt(RegExp.$1))) return; resolve(imageSize); abort.abort(); }, onload: function(response) { // fail-safe if (imageSize) return; if (response.status >= 200 && response.status < 400) resolve(response.responseText.length /*response.response.byteLength*/); else reject('image not accessible'); }, onerror: response => { reject('image not accessible') }, ontimeout: response => { reject('image not accessible') }, }); }); } function formattedSize(size) { return size < 1024**1 ? Math.round(size) + ' B' : size < 1024**2 ? (Math.round(size * 10 / 2**10) / 10) + ' KiB' : size < 1024**3 ? (Math.round(size * 100 / 2**20) / 100) + ' MiB' : size < 1024**4 ? (Math.round(size * 100 / 2**30) / 100) + ' GiB' : size < 1024**5 ? (Math.round(size * 100 / 2**40) / 100) + ' TiB' : (Math.round(size * 100 / 2**50) / 100) + ' PiB'; } var acceptableCoverSize = GM_getValue('acceptable_cover_size'); if (!(acceptableCoverSize > 0)) GM_setValue('acceptable_cover_size', acceptableCoverSize = 2048); var acceptableCoverResolution = GM_getValue('acceptable_cover_resolution'); if (!(acceptableCoverResolution > 0)) GM_setValue('acceptable_cover_resolution', acceptableCoverResolution = 200); document.querySelectorAll('div#covers p > img').forEach(function(img) { if (img.src.startsWith(document.location.origin) && img.src.endsWith('/noartwork/music.png')) return; getRemoteFileSize(img.src).catch(function(reason) { console.warn('Failed to get remote image size (' + img.src + '):', reason); return undefined; }).then(function(size) { const span = (content, isOK = false) => (isOK ? '' : '') + content + '', isProxied = img.src.startsWith(document.location.origin + '/image.php?'), isPreferredHost = img.src.startsWith('https://ptpimg.me'), isInvalid = isProxied && size < 2 * 2**10 && img.naturalWidth == 400 && img.naturalHeight == 100, isSizeOK = !(size > acceptableCoverSize * 2**10), isResolutionOK = Math.min(img.naturalWidth, img.naturalHeight) >= acceptableCoverResolution; if (isPreferredHost && isSizeOK && isResolutionOK) return; let div = document.createElement('div'); div.style = 'color: white; border: 1px solid whitesmoke; background-color: #ae2300; ' + 'position: relative; font: 700 8pt "Segoe UI"; padding: 1px 5px;'; if (!isInvalid) { div.style.float = 'right'; div.style.right = '5px'; div.style.bottom = '25px'; div.innerHTML = span(formattedSize(size), isSizeOK) + ' / ' + span(img.naturalWidth + '×' + img.naturalHeight, isResolutionOK); if (isProxied) div.innerHTML = span('PROXY') + ' / ' + div.innerHTML; else if (!isPreferredHost) div.innerHTML = span('XTRN') + ' / ' + div.innerHTML; } else { div.style.bottom = '3px'; div.innerHTML = span('INVALID'); } img.insertAdjacentElement('afterend', div); if (isInvalid) img.remove(); }); });