// ==UserScript==
// @name PTH Collector
// @version 1.8
// @description Download multiple torrents by some criteria on PTH
// @author Chameleon
// @include http*://redacted.ch/*
// @grant none
// @require https://greasyfork.org/scripts/19855-jszip/code/jszip.js?version=126859
// @namespace https://greasyfork.org/users/87476
// ==/UserScript==
(function() {
'use strict';
var wH=window.location.href;
if(wH.indexOf('artist.php?id=') != -1)
{
addToX(compileArtist);
}
else if(wH.indexOf('threadid=3543') != -1)
showSettings();
else if(wH.indexOf('collages.php?id=') != -1)
addToX(compileCollage);
else if(wH.indexOf('bookmarks.php?type=torrents') != -1)
addToX(compileCollage.bind('Bookmarks'));
//else if(wH.indexOf('torrents.php') != -1 && wH.indexOf('?id=') == -1)
//addToSearch();
})();
function addToSearch()
{
var sidebar=document.createElement('div');
sidebar.setAttribute('class', 'sidebar');
sidebar.setAttribute('style', 'float: initial; margin: auto;');
/*var left=(document.body.clientWidth/2)+425;
sidebar.setAttribute('style', 'position: absolute; left: '+left+'px;');
var before=document.getElementsByClassName('header')[0].nextElementSibling;
before.parentNode.insertBefore(sidebar, before);*/
document.getElementsByClassName('thin')[0].appendChild(sidebar);
addToX(compileCollage.bind('Search'));
}
function showSettings()
{
var div=document.getElementById('collectorSettings');
if(!div)
{
var before = document.getElementsByClassName('forum_post')[0];
div = document.createElement('div');
div.setAttribute('id', 'collectorSettings');
before.parentNode.insertBefore(div, before);
div.setAttribute('style', 'width: 100%; text-align: center; padding-bottom: 10px;');
div.setAttribute('class', 'box');
}
div.innerHTML = '<h2>Collector Settings</h2><br />';
var settings = getSettings();
var a=document.createElement('a');
a.href='javascript:void(0);';
a.innerHTML = 'Sequential torrent download: '+(settings.sequential ? 'On':'Off');
a.addEventListener('click', changeLink.bind(undefined, a, div), false);
div.appendChild(a);
div.appendChild(document.createElement('br'));
var a=document.createElement('a');
a.href='javascript:void(0);';
a.innerHTML = 'Include summary txt in .zip: '+(settings.summary ? 'On':'Off');
a.addEventListener('click', changeLink.bind(undefined, a, div), false);
div.appendChild(a);
div.appendChild(document.createElement('br'));
}
function changeLink(a, div)
{
if(a.innerHTML.indexOf('On') != -1)
a.innerHTML = a.innerHTML.replace(/On/, 'Off');
else
a.innerHTML = a.innerHTML.replace(/Off/, 'On');
changeSettings(div);
}
function changeSettings(div)
{
var settings = getSettings();
var as=div.getElementsByTagName('a');
if(as[0].innerHTML.indexOf('On') != -1)
settings.sequential=true;
else
settings.sequential=false;
if(as[1].innerHTML.indexOf('On') != -1)
settings.summary=true;
else
settings.summary=false;
setSettings(settings);
showSettings();
}
function setSettings(settings)
{
window.localStorage.collectorOperationSettings = JSON.stringify(settings);
}
function getSettings()
{
var settings = window.localStorage.collectorOperationSettings;
if(!settings)
{
settings = {sequential:false};
}
else
{
settings = JSON.parse(settings);
}
return settings;
}
function addToX(compileFunc)
{
var style=document.createElement('style');
style.innerHTML = '.collectorAdded { background-color: #151 !important; } ';
style.innerHTML+= '.collectorAddedSuboptimal { background-color: #551 !important; } ';
style.innerHTML+= '.collectorMissing { background: rgba(255, 0, 0, 0.2) !important;} ';
style.innerHTML+= '.collectorSuboptimal { background: rgba(255, 255, 0, 0.2) !important;}';
document.head.appendChild(style);
var settings=getPersistence();
var sidebar=document.getElementsByClassName('sidebar')[0];
var box=document.createElement('div');
box.setAttribute('class', 'box');
sidebar.appendChild(box);
//sidebar.insertBefore(box, sidebar.firstElementChild);
var head=document.createElement('div');
box.appendChild(head);
head.setAttribute('class', 'head');
head.innerHTML = '<strong>Collector</strong>';
var list=document.createElement('ul');
box.appendChild(list);
list.setAttribute('class', 'nobullet');
var labelStyle='';
var inputStyle='';
var li=document.createElement('li');
list.appendChild(li);
var label=document.createElement('span');
label.setAttribute('style', labelStyle);
label.innerHTML = 'Format [?]: ';
var options = ["Any", "FLAC", "MP3", "AAC", "AC3", "DTS"];
li.addEventListener('mouseover', mouseOverLabel.bind(undefined, options), false);
li.addEventListener('mouseout', mouseOutLabel.bind(undefined, options), false);
li.appendChild(label);
var format=document.createElement('input');
format.setAttribute('style', inputStyle);
li.appendChild(format);
format.value = settings.format.join(', ');
format.placeholder="Format";
var li=document.createElement('li');
list.appendChild(li);
var label=document.createElement('span');
label.setAttribute('style', labelStyle);
label.innerHTML = 'Bitrate [?]: ';
var options = ["Any", "192", "APS (VBR)", "V2 (VBR)", "V1 (VBR)", "256", "APX", "V0 (VBR)", "320", "Lossless", "24bit Lossless", "Other"];
li.addEventListener('mouseover', mouseOverLabel.bind(undefined, options), false);
li.addEventListener('mouseout', mouseOutLabel.bind(undefined, options), false);
li.appendChild(label);
var bitrate=document.createElement('input');
bitrate.setAttribute('style', inputStyle);
li.appendChild(bitrate);
bitrate.value = settings.bitrate.join(', ');
bitrate.placeholder="Bitrate";
var li=document.createElement('li');
list.appendChild(li);
var label=document.createElement('span');
label.setAttribute('style', labelStyle);
label.innerHTML = 'Media [?]: ';
var options = ["Any", "CD", "DVD", "Vinyl", "Soundboard", "SACD", "DAT", "Cassette", "WEB", "Blu-Ray"];
li.addEventListener('mouseover', mouseOverLabel.bind(undefined, options), false);
li.addEventListener('mouseout', mouseOutLabel.bind(undefined, options), false);
li.appendChild(label);
var media=document.createElement('input');
media.setAttribute('style', inputStyle);
li.appendChild(media);
media.value = settings.media.join(', ');
media.placeholder="Media";
var li=document.createElement('li');
list.appendChild(li);
var label=document.createElement('span');
label.setAttribute('style', labelStyle);
label.innerHTML = 'Type: ';
li.appendChild(label);
var type=document.createElement('input');
type.placeholder = 'Release Type';
type.value = settings.types.join(', ');
type.setAttribute('style', inputStyle);
li.appendChild(type);
var li=document.createElement('li');
list.appendChild(li);
var label=document.createElement('span');
label.setAttribute('style', labelStyle);
label.innerHTML = 'Minimum number of seeders: ';
li.appendChild(label);
var minSeedCount=document.createElement('input');
minSeedCount.type='number';
minSeedCount.value = settings.minSeedCount;
minSeedCount.setAttribute('style', inputStyle);
li.appendChild(minSeedCount);
var messageDiv=document.createElement('div');
messageDiv.setAttribute('style', 'text-align: center;');
format.addEventListener('keyup', compileFunc.bind(undefined, {format:format, bitrate:bitrate, media:media, type:type, minSeedCount:minSeedCount}, messageDiv), false);
bitrate.addEventListener('keyup', compileFunc.bind(undefined, {format:format, bitrate:bitrate, media:media, type:type, minSeedCount:minSeedCount}, messageDiv), false);
media.addEventListener('keyup', compileFunc.bind(undefined, {format:format, bitrate:bitrate, media:media, type:type, minSeedCount:minSeedCount}, messageDiv), false);
type.addEventListener('keyup', compileFunc.bind(undefined, {format:format, bitrate:bitrate, media:media, type:type, minSeedCount:minSeedCount}, messageDiv), false);
minSeedCount.addEventListener('keyup', compileFunc.bind(undefined, {format:format, bitrate:bitrate, media:media, type:type, minSeedCount:minSeedCount}, messageDiv), false);
minSeedCount.addEventListener('change', compileFunc.bind(undefined, {format:format, bitrate:bitrate, media:media, type:type, minSeedCount:minSeedCount}, messageDiv), false);
minSeedCount.addEventListener('click', compileFunc.bind(undefined, {format:format, bitrate:bitrate, media:media, type:type, minSeedCount:minSeedCount}, messageDiv), false);
var div=document.createElement('div');
div.setAttribute('style', 'text-align: center;');
box.appendChild(div);
var a=document.createElement('a');
div.appendChild(a);
a.href='javascript:void(0);';
a.innerHTML = 'Collect';
a.addEventListener('click', save.bind(undefined, messageDiv), false);
div.appendChild(document.createTextNode(' | '));
var a=document.createElement('a');
div.appendChild(a);
a.href='javascript:void(0);';
a.innerHTML = 'Preview';
a.setAttribute('id', 'collectorPreviewLink');
a.addEventListener('click', compileFunc.bind(undefined, {format:format, bitrate:bitrate, media:media, type:type, minSeedCount:minSeedCount}, messageDiv, true), false);
div.appendChild(document.createTextNode(' | '));
var a=document.createElement('a');
div.appendChild(a);
a.href='javascript:void(0);';
a.innerHTML = 'List';
a.addEventListener('click', listC.bind(undefined, messageDiv), false);
var div=document.createElement('div');
div.setAttribute('style', 'text-align: center; white-space:nowrap; text-overflow:ellipsis; overflow:hidden;');
box.appendChild(div);
div.id='collectorList';
box.appendChild(messageDiv);
}
function listC(messageDiv)
{
var div=document.getElementById('collectorList');
div.innerHTML='';
var torrentList=messageDiv.getAttribute('torrentList');
if(!torrentList)
messageDiv.innerHTML = "You need to preview first";
torrentList=JSON.parse(torrentList);
for(var i=0; i<torrentList.length; i++)
{
var t=torrentList[i];
var id=parseInt(t.dl.split('id=')[1]);
var name=t.name.split('.torrent')[0];
div.innerHTML+='<br /><a href="/torrents.php?torrentid='+id+'" title="'+name+'">'+name+'</a>';
}
}
function mouseOverLabel(options, event)
{
var div=document.createElement('div');
document.body.appendChild(div);
div.setAttribute('class', 'labelPopups');
div.setAttribute('style', 'position: fixed; left: '+event.clientX+'px; top: '+event.clientY+'px; border-radius: 10px; padding: 10px; background: rgba(0,0,0,0.8); color: white;');
for(var i=0; i<options.length; i++)
{
div.innerHTML+=options[i]+'<br />';
}
}
function mouseOutLabel()
{
var l=document.getElementsByClassName('labelPopups');
for(var i=0; i<l.length; i++)
{
l[i].parentNode.removeChild(l[i]);
}
}
function compileCollage(filters, messageDiv, hilight)
{
setPersistence(filters);
var pers=getPersistence();
var format = pers.format;
var bitrate = pers.bitrate;
var media = pers.media;
var minSeedCount = pers.minSeedCount;
var collage=document.getElementsByTagName('h2')[0].textContent;
if(this == "Bookmarks")
collage="Bookmarks";
var title = "Collection Collage - "+collage+".zip";//+" - "+format+"_"+bitrate+"_"+media+".zip";
messageDiv.setAttribute('zipName', title);
messageDiv.innerHTML = 'Collecting torrents';
var torrents=[];
var missed=[];
var suboptimal=[];
var albumCount=0;
if(hilight)
{
var tRows = document.getElementsByClassName('torrent_row');
for(var i=0; i<tRows.length; i++)
{
var t=tRows[i];
t.setAttribute('class', t.getAttribute('class').replace(' collectorAddedSuboptimal', ''));
t.setAttribute('class', t.getAttribute('class').replace(' collectorAdded', ''));
if(t.getAttribute('collectorPreviewing') != "true")
{
t.addEventListener('click', addAnywayFunc.bind(undefined, t), false);
t.setAttribute('collectorPreviewing', "true");
}
}
var groups=document.getElementsByClassName('group');
for(var i=0; i<groups.length; i++)
{
groups[i].setAttribute('class', groups[i].getAttribute('class').replace(' collectorMissing', ''));
groups[i].setAttribute('class', groups[i].getAttribute('class').replace(' collectorSuboptimal', ''));
}
}
var totalSize=0;
var groups=document.getElementsByClassName('group');
for(var i=0; i<groups.length; i++)
{
var g=groups[i];
var album=g.getElementsByTagName('strong');
if(album.length === 0)
album=g.getElementsByClassName('group_info')[0].getElementsByTagName('a');
else
album = album[0].getElementsByTagName('a');
var artist=album[0].innerHTML;
album = album[album.length-1].innerHTML;
g.setAttribute('artist', artist);
g.setAttribute('album', album);
}
var output=doGroups(groups, torrents, hilight, albumCount, suboptimal, missed);
torrents=output.torrents;
totalSize+=output.totalSize;
albumCount=output.albumCount;
suboptimal=output.suboptimal;
missed=output.missed;
messageDiv.innerHTML = '';
var summaryText=(title.replace(/.zip$/, ''))+"\n\nDate: "+Date()+"\n\nTorrent groups analyzed: "+albumCount;
if(missed.length > 0)
summaryText+="\nTorrent groups filtered: "+missed.length+"\nTorrents downloaded: "+(albumCount-missed.length);
if(suboptimal.length > 0)
summaryText+="\nSuboptimal torrents: "+suboptimal.length;
summaryText+="\n\nFormat filter: "+format.join(', ')+'\nBitrate filter: '+bitrate.join(', ')+'\nMedia filter: '+media.join(', ');
summaryText+="\n\nTotal size of torrents (ratio hit): "+prettySize(totalSize);
if(missed.length > 0)
{
summaryText+="\n\nAlbums unavailable within your criteria (consider making a request for your desired format):";
for(var i=0; i<missed.length; i++)
{
var m=missed[i];
summaryText+="\n/torrents.php?id="+m.groupid+" - "+m.artist+" - "+m.album;
}
}
if(suboptimal.length > 0)
{
summaryText+="\n\nAlbums suboptimal within your criteria (consider making a request for your optimal format):";
for(var i=0; i<suboptimal.length; i++)
{
var m=suboptimal[i];
summaryText+="\n/torrents.php?id="+m.groupid+" - "+m.artist+" - "+m.album;
}
}
messageDiv.setAttribute('summaryText', summaryText);
if(missed.length > 0)
{
messageDiv.innerHTML = "Missing "+missed.length+" of "+albumCount+" groups";
}
else
{
messageDiv.innerHTML = 'Added torrents from all '+albumCount+' groups';
}
if(suboptimal.length > 0)
{
messageDiv.innerHTML+= '<br />'+suboptimal.length+' of '+(albumCount-missed.length)+' selected are suboptimal';
}
messageDiv.innerHTML+="<br />Total size: "+prettySize(totalSize);
messageDiv.setAttribute('torrentList', JSON.stringify(torrents));
}
function getPersistence()
{
var settings = window.localStorage.collectorSettings;
if(!settings)
{
settings = {format: [], bitrate: [], media: [], types: [], minSeedCount: 0};
}
else
{
settings = JSON.parse(settings);
}
if(typeof(settings.format) != "object")
settings = {format: [], bitrate: [], media: [], types: [], minSeedCount: 0};
return settings;
}
function setPersistence(filters)
{
var settings = {
format: filters.format.value.split(', '),
bitrate: filters.bitrate.value.split(', '),
media: filters.media.value.split(', '),
types: filters.type.value.split(', '),
minSeedCount: parseInt(filters.minSeedCount.value),
};
if(isNaN(settings.minSeedCount))
settings.minSeedCount=0;
window.localStorage.collectorSettings = JSON.stringify(settings);
}
function compileArtist(filters, messageDiv, hilight)
{
setPersistence(filters);
var pers=getPersistence();
var format = pers.format;
var bitrate = pers.bitrate;
var media = pers.media;
var types = pers.types;
var artist=document.getElementsByTagName('h2')[0].textContent;
var title = "Collection Artist - "+artist+".zip";//+" - "+format+"_"+bitrate+"_"+media+".zip";
messageDiv.setAttribute('zipName', title);
messageDiv.innerHTML = 'Collecting torrents';
var torrents=[];
var missed=[];
var suboptimal=[];
var albumCount=0;
if(hilight)
{
var tRows = document.getElementsByClassName('torrent_row');
for(var i=0; i<tRows.length; i++)
{
var t=tRows[i];
t.setAttribute('class', t.getAttribute('class').replace(' collectorAddedSuboptimal', ''));
t.setAttribute('class', t.getAttribute('class').replace(' collectorAdded', ''));
if(t.getAttribute('collectorPreviewing') != "true")
{
t.addEventListener('click', addAnywayFunc.bind(undefined, t), false);
t.setAttribute('collectorPreviewing', "true");
}
}
var groups=document.getElementsByClassName('group');
for(var i=0; i<groups.length; i++)
{
groups[i].setAttribute('class', groups[i].getAttribute('class').replace(' collectorMissing', ''));
groups[i].setAttribute('class', groups[i].getAttribute('class').replace(' collectorSuboptimal', ''));
}
}
for(var i=0; i<groups.length; i++)
{
var g=groups[i];
var album=g.getElementsByClassName('group_info')[0].getElementsByTagName('strong')[0].getElementsByTagName('a');
album = album[album.length-1].innerHTML;
g.setAttribute('artist', artist);
g.setAttribute('album', album);
}
var totalSize=0;
var tables = document.getElementsByClassName('release_table');
for(var i=0; i<tables.length; i++)
{
var t=tables[i];
var releaseType=t.getElementsByTagName('tr')[0].getElementsByTagName('strong')[0].innerHTML;
var inTypes=false;
for(var m=0; m<types.length; m++)
{
if(types[m] == releaseType)
{
inTypes=true;
break;
}
}
if(!inTypes && !(types[0] == '' && types.length == 1))
continue;
var groups=t.getElementsByClassName('group');
var output=doGroups(groups, torrents, hilight, albumCount, suboptimal, missed);
torrents=output.torrents;
totalSize+=output.totalSize;
albumCount=output.albumCount;
suboptimal=output.suboptimal;
missed=output.missed;
}
messageDiv.innerHTML = '';
var summaryText=(title.replace(/.zip$/, ''))+"\n\nDate: "+Date()+"\n\nTorrent groups analyzed: "+albumCount;
if(missed.length > 0)
summaryText+="\nTorrent groups filtered: "+missed.length+"\nTorrents downloaded: "+(albumCount-missed.length);
if(suboptimal.length > 0)
summaryText+="\nSuboptimal torrents: "+suboptimal.length;
summaryText+="\n\nFormat filter: "+format.join(', ')+'\nBitrate filter: '+bitrate.join(', ')+'\nMedia filter: '+media.join(', ')+'\nRelease type filter: '+types.join(', ');
summaryText+="\n\nTotal size of torrents (ratio hit): "+prettySize(totalSize);
if(missed.length > 0)
{
summaryText+="\n\nAlbums unavailable within your criteria (consider making a request for your desired format):";
for(var i=0; i<missed.length; i++)
{
var m=missed[i];
summaryText+="\n/torrents.php?id="+m.groupid+" - "+m.artist+" - "+m.album;
}
}
if(suboptimal.length > 0)
{
summaryText+="\n\nAlbums suboptimal within your criteria (consider making a request for your optimal format):";
for(var i=0; i<suboptimal.length; i++)
{
var m=suboptimal[i];
summaryText+="\n/torrents.php?id="+m.groupid+" - "+m.artist+" - "+m.album;
}
}
messageDiv.setAttribute('summaryText', summaryText);
if(missed.length > 0)
{
messageDiv.innerHTML = "Missing "+missed.length+" of "+albumCount+" groups";
}
else
{
messageDiv.innerHTML = 'Added torrents from all '+albumCount+' groups';
}
if(suboptimal.length > 0)
{
messageDiv.innerHTML+= '<br />'+suboptimal.length+' of '+(albumCount-missed.length)+' selected are suboptimal';
}
messageDiv.innerHTML+="<br />Total size: "+prettySize(totalSize);
messageDiv.setAttribute('torrentList', JSON.stringify(torrents));
}
function doGroups(groups, torrents, hilight, albumCount, suboptimal, missed)
{
var searchPage=false;
if(window.location.href.indexOf('torrents.php') != -1 && window.location.href.indexOf('?id=') == -1)
searchPage=true;
var totalSize=0;
for(var j=0; j<groups.length; j++)
{
var g=groups[j];
var groupId=g.getElementsByTagName('div')[0].getAttribute('id').split('_')[1];
var artist=g.getAttribute('artist');
var album=g.getAttribute('album');
var editions=document.getElementsByClassName('groupid_'+groupId+' edition');
var added=0;
var allEditions=[];
for(var k=0; k<editions.length; k++)
{
var editionMeta=editions[k].textContent.split(' / ');
var editionMedia = editionMeta[editionMeta.length-1].trim();
var torrentRows = document.getElementsByClassName('torrent_row groupid_'+groupId+' edition_'+(k+1));
if(searchPage)
{
torrentRows = document.getElementsByClassName('groupid_'+groupId+' edition_'+(k+1));
}
for(var l=0; l<torrentRows.length; l++)
{
var e=torrentRows[l];
e.setAttribute('media', editionMedia);
allEditions.push(e);
}
}
var best=getBest(allEditions);
var addIndexes=[];
var score=best.score;
for(var k=0; k<allEditions.length; k++)
{
var e=allEditions[k];
var addAnyway = e.getAttribute('addAnyway');
if(addAnyway == "true")
{
var score1=getBest([e]).score;
addIndexes.push({index:k, score:score1});
if(score1 < score)
score=score1;
}
if(addIndexes.length === 0 && best.index != -1 && allEditions[best.index].getAttribute('addAnyway') != "false")
addIndexes.push(best);
}
var secondCount=0;
for(var l=0; l<addIndexes.length; l++)
{
var e=allEditions[addIndexes[l].index];
var as=e.getElementsByTagName('a');
var dl=as[0].href;
var linkCount=1;
while(dl.indexOf('authkey') == -1)
{
dl=as[linkCount].href;
linkCount++;
}
var meta=as[as.length-1].innerHTML.split(' / ');
var tdIndex=1;
if(searchPage)
tdIndex=3;
var size=unPretty(e.getElementsByTagName('td')[tdIndex].textContent);
var editionMedia=e.getAttribute('media');
totalSize+=size;
var addAnyway = e.getAttribute('addAnyway');
if(addAnyway == "false")
continue;
var torrentId=as[as.length-1].href.split('&torrentid=')[1];
var torrentName=artist+' - '+album+' - '+meta[0]+"_"+meta[1]+"_"+editionMedia+" - "+torrentId+".torrent";
torrents.push({dl:dl, name:torrentName});
if(hilight)
{
if(score === 0)
e.setAttribute('class', e.getAttribute('class')+' collectorAdded');
else if(addIndexes.length > 0)
e.setAttribute('class', e.getAttribute('class')+' collectorAddedSuboptimal');
}
secondCount++;
}
if(score === 0)
added=1;
else if(addIndexes.length > 0)
added=2;
if(secondCount === 0)
added=0;
albumCount++;
if(added === 0)
{
if(hilight)
g.setAttribute('class', g.getAttribute('class')+' collectorMissing');
missed.push({groupid:groupId, artist:artist, album:album});
}
else if(added == 2)
{
if(hilight)
g.setAttribute('class', g.getAttribute('class')+' collectorSuboptimal');
suboptimal.push({groupid:groupId, artist:artist, album:album});
}
}
return {totalSize:totalSize, torrents:torrents, albumCount:albumCount, suboptimal:suboptimal, missed:missed};
}
function unPretty(size)
{
var s=parseFloat(size);
if(size.indexOf('KB') != -1)
s = s*Math.pow(2, 10);
else if(size.indexOf('MB') != -1)
s = s*Math.pow(2, 20);
else if(size.indexOf('GB') != -1)
s = s*Math.pow(2, 30);
else if(size.indexOf('TB') != -1)
s = s*Math.pow(2, 40);
else if(size.indexOf('PB') != -1)
s = s*Math.pow(2, 50);
return Math.round(s);
}
function prettySize(size)
{
var newSize=size;
var i=0;
while(newSize > 1)
{
i++;
newSize = size/Math.pow(2, i*10);
}
i--;
if(i<0)
i=0;
newSize=size/Math.pow(2, (i)*10);
var suffixes=["B", "KB", "MB", "GB", "TB", "PB"];
newSize = Math.round(newSize*100)/100;
newSize = newSize+' '+suffixes[i];
return newSize;
}
function getBest(rows)
{
var pers=getPersistence();
var best={index:-1, score:100000};
for(var i=0; i<rows.length; i++)
{
var e=rows[i];
var editionMedia=e.getAttribute('media');
if(e.getAttribute('addAnyway') == "false")
continue;
var seedCount=parseInt(e.getElementsByTagName('td')[3].textContent);
if(seedCount < pers.minSeedCount)
continue;
var meta=e.getElementsByTagName('a');
meta=meta[meta.length-1].innerHTML.split(' / ');
if(meta[0] == pers.format[0] && meta[1] == pers.bitrate[0] && editionMedia == pers.media[0])
{
best.index=i;
best.score=0;
break;
}
if(pers.format.length === 0)
pers.format.push("Any");
if(pers.bitrate.length === 0)
pers.format.push("Any");
if(pers.media.length === 0)
pers.format.push("Any");
for(var j=0; j<pers.format.length; j++)
{
var f=pers.format[j];
if(f==='')
f='Any';
if(f=="Any" || meta[0]==f)
{
for(var k=0; k<pers.bitrate.length; k++)
{
var b=pers.bitrate[k];
if(b==='')
b='Any';
if(b=="Any" || meta[1]==b)
{
for(var l=0; l<pers.media.length; l++)
{
var m=pers.media[l];
if(m==='')
m='Any';
if(m=="Any" || editionMedia==m)
{
var score = (j*100)+(k*10)+l;
if(score < best.score)
{
best.index=i;
best.score=score;
}
}
}
}
}
}
}
}
return best;
}
function addAnywayFunc(tr, event)
{
if(!event.ctrlKey && !event.metaKey)
return;
event.preventDefault();
var addAnyway = tr.getAttribute("addAnyway");
var adding = tr.getAttribute('class').indexOf('collectorAdded') != -1;
if(adding)
{
tr.setAttribute("addAnyway", false);
document.getElementById('collectorPreviewLink').click();
return;
}
else
{
tr.setAttribute("addAnyway", true);
document.getElementById('collectorPreviewLink').click();
return;
}
}
function save(messageDiv)
{
var torrentList=messageDiv.getAttribute('torrentList');
if(!torrentList)
messageDiv.innerHTML = "You need to preview first";
torrentList=JSON.parse(torrentList);
var opSettings = getSettings();
if(opSettings.sequential)
{
messageDiv.setAttribute('stopSequential', "false");
sequentialGet(torrentList, 0, messageDiv);
}
else
{
var zip=new JSZip();
var settings=getSettings();
if(settings.summary)
{
var name=messageDiv.getAttribute('zipName').replace(/zip$/, "txt");
var text=messageDiv.getAttribute('summaryText');
zip.file(name.replace(/\//g, '_'), text);
}
getTorrent(torrentList, 0, zip, messageDiv);
}
}
function sequentialGet(list, index, messageDiv)
{
if(messageDiv.getAttribute('stopSequential') == "true")
{
messageDiv.innerHTML = 'Stopped';
return;
}
if(index >= list.length)
{
messageDiv.innerHTML = 'Finished';
return;
}
messageDiv.innerHTML = "Downloading torrent "+(index+1)+" of "+list.length+"<br />";
var a=document.createElement('a');
messageDiv.appendChild(a);
a.innerHTML='Stop';
a.href='javascript:void(0);';
a.addEventListener('click', stopSequential.bind(undefined, messageDiv), false);
var a=document.createElement('a');
a.href=list[index].dl;
a.download=list[index].name;
document.body.appendChild(a);
a.click();
window.setTimeout(sequentialGet.bind(undefined, list, index+1, messageDiv), 1000);
}
function stopSequential(messageDiv)
{
messageDiv.setAttribute('stopSequential', "true");
}
function getTorrent(list, index, zip, messageDiv)
{
if(index >= list.length)
{
gotTorrents(zip, messageDiv);
return;
}
messageDiv.innerHTML = "Getting torrent "+(index+1)+" of "+list.length+"<br />"+list[index].name;
var xhr = new XMLHttpRequest();
xhr.open('GET', list[index].dl);
xhr.responseType = "arraybuffer";
xhr.onreadystatechange = xhr_func.bind(undefined, messageDiv, xhr, gotTorrent.bind(undefined, list, index, zip, messageDiv), getTorrent.bind(undefined, list, index, zip, messageDiv), true);
xhr.send();
}
function gotTorrent(list, index, zip, messageDiv, response)
{
zip.file(list[index].name.replace(/\//g, '_'), response);
window.setTimeout(getTorrent.bind(undefined, list, index+1, zip, messageDiv), 1000);
}
function gotTorrents(zip, messageDiv)
{
messageDiv.innerHTML = 'Generating zip file of torrents';
zip.generateAsync({type:"blob"}).then(saveLink.bind(undefined, messageDiv));
}
function saveLink(messageDiv, blob)
{
messageDiv.innerHTML = '';
var a=document.createElement('a');
messageDiv.appendChild(a);
var name=messageDiv.getAttribute('zipName');
a.innerHTML = name;
a.href = URL.createObjectURL(blob);
a.download = name;
}
function xhr_func(messageDiv, xhr, func, repeatFunc, binary)
{
if(xhr.readyState == 4)
{
if(xhr.status == 200)
{
if(binary)
{
var byteArray = new Uint8Array(xhr.response);
func(byteArray);
}
else
{
func(xhr.responseText);
}
}
else
{
messageDiv.innerHTML = 'Error: '+xhr.status+'<br />retrying in 1 second';
window.setTimeout(repeatFunc, 1000);
}
}
}