// ==UserScript==
// @name RARBG Advanced Filters [BETA]
// @namespace http://tampermonkey.net/
// @version 1.27
// @description Additional quality of life filters: - Show or hide category icons; - Show or hide torrent thumbnails; - Show or hide movie and tv filters (Removes torrents with KORSUB and 720p); - Show or hide porn; - Filter based on minimum IMDB rating;
// @author Kxmode
// @match *://rarbg.to/*
// @grant none
// @require //ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
// ==/UserScript==
$(function() {
// .PLAN:
// - Grid layout
// - Torrent category, IMDB, icons sorting
// - Hides torrents with seeders equal to or lower than a number
// - Large grid icon
// - Minimalist layout: e.g. torrent thumbnail, name, # of seeders
// - Filter counter
// - Category specific filters (e.g. genre for Music; torrent group for Games; and so forth) [IN DEVELOPMENT]
// - Normalizing search URL parameters [IN DEVELOPMENT]
// General variables bucket
var nonStandardUrlParamType = (GetParameterByName("category%5B%5D") !== null) ? true : false,
arrayValuePresent,
isCategoryMovies,
showAdvancedOptions = false,
showIcon,
showTorrentThumbnail, // TODO: child of showIcon (=true)
showMoviesTVFilters,
showPorn,
minRating,
genreFilter = "",
i;
// String arrays of known categories
var arrayMovies = ["movies", 14, 17, 42, 44, 45, 46, 47, 48].map(String),
arrayTVShows = [18, 41, 49].map(String),
arrayGames = [27, 28, 29, 30, 31, 32, 40].map(String),
arrayMusic = [23, 24, 25, 26].map(String),
arraySoftware = [33, 34, 43].map(String),
arrayNonPorn = [14, 15, 16, 17, 21, 22, 42, 18, 19, 41, 27, 28, 29, 30, 31, 32, 40, 23, 24, 25, 26, 33, 34, 43, 44, 45, 46, 47, 48, 49].map(String);
// Normalization/boilerplate for RARBG's inconsistent URL parameter types (e.g. category=movies, &category%5B%5D=48, and category=1;18;41;49; Not sure why this needs to be like this)
if (nonStandardUrlParamType)
{
var currentUrl = new RegExp("[\?&]category%5B%5D=([^]*)").exec(window.location.href); // Grab all URL parameters
if (currentUrl === null) // If none exist, then stop and return nothing
return null;
else // Otherwise...
{
arrayValuePresent = String(currentUrl).match(/(=)\w+/g).map(String); // Create an array of values separated by the equal sign
for (i = 0; i < arrayValuePresent.length; i++)
{
arrayValuePresent[i] = arrayValuePresent[i].replace("=", ""); // Remove the equal sign from the array
}
}
}
else if (GetParameterByName("category") !== null)
{
arrayValuePresent = GetParameterByName("category").split(";").map(String);
}
// Compares current url parameters with known categories. If the value is greater than -1 this means at least one match is found
if (GetParameterByName("category") !== null)
{
for (i = 0; i < arrayValuePresent.length; i++)
{
isCategoryMovies = arrayMovies.indexOf(arrayValuePresent[i]);
}
}
// Dynamic boolean
var categoryMoviesArray = (isCategoryMovies !== -1) ? true : false;
// TODO: Update these legacy booleans
var categoryTVShows = (GetParameterByName("category") === "1;18;41;49") ? true : false;
var categoryGames = (GetParameterByName("category") === "1;27;28;29;30;31;32;40") ? true : false;
var categoryMusic = (GetParameterByName("category") === "1;23;24;25;26") ? true : false;
var categorySoftware = (GetParameterByName("category") === "1;33;34;43") ? true : false;
var categoryNonPorn = (GetParameterByName("category") === "1;14;15;16;17;21;22;42;18;19;41;27;28;29;30;31;32;40;23;24;25;26;33;34;43;44;45;46;47;48;49") ? true : false;
// Grabs the Parameter name and value (Note: single use only. See line 48 for multiple URL parameters and if needed move to function.)
function GetParameterByName(name, url) {
// credit: https://stackoverflow.com/a/901144
if (!url) url = window.location.href;
name = name.replace(/[\[\]]/g, "\\$&");
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"),
results = regex.exec(url);
if (!results) return null;
if (!results[2]) return '';
return decodeURIComponent(results[2].replace(/\+/g, " "));
}
// Activates and deactives filters inside this plugin's HTML box
function ToggleFilter(target, data, bool, optional)
{
optional = (optional !== undefined) ? true : false;
var targetID = target.replace("#","");
if (bool) {
if (!optional)
{
$(target).find("i").removeClass("fa-eye-slash").addClass("fa-eye");
$(target).removeClass("disabled");
}
$(target).attr(data, "true");
window.localStorage.setItem(targetID, true);
}
else
{
if (!optional)
{
$(target).find("i").removeClass("fa-eye").addClass("fa-eye-slash");
$(target).addClass("disabled");
}
$(target).attr(data, "false");
window.localStorage.setItem(targetID, false);
}
}
// Show and Hides this plugin's HTML box
function ToggleAdvancedFilters(bool, isClicked)
{
isClicked = (isClicked !== undefined) ? true : false;
var parentTarget = $(".new-search form");
var target = $(".advanced-search");
if (GetParameterByName("category") !== null && isClicked === false)
{
$("#shadvbutton").attr("data-shadvbutton", "true");
window.localStorage.setItem("shadvbutton", true);
parentTarget.removeAttr("style");
parentTarget.removeClass("disabled");
target.show();
}
else if (GetParameterByName("category") === null && isClicked === false)
{
$("#shadvbutton").attr("data-shadvbutton", "false");
window.localStorage.setItem("shadvbutton", false);
parentTarget.attr("style", "width: 100%; border-right: 1px solid #9faabc;");
target.hide();
}
else
{
if (bool) {
showhideadvsearch('show');
parentTarget.removeAttr("style");
parentTarget.removeClass("disabled");
target.show();
} else {
parentTarget.attr("style", "width: 100%; border-right: 1px solid #9faabc;");
target.hide();
}
}
}
$("#searchTorrent").parent().addClass("new-search");
// Removes extra space between Recommended torrents and search bar
$("#searchTorrent").parent().parent().find("div:nth-of-type(2)").remove();
for(i = 1; i <= 4; i++)
{
$("#searchTorrent").parent().parent().find("br:nth-of-type(1)").remove();
}
// Attach Font Awesome script and required CSS styles to RARBG. Font Awesome is used for the active and inactive "eye" icons.
$("head").append( '<script src="//use.fontawesome.com/2d73a39974.js"></script>');
$("head").append( '<style>\n' +
'.content-rounded .new-search,\n' +
'.content-rounded div.new-search div { margin-left: auto; }\n' +
'.new-search { width: 1170px; display: flex; display: -webkit-flex; display: -moz-flex; margin: 30px auto; }\n' +
'.new-search div { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; }\n' +
'.new-search div { border-radius: 0; -moz-border-radius: 0; -webkit-border-radius: 0; }\n' +
'.new-search form { width: 75%; border-radius: 0; -moz-border-radius: 0; -webkit-border-radius: 0; }\n' +
'.new-search form { border: 0; border-top: 1px solid #9faabc; border-bottom: 1px solid #9faabc; border-left: 1px solid #9faabc; }\n' +
'.new-search .divadvscat { width: 153px; display: inline-block; height: auto; padding: 7px; float: none; }\n' +
'.new-search .divadvclearcats { padding: 10px; }\n' +
'.new-search .advanced-search { width: 25%; background: #e7f3fb; font-size: 110%; padding: 5px; border: 1px solid #9faabc; float: left; }\n' +
'.new-search .advanced-search { border: 0; border-top: 1px solid #9faabc; border-bottom: 1px solid #9faabc; border-right: 1px solid #9faabc; }\n' +
'.new-search .advanced-search h4 { padding: 0; margin: 0 0 10px 0; text-align: center; }\n' +
'.advanced-search .section-wrapper { border: 1px dotted #9faabc; padding: 10px; }\n' +
'.advanced-search .section-wrapper:first-child { border-bottom: 0; }\n' +
'.advanced-search .no-border { border: 0; }\n' +
'.advanced-search .divadvscat { width: auto; border: 1px solid transparent; cursor: pointer; }\n' +
'.advanced-search .divadvscat i { padding-right: 2px; }\n' +
'.advanced-search .disabled { border: 1px solid #DDD; background-color: #f5f5f5; color: #999; }\n' +
'.advanced-search .centered { text-align: center; }\n' +
'.section-wrapper input { width: 30%; border: 0; margin: 0 10px; border: 1px solid #9faabc; }\n' +
'.clearfix:before, .clearfix:after { display: table; content: ""; line-height: 0;}\n' +
'</style>');
// Creates the HTML for category specific filters
genreFilter = '<div class="section-wrapper">\n';
if (GetParameterByName("category") !== null || nonStandardUrlParamType)
{
if (categoryMoviesArray || categoryTVShows)
{
genreFilter += '<div id="jQminRating" class="divadvscat centered">Min Rating <input name="minprice" type="text" /></div>\n';
}
else if (categoryGames)
{
genreFilter += '<div id="jQminRating" class="divadvscat centered">Game Filters Coming Soon</div>\n'; // Update id and input
}
else if (categoryMusic)
{
genreFilter += '<div id="jQminRating" class="divadvscat centered">Music Filters Coming Soon</div>\n'; // Update id and input
}
else if (categorySoftware)
{
genreFilter += '<div id="jQminRating" class="divadvscat centered">Software Filters Coming Soon</div>\n'; // Update id and input
}
else if (categoryNonPorn)
{
genreFilter += '<div id="jQminRating" class="divadvscat centered">Non Porn Filters Coming Soon</div>\n'; // Update id and input
}
}
else
{
genreFilter += '<div id="jQminRating" class="divadvscat centered">All Filters Coming Soon</div>\n'; // Update id and input
}
genreFilter += '</div>\n';
// Creates this plugin's HTML box
var AdvancedFiltersHTML = '<div class="advanced-search">\n' +
'<div class="section-wrapper">\n' +
'<div id="jQIcon" class="divadvscat"><i class="fa fa-eye fa-1x"></i> Category Icons</div>\n' +
'<div id="jQTorrentThumbnail" class="divadvscat"><i class="fa fa-eye fa-1x"></i> Torrent Images</div>\n' + // Eventually make this a child of Show Thumbnails
'<div id="jQMoviesTVFilters" class="divadvscat" title="Hides low-quality KORSUB torrents and 720p torrents"><i class="fa fa-eye fa-1x"></i> Media Filters</div>\n' + // Eventually break this up
'<div id="jQShowPorn" class="divadvscat"><i class="fa fa-eye fa-1x"></i> Porn</div>\n' +
'</div>\n' +
genreFilter +
'<div class="section-wrapper no-border">\n' +
'<span class="jQUpdateFilters btn btn-primary btn-mini">Update Page with Filters</span>\n' +
'<span class="jQResetFilters btn btn-mini">Reset Filters</span>\n' +
'</div>\n' +
'<div class="clearfix"></div>\n' +
'</div>';
// Attaches HTML box to RARBG
$("#searchTorrent").parent().append(AdvancedFiltersHTML);
// Likely going to need to move the ToggleFilter and ToggleAdvancedFilters functions into this gate
if (nonStandardUrlParamType)
{
ToggleFilter("#shadvbutton", "data-shadvbutton", showAdvancedOptions, true);
ToggleAdvancedFilters(true, true);
}
else
{
showAdvancedOptions = ((window.localStorage.getItem("shadvbutton") == "true") ? true : false);
ToggleFilter("#shadvbutton", "data-shadvbutton", showAdvancedOptions, true);
ToggleAdvancedFilters(showAdvancedOptions);
}
// Logic for HTML box icons
showIcon = ((window.localStorage.getItem("jQIcon") == "false") ? false : true);
ToggleFilter("#jQIcon", "data-icon", showIcon);
showTorrentThumbnail = ((window.localStorage.getItem("jQTorrentThumbnail") == "false") ? false : true);
ToggleFilter("#jQTorrentThumbnail", "data-torrent-thumbs", showTorrentThumbnail);
showMoviesTVFilters = ((window.localStorage.getItem("jQMoviesTVFilters") == "false") ? false : true);
ToggleFilter("#jQMoviesTVFilters", "data-tvmovie", showMoviesTVFilters);
showPorn = ((window.localStorage.getItem("jQShowPorn") == "false") ? false : true);
ToggleFilter("#jQShowPorn", "data-porn", showPorn);
$("#shadvbutton").on("click", function() {
showAdvancedOptions = ($(this).attr("data-shadvbutton") == "false") ? true : false;
ToggleFilter("#shadvbutton", "data-shadvbutton", showAdvancedOptions, true);
ToggleAdvancedFilters(showAdvancedOptions, true);
});
$("#jQIcon").on("click", function() {
showIcon = ($(this).attr("data-icon") == "false") ? true : false;
ToggleFilter("#jQIcon", "data-icon", showIcon);
});
$("#jQTorrentThumbnail").on("click", function() {
showTorrentThumbnail = ($(this).attr("data-torrent-thumbs") == "false") ? true : false;
ToggleFilter("#jQTorrentThumbnail", "data-torrent-thumbs", showTorrentThumbnail);
});
$("#jQMoviesTVFilters").on("click", function() {
showMoviesTVFilters = ($(this).attr("data-tvmovie") == "false") ? true : false;
ToggleFilter("#jQMoviesTVFilters", "data-tvmovie", showMoviesTVFilters);
});
$("#jQShowPorn").on("click", function() {
showPorn = ($(this).attr("data-porn") == "false") ? true : false;
ToggleFilter("#jQShowPorn", "data-porn", showPorn);
});
// Gets and sets min rating value from localStorage and if nothing is found defaults to 0
if (window.localStorage.getItem("minimum-rating") > 0) {
var mr = window.localStorage.getItem("minimum-rating");
$("#jQminRating").find("input").attr("value", mr);
minRating = mr;
}
else
{
$("#jQminRating").find("input").attr("value", 0);
}
// Events for Update Filters button
$(".jQUpdateFilters").on("click", function () {
var minRating = $("#jQminRating").parent().find("input").val();
window.localStorage.setItem("minimum-rating", minRating);
location.reload();
});
// Events for Reset Filters button
$(".jQResetFilters").on("click", function() {
window.localStorage.removeItem("jQIcon");
window.localStorage.removeItem("jQTorrentThumbnail");
window.localStorage.removeItem("jQMoviesTVFilters");
window.localStorage.removeItem("jQShowPorn");
window.localStorage.removeItem("minimum-rating");
location.reload();
});
// CATEGORY SPECIFIC =================================================================================================
// Hides torrents with seeders equal to or lower than a number [TODO: make this a form input filter]
// use inArray method from work (Configurator height normalizer)
/*
if (parseInt(title.indexOf("720p")) > 0)
{
$(this).parents(".lista2").remove();
}
*/
// Logic to hide porn
if (!showPorn)
{
$.each($(".tdlinkfull2"), function() {
var targetText = $(this).text().toLowerCase();
if (targetText == "xxx")
{
$(this).parent().parent().remove();
}
});
$.each($(".divadvscat a"), function() {
var targetText = $(this).text().toLowerCase();
if(targetText == "xxx (18+)")
{
$(this).parent().remove();
}
});
}
// Loops through all available torrents
$.each($(".lista a"), function(index, value) {
var title = $(this).attr("title");
var icon = $(this).find("img").attr("src");
if (title !== undefined)
{
if (showMoviesTVFilters)
{
// Hides low-quality KORSUB torrents [TODO: make this a genre checkbox filter]
if (parseInt(title.indexOf("KORSUB")) > 0)
{
$(this).parents(".lista2").remove();
}
// Hides 720p torrents [TODO: make this a genre checkbox filter]
if (parseInt(title.indexOf("720p")) > 0)
{
$(this).parents(".lista2").remove();
}
}
// Creates the logic for category specific filters
if (GetParameterByName("category") !== null || nonStandardUrlParamType)
{
if (categoryMoviesArray || categoryTVShows)
{
// Min ratings logic
$.each($("span"), function(index, value) {
var ratings = $(this).text();
var imdb = ratings.indexOf("IMDB: ") + 6;
if (ratings !== undefined && imdb !== -1)
{
minRating = parseFloat(minRating);
var rateValue = parseFloat(ratings.substring(imdb,ratings.length-3));
if (!isNaN(rateValue))
{
if (showMoviesTVFilters) { $(this).attr("style", "display: block;"); }
if (rateValue <= minRating)
{
$(this).parents(".lista2").remove();
}
}
}
});
}
// Coming soon
else if (categoryGames) { }
else if (categoryMusic) { }
else if (categorySoftware) { }
else if (categoryNonPorn) { }
}
}
// Logic to hide porn
if (!showPorn)
{
if (title !== undefined)
{
title = title.indexOf("XXX");
if (title >= 0)
{
$(this).parents(".lista2").remove();
}
}
if (icon !== undefined)
{
icon = icon.indexOf("cat_new4.gif");
if (icon >= 0)
{
$(this).parents(".lista2").remove();
}
}
}
});
// NON-CATEGORY SPECIFIC =================================================================================================
// Logic to hide icons
if (!showIcon)
{
$(".lista2t tr td:nth-of-type(1)").attr("style","display:none;");
}
else
{
// TODO: Make child of showIcon (=true)
// Logic to show torrent thumbnails
if (showTorrentThumbnail)
{
$(".lista2t").find("tr:first-child td:first-child").text("Thumbnail");
$.each($(".lista2t .lista2"), function() {
var anchor = $(this);
$.each(anchor.find(".lista"), function() {
var image = $(this).find("a");
var target = anchor.find(":nth-child(1) a");
if (image.attr("onmouseover") !== undefined)
{
var href = image.attr("href");
var sourceThumb = image.attr("onmouseover");
var val1 = sourceThumb.lastIndexOf("//dyncdn.me/");
var val2 = sourceThumb.indexOf("\' border=0>')")-1;
var imageID = sourceThumb.substring(val1,val2);
var thumbnailImage = "<img src=\'" + imageID + "' />";
image.removeAttr("onmouseover").removeAttr("onmouseout");
target.find("img").replaceWith(thumbnailImage);
target.attr("href", href);
anchor.find("td:nth-child(1)").attr( "align", "center" );
}
});
});
}
}
/*
TODO: Filter counter [ALPHA]
$(".container-sales").prepend("<div class='sales-section table-sales' id='min-usd-totals'>\n" +
"<div class='pre-table-title' style='font-size: 15px;'>\n" +
"<strong>357 products shown\n" +
"<span class='pull-right'>135 products hidden</span>\n" +
"</strong>\n" +
"</div>\n" +
"</div>");
*/
});