// ==UserScript==
// @name Saiko Animes Download Helper (SADH)
// @namespace sadh
// @include /^https?://my\.pcloud\.com/publink/show\?code=.*/
// @include /^https?://saikoanimes\.net/.*/
// @version 1.3.3
// @description Captura os links de download automaticamente do site Saiko Animes.
// @copyright 2016 Foca.
// @grant none
// ==/UserScript==
// Função retirada do StackOverflow.
// Link: http://stackoverflow.com/a/33486055
var MD5 = function(s){function L(k,d){return(k<<d)|(k>>>(32-d))}function K(G,k){var I,d,F,H,x;F=(G&2147483648);H=(k&2147483648);I=(G&1073741824);d=(k&1073741824);x=(G&1073741823)+(k&1073741823);if(I&d){return(x^2147483648^F^H)}if(I|d){if(x&1073741824){return(x^3221225472^F^H)}else{return(x^1073741824^F^H)}}else{return(x^F^H)}}function r(d,F,k){return(d&F)|((~d)&k)}function q(d,F,k){return(d&k)|(F&(~k))}function p(d,F,k){return(d^F^k)}function n(d,F,k){return(F^(d|(~k)))}function u(G,F,aa,Z,k,H,I){G=K(G,K(K(r(F,aa,Z),k),I));return K(L(G,H),F)}function f(G,F,aa,Z,k,H,I){G=K(G,K(K(q(F,aa,Z),k),I));return K(L(G,H),F)}function D(G,F,aa,Z,k,H,I){G=K(G,K(K(p(F,aa,Z),k),I));return K(L(G,H),F)}function t(G,F,aa,Z,k,H,I){G=K(G,K(K(n(F,aa,Z),k),I));return K(L(G,H),F)}function e(G){var Z;var F=G.length;var x=F+8;var k=(x-(x%64))/64;var I=(k+1)*16;var aa=Array(I-1);var d=0;var H=0;while(H<F){Z=(H-(H%4))/4;d=(H%4)*8;aa[Z]=(aa[Z]| (G.charCodeAt(H)<<d));H++}Z=(H-(H%4))/4;d=(H%4)*8;aa[Z]=aa[Z]|(128<<d);aa[I-2]=F<<3;aa[I-1]=F>>>29;return aa}function B(x){var k="",F="",G,d;for(d=0;d<=3;d++){G=(x>>>(d*8))&255;F="0"+G.toString(16);k=k+F.substr(F.length-2,2)}return k}function J(k){k=k.replace(/rn/g,"n");var d="";for(var F=0;F<k.length;F++){var x=k.charCodeAt(F);if(x<128){d+=String.fromCharCode(x)}else{if((x>127)&&(x<2048)){d+=String.fromCharCode((x>>6)|192);d+=String.fromCharCode((x&63)|128)}else{d+=String.fromCharCode((x>>12)|224);d+=String.fromCharCode(((x>>6)&63)|128);d+=String.fromCharCode((x&63)|128)}}}return d}var C=Array();var P,h,E,v,g,Y,X,W,V;var S=7,Q=12,N=17,M=22;var A=5,z=9,y=14,w=20;var o=4,m=11,l=16,j=23;var U=6,T=10,R=15,O=21;s=J(s);C=e(s);Y=1732584193;X=4023233417;W=2562383102;V=271733878;for(P=0;P<C.length;P+=16){h=Y;E=X;v=W;g=V;Y=u(Y,X,W,V,C[P+0],S,3614090360);V=u(V,Y,X,W,C[P+1],Q,3905402710);W=u(W,V,Y,X,C[P+2],N,606105819);X=u(X,W,V,Y,C[P+3],M,3250441966);Y=u(Y,X,W,V,C[P+4],S,4118548399);V=u(V,Y,X,W,C[P+5],Q,1200080426);W=u(W,V,Y,X,C[P+6],N,2821735955);X=u(X,W,V,Y,C[P+7],M,4249261313);Y=u(Y,X,W,V,C[P+8],S,1770035416);V=u(V,Y,X,W,C[P+9],Q,2336552879);W=u(W,V,Y,X,C[P+10],N,4294925233);X=u(X,W,V,Y,C[P+11],M,2304563134);Y=u(Y,X,W,V,C[P+12],S,1804603682);V=u(V,Y,X,W,C[P+13],Q,4254626195);W=u(W,V,Y,X,C[P+14],N,2792965006);X=u(X,W,V,Y,C[P+15],M,1236535329);Y=f(Y,X,W,V,C[P+1],A,4129170786);V=f(V,Y,X,W,C[P+6],z,3225465664);W=f(W,V,Y,X,C[P+11],y,643717713);X=f(X,W,V,Y,C[P+0],w,3921069994);Y=f(Y,X,W,V,C[P+5],A,3593408605);V=f(V,Y,X,W,C[P+10],z,38016083);W=f(W,V,Y,X,C[P+15],y,3634488961);X=f(X,W,V,Y,C[P+4],w,3889429448);Y=f(Y,X,W,V,C[P+9],A,568446438);V=f(V,Y,X,W,C[P+14],z,3275163606);W=f(W,V,Y,X,C[P+3],y,4107603335);X=f(X,W,V,Y,C[P+8],w,1163531501);Y=f(Y,X,W,V,C[P+13],A,2850285829);V=f(V,Y,X,W,C[P+2],z,4243563512);W=f(W,V,Y,X,C[P+7],y,1735328473);X=f(X,W,V,Y,C[P+12],w,2368359562);Y=D(Y,X,W,V,C[P+5],o,4294588738);V=D(V,Y,X,W,C[P+8],m,2272392833);W=D(W,V,Y,X,C[P+11],l,1839030562);X=D(X,W,V,Y,C[P+14],j,4259657740);Y=D(Y,X,W,V,C[P+1],o,2763975236);V=D(V,Y,X,W,C[P+4],m,1272893353);W=D(W,V,Y,X,C[P+7],l,4139469664);X=D(X,W,V,Y,C[P+10],j,3200236656);Y=D(Y,X,W,V,C[P+13],o,681279174);V=D(V,Y,X,W,C[P+0],m,3936430074);W=D(W,V,Y,X,C[P+3],l,3572445317);X=D(X,W,V,Y,C[P+6],j,76029189);Y=D(Y,X,W,V,C[P+9],o,3654602809);V=D(V,Y,X,W,C[P+12],m,3873151461);W=D(W,V,Y,X,C[P+15],l,530742520);X=D(X,W,V,Y,C[P+2],j,3299628645);Y=t(Y,X,W,V,C[P+0],U,4096336452);V=t(V,Y,X,W,C[P+7],T,1126891415);W=t(W,V,Y,X,C[P+14],R,2878612391);X=t(X,W,V,Y,C[P+5],O,4237533241);Y=t(Y,X,W,V,C[P+12],U,1700485571);V=t(V,Y,X,W,C[P+3],T,2399980690);W=t(W,V,Y,X,C[P+10],R,4293915773);X=t(X,W,V,Y,C[P+1],O,2240044497);Y=t(Y,X,W,V,C[P+8],U,1873313359);V=t(V,Y,X,W,C[P+15],T,4264355552);W=t(W,V,Y,X,C[P+6],R,2734768916);X=t(X,W,V,Y,C[P+13],O,1309151649);Y=t(Y,X,W,V,C[P+4],U,4149444226);V=t(V,Y,X,W,C[P+11],T,3174756917);W=t(W,V,Y,X,C[P+2],R,718787259);X=t(X,W,V,Y,C[P+9],O,3951481745);Y=K(Y,h);X=K(X,E);W=K(W,v);V=K(V,g)}var i=B(Y)+B(X)+B(W)+B(V);return i.toLowerCase()};
// Função retirada do MDN (Mozilla Developer Network)
// Link: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random
function getRandomInt(min, max) {
min = Math.ceil(min);
max = Math.floor(max);
return Math.floor(Math.random() * (max - min + 1)) + min;
}
// Função retirada do StackOverflow.
// Link: http://stackoverflow.com/a/1349426
function makeId() {
var text = "";
var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
var len = getRandomInt(4, 8);
for (var i = 0; i < len; i++)
text += possible.charAt(Math.floor(Math.random() * possible.length));
return text;
}
var SADH = {
domain: document.domain,
working: false,
currentTab: null,
linkElements: null,
totalLinks: 0,
retrievedLinks: 0,
statusBox: null,
init: function() {
switch (this.domain) {
case "my.pcloud.com":
this.setupPCloud();
break;
case "saikoanimes.net":
this.setupSaiko();
break;
}
},
setupPCloud: function() {
var fileName = $('.filename').text();
if (typeof fileName === 'undefined')
return;
if (fileName.match(/(Saiko\-Anime[s]|Saiko_Anime[s])/)) {
window.addEventListener('message', function(event) {
if (typeof event.data.cmd === 'undefined')
return;
if (event.data.cmd == "getVideoLink") {
var videoUrl = typeof publinkData !== 'undefined' ? publinkData.downloadlink : '';
if (videoUrl == '')
videoUrl = $('video').attr('src');
event.source.postMessage({cmd:'retVideoLink', link:videoUrl, id:event.data.id}, "*");
}
});
}
},
setupSaiko: function() {
$('.omsc-tab-pcloud').find('a[href]').each(function() {
var idx = $(this).attr('href').indexOf('protetor.php?url=');
if (idx > 0) {
var newUrl = $(this).attr('href').substr(idx).replace('protetor.php?url=', '');
$(this).attr('href', newUrl);
}
});
var self = this;
self.saikoGUI.create();
window.addEventListener('message', function(event) {
if (typeof event.data.cmd === 'undefined')
return;
if (event.data.cmd == "retVideoLink") {
var btn = $('a[data-ident=' + event.data.id + ']');
btn.removeClass(self.saikoGUI._masks['downloading']);
btn.addClass(self.saikoGUI._masks['downloaded']);
btn.attr('href', event.data.link);
btn.removeAttr('data-ident');
SADH.saikoGUI.updateStatus();
$('iframe[data-ident=' + event.data.id + ']').remove();
}
});
},
retrieveLinks: function() {
var self = this;
var links = $(SADH.linkElements);
this.totalLinks = links.length;
this.retrievedLinks = 0;
this.saikoGUI.zeroStatus();
var sequence = Promise.resolve();
links.each(function() {
var href = $(this).attr('href');
if (href.indexOf('my.pcloud.com/publink/show?code=') < 0) {
console.warn('INVALID LINK!');
SADH.saikoGUI.updateStatus();
return;
}
var ident = MD5(href);
$(this).attr('data-ident', ident);
$(this).addClass(self.saikoGUI._getMasks('sadh-status idle'));
sequence = sequence.then(function() {
var makeIframe = function(src, id) {
var btn = $('a[data-ident=' + ident + ']');
btn.removeClass(self.saikoGUI._masks['idle']);
btn.addClass(self.saikoGUI._masks['downloading']);
var def = $.Deferred();
var el = $('<iframe style="display: none;"></iframe>').attr({
'data-ident': id,
'src': src
});
el.load(def.resolve);
el.appendTo('body');
def.done(function() {
var iframe = $('iframe[data-ident=' + ident + ']')[0];
iframe.contentWindow.postMessage({cmd:'getVideoLink', id:ident}, '*');
});
return def.promise();
};
return makeIframe(href, ident);
});
});
},
saikoGUI: {
_masks: {
// Classes.
'sadh-box': '',
'fw': '',
'sadh-pb-container': '',
'sadh-pb-text': '',
'sadh-pb-bar': '',
'sadh-button': '',
'red': '',
'green': '',
'sadh-social': '',
'sadh-title': '',
'sadh-content': '',
'sadh-item-content': '',
'sadh-item': '',
'expandButton': '',
'single': '',
'inv': '',
'sadh-info': '',
'sadh-footer': '',
'sadh-status': '',
'idle': '',
'downloading': '',
'downloaded': '',
'pbBox': '',
'selected': '',
'content-1': '',
'content-2': '',
'itemLoadSelection': '',
// Icons.
'fa-arrow-circle-o-down': '',
'fa-twitter': '',
'fa-facebook-official': '',
'fa-question': '',
'fa-warning': '',
'fa-link': '',
'fa-tasks': '',
'faicb': '',
// Roles.
'loadAll': '',
'loadSelection': '',
'loadOk': '',
'loadCancel': '',
'EpSelect': '',
'expButton': '',
'txtLinks': ''
},
_initMasks: function() {
var self = this;
Object.getOwnPropertyNames(this._masks).forEach(function(key) {
self._masks[key] = makeId();
});
},
_fixStyle: function(text) {
var self = this;
Object.getOwnPropertyNames(this._masks).forEach(function(key) {
text = text.replace(new RegExp(key, 'g'), self._masks[key]);
});
return text;
},
_getMasks: function(classes) {
var self = this;
var cls = '';
classes.split(' ').forEach(function(key) {
cls += self._masks[key] + ' ';
});
return cls.trim();
},
create: function() {
this._initMasks();
this._loadStyle();
var boxHtml = `
<div class="sadh-box">
<div class="sadh-social">
<a href="https://twitter.com/shitcodebr" target="blank"><i class="faicb fa-twitter"></i></a>
<a href="https://www.facebook.com/shitcodebr" target="blank"><i class="faicb fa-facebook-official"></i></a>
<a href="http://shitcodebr.com/2016/10/05/saiko-animes-download-helper-sadh/" target="blank"><i class="faicb fa-question"></i></a>
</div>
<span class="sadh-title">Saiko Animes Download Helper (SADH)</span>
<div class="sadh-content">
<div class="sadh-item single">
<h4><i class="faicb fa-warning"></i> Aviso!</h4>
<div class="sadh-item-content" style="display: block">
Lembre-se: vários animes presentes neste site não são encontrados vias "oficiais" (Crunchyroll, por exemplo), portanto, não deixe de apoiar
o trabalho da Equipe Saiko. Se você não pode pagar o VIP, ao menos desabilite seu AdBlock.
</div>
</div>
<div class="sadh-item">
<div class="sadh-button fw" role="loadAll">Carregar Todos</div>
<div class="sadh-info">
Com esta opção será carregado o link de todos os episódios, portanto, poderá levar vários minutos dependendo da sua
conexão e da quantidade de episódios.
</div>
</div>
<div class="sadh-item itemLoadSelection">
<div class="content-1">
<div class="sadh-button fw" role="loadSelection">Selecionar Episódios</div>
<div class="sadh-info">
Com esta opção será carregado apenas os links que você selecionar.
</div>
</div>
<div class="content-2" style="display: none;">
<div class="sadh-button red" role="loadCancel"><i class="faicb fa-times"></i></div>
<div class="sadh-button green" role="loadOk" style="float: right;"><i class="faicb fa-check"></i></div>
<div class="sadh-info">
Agora, clique nos links que você deseja baixar. Quando terminar, clique no botão verde acima para iniciar. Clique no vermelho
para cancelar.
</div>
</div>
</div>
<div class="sadh-item inv"></div>
<div class="sadh-item inv"></div>
<div class="sadh-item inv"></div>
<div class="sadh-item single pbBox" style="display: none;">
<h4><i class="faicb fa-tasks"></i> Status</h4>
<div class="sadh-pb-container">
<div class="sadh-pb-text">0 de 0 (0%)</div>
<div class="sadh-pb-bar"></div>
</div>
</div>
<div class="sadh-item single">
<div class="expandButton" role="expButton"><i class="faicb fa-arrow-circle-o-down"></i></div>
<h4><i class="faicb fa-link"></i> Links</h4>
<div class="sadh-item-content">
<textarea role="txtLinks" readonly></textarea>
</div>
</div>
</div>
<div class="sadh-footer">
Saiko Animes Download Helper (SADH) foi desenvolvido por Foca. Meu blog: <a href="http://shitcodebr.com" target="blank">shitcodebr.com</a>.
</div>
</div>
`;
var box = $(this._fixStyle(boxHtml));
$('.omsc-tab-pcloud').prepend(box);
this._applyEvents();
},
zeroStatus: function() {
SADH.statusBox.find('.' + this._masks['sadh-pb-text']).text('0 de ' + SADH.totalLinks + ' (0%)');
SADH.statusBox.find('.' + this._masks['sadh-pb-bar']).css('width', '0%');
},
updateStatus: function() {
SADH.retrievedLinks += 1;
var percent = (SADH.retrievedLinks * 100) / SADH.totalLinks;
SADH.statusBox.find('.' + this._masks['sadh-pb-text']).text(SADH.retrievedLinks + ' de ' + SADH.totalLinks + ' (' + percent.toFixed() + '%)');
SADH.statusBox.find('.' + this._masks['sadh-pb-bar']).css('width', percent.toFixed(2) + '%');
if (SADH.retrievedLinks >= SADH.totalLinks) {
SADH.currentTab.find('[role=' + this._masks['txtLinks'] + ']').val(SADH.linkElements.join("\n"));
SADH.working = false;
var expBtn = SADH.currentTab.find('[role=' + this._masks['expButton'] + ']');
if (expBtn.data('expanded') == 'false')
expBtn.click();
}
},
_applyEvents: function() {
var self = this;
$('[role=' + self._masks['expButton'] + ']').data('expanded', 'false');
$('.' + self._masks['sadh-box']).find('a').each(function() {
var href = $(this).attr('href');
$(this).attr('href', '#');
$(this).removeAttr('target');
$(this).click(function(e) {
window.open(href, 'blank');
e.preventDefault();
});
});
$('[role=' + self._masks['loadAll'] + ']').click(function() {
if (SADH.working)
return;
SADH.currentTab = $(this).parents('.omsc-tab-pcloud');
SADH.statusBox = SADH.currentTab.find('.' + self._masks['pbBox']);
if (SADH.statusBox.css('display') == 'none')
SADH.statusBox.slideToggle(400);
SADH.working = true;
SADH.linkElements = SADH.currentTab.children('a').get();
SADH.retrieveLinks();
});
$('[role=' + self._masks['loadSelection'] + ']').click(function() {
if (SADH.working)
return;
SADH.currentTab = $(this).parents('.omsc-tab-pcloud');
SADH.statusBox = SADH.currentTab.find('.' + self._masks['pbBox']);
if (SADH.statusBox.css('display') == 'none')
SADH.statusBox.slideToggle(400);
SADH.currentTab.children('a').attr('role', self._masks['EpSelect']);
$(this).parent().fadeOut(50, function() {
$(this).siblings('.' + self._masks['content-2']).fadeIn(50);
});
});
$('[role=' + self._masks['loadOk'] + ']').click(function() {
var links = SADH.currentTab.children('a.' + self._masks['sadh-status'] + '.' + self._masks['idle']);
if (links.length <= 0) {
alert('Nenhum episódio selecionado!');
return;
}
SADH.currentTab.children('a').each(function() {
$(this).removeAttr('role');
if (!$(this).hasClass(self._masks['selected']))
$(this).removeClass(self._getMasks('sadh-status idle'));
});
$(this).parent().fadeOut(50, function() {
$(this).siblings('.' + self._masks['content-1']).fadeIn(50);
});
SADH.linkElements = links.get();
SADH.working = true;
SADH.retrieveLinks();
});
$('[role=' + self._masks['loadCancel'] + ']').click(function() {
$('[role=' + self._masks['EpSelect'] + ']').removeAttr('role').removeClass(self._getMasks('sadh-status idle'));
$(this).parent().fadeOut(50, function() {
$(this).siblings('.' + self._masks['content-1']).fadeIn(50);
});
});
$('[role=' + self._masks['expButton'] + ']').click(function() {
$(this).siblings('.' + self._masks['sadh-item-content']).slideToggle(450);
var exp = $(this).data('expanded');
var icon = $(this).children('i');
$(this).data('expanded', exp == 'true' ? 'false' : 'true');
exp = exp == 'true' ? 'false' : 'true';
if (exp == 'true') {
icon.removeClass(self._getMasks('faicb fa-arrow-circle-o-down'));
icon.addClass(self._getMasks('faicb fa-arrow-circle-o-up'));
} else {
icon.removeClass(self._getMasks('faicb fa-arrow-circle-o-up'));
icon.addClass(self._getMasks('faicb fa-arrow-circle-o-down'));
}
});
$('body').on('click', '[role=' + self._masks['EpSelect'] + ']', function(e) {
$(this).toggleClass(self._getMasks('sadh-status idle selected'));
e.preventDefault();
});
},
_loadStyle: function() {
var style = `
[role=txtLinks] {
width: 100%;
height: 200px;
resize: none;
margin-bottom: 0;
word-wrap: normal;
word-break: keep-all;
}
.fw {
width: 100%;
}
.sadh-pb-container {
position: relative;
display: block;
width: 100%;
height: 30px;
background: #adadad;
color: #fff !important;
}
.sadh-pb-text {
position: absolute;
width: 100%;
height: 100%;
font-size: 13px;
line-height: 28px;
text-align: center;
z-index: 10;
}
.sadh-pb-bar {
position: absolute;
width: 0%;
height: 100%;
background: #0090ff;
left: 0;
top: 0;
}
.sadh-button {
display: inline-block;
font-size: 14px;
font-family: 'Open Sans';
padding: 12px 0;
color: #fff;
background: rgba(0, 0, 0, 0.55);
text-align: center;
cursor: pointer;
min-width: 74px;
}
.sadh-button:hover {
background: rgba(0, 0, 0, 0.4);
}
.sadh-button.red {
background: #da4453;
}
.sadh-button.red:hover {
background: #ed5565;
}
.sadh-button.green {
background: #8cc152;
}
.sadh-button.green:hover {
background: #a0d468;
}
.sadh-box {
display: block;
position: relative;
width: calc(100% - 2px);
box-sizing: border-box;
border: 1px solid #c5c5c5;
padding: 10px;
margin-bottom: 10px;
}
.sadh-box .sadh-social {
position: absolute;
padding: 5px;
right: 0;
top: 0;
}
.sadh-box .sadh-title {
display: block;
width: 100%;
padding: 0 0 15px 0;
font-family: 'Open Sans';
font-size: 18px;
color: #434a54;
text-align: center;
}
.sadh-box .sadh-content {
display: flex;
flex-flow: row wrap;
justify-content: space-around;
}
.sadh-content .sadh-item {
display: block;
position: relative;
box-sizing: border-box;
width: 180px;
border: 1px solid #c5c5c5;
padding: 10px;
margin-bottom: 10px;
color: #111;
}
.sadh-item-content {
display: none;
margin-top: 10px;
}
.sadh-item .expandButton {
position: absolute;
top: 14px;
right: 10px;
font-size: 14px;
cursor: pointer;
}
.sadh-item h4 {
margin-top: 0;
margin-bottom: 0;
font-size: 18px;
font-weight: bold;
}
.sadh-item.single {
width: calc(100% - 7px);
}
.sadh-item.inv {
height: 0;
opacity: 0;
margin-bottom: 0;
padding: 0 10px;
}
.sadh-item .sadh-info {
width: 100%;
padding-top: 18px;
line-height: 14px;
font-family: 'Open Sans';
font-size: 12px;
color: #777;
}
.sadh-box .sadh-footer {
width: 100%;
margin-top: 32px;
font-family: 'Open Sans';
font-size: 12px;
font-style: italic;
color: #444;
}
.sadh-footer:after {
position: absolute;
right: 10px;
content: '1.3.3';
color: #f00000;
font-style: normal;
}
.sadh-footer a {
text-decoration: underline;
}
.sadh-status:before {
position: absolute;
content: '';
width: 100%;
height: 4px;
left: 0;
top: 0;
}
.sadh-status.idle:before {
background: #000;
}
.sadh-status.downloading:before {
background: #ff7200;
}
.sadh-status.downloaded:before {
background: #0090ff;
}
.faicb {
display: inline-block;
font: normal normal normal 14px/1 FontAwesome;
font-size: inherit;
text-rendering: auto;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.fa-arrow-circle-o-down:before {
content: '\\f01a';
}
.fa-twitter:before {
content: '\\f099';
}
.fa-facebook-official:before {
content: '\\f230';
}
.fa-question:before {
content: '\\f128';
}
.fa-warning:before {
content: '\\f071';
}
.fa-link:before {
content: '\\f0c1';
}
.fa-tasks:before {
content: '\\f0ae';
}
`;
$(document.head).append('<style type="text/css">' + this._fixStyle(style) + '</style>');
}
}
}
$(document).ready(function() {
SADH.init();
});