Last active
January 8, 2024 19:33
-
-
Save 730730/241caafc5ee60ea83d537a80051aecc4 to your computer and use it in GitHub Desktop.
Tampermonkey script that adds filtering and sorting capabilities to AnimeBytes torrent groups
This file contains hidden or 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
// ==UserScript== | |
// @name AB Filter/Sorter | |
// @version 1.0 | |
// @description Adds a table of filters to AnimeBytes torrent groups and the possibility to sort by size/snatches/seeders/leechers | |
// @author 730 | |
// @match https://animebytes.tv/torrents.php?id=* | |
// @updateURL https://gist.githubusercontent.com/730730/241caafc5ee60ea83d537a80051aecc4/raw/ab-filter.user.js | |
// @downloadURL https://gist.githubusercontent.com/730730/241caafc5ee60ea83d537a80051aecc4/raw/ab-filter.user.js | |
// @grant none | |
// ==/UserScript== | |
(function() { | |
'use strict'; | |
/*TODO: | |
show filter in series page too | |
create selects dinamically with only the available options out of the existing torrents | |
hide snatched (checkbox that toggles hiding) | |
*/ | |
const torrentAttributes = { | |
"media": { | |
"TV": 1, | |
"DVD": 2, | |
"Blu-ray": 3, | |
"UHD Blu-ray": 4, | |
"HD DVD": 5, | |
"VHS": 6, | |
"VCD": 7, | |
"LD": 8, | |
"Web": 9 | |
}, | |
"container": { | |
"AVI": 1, | |
"MKV": 2, | |
"MP4": 3, | |
"OGM": 4, | |
"WMV": 5, | |
"MPG": 6, | |
"MPEG": 7, | |
"ISO": 8, | |
"VOB": 9, | |
"VOB IFO": 10, | |
"TS": 11, | |
"M2TS": 12 | |
}, | |
"codec": { | |
"h264": 1, | |
"h264 10-bit": 2, | |
"h265": 3, | |
"h265 10-bit": 4, | |
"XviD": 5, | |
"DivX": 6, | |
"WMV": 7, | |
"MPEG": 8, | |
"VC-1": 9, | |
"MPEG-TS": 10, | |
"DVD5": 11, | |
"DVD9": 12 | |
}, | |
"resolution": { | |
"640x480": 1, | |
"720x480": 2, | |
"720x486": 3, | |
"720x576": 4, | |
"704x396": 5, | |
"848x480": 6, | |
"1024x576": 7, | |
"720p": 8, | |
"1080i": 9, | |
"1080p": 10, | |
"4K": 11, | |
"Other": 12 | |
}, | |
"region": { | |
"R1": 1, | |
"R2 Japan": 2, | |
"R2 Europe": 3, | |
"R3": 4, | |
"R4": 5, | |
"R5": 6, | |
"R6": 7, | |
"A": 8, | |
"B": 9, | |
"C": 10 | |
}, | |
"aspectRatio": { | |
"4:3": 1, | |
"16:9": 2, | |
"1.85:1": 3, | |
"2.39:1": 4, | |
"2.4:1": 5 | |
}, | |
"audio": { | |
"MP3": 1, | |
"Vorbis": 2, | |
"Opus": 3, | |
"AAC": 4, | |
"AC3": 5, | |
"TrueHD": 6, | |
"DTS": 7, | |
"DTS-ES": 8, | |
"FLAC": 9, | |
"PCM": 10, | |
"WMA": 11, | |
"Real Audio": 12, | |
"DTS-HD": 13, | |
"DTS-HD MA": 14 | |
}, | |
"audioChannels": { | |
"1.0": 1, | |
"2.0": 2, | |
"2.1": 3, | |
"5.0": 4, | |
"5.1": 5, | |
"6.0": 6, | |
"6.1": 7, | |
"7.1": 8 | |
}, | |
"subs": { | |
"Softsubs": 1, | |
"Hardsubs": 2, | |
"RAW": 3 | |
}, | |
"dualAudio": { | |
"Yes": 1, | |
"No": 2 | |
} | |
} | |
const units = { | |
"MiB": 1024, | |
"GiB": 1048576, | |
"TiB": 1073741824 | |
} | |
function Torrent() { | |
this.html = null; | |
this.pad = null; | |
this.size = null; | |
this.snatches = null; | |
this.seeders = null; | |
this.leechers = null; | |
this.media = null; | |
this.container = null; | |
this.codec = null; | |
this.resolution = null; | |
//these 2 exists only when container is ISO/VOB IFO/M2TS | |
this.region = null; | |
this.aspectRatio = null; | |
this.audio = null; | |
this.audioChannels = null; | |
this.dualAudio = null; | |
this.subs = null; | |
this.subgroup = null; | |
} | |
//example: media, container (region), [aspectRatio], codec, resolution, | |
// audio (audioChannels), [dualAudio], subs (subgroup), [irrelevant] | |
//INIT SCRAPING | |
var torrents = $(".group_torrent"); | |
var info = torrents.find("td > a"); | |
var torrentNumbers = torrents.find("td + td"); | |
var pads = $("tr.pad"); | |
//fill info with arrays of each torrent's properties | |
for (var i = 0; i < info.length; i++) { | |
info[i] = $(info[i]).text().replace(/[\n\t»]/g, "").split(" | "); | |
//remove empty info (remaster tag) | |
for (var j = 0; j < info[i].length; j++) { | |
if (info[i][j] === "") { | |
info[i].splice(j, 1); | |
} | |
} | |
} | |
//fill torrents array with corresponding Torrent objects | |
for (var i = 0; i < torrents.length; i++) { | |
var auxTorrent = $(torrents[i]); | |
torrents[i] = new Torrent(); | |
torrents[i].html = auxTorrent; | |
torrents[i].pad = $(pads[i]); | |
let size = parseFloat($(torrentNumbers[(i * 4)]).text().split(" ")[0]); | |
let unit = $(torrentNumbers[(i * 4)]).text().split(" ")[1]; | |
torrents[i].size = size * units[unit]; | |
torrents[i].snatches = parseInt($(torrentNumbers[(i * 4) + 1]).text().replace(/,/g, "")); | |
torrents[i].seeders = parseInt($(torrentNumbers[(i * 4) + 2]).text().replace(/,/g, "")); | |
torrents[i].leechers = parseInt($(torrentNumbers[(i * 4) + 3]).text().replace(/,/g, "")); | |
torrents[i].media = torrentAttributes.media[info[i][0]]; | |
//ISO/VOB IFO/M2TS route | |
if (info[i][1].match(/\(/)) { //check if it has a parenthesis | |
torrents[i].container = torrentAttributes.container[info[i][1].split(" ")[0]]; | |
//match inside of parentheses | |
torrents[i].region = torrentAttributes.region[info[i][1].match(/\(([^)]+)\)/)[1]]; | |
torrents[i].aspectRatio = torrentAttributes.aspectRatio[info[i][2]]; | |
torrents[i].codec = torrentAttributes.codec[info[i][3]]; | |
torrents[i].resolution = torrentAttributes.resolution[info[i][4]] || 12; | |
torrents[i].audio = torrentAttributes.audio[info[i][5].split(" ")[0]]; | |
torrents[i].audioChannels = torrentAttributes.audioChannels[info[i][5].split(" ")[1]]; | |
//dual audio route | |
if (info[i][6] == "Dual Audio") { | |
torrents[i].dualAudio = 1; | |
torrents[i].subs = torrentAttributes.subs[info[i][7]]; | |
} else { | |
//non-dual audio route | |
torrents[i].dualAudio = 2; | |
torrents[i].subs = torrentAttributes.subs[info[i][6]]; | |
} | |
} else { | |
//non-ISO/VOB IFO/M2TS route | |
torrents[i].container = torrentAttributes.container[info[i][1]]; | |
torrents[i].codec = torrentAttributes.codec[info[i][2]]; | |
torrents[i].resolution = torrentAttributes.resolution[info[i][3]] || 12; | |
torrents[i].audio = torrentAttributes.audio[info[i][4].split(" ")[0]]; | |
torrents[i].audioChannels = torrentAttributes.audioChannels[info[i][4].split(" ")[1]]; | |
//dual audio route | |
if (info[i][5] == "Dual Audio") { | |
torrents[i].dualAudio = 1; | |
torrents[i].subs = torrentAttributes.subs[info[i][6].split(" ")[0]]; | |
//torrents[i].subgroup = info[i][6].match(/\(([^)]+)\)/)[1]; | |
} else { | |
//non-dual audio route | |
torrents[i].dualAudio = 2; | |
torrents[i].subs = torrentAttributes.subs[info[i][5].split(" ")[0]]; | |
//torrents[i].subgroup = info[i][5].match(/\(([^)]+)\)/)[1]; | |
} | |
} | |
} | |
//END SCRAPING | |
//INIT HTML CREATION | |
var table = $( | |
`<table id="filter"> | |
<tbody> | |
<tr> | |
<td> | |
<label for="media"><strong>Media</strong></label> | |
<select id="media"> | |
<option value="-1" selected>Don't care</option> | |
</select> | |
</td> | |
<td> | |
<label for="resolution"><strong>Resolution</strong></label> | |
<select id="resolution"> | |
<option value="-1" selected>Don't care</option> | |
</select> | |
</td> | |
<td> | |
<label for="audio"><strong>Audio</strong></label> | |
<select id="audio"> | |
<option value="-1" selected>Don't care</option> | |
</select> | |
<select id="audioChannels"> | |
<option value="-1" selected>Don't care</option> | |
</select> | |
</td> | |
</tr> | |
<tr> | |
<td> | |
<label for="codec"><strong>Codec</strong></label> | |
<select id="codec"> | |
<option value="-1" selected>Don't care</option> | |
</select> | |
</td> | |
<td> | |
<label for="dualAudio"><strong>Dual Audio</strong></label> | |
<select id="dualAudio"> | |
<option value="-1" selected>Don't care</option> | |
</select> | |
</td> | |
<td> | |
<label for="subs"><strong>Subs</strong></label> | |
<select id="subs"> | |
<option value="-1" selected>Don't care</option> | |
</select> | |
</td> | |
</tr> | |
<tr> | |
<td> | |
<label for="container"><strong>Container</strong></label> | |
<select id="container"> | |
<option value="-1" selected>Don't care</option> | |
</select> | |
</td> | |
<td> | |
<label for="aspectRatio"><strong>Aspect Ratio</strong></label> | |
<select id="aspectRatio"> | |
<option value="-1" selected>Don't care</option> | |
</select> | |
</td> | |
<td> | |
<label for="region"><strong>Region</strong></label> | |
<select id="region"> | |
<option value="-1" selected>Don't care</option> | |
</select> | |
</td> | |
<td> | |
<button id="filter-reset" style="width: 70px; height: 30px;">Reset</button> | |
</td> | |
</tr> | |
</tbody> | |
</table>`); | |
//add filter table to document | |
$(".main_column").prepend(table); | |
//set change handlers for all filtering <select>s | |
$("#filter select").change(filterTorrents); | |
//set click handler for "Size" label and change cursor | |
$(".torrent_table > tbody > tr:first-child > td:nth-child(2) strong").click(function(){sortTorrents(0)}); | |
$(".torrent_table > tbody > tr:first-child > td:nth-child(2) strong").css("cursor", "pointer"); | |
//set click handlers and change cursor for the other 3 icons | |
$($(".sign img")[0]).click(function(){sortTorrents(1)}); | |
$($(".sign img")[0]).css("cursor", "pointer"); | |
$($(".sign img")[1]).click(function(){sortTorrents(2)}); | |
$($(".sign img")[1]).css("cursor", "pointer"); | |
$($(".sign img")[2]).click(function(){sortTorrents(3)}); | |
$($(".sign img")[2]).css("cursor", "pointer"); | |
//fill filtering <select>s with their corresponding <option>s | |
for (var attr in torrentAttributes) { | |
for (var val in torrentAttributes[attr]) { | |
$("#" + attr).append("<option value='" + torrentAttributes[attr][val] + | |
"'>" + val + "</option>"); | |
} | |
} | |
$("#filter-reset").click(resetFilter); | |
//END HTML CREATION | |
function hideTorrent(torrent) { | |
torrent.html.hide(); | |
torrent.pad.addClass("hide"); | |
} | |
function showTorrent(torrent) { | |
torrent.html.show(); | |
} | |
function getFilterValues() { | |
let values = new Torrent(); | |
for (var attr in torrentAttributes) { | |
values[attr] = parseInt($("#" + attr).val()); | |
} | |
return values; | |
} | |
function filterTorrents() { | |
let filterValues = getFilterValues(); | |
for (var i = 0; i < torrents.length; i++) { | |
let matches = true; | |
for (var attr in torrentAttributes) { | |
if (torrents[i][attr] != filterValues[attr] && filterValues[attr] != -1) { | |
matches = false; | |
} | |
} | |
if (!matches) { | |
hideTorrent(torrents[i]); | |
} else { | |
showTorrent(torrents[i]); | |
} | |
} | |
} | |
function sortBySize() { | |
if (typeof sortBySize.descending == 'undefined') { | |
sortBySize.descending = false; | |
} | |
if (!sortBySize.descending) { | |
torrents.sort(function (a, b) { | |
return a.size - b.size; | |
}); | |
sortBySize.descending = true; | |
} else { | |
torrents.sort(function (a, b) { | |
return b.size - a.size; | |
}); | |
sortBySize.descending = false; | |
} | |
} | |
function sortBySnatches() { | |
if (typeof sortBySnatches.descending == 'undefined') { | |
sortBySnatches.descending = false; | |
} | |
if (!sortBySnatches.descending) { | |
torrents.sort(function (a, b) { | |
return a.snatches - b.snatches; | |
}); | |
sortBySnatches.descending = true; | |
} else { | |
torrents.sort(function (a, b) { | |
return b.snatches - a.snatches; | |
}); | |
sortBySnatches.descending = false; | |
} | |
} | |
function sortBySeeders() { | |
if (typeof sortBySeeders.descending == 'undefined') { | |
sortBySeeders.descending = false; | |
} | |
if (!sortBySeeders.descending) { | |
torrents.sort(function (a, b) { | |
return a.seeders - b.seeders; | |
}); | |
sortBySeeders.descending = true; | |
} else { | |
torrents.sort(function (a, b) { | |
return b.seeders - a.seeders; | |
}); | |
sortBySeeders.descending = false; | |
} | |
} | |
function sortByLeechers() { | |
if (typeof sortByLeechers.descending == 'undefined') { | |
sortByLeechers.descending = false; | |
} | |
if (!sortByLeechers.descending) { | |
torrents.sort(function (a, b) { | |
return a.leechers - b.leechers; | |
}); | |
sortByLeechers.descending = true; | |
} else { | |
torrents.sort(function (a, b) { | |
return b.leechers - a.leechers; | |
}); | |
sortByLeechers.descending = false; | |
} | |
} | |
function displayTorrents() { | |
let torrentsHeader = $(".torrent_table > tbody > tr:first-child"); | |
for (var i = 0; i < torrents.length; i++) { | |
torrentsHeader.after(torrents[i].html); | |
torrents[i].html.after(torrents[i].pad); | |
} | |
} | |
function sortTorrents(criterion) { | |
switch (criterion) { | |
case 0: //size | |
sortBySize(); | |
break; | |
case 1: //snatches | |
sortBySnatches(); | |
break; | |
case 2: //seeders | |
sortBySeeders(); | |
break; | |
case 3: //leechers | |
sortByLeechers(); | |
break; | |
} | |
displayTorrents(); | |
} | |
function resetFilter() { | |
for (var attr in torrentAttributes) { | |
$("#" + attr).val("-1"); | |
} | |
filterTorrents(); | |
} | |
})(); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Exactly what i was googling for. thanks 730 🙇♂️