// ==UserScript==
// @name Image Host Helper
// @namespace https://greasyfork.org/users/321857-anakunda
// @version 1.065
// @description Directly upload local / rehost remote image(s) or galleries to whatever supported image host by dropping/pasting them to target field
// @icon data:image/png;base64,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
// @author Anakunda
// @match https://passthepopcorn.me/*
// @match https://broadcasthe.net/*
// @match https://dicmusic.club/*
// @match https://*/torrents.php?id=*
// @match https://*/artist.php?id=*
// @match https://*/artist.php?action=edit&artistid=*
// @match https://*/reportsv2.php?action=report&id=*
// @match https://*/forums.php?action=new*
// @match https://*/forums.php?*action=viewthread*
// @match https://*/requests.php?action=view*
// @match https://*/collages.php?id=*
// @match https://*/collages.php?action=edit&collageid=*
// @match https://*/collages.php?action=comments&collageid=*
// @match https://*/collages.php?action=new
// @match http*://tracker.czech-server.com/*
// @connect *
// @grant GM_xmlhttpRequest
// @grant GM_getValue
// @grant GM_setValue
// @grant GM_deleteValue
// @require https://greasyfork.org/scripts/401725-xhrlib/code/xhrLib.js
// @require https://greasyfork.org/scripts/394414-ua-resource/code/UA-resource.js
// @require https://greasyfork.org/scripts/401726-imagehostuploader/code/imageHostUploader.js
// ==/UserScript==
'use strict';
['input[id*="image"]', 'input[name*="image"]']
.forEach(selector => { document.querySelectorAll(selector).forEach(setInputHandlers) });
if (document.domain == 'tracker.czech-server.com') document.querySelectorAll('input[name="urlobr"]').forEach(setInputHandlers);
Array.from(document.getElementsByTagName('textarea')).forEach(setTextAreahandlers);
if (document.URL.includes('/torrents.php?id=')) {
let a = document.querySelector('span.additional_add_artists > a');
if (a != null) a.addEventListener('click', function() {
document.querySelectorAll('input[name="image[]"]').forEach(setInputHandlers);
});
}
if (document.URL.includes('/reportsv2.php')) {
setReportHandlers();
var reportTypeSelect = document.querySelector('select#type');
if (reportTypeSelect != null) reportTypeSelect.addEventListener('change', setReportHandlers);
}
// HJ Toolkit helper
if (document.domain.endsWith('passthepopcorn.me')) setTimeout(function() {
if (document.querySelector('div.HJ-toolkit-badge') != null) {
let hjtkTimer = setInterval(function() {
document.querySelectorAll('textarea[id^="HJMA"], textarea.form-control[name="screen"], textarea.form-control[name="comp"]')
.forEach(setTextAreahandlers);
}, 1000);
}
}, 1000);
function setReportHandlers(evt) {
setTimeout(function() {
document.querySelectorAll('input[id*="image"]').forEach(setInputHandlers);
document.querySelectorAll('textarea').forEach(setTextAreahandlers);
}, 2000);
}
function coverPreview(input, imgUrl, size) {
var div, child = document.getElementById('cover-preview');
if (child == null) {
return;
// if (!(input instanceof HTMLElement) || input.parentNode.previousElementSibling == null) return;
// var elem = document.createElement('div');
// elem.style = 'padding-top: 10px; float: right; width: 90%;';
// child = document.createElement('img');
// child.id = 'cover-preview';
// elem.append(child);
// var div = document.createElement('div');
// div.id = 'cover-size';
// elem.append(div);
// input.parentNode.previousElementSibling.append(document.createElement('br'));
// input.parentNode.previousElementSibling.append(elem);
}
if ((div = div || document.getElementById('cover-size')) == null) return;
if (urlParser.test(imgUrl)) {
child.onload = function(evt) {
this.onload = null;
if (!this.naturalWidth || !this.naturalHeight) return; // invalid image
(size > 0 ? Promise.resolve(size) : getRemoteFileSize(imgUrl)).then(function(size) {
div.textContent = this.naturalWidth + '×' + this.naturalHeight + ' (' + formattedSize(size) + ')';
}.bind(this)).catch(reason => { div.textContent = this.naturalWidth + '×' + this.naturalHeight });
};
child.onerror = function(evt) {
this.onerror = null;
div.textContent = this.src = '';
console.warn('Image source cannot be updated:', evt, imgUrl);
};
child.src = imgUrl;
} else div.textContent = child.src = '';
}
function imageDataHandler(evt, data) {
if (!data) return true;
if (data.files.length > 0) {
if (!data.files[0].type.toLowerCase().startsWith('image/')) return true;
evt.target.disabled = true;
if (evt.target.hTimer) {
clearTimeout(evt.target.hTimer);
delete evt.target.hTimer;
}
evt.target.style.backgroundColor = '#800000';
let elem = evt.target, file = data.files[0], size = data.files[0].size;
uploadImages([file], evt.target).then(function(urls) {
elem.value = urls[0];
elem.style.backgroundColor = '#008000';
elem.style.color = 'white';
elem.hTimer = setTimeout(function() {
elem.style.backgroundColor = null;
elem.style.color = null;
delete elem.hTimer;
}, 10000);
coverPreview(elem, urls[0], size);
}).catch(function(error) {
elem.style.backgroundColor = null;
imageClear(evt);
Promise.resolve(error).then(msg => { alert(msg) });
}).then(function() { elem.disabled = false });
return false;
} else if (data.items.length > 0) {
let links = data.getData('text/uri-list');
if (links) links = links.split(/\r?\n/); else {
links = data.getData('text/x-moz-url');
if (links) links = links.split(/\r?\n/).filter((item, ndx) => ndx % 2 == 0);
else if (links = data.getData('text/plain')) links = links.split(/\r?\n/);
}
if (Array.isArray(links) && links.length > 0) imageUrlResolver(links[0]).then(verifyImageUrl).then(function(imageUrl) {
evt.target.value = imageUrl;
coverPreview(evt.target, imageUrl);
if (imageUrl.toLowerCase().startsWith(ptpimgOrigin)) return;
evt.target.disabled = true;
rehostImages([imageUrl])
.then(urls => { if (urls.length > 0 && urls[0] != evt.target.value) evt.target.value = urls[0] })
.catch(reason => { Promise.resolve(reason).then(msg => { alert(msg + ' (not rehosted)') }) })
.then(function() { evt.target.disabled = false });
}).catch(function(e) {
console.error(e);
alert(e);
});
return false;
}
return true;
}
function descDropHandler(evt) {
if (evt.dataTransfer == null || evt.shiftKey) return true;
if (evt.dataTransfer.files.length > 0) {
let images = Array.from(evt.dataTransfer.files)
.filter(file => ['image/png', 'image/jpeg', 'image/gif', 'image/bmp', 'image/webp'/*, 'image/svg+xml'*/]
.some(mimeType => file.type == mimeType))
if (images.length <= 0) return true;
evt.target.disabled = true;
evt.target.style.background = '#FF000040 no-repeat center center url(' + ulImgData + ')';
//evt.target.style.background = '#FF000040 no-repeat center center url(https://svgshare.com/i/H16.svg)';
let elem = evt.target;
uploadImages(images).then(urlHandler).catch(reason => { Promise.resolve(reason).then(msg => { alert(msg) }) }).then(function() {
elem.style.background = null;
elem.disabled = false;
});
return false;
} else if (evt.dataTransfer.items.length > 0) {
let content = evt.dataTransfer.getData('text/uri-list');
if (content) content = content.split(/\r?\n/); else {
content = evt.dataTransfer.getData('text/x-moz-url');
if (content) content = content.split(/\r?\n/).filter((item, ndx) => ndx % 2 == 0);
};
if (!Array.isArray(content) || content.length <= 0) return true;
Promise.all(content.map(imageUrlResolver)).then(function(resolvedUrls) {
evt.target.disabled = true;
rehostImages(resolvedUrls.flatten()).catch(function(reason) {
Promise.resolve(reason).then(msg => { alert(msg + ' (not rehosted)') });
return verifyImageUrls(resolvedUrls.flatten());
}).then(function(imgUrls) {
urlHandler(imgUrls, content.length == 1 && [
'caps-a-holic.com/',
'screenshotcomparison.com/',
//'dvdbeaver.com/',
].some(patternt => content[0].includes(patternt)));
evt.target.disabled = false;
});
});
return false;
}
return true;
function urlHandler(urls, coupled = false) {
urls.forEach(function(url, ndx) {
if (url.length <= 0 || !urlParser.test(url)) return;
var phpBB = evt.target.nophpbb ? url : '[img]'.concat(url, '[/img]');
if (evt.target.value.trimRight().length <= 0) evt.target.value = phpBB; else if (evt.ctrlKey) {
evt.target.value = evt.target.value.slice(0, evt.rangeOffset) + phpBB + evt.target.value.slice(evt.rangeOffset);
} else if (!evt.target.nophpbb && /\[img\]\[\/img\]/i.test(evt.target.value)) {
evt.target.value = RegExp.leftContext + phpBB + RegExp.rightContext;
} else evt.target.value = evt.target.value.trimRight()
.concat(ndx <= 0 || coupled && ndx % 2 == 0 ? '\n\n' : '\n', phpBB);
});
}
}
function descPasteHandler(evt) {
if (evt.clipboardData == null || evt.clipboardData.files.length <= 0) return true;
var images = Array.from(evt.clipboardData.files)
.filter(file => ['image/png', 'image/jpeg', 'image/gif', 'image/bmp', 'image/webp', 'image/svg+xml']
.some(mimeType => file.type == mimeType))
if (images.length <= 0) return true;
evt.target.disabled = true;
evt.target.style.background = '#FF000040 no-repeat center center url(' + ulImgData + ')';
uploadImages(images).then(urls => { insert(urls.map(url => '[img]'.concat(url, '[/img]')).join('\n')) })
.catch(reason => { Promise.resolve(reason).then(msg => { alert(msg) }) }).then(function() {
evt.target.style.background = null;
evt.target.disabled = false;
});
return false;
function insert(phpBB) {
var selStart = evt.target.selectionStart;
evt.target.value = evt.target.value.slice(0, evt.target.selectionStart)
.concat(phpBB, evt.target.value.slice(evt.target.selectionEnd));
evt.target.setSelectionRange(selStart + phpBB.length, selStart + phpBB.length);
}
}
function imageUrlResolver(url) {
return urlResolver(url).then(url => verifyImageUrl(url).catch(function(reason) {
try { url = new URL(url) } catch(e) { return Promise.reject(e) }
const notFound = Promise.reject('No title image for this URL');
if (url.hostname.endsWith('pinterest.com'))
return pinterestResolver(url);
else if (url.hostname.endsWith('free-picload.com')) {
if (url.pathname.startsWith('/album/')) return cheveretoGalleryResolver('free-picload.com', url);
} else switch (url.hostname) {
// general image hostings
case 'www.imgur.com': case 'imgur.com':
if (url.pathname.startsWith('/a/')) return globalFetch(url, { responseType: 'text' }).then(function(response) {
if (/^\s*(?:image)\s*:\s*(\{.+\}),\s*$/m.test(response.responseText)) try {
return JSON.parse(RegExp.$1).album_images.images.map(image => 'https://i.imgur.com/'.concat(image.hash, image.ext));
} catch(e) { debug.warn(e) }
return notFound;
});
return globalFetch(url).then(response => response.document.querySelector('link[rel="image_src"]').href);
case 'pixhost.to':
if (url.pathname.startsWith('/gallery/')) return globalFetch(url).then(response =>
Promise.all(Array.from(response.document.querySelectorAll('div.images > a')).map(a => imageUrlResolver(a.href))));
if (url.pathname.startsWith('/show/')) return globalFetch(url)
.then(response => response.document.querySelector('img#image').src);
break;
case 'malzo.com':
if (url.pathname.startsWith('/al/')) return cheveretoGalleryResolver('malzo.com', url);
break;
case 'imgbb.com': case 'ibb.co':
if (url.pathname.startsWith('/album/')) return cheveretoGalleryResolver('imgbb.com', url);
break;
case 'jerking.empornium.ph':
if (url.pathname.startsWith('/album/')) return cheveretoGalleryResolver('jerking.empornium.ph', url);
break;
case 'imgbox.com':
if (url.pathname.startsWith('/g/')) return globalFetch(url).then(response =>
Promise.all(Array.from(response.document.querySelectorAll('div#gallery-view-content > a'))
.map(a => imageUrlResolver('https://imgbox.com'.concat(a.pathname)))));
break;
case 'postimage.org': case 'postimg.cc':
if (url.pathname.startsWith('/gallery/')) return globalFetch(url, { responseType: 'text' }).then(function(response) {
if (/\bvar\s+embed_value=(\{[\S\s]+?\});/.test(response.responseText)) try {
let embed_value = JSON.parse(RegExp.$1);
return Object.keys(embed_value).map(key => 'https://i.postimg.cc/'
.concat(embed_value[key][2], '/', embed_value[key][0], '.', embed_value[key][1]))
} catch(e) { console.warn(e) }
return notFound;
});
break;
case 'www.imagevenue.com': case 'imagevenue.com':
return globalFetch(url, { headers: { Referer: 'http://www.imagevenue.com/' } }).then(function(response) {
var images = Array.from(response.document.querySelectorAll('div.card img')).map(function(img) {
return img.src.includes('://cdn-images') ? Promise.resolve(img.src) : imageUrlResolver(img.parentNode.href);
});
return images.length > 1 ? Promise.all(images) : images.length == 1 ? images[0] : notFound;
});
case 'www.imageshack.us': case 'imageshack.us':
return globalFetch(url).then(response => response.document.querySelector('a#share-dl').href);
case 'www.flickr.com': case 'flickr.com':
if (!url.pathname.startsWith('/photos/')) break;
return globalFetch(url).then(function(response) {
if (/\b(?:modelExport)\s*:\s*(\{.+\}),/.test(response.responseText)) try {
var urls = JSON.parse(RegExp.$1).main['photo-models'].map(function(photoModel) {
var sizes = Object.keys(photoModel.sizes).sort((a, b) => photoModel.sizes[b].width * photoModel.sizes[b].height
- photoModel.sizes[a].width * photoModel.sizes[a].height);
return sizes.length > 0 ? 'https:'.concat(photoModel.sizes[sizes[0]].url) : null;
});
if (urls.length == 1) return urls[0]; else if (urls.length > 1) return urls;
} catch(e) { console.warn(e) }
return notFound;
});
case 'photos.google.com':
return googlePhotosResolver(url);
case 'www.500px.com': case 'web.500px.com': case '500px.com':
if (/^\/photo\/(\d+)\b/i.test(url.pathname))
return _500pxUrlHandler('photos?ids='.concat(RegExp.$1));
else if (/\/galleries\/([\w\-]+)/i.test(url.pathname)) {
let galleryId = RegExp.$1;
return globalFetch(url, { rsponseType: 'text' }).then(function(response) {
if (!/\b(?:App\.CuratorId)\s*=\s*"(\d+)"/.test(response.responseText)) return Promise.reject('Unexpected page structure');
return _500pxUrlHandler('users/' + RegExp.$1 + '/galleries/' + galleryId + '/items?sort=position&sort_direction=asc&rpp=999');
});
}
break;
case 'www.pxhere.com': case 'pxhere.com':
if (url.pathname.includes('/photo/')) return globalFetch(url).then(response =>
JSON.parse(response.document.querySelector('div.hub-media-content > script[type="application/ld+json"]').text).contentUrl);
else if (url.pathname.includes('/collection/')) return pxhereCollectionResolver(url);
break;
case 'www.unsplash.com': case 'unsplash.com':
if (url.pathname.startsWith('/photos/')) return globalFetch(url.origin + url.pathname + '/download', { method: 'HEAD' })
.then(response => response.finalUrl.replace(/\?.*$/, ''));
else if (url.pathname.includes('/collections/')) return unsplashCollectionResolver(url);
break;
case 'www.pexels.com': case 'pexels.com':
if (url.pathname.startsWith('/photo/')) return globalFetch(url)
.then(response => response.document.querySelector('meta[property="og:image"][content]').content.replace(/\?.*$/, ''));
else if (url.pathname.startsWith('/collections/')) return pexelsCollectionResolver(url);
break;
case 'www.piwigo.org': case 'piwigo.org':
/*if (url.pathname.includes('/picture/')) */return globalFetch(url, { responseType: 'text' }).then(function(response) {
if (/^(?:RVAS)\s*=\s*(\{[\S\s]+?\})$/m.test(response.responseText)) try {
var derivatives = eval('(' + RegExp.$1 + ')').derivatives.sort((a, b) => b.w * b.h - a.w * a.h);
return derivatives.length > 0 ? 'https://piwigo.org/demo/'.concat(derivatives[0].url) : notFound;
} catch(e) { console.warn(e) }
return Promise.reject('Unexpected page structure');
});
break;
case 'www.freeimages.com': case 'freeimages.com':
if (url.pathname.startsWith('/photo/')) return globalFetch(url).then(function(response) {
var types = Array.from(response.document.querySelectorAll('ul.download-type > li > span.reso'))
.sort((a, b) => eval(b.textContent.replace('x', '*')) - eval(a.textContent.replace('x', '*')));
return types.length > 0 ? url.origin.concat(types[0].parentNode.querySelector('a').pathname) : notFound;
});
break;
case 'redacted.ch':
if (url.pathname != '/image.php') break;
return globalFetch(url, { method: 'HEAD' }).then(response => response.finalUrl);
case 'demo.cloudimg.io':
if (!/\b(https?:\/\/\S+)$/.test(url.pathname.concat(url.search, url.hash))) break;
var resolved = RegExp.$1;
if (/\b(?:https?):\/\/(?:\w+\.)*discogs\.com\//i.test(resolved)) break;
return imageResolver(resolved);
case 'fastpic.ru':
if (url.pathname.startsWith('/view/'))
return globalFetch(url).then(response => imageUrlResolver(response.document.querySelector('a.img-a').href));
if (url.pathname.startsWith('/fullview/')) return globalFetch(url).then(function(response) {
var node = response.document.getElementById('image');
if (node != null) return node.src;
return /\bvar\s+loading_img\s*=\s*'(\S+?)';/.test(response.responseText) ? RegExp.$1 : notFound;
});
break;
case 'www.radikal.ru': case 'radikal.ru': case 'a.radikal.ru':
return globalFetch(url).then(response => response.document.querySelector('div.mainBlock img').src);
case 'imageban.ru': case 'ibn.im':
return globalFetch(url).then(response => response.document.getElementById('img_main').src /* dataset.original */);
// music-related
case 'www.musicbrainz.org': case 'musicbrainz.org':
if (!['release', 'release-group'].some(branch => url.pathname.includes('/'.concat(branch, '/')))) break;
return globalFetch(url).then(function(response) {
var node = response.document.querySelector('a.artwork-image');
if (node != null) return node.href;
return (node = response.document.querySelector('div.cover-art > img')) != null ? node.src : notFound;
});
case 'music.apple.com':
if (!/^https?:\/\/(?:\w+\.)*apple\.com\/.*\/(\d+)(?=$|\?)/i.test(url)) break;
return globalFetch(url).then(function(response) {
var meta = response.document.querySelector('meta[property="og:image"][content]');
if (meta == null || !meta.content) return notFound;
return verifyImageUrl(meta.content.replace(/\/\d+x\d+\w*(?=\.\w+$)/, '/100000x100000-999')).catch(reason => meta.content);
});
case 'www.deezer.com': case 'deezer.com':
return globalFetch(url).then(function(response) {
var meta = response.document.querySelector('meta[property="og:image"][content]');
if (meta == null || !meta.content) return notFound;
return verifyImageUrl(meta.content.replace(/\/\d+x\d+\w*(?=\.\w+$)/, '/1400x1400-000000-100-0-0'))
.catch(reason => meta.content);
});
case 'www.qobuz.com': case 'qobuz.com':
if (!url.pathname.includes('/album/')) break;
return globalFetch(url).then(function(response) {
var img = response.document.querySelector('div.album-cover > img');
if (img == null) return notFound;
return verifyImageUrl(img.src.replace(/_\d{3}(?=\.\w+$)/, '_max')).catch(reason => img.src);
});
case 'www.prestomusic.com': case 'prestomusic.com':
if (!url.pathname.includes('/products/')) break;
return globalFetch(url)
.then(response => verifyImageUrl(response.document.querySelector('div.c-product-block__aside > a').href.replace(/\?\d+$/)));
case 'www.bontonland.cz':case 'bontonland.cz':
return globalFetch(url).then(response => response.document.querySelector('a.detailzoom').href);
case 'www.nativedsd.com':case 'nativedsd.com':
if (!url.pathname.includes('/albums/')) break;
return globalFetch(url).then(response => response.document.querySelector('a#album-cover').href);
case 'www.prostudiomasters.com': case 'prostudiomasters.com':
if (!url.pathname.includes('/album/')) break;
return globalFetch(url).then(function(response) {
var a = response.document.querySelector('img.album-art');
return verifyImageUrl(a.currentSrc).catch(reason => a.src);
});
case 'www.e-onkyo.com': case 'e-onkyo.com':
if (!url.pathname.includes('/album/')) break;
return globalFetch(url).then(function(response) {
var a = response.document.querySelector('figure > a.colorbox');
return new URL(response.finalUrl).origin.concat(a.pathname);
})
case 'store.acousticsounds.com':
return globalFetch(url).then(function(response) {
var link = response.document.querySelector('div#detail > link[rel="image_src"]');
return verifyImageUrl(link.href.replace(/\/medium\//i, '/large/')).catch(reason => link.href);
});
case 'www.indies.eu': case 'indies.eu':
if (!url.pathname.includes('/alba/')) break;
return globalFetch(url).then(response => verifyImageUrl)(response.document.querySelector('div.obrazekDetail > img').src);
case 'www.beatport.com': case 'beatport.com':
if (!url.pathname.includes('/release/')) break;
return globalFetch(url).then(response =>
verifyImageUrl(response.document.querySelector('div > img.interior-release-chart-artwork').src));
case 'www.supraphonline.cz': case 'supraphonline.cz':
if (!url.pathname.includes('/album/')) break;
return globalFetch(url).then(function(response) {
verifyImageUrl(response.document.querySelector('meta[itemprop="image"]').content.replace(/\?.*$/, '')).catch(reason => notFound);
});
case 'vgmdb.net':
if (!url.pathname.includes('/album/')) break;
return globalFetch(url).then(function(response) {
var div = response.document.querySelector('div#coverart');
return verifyImageUrl(/\b(?:url)\s*\(\"(.*)"\)/i.test(div.style['background-image']) && RegExp.$1).catch(reason => notFound);
});
case 'www.ototoy.jp': case 'ototoy.jp':
return globalFetch(url).then(function(response) {
var img = response.document.querySelector('div#tralbumArt > a.popupImage');
return verifyImageUrl(img.dataset.src).catch(reason => img.src);
});
case 'music.yandex.ru':
if (!url.pathname.includes('/album/')) break;
return globalFetch(url).then(function(response) {
var script = response.document.querySelector('script.light-data');
return verifyImageUrl(JSON.parse(script.text).image).catch(reason => notFound);
});
// movie-related
case 'www.imdb.com': case 'imdb.com':
if (!['title/tt', 'name/nm'].some(cat => url.pathname.startsWith('/' + cat))) break;
return globalFetch(url).then(function(response) {
const galleryDetector = /\/mediaindex(?:[\/\?].*)?$/i, imgStripper = /\._V\d+_[\w\,]*(?=\.)/;
if (!galleryDetector.test(response.finalUrl)) {
//let node = response.document.head.querySelector(':scope > script[type="application/ld+json"]');
//if (node != null) return verifyImageUrl(JSON.parse(node.text).image.replace(imgStripper, '')).catch(reason => notFound);
let node = response.document.querySelector('meta[property="og:image"][content]');
return node != null && !/\/imdb\w*_logo\./i.test(node.content) ?
node.content.replace(imgStripper, '') : notFound;
}
var titleId = /\/title\/(tt\d+)\//i.test(response.finalUrl) && RegExp.$1;
return titleId ? globalFetch(response.finalUrl.replace(galleryDetector, '/mediaviewer'), { responseType: 'text' }).then(function(response) {
if (/\b(?:window\.IMDbMediaViewerInitialState)\s*=\s*(\{.*\});/.test(response.responseText)) try {
let allImages = eval('(' + RegExp.$1 + ')').mediaviewer.galleries[titleId].allImages;
if (allImages.length > 0) return allImages.map(image => image.src.replace(imgStripper, ''));
} catch(e) { console.warn(e) }
return notFound;
}) : Promise.reject('title id not found');
});
case 'www.themoviedb.org': case 'themoviedb.org':
if (!['movie', 'person'].some(cat => url.pathname.startsWith('/' + cat + '/'))) break;
return globalFetch(url).then(function(response) {
var node = response.document.querySelector('meta[property="og:image"][content]');
return verifyImageUrl(node.content.replace(/\/p\/\w+\//i, '/p/original/')).catch(function(reason) {
node = response.document.querySelector('div.image_content > img');
return verifyImageUrl(node.dataset.src.replace(/\/p\/\w+\//i, '/p/original/'))
.catch(reason => verifyImageUrl(node.src.replace(/\/p\/\w+\//i, '/p/original/')))
.catch(reason => verifyImageUrl(dataset.src)).catch(reason => node.src);
}).catch(reason => notFound);
});
case 'www.omdb.org': case 'omdb.org':
if (!['movie', 'person'].some(cat => url.pathname.startsWith('/' + cat + '/'))) break;
return globalFetch(url).then(function(response) {
var node = response.document.querySelector('meta[property="og:image"][content]');
return node != null ? verifyImageUrl(node.content) : notFound;
});
case 'www.thetvdb.com': case 'thetvdb.com':
if (!['movies', 'series', 'people'].some(cat => url.pathname.startsWith('/' + cat + '/'))) break;
return globalFetch(url).then(response => verifyImageUrl(response.document.querySelector('img.img-responsive').src));
case 'www.rottentomatoes.com': case 'rottentomatoes.com':
if (!['m', 'celebrity', 'tv'].some(cat => url.pathname.startsWith('/' + cat + '/'))) break;
return globalFetch(url).then(function(response) {
// if (/\b(?:context\.shell)\s*=\s*(\{.+?});/.test(response.responseText)) try {
// return JSON.parse(RegExp.$1).header.certifiedMedia.certifiedFreshMovieInTheater4.media.posterImg;
// } catch(e) { console.warn(e) }
return verifyImageUrl(response.document.querySelector('meta[property="og:image"]').content);
});
case 'www.bcdb.com': case 'bcdb.com':
if (!['cartoon'].some(cat => url.pathname.startsWith('/' + cat + '/'))) break;
return globalFetch(url).then(response =>
verifyImageUrl(document.location.protocol.concat(response.document.querySelector('meta[property="og:image"]').content)));
case 'www.boxofficemojo.com': case 'boxofficemojo.com':
if (!['releasegroup'].some(cat => url.pathname.startsWith('/' + cat + '/'))) break;
return globalFetch(url).then(response => verifyImageUrl(response.document.querySelector('div.mojo-primary-image img').src));
case 'www.metacritic.com': case 'metacritic.com':
return globalFetch(url).then(function(response) {
var image = response.document.querySelector('meta[property="og:image"]').content;
return verifyImageUrl(image.replace(/-\d+h(?=(?:\.\w+)?$)/, '')).catch(reason => image);
});
case 'www.csfd.cz': case 'csfd.cz':
if (!['film', 'tvurce'].some(cat => url.pathname.startsWith('/' + cat + '/'))) break;
return globalFetch(url).then(function(response) {
const gallerySel = 'div.ct-general.photos > div.content > ul > li > div.photo';
if (response.document.querySelectorAll(gallerySel).length > 0) return new Promise(function(resolve, reject) {
var urls = [], domParser = new DOMParser, origin = new URL(response.finalUrl).origin;
loadPage(response.finalUrl.replace(/\/strana-\d+(?=$|\/|\?)/, ''));
function loadPage(url) {
GM_xmlhttpRequest({ method: 'GET', url: url,
onload: function(response) {
if (response.status < 200 || response.status >= 400) return reject(defaultErrorHandler(response));
var dom = domParser.parseFromString(response.responseText, 'text/html');
Array.prototype.push.apply(urls, Array.from(dom.querySelectorAll(gallerySel))
.map(div => /^(?:url)\s*\("?(.+?)"?\)$/i.test(div.style.backgroundImage) ?
'https:'.concat(RegExp.$1).replace(/\?.*$/, '') : null));
var nextPage = dom.querySelector('div.paginator > a.next[href]');
if (nextPage != null) loadPage(origin.concat(nextPage.pathname, nextPage.search)); else resolve(urls);
},
onerror: response => { reject(defaultErrorHandler(response)) },
ontimeout: response => { reject(defaultTimeoutHandler(response)) },
});
}
});
var img = ['img.film-poster', 'img.creator-photo', 'div.image > img']
.reduce((acc, selector) => acc || response.document.querySelector(selector), null);
return img != null ? verifyImageUrl(img.src.replace(/\?.*$/, '')) : notFound;
});
case 'www.fdb.cz': case 'fdb.cz':
//if (!url.pathname.startsWith('/film/')) break;
return globalFetch(url).then(function(response) {
var a = response.document.querySelector('a.boxPlakaty');
if (a == null) return Promise.reject('Invalid page structure');
a.hostname = 'www.fdb.cz';
return globalFetch(a.href).then(function(response) {
var imgs = response.document.querySelectorAll('span#popup_plakaty > img');
return imgs.length > 0 ? verifyImageUrl(imgs[0].src) : notFound;
});
});
case 'www.caps-a-holic.com': case 'caps-a-holic.com':
if (url.pathname != '/c.php') break;
return globalFetch(url).then(function(response) {
function heightExtractor(n) {
var node = response.document.querySelector('div.main > div.c_table > div[style]:nth-of-type(' + n + ')');
if (node != null && /\b(\d{3,})\s?[x×]\s?(\d{3,})\b/.test(node.textContent)) return parseInt(RegExp.$2);
console.warn(response.finalUrl, 'failed to get resolution (' + n + ')', node);
return null;
}
const baseUrl = 'https://caps-a-holic.com/c_image.php?a=0&x=0&y=0&l=1';
return Array.from(response.document.querySelectorAll('div.main > div[style] > a > img.thumb')).map(function(img) {
var query = new URLSearchParams(new URL(img.parentNode.href).search);
return [
baseUrl.concat('&s=', parseInt(query.get('s1')), '&max_height=', heightExtractor(2)),
baseUrl.concat('&s=', parseInt(query.get('s2')), '&max_height=', heightExtractor(3)),
];
});
});
case 'www.screenshotcomparison.com': case 'screenshotcomparison.com':
if (url.pathname.startsWith('/comparison/')) return globalFetch(url).then(function(response) {
const origin = new URL(response.finalUrl).origin;
return Array.from(response.document.querySelectorAll('div#img_nav li > a')).map(function(a) {
return globalFetch(origin.concat(a.pathname), { responseType: 'text' }).then(response => [
/\b(?:images)\[1\]='(\S+?)'/.test(response.responseText) && RegExp.$1,
/\b(?:images)\[0\]='(\S+?)'/.test(response.responseText) && RegExp.$1,
].map(src => origin.concat(src)));
});
});
break;
case 'www.dvdbeaver.com': case 'dvdbeaver.com':
if (url.pathname.startsWith('/film')) return globalFetch(url).then(function(response) {
const origin = new URL(response.finalUrl).origin;
return Array.from(response.document.querySelectorAll('div[align="center"] > table > tbody > tr > td > a[target="_blank"] > img'))
.map(img => origin.concat(img.parentNode.pathname));
});
break;
}
return globalFetch(url, { headers: { 'Referer': url.origin } }).then(function(response) {
if (url.pathname.startsWith('/album/')
&& response.document.querySelector('div#tabbed-content-group > div.content-listing > div.pad-content-listing') != null)
return cheveretoGalleryResolver(url.hostname, url);
var meta = [
'head > meta[property="og:image"][content]', 'head > meta[itemprop="image"][content]', 'head > meta[name="og:image"][content]',
].reduce((acc, selector) => acc || response.document.querySelector(selector), null);
return meta != null && meta.content ? meta.content : notFound;
});
}));
}