RARBG Advanced Filters [BETA]

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;

Verze ze dne 15. 07. 2017. Zobrazit nejnovější verzi.

// ==UserScript==
// @name         RARBG Advanced Filters [BETA]
// @namespace    http://tampermonkey.net/
// @version      1.30
// @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() {

    // Define general variables
    var nonStandardUrlParams = (GetParameterByName("category%5B%5D") !== null || GetParameterByName("category[]") !== null) ? true : false,
        arrayCurrentUrlParams = -1,
        showAdvancedOptions = false,
        showIcon,
        showTorrentThumbnail, // TODO: child of showIcon (=true)
        showMoviesTVFilters,
        showPorn,
        minRating,
        genreFilter = "",
        currentUrlNormal,
        currentUrlAbnormal,
        i;

    // Define array of known RARBG 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, 18, 19, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49].map(String),
        arrayEBooks         = [35].map(String);

    // Define conditional checks
    var isCategoryMovies,
        isCategoryTVShows,
        isCategoryGames,
        isCategoryMusic,
        isCategorySoftware,
        isCategoryNonPorn,
        isCategoryEBooks;

    // Define booleans
    var categoryMoviesArray,
        categoryTVShowsArray,
        categoryGamesArray,
        categoryMusicArray,
        categorySoftwareArray,
        categoryNonPornArray,
        categoryEBooks;

    // Normalization for RARBG's inconsistent URL parameter types (e.g. category=movies, category%5B%5D=48, category=1;18;41;49;, and category[]=42... whew)
    if (nonStandardUrlParams)
    {
        currentUrlNormal    = new RegExp("[\?&]category%5B%5D=([^]*)").exec(window.location.href);              // Grab all URL parameters %5B%5D
        currentUrlAbnormal  = new RegExp("[\?&]category\[[^\[\]]*\]=([^]*)").exec(window.location.href);        // Grab all URL parameters []
        if (currentUrlNormal === null && currentUrlAbnormal === null)                                           // If neither unique parameter exists, then stop this logic, and return nothing
            return null;
        else                                                                                                    // Otherwise...
        {
            if (currentUrlAbnormal !== null)                                                                    // If URL parameters is [] (abnormal)
            {
                arrayCurrentUrlParams = String(currentUrlAbnormal).match(/(=)\w+/g).map(String);                // Create an array of values separated by the equal sign
            }
            else                                                                                                // Otherwise conclude URL parameters are normal (%5B%5D)
            {
                arrayCurrentUrlParams = String(currentUrlNormal).match(/(=)\w+/g).map(String);                  // Create an array of values separated by the equal sign
            }
            for (i = 0; i < arrayCurrentUrlParams.length; i++)                                                  // Iterate through array look for equal signs
            {
                arrayCurrentUrlParams[i] = arrayCurrentUrlParams[i].replace("=", "");                           // Remove the equal sign from the array
            }
        }
    }
    else if (GetParameterByName("category") !== null || arrayCurrentUrlParams.length > -1)
    {
        arrayCurrentUrlParams = GetParameterByName("category").split(";").map(String);
    }

    // Compares current url parameters with known RARBG categories. If the value is greater than -1 we have at least one match.
    if (GetParameterByName("category") !== null || arrayCurrentUrlParams.length > -1)
    {
        for (i = 0; i < arrayCurrentUrlParams.length; i++)
        {
            isCategoryMovies        = arrayMovies.indexOf(arrayCurrentUrlParams[i]);
            categoryMoviesArray     = (isCategoryMovies !== -1) ? true : false;
        }
        for (i = 0; i < arrayCurrentUrlParams.length; i++)
        {
            isCategoryTVShows       = arrayTVShows.indexOf(arrayCurrentUrlParams[i]);
            categoryTVShowsArray    = (isCategoryTVShows !== -1) ? true : false;
        }
        for (i = 0; i < arrayCurrentUrlParams.length; i++)
        {
            isCategoryGames         = arrayGames.indexOf(arrayCurrentUrlParams[i]);
            categoryGamesArray      = (isCategoryGames !== -1) ? true : false;
        }
        for (i = 0; i < arrayCurrentUrlParams.length; i++)
        {
            isCategoryMusic         = arrayMusic.indexOf(arrayCurrentUrlParams[i]);
            categoryMusicArray      = (isCategoryMusic !== -1) ? true : false;
        }
        for (i = 0; i < arrayCurrentUrlParams.length; i++)
        {
            isCategorySoftware      = arraySoftware.indexOf(arrayCurrentUrlParams[i]);
            categorySoftwareArray   = (isCategorySoftware !== -1) ? true : false;
        }
        for (i = 0; i < arrayCurrentUrlParams.length; i++)
        {
            isCategoryNonPorn       = arrayNonPorn.indexOf(arrayCurrentUrlParams[i]);
            categoryNonPornArray    = (isCategoryNonPorn !== -1) ? true : false;
        }
        for (i = 0; i < arrayCurrentUrlParams.length; i++)
        {
            isCategoryEBooks        = arrayEBooks.indexOf(arrayCurrentUrlParams[i]);
            categoryEBooks          = (isCategoryEBooks !== -1) ? true : false;
        }
    }

    // Method to grab 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 (Modified by Kxmode)
        // Used under StackOverflow's standard CC BY-SA 3.0 license
        if (!url) url = window.location.href;
        name = name.replace(/[\[\]]/g, "\\$&");
        var regex = new RegExp('[?&]' + name + '(=([^&#]*)|&|#|$|((%\d\D)*\D\d*))'),
            results = regex.exec(url);
        if (!results) return null;
        if (!results[2]) return '';
        return decodeURIComponent(results[2].replace(/\+/g, " "));
    }

    // Method to activate and deactive 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);
        }
    }

    // Method to show and hide 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();
    }

    // Attaches FontAwesome script to display active and inactive "eye" icons. fontawesome.io for more info.
    $("head").append(           '<script src="//use.fontawesome.com/2d73a39974.js"></script>');

    // Attaches CSS for the custom Advanced Filters HTML box.
    $("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';

    // TODO: Handle for: if (GetParameterByName("category") !== null || arrayCurrentUrlParams.length > -1 || nonStandardUrlParams) ----------
    if (GetParameterByName("category") !== null || nonStandardUrlParams)
    {
        if (categoryMoviesArray || categoryTVShowsArray)
        {
            genreFilter += '<div id="jQcategoryFilter" class="divadvscat centered">Min Rating <input name="minprice" type="text" /></div>\n';
        }
        else if (categoryGamesArray)
        {
            genreFilter += '<div id="jQcategoryFilter" class="divadvscat centered">Game Filters Coming Soon</div>\n';
        }
        else if (categoryMusicArray)
        {
            genreFilter += '<div id="jQcategoryFilter" class="divadvscat centered">Music Filters Coming Soon</div>\n';
        }
        else if (categorySoftwareArray)
        {
            genreFilter += '<div id="jQcategoryFilter" class="divadvscat centered">Software Filters Coming Soon</div>\n';
        }
        else if (categoryNonPornArray)
        {
            genreFilter += '<div id="jQcategoryFilter" class="divadvscat centered">Non Porn Filters Coming Soon</div>\n';
        }
        else if (categoryEBooks)
        {
            genreFilter += '<div id="jQcategoryFilter" class="divadvscat centered">e-Books Filters Coming Soon</div>\n';
        }
    }
    else
    {
        genreFilter += '<div id="jQcategoryFilter" class="divadvscat centered">All Filters Coming Soon</div>\n';
    }
    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);

    // TODO: Likely going to need to move ToggleFilter and ToggleAdvancedFilters method calls into this gated logic
    if (nonStandardUrlParams)
    {
        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);
    });

    // Gated logic to show IMDB ratings for Movies and TV Shows only 
    if (categoryMoviesArray || categoryTVShowsArray)
    {
        if (window.localStorage.getItem("minimum-rating") > 0)
        {
            var mr = window.localStorage.getItem("minimum-rating");
            $("#jQcategoryFilter").find("input").attr("value", mr);
            minRating = mr;
        }
        else
        {
            $("#jQcategoryFilter").find("input").attr("value", 0);
        }
    }

    // Events for the "Update Filters" button
    $(".jQUpdateFilters").on("click", function () {
        var minRating = $("#jQcategoryFilter").parent().find("input").val();
        window.localStorage.setItem("minimum-rating", minRating);
        location.reload();
    });

    // Events for the "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 || nonStandardUrlParams)
            {
                if (categoryMoviesArray || categoryTVShowsArray)
                {
                    // 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 (categoryGamesArray) { }
                else if (categoryMusicArray) { }
                else if (categorySoftwareArray) { }
                else if (categoryNonPornArray) { }
            }
        }

        // 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>");
    */
});