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;

当前为 2017-07-15 提交的版本,查看 最新版本

您需要先安装一个扩展,例如 篡改猴Greasemonkey暴力猴,之后才能安装此脚本。

You will need to install an extension such as Tampermonkey to install this script.

您需要先安装一个扩展,例如 篡改猴暴力猴,之后才能安装此脚本。

您需要先安装一个扩展,例如 篡改猴Userscripts ,之后才能安装此脚本。

您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。

您需要先安装用户脚本管理器扩展后才能安装此脚本。

(我已经安装了用户脚本管理器,让我安装!)

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展,比如 Stylus,才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

您需要先安装一款用户样式管理器扩展后才能安装此样式。

(我已经安装了用户样式管理器,让我安装!)

// ==UserScript==
// @name         RARBG Advanced Filters [BETA]
// @namespace    http://tampermonkey.net/
// @version      1.29
// @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 = "",
        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)
    {
        var currentUrlNormal    = new RegExp("[\?&]category%5B%5D=([^]*)").exec(window.location.href);          // Grab all URL parameters %5B%5D
        var 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>");
    */
});