Last active
December 16, 2019 01:42
-
-
Save jaideejung007/f26fdb2bd72d75539c2a926dc96327f7 to your computer and use it in GitHub Desktop.
Source Tampermonkey-SiamBitZoomScreenShot
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
(function ( $ ) { | |
/* | |
* ##REQUIRE## | |
* jquery | |
* md5 | |
* fancybox | |
* | |
* ##CDN https://raw.githack.com/ ## | |
* release new version must purge cached | |
* use source url for purge cached | |
*/ | |
"use strict" | |
let SiambitZoomScreenShot = function ( options ) { | |
let defaults = { | |
debug : false, | |
cache : true, //Enable local cache | |
cacheTimeout : 604800, //Min for local cache timeout | |
directLink : true, //Enable DirectLink Cache | |
directLinkApi : 'https://nekotools.info/direct-links', | |
directLinkTimeout : 2500, | |
previewColumnMaxHeight : 171, //Set false for use auto detect column height | |
previewMaxHeight : 80, | |
previewMaxWidth : 120, | |
previewFail : 'https://i.imgur.com/jaM7eqT.png?1', | |
previewExcept : 'https://i.imgur.com/blbuhiy.png?1', | |
exceptCategories : null, | |
} | |
let settings = $.extend({}, defaults, options) | |
let debug = settings.debug | |
let cacheKey = 'SIAMBIT_ZOOM_SCREEN_SHOT_CACHE' | |
let patterns = { | |
"selector" : [ | |
{ | |
attr : "src", | |
selector : "div.image_view img", | |
domains : [ | |
"postto.me", | |
] | |
}, | |
{ | |
attr : "src", | |
selector : "div#image img", | |
domains : [ | |
"pic.8e88.in.th", | |
] | |
}, | |
], | |
"meta" : [ | |
{ | |
selector : "og:image", | |
domains : [ | |
"www.imgbb.me", | |
"imgbb.me", | |
"www.picz.in.th", | |
"picz.in.th", | |
"www.imgtrue.com", | |
"imgtrue.com", | |
"imdb.com", | |
"www.imdb.com", | |
"ibb.co", | |
"www.lmgbb.me", | |
"roop.xyz", | |
"www.roop.xyz", | |
"bpicc.com", | |
"www.bpicc.com", | |
"lmgbb.me", | |
"www.img.live", | |
"img.live", | |
] | |
} | |
], | |
"replace" : [ | |
{ | |
replace_find : "viewer.php?file=", | |
replace_new : "files/", | |
domains : [ | |
"img.best-story.net", | |
] | |
}, | |
{ | |
replace_find : ".cc/v", | |
replace_new : ".cc/d", | |
domains : [ | |
"uppic.cc", | |
] | |
}, | |
], | |
"direct" : { | |
excepts : [ | |
'img.best-story.net/viewer', | |
] | |
}, | |
"custom" : [ | |
{ | |
domains : [ | |
'imgur.com', | |
], | |
synchronous : true, | |
callback : async function ( url, self ) { | |
let _url = url.replace("https://", "") | |
.replace("http://", "") | |
if (_url.startsWith("imgur.com/a/")) { | |
url = await this.getDirectSourceSite(url, 'meta', { selector : 'twitter:image' }) | |
} else if (_url.startsWith("imgur.com/") | |
&& _url.lastIndexOf(".jpg") === -1 | |
&& _url.lastIndexOf(".jpeg") === -1 | |
&& _url.lastIndexOf(".gif") === -1 | |
&& _url.lastIndexOf(".png") === -1 | |
) { | |
url = "https://i." + _url + ".jpg" | |
} | |
return url | |
} | |
} | |
] | |
} | |
let locationCurrent = window.location | |
let locationList = [ | |
'/viewno18.php', | |
'/viewbr.php', | |
'/upfinish.php', | |
] | |
let downloadListHead = { | |
element : null, | |
td : null, | |
index : {} | |
} | |
let downloadList = [] | |
let progressBar = { | |
all : 0, | |
run : 0, | |
template : $("<span>", { title : 'Direct source status.' }), | |
} | |
let loading = '<div class="lds-grid"><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div></div>' | |
let hoverPreview = { | |
xOffset : 10, | |
yOffset : 30, | |
yOffsetFix : 0, | |
yOffsetPreLoadFix : 0, | |
previewTop : 0, | |
previewLeft : 0, | |
popup : $('<p>', { class : 'hover-popup' }), | |
img : $('<img>'), | |
imgHeight : 0, | |
} | |
function log( index, message ) { | |
console.log("#" + index + " " + message) | |
} | |
return { | |
init : function () { | |
this.css() | |
this.loadDownloadList() | |
//Add popup to body | |
$("body").append(hoverPreview.popup.append(hoverPreview.img)) | |
}, | |
css : function () { | |
//Loading | |
GM_addStyle('.lds-grid{display:inline-block;position:relative;width:80px;height:80px}.lds-grid div{position:absolute;width:16px;height:16px;border-radius:50%;background:#7369af;animation:lds-grid 1.2s linear infinite}.lds-grid div:nth-child(1){top:8px;left:8px;animation-delay:0s}.lds-grid div:nth-child(2){top:8px;left:32px;animation-delay:-.4s}.lds-grid div:nth-child(3){top:8px;left:56px;animation-delay:-.8s}.lds-grid div:nth-child(4){top:32px;left:8px;animation-delay:-.4s}.lds-grid div:nth-child(5){top:32px;left:32px;animation-delay:-.8s}.lds-grid div:nth-child(6){top:32px;left:56px;animation-delay:-1.2s}.lds-grid div:nth-child(7){top:56px;left:8px;animation-delay:-.8s}.lds-grid div:nth-child(8){top:56px;left:32px;animation-delay:-1.2s}.lds-grid div:nth-child(9){top:56px;left:56px;animation-delay:-1.6s}@keyframes lds-grid{0%,100%{opacity:1}50%{opacity:.5}}') | |
//Preview Cover | |
GM_addStyle('img.preview{max-height:' + settings.previewMaxHeight + 'px;max-width:' + settings.previewMaxWidth + 'px;display:none;}') | |
//Preview hover | |
GM_addStyle('.hover-popup { position: absolute; border: 2px solid #fff; background: #fff; padding: 4px 4px 4px 4px; display: none; border-radius:5px; color: #fff ;}') | |
}, | |
workingSource : async function () { | |
let self = this | |
//Get cache direct links | |
let caches = [] | |
if (settings.directLink) { | |
if (debug) log('+', 'Use DirectLink') | |
if (debug) log('+', 'Host is ' + settings.directLinkApi) | |
let find = downloadList.filter(r => !r.coverSource || !r.coverThumbnail).map(r => r.coverHash).join(',') | |
if (debug) log('+', 'Find: ' + find) | |
if (find !== '') { | |
try { | |
caches = await this.getDirectLinks(downloadList.map(r => r.coverHash).join(',')) | |
if (!Array.isArray(caches)) throw "response not array" | |
} catch (err) { | |
if (debug) log('+', 'Get DirectLink error ' + err) | |
caches = [] | |
} | |
} | |
} | |
Promise.all(downloadList.map(async function ( item, index ) { | |
if (debug) log(item.index, 'Working') | |
if (debug) log(item.index, 'Title: ' + item.title) | |
let cache = caches.find(r => r.link_hash === item.coverHash) | |
if (cache) { | |
if (!item.coverSource) { | |
item.coverSource = cache.direct | |
if (debug) log(item.index, 'DirectLink source: ' + cache.direct) | |
} | |
if (!item.coverThumbnail && cache.thumbnail) { | |
item.coverThumbnail = cache.thumbnail.link | |
if (debug) log(item.index, 'DirectLink thumbnail: ' + cache.thumbnail.link) | |
} | |
} | |
if (!item.coverSource) { | |
if (debug) log(item.index, 'Load cover ' + item.cover) | |
item.coverSource = await self.getDirectSource(item.cover) | |
if (debug) log(item.index, 'Sourced is ' + item.coverSource) | |
} else { | |
if (debug) log(item.index, 'No need to load source') | |
if (debug) log(item.index, 'Source form DirectLink') | |
} | |
self.afterCoverSourced(item) | |
return item | |
})).then(() => { | |
self.afterCoversSourced() | |
}) | |
}, | |
working : function () { | |
let self = this | |
//Column picture | |
$(downloadListHead.td.get(0)).after( | |
$("<td>", { | |
class : 'colhead 11', | |
align : 'center', | |
width : '125px', | |
text : "รูป" | |
}).append(progressBar.template) | |
) | |
downloadList.map(function ( item, index ) { | |
if (debug) log(item.index, 'Add event preview loaded') | |
//Add Event | |
item.coverHoverPreviewImg | |
// .onerror(self.errorCoverPreview) | |
.onload = () => { | |
self.loadedHoverPreview(self, item) | |
} | |
item.coverPreviewImg.on('error', self.errorCoverPreview).on('load', ( e ) => { | |
self.loadedCoverPreview(e.target) | |
// self.afterLoadedCoverPreview(self, item) | |
}) | |
item.coverPreview.html(loading) | |
let td = $("<td>", { | |
align : 'center', | |
'bgcolor' : item.tdColor | |
}).append(item.coverPreview) | |
$(item.elements.td.get(0)).after(td) | |
//reset preview max height to column height | |
let columnHeight = td.height() | |
if (settings.previewMaxHeight < columnHeight) | |
item.coverPreviewImg.css('max-height', (settings.previewColumnMaxHeight === false ? columnHeight : settings.previewColumnMaxHeight) + 'px') | |
}) | |
}, | |
afterDownloadListed : function () { | |
this.working() | |
this.workingSource() | |
}, | |
afterCoverSourced : function ( dList ) { | |
//progressBar Head Column | |
progressBar.run++ | |
this.updateProgressBar() | |
//update cover preview | |
this.updateCoverPreview(dList) | |
//update hover preview | |
this.updateHoverPreview(dList) | |
}, | |
afterCoversSourced : function () { | |
//Add DirectLink | |
let coverSources = downloadList.filter(r => r.coverSource && r.except === false).map(r => { | |
return { 'link' : r.cover, 'direct' : r.coverSource } | |
}) | |
if (coverSources.length > 0) this.addDirectLinks(coverSources) | |
}, | |
timestamp : function () { | |
return (Date.now() / 1000 | 0) | |
}, | |
cacheGenKey : function ( url ) { | |
return cacheKey + md5(url) | |
}, | |
cacheGet : function ( key, valueDefault ) { | |
let cache = GM_getValue(key, null) | |
if (cache) { | |
cache = JSON.parse(cache) | |
cache = $.extend({ | |
val : null, | |
timeout : this.timestamp(), | |
}, cache) | |
if (cache.timeout > this.timestamp()) { | |
return cache.val | |
} else { | |
GM_deleteValue(key) | |
} | |
} | |
return valueDefault | |
}, | |
cacheSet : function ( key, val, minute ) { | |
let cache = { | |
val : val, | |
timeout : this.timestamp() + (minute * 60), | |
} | |
GM_setValue(key, JSON.stringify(cache)) | |
}, | |
cacheHas : function ( key ) { | |
return this.cacheGet(key, null) !== null | |
}, | |
extractHostname : function ( url ) { | |
let hostname | |
if (url.indexOf("//") > -1) { | |
hostname = url.split('/')[ 2 ] | |
} else { | |
hostname = url.split('/')[ 0 ] | |
} | |
hostname = hostname.split(':')[ 0 ] | |
hostname = hostname.split('?')[ 0 ] | |
return hostname | |
}, | |
loadDownloadList : function () { | |
let self = this | |
//List pages | |
if (locationList.includes(locationCurrent.pathname)) { | |
$.when($(".mainouter table[width='100%'] tr").each(function ( index, element ) { | |
let _this = $(this) | |
let _td = $("td", _this) | |
//Head | |
if (index === 0) { | |
downloadListHead.element = element | |
downloadListHead.td = _td | |
_td.each(function ( index, tdElement ) { | |
if (tdElement.textContent === "ขนาด") downloadListHead.index.fileSize = index | |
if (tdElement.textContent === "เสร็จ") downloadListHead.index.downloaded = index | |
if (tdElement.textContent === "ปล่อย") downloadListHead.index.seed = index | |
if (tdElement.textContent === "ดูด") downloadListHead.index.peer = index | |
}) | |
} else { | |
//Title | |
let _title = $("a:first-child b", _td.get(1)).first() | |
let title = _title.text() | |
//Cover | |
let _cover = $(locationCurrent.pathname === '/upfinish.php' ? "td a>img[src='/pic/cam.gif']" : "td[width='900'] a>img[src='pic/cam.gif ']", _this).parent() | |
let cover = null | |
if (_cover.is('a')) { | |
cover = _cover.attr('href') | |
} | |
//Category | |
let _category = $("img", _td.get(0)).first() | |
let category = null | |
if (_category.length === 1) { | |
category = _category.attr('src').replace('pic/categories/cat-', '') | |
.replace('pic/categories/', '') | |
.replace('.gif', '') | |
.replace('.png', '') | |
} | |
//FileSize | |
let _fileSize = _td.get(downloadListHead.index.fileSize) | |
let fileSize = _fileSize.textContent | |
//Downloaded | |
let _downloaded = _td.get(downloadListHead.index.downloaded) | |
let downloaded = _downloaded.textContent | |
//Seed | |
let _seed = _td.get(downloadListHead.index.seed) | |
let seed = _seed.textContent | |
//Peer | |
let _peer = _td.get(downloadListHead.index.peer) | |
let peer = _peer.textContent | |
//TdColor | |
let tdColor = $(_td.get(0)).attr('bgcolor') | |
//Elements | |
let elements = { | |
'element' : element, | |
'title' : _title, | |
'cover' : _cover, | |
'category' : _category, | |
'fileSize' : _fileSize, | |
'downloaded' : _downloaded, | |
'seed' : _seed, | |
'peer' : _peer, | |
'td' : _td, | |
} | |
self.addDownloadList(title, cover, category, fileSize, downloaded, seed, peer, tdColor, elements) | |
} | |
})).then(() => { | |
this.afterDownloadListed() | |
}) | |
} | |
}, | |
addDownloadList : function ( title, cover, category, fileSize, downloaded, seed, peer, tdColor, elements ) { | |
let data = { | |
title : title, | |
cover : cover, | |
coverSource : null, | |
coverHoverPreviewImg : new Image(), | |
coverThumbnail : null, | |
coverHash : md5(cover), | |
coverPreview : $('<div>'), | |
coverPreviewImg : $('<img>', { class : 'preview' }), | |
category : category, | |
fileSize : fileSize, | |
downloaded : downloaded, | |
seed : seed, | |
peer : peer, | |
tdColor : tdColor, | |
except : false, | |
elements : elements, | |
} | |
//Add Index | |
data.index = downloadList.length + 1 | |
//Use Cache before add downloadList | |
if (settings.cache) { | |
let coverSourceCache = this.cacheGet(this.cacheGenKey(cover), null) | |
if (coverSourceCache) { | |
if (debug) log(data.index, 'Use cache ' + coverSourceCache) | |
data.coverSource = coverSourceCache | |
} | |
let coverThumbnailCache = this.cacheGet(this.cacheGenKey(cover + '-thumbnail'), null) | |
if (coverThumbnailCache) { | |
if (debug) log(data.index, 'Use cache thumbnail ' + coverThumbnailCache) | |
data.coverThumbnail = coverThumbnailCache | |
} | |
} | |
//Check exclude preview | |
if (settings.exceptCategories.includes(category)) { | |
data.coverSource = settings.previewExcept | |
data.coverThumbnail = settings.previewExcept | |
data.except = true | |
} | |
//Check no cover | |
if (data.cover === null) { | |
data.cover = settings.previewFail | |
data.except = true | |
} | |
downloadList.push(data) | |
progressBar.all++ | |
}, | |
getDirectSource : async function ( url ) { | |
let domain = this.extractHostname(url) | |
//Custom | |
let custom = patterns.custom.find(r => r.domains.includes(domain)) | |
if (custom) { | |
if (custom.synchronous) { | |
return await custom.callback(url, this) | |
} else { | |
return custom.callback(url, this) | |
} | |
} | |
//Direct | |
if (url.match(/\.(jpeg|jpg|gif|png)$/) != null) { | |
if (patterns.direct.excepts.indexOf(domain) === -1) | |
return url | |
} | |
//Meta | |
let meta = patterns.meta.find(r => r.domains.includes(domain)) | |
if (meta) { | |
if (debug) log('+', 'Get source from meta') | |
return await this.getDirectSourceSite(url, 'meta', { selector : meta.selector }) | |
} | |
//Selector | |
let selector = patterns.selector.find(r => r.domains.includes(domain)) | |
if (selector) { | |
if (debug) log('+', 'Get source from selector') | |
return await this.getDirectSourceSite(url, 'selector', { | |
selector : selector.selector, | |
attr : selector.attr, | |
}) | |
} | |
//Replace | |
let replace = patterns.replace.find(r => r.domains.includes(domain)) | |
if (replace) { | |
if (debug) log('+', 'Get source from replace') | |
return url.replace(replace.replace_find, replace.replace_new) | |
} | |
return url | |
}, | |
getDirectSourceSite : async function ( url, mode, argument, callback ) { | |
return await new Promise(resolve => { | |
GM_xmlhttpRequest({ | |
method : "GET", | |
url : url, | |
synchronous : true, | |
onload : function ( res ) { | |
let responseHTML = new DOMParser().parseFromString(res.responseText, "text/html") | |
let data | |
if (mode === 'meta') { | |
data = $("meta[property='" + argument.selector + "']", responseHTML).attr("content") | |
} else if (mode === 'selector') { | |
data = $(argument.selector, responseHTML).first().attr(argument.attr) | |
} | |
if (callback) { | |
callback(res) | |
} | |
resolve(data) | |
}, | |
ontimeout : () => { | |
resolve(null) | |
}, | |
onerror : () => { | |
resolve(null) | |
} | |
}) | |
}) | |
}, | |
getDirectLinks : async function ( coversHash ) { | |
return await new Promise(resolve => { | |
GM_xmlhttpRequest({ | |
method : "GET", | |
url : settings.directLinkApi + '?find=' + coversHash, | |
responseType : "json", | |
timeout : settings.directLinkTimeout, | |
synchronous : true, | |
onload : function ( res ) { | |
resolve(res.response) | |
}, | |
ontimeout : () => { | |
resolve([]) | |
}, | |
onerror : () => { | |
resolve([]) | |
}, | |
onabort : () => { | |
resolve([]) | |
} | |
}) | |
}) | |
}, | |
addDirectLinks : function ( sources ) { | |
GM_xmlhttpRequest({ | |
method : "PUT", | |
url : settings.directLinkApi, | |
headers : { | |
"Content-Type" : "application/x-www-form-urlencoded" | |
}, | |
responseType : "json", | |
synchronous : false, | |
data : 'data=' + JSON.stringify(sources), | |
onload : function ( res ) { | |
if (res.response.status) | |
if (debug) log('+', 'Add DirectLink success ' + res.response.count_created + ' items') | |
} | |
}) | |
}, | |
updateProgressBar : function () { | |
progressBar.template.html(" [" + progressBar.run + "/" + progressBar.all + "]") | |
}, | |
updateHoverPreview : function ( dList ) { | |
if (debug) log(dList.index, 'Update cover hover preview') | |
if (dList.coverSource) { | |
dList.coverHoverPreviewImg.src = dList.coverSource | |
} | |
}, | |
updateCoverPreview : function ( dList ) { | |
if (debug) log(dList.index, 'Update cover preview') | |
let src = dList.coverThumbnail || dList.coverSource | |
if (src) { | |
dList.coverPreviewImg.attr('src', src) | |
} else { | |
dList.coverPreviewImg.trigger('error') | |
} | |
dList.coverPreview.append(dList.coverPreviewImg) | |
}, | |
errorCoverPreview : function () { | |
this.src = settings.previewFail | |
this.title = 'Loaded image fail!' | |
let element = $(this) | |
element.prev().hide() | |
element.show() | |
}, | |
loadedCoverPreview : function ( self ) { | |
if (debug) log('+', 'Loaded cover ' + self.src) | |
let element = $(self) | |
element.prev().hide() | |
element.show() | |
//Title for except | |
if (settings.previewExcept === self.src) | |
self.title = 'Except image!' | |
}, | |
loadedHoverPreview : function ( self, dList ) { | |
if (debug) log(dList.index, 'Call loaded hover preview') | |
//Cache cover thumbnail | |
if (settings.cache | |
&& !self.cacheHas(self.cacheGenKey(dList.cover + '-thumbnail')) | |
&& dList.coverThumbnail | |
&& dList.except === false) { | |
if (debug) log(dList.index, 'Write cache thumbnail') | |
self.cacheSet(self.cacheGenKey(dList.cover + '-thumbnail'), dList.coverThumbnail, settings.cacheTimeout) | |
} | |
//Cache cover source | |
if (settings.cache | |
&& !self.cacheHas(self.cacheGenKey(dList.cover)) | |
&& dList.coverSource | |
&& dList.except === false) { | |
if (debug) log(dList.index, 'Write cache source') | |
self.cacheSet(self.cacheGenKey(dList.cover), dList.coverSource, settings.cacheTimeout) | |
} | |
//Add hover | |
if (!dList.except) { | |
self.hoverPreview(dList.elements.title, dList) | |
self.hoverPreview(dList.coverPreview, dList) | |
} | |
}, | |
hoverPreview : function ( element, dList ) { | |
let self = this | |
let imageHeight = Math.ceil(window.innerHeight * 0.6) | |
let offset = element.offset() | |
element.hover(function ( e ) { | |
//Change img src | |
hoverPreview.img | |
.attr('src', dList.coverSource) | |
.css('max-height', imageHeight + 'px') | |
.on('load', function () { | |
hoverPreview.imgHeight = $(this).height() + 10 | |
}) | |
hoverPreview.previewTop = e.pageY - hoverPreview.xOffset | |
hoverPreview.previewLeft = e.pageX + hoverPreview.yOffset | |
hoverPreview.yOffsetPreLoadFix = 0 | |
hoverPreview.yOffsetFix = (window.innerHeight - e.clientY) | |
hoverPreview.yOffsetFix = hoverPreview.yOffsetFix < 0 ? (hoverPreview.yOffsetFix - 50) : 0 | |
hoverPreview.yOffsetPreLoadFix = hoverPreview.yOffsetFix | |
//Show popup | |
hoverPreview.popup.css({ | |
top : hoverPreview.previewTop + "px", | |
left : hoverPreview.previewLeft + "px" | |
}).show() | |
}, function ( e ) { | |
hoverPreview.previewTop = e.pageY - hoverPreview.xOffset | |
hoverPreview.popup.hide() | |
}) | |
$(element).mousemove(function ( e ) { | |
let fixY = 60 | |
if (e.clientY < hoverPreview.imgHeight) { | |
fixY = hoverPreview.yOffsetPreLoadFix + hoverPreview.imgHeight - e.clientY | |
} | |
hoverPreview.popup.css("top", e.pageY - hoverPreview.xOffset + hoverPreview.yOffsetPreLoadFix - hoverPreview.imgHeight + fixY + "px").css("left", e.pageX + hoverPreview.yOffset + "px") | |
}) | |
} | |
} | |
} | |
SiambitZoomScreenShot().init() | |
}(jQuery)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment