RARBG Advanced Filters

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; - search for movies and tv shows by genre - Filter based on minimum IMDB rating;

  1. // ==UserScript==
  2. // @name RARBG Advanced Filters
  3. // @namespace http://tampermonkey.net/
  4. // @version 1.65
  5. // @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; - search for movies and tv shows by genre - Filter based on minimum IMDB rating;
  6. // @author Kxmode
  7. // @contributor darkred, phpcitizen, fixed
  8. // @license MIT
  9. // @include /(https?:)?\/\/(www\.)?(proxy|unblocked)?rarbg((2018|2019|2020|2021)?|access(ed)?|cdn|core|data|enter|get|go|index|mirror(ed)?|p2p|prox(ied|ies|y)|prx|to(r|rrents)?|unblock(ed)?|way|web)\.(to|com|org|is)\/((index\d{2}|torrents)\.php.*|torrent|catalog\/.*|s\/.*|tv\/.*|top10)/
  10. // @grant none
  11. // @require https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js
  12. // @run-at document-idle
  13. // ==/UserScript==
  14.  
  15. /* jshint esversion: 6 */
  16. /* eslint-disable */
  17.  
  18. const $ = (window).$;
  19.  
  20. $(function() {
  21.  
  22. // Define general variables
  23. let nonStandardUrlParams = (getParameterByName('category%5B%5D') !== null || getParameterByName('category[]') !== null) ? true : false,
  24. currentUrlParams = -1,
  25. showAdvancedOptions = false,
  26. showIcon,
  27. showTorrentThumbnail, // TODO: child of showIcon (=true)
  28. showPorn,
  29. genreFilter = '',
  30. currentUrlNormal,
  31. currentUrlAbnormal,
  32. i;
  33.  
  34. // Define Category specific filters
  35. let minRating,
  36. searchGenre,
  37. gameGroup,
  38. musicGenre,
  39. showKORSUB,
  40. show720p;
  41.  
  42. // Define array of known RARBG categories
  43. const MOVIES = ['movies', 14, 17, 42, 44, 45, 46, 47, 48, 50, 51, 52, 54].map(String),
  44. TV_SHOWS = [18, 41, 49].map(String),
  45. GAMES = [27, 28, 29, 30, 31, 32, 40].map(String),
  46. MUSIC = [23, 24, 25, 26].map(String),
  47. SOFTWARE = [33, 34, 43].map(String),
  48. NON_PORN = [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, 50, 51, 52].map(String);
  49.  
  50. // Define booleans
  51. let isCategoryMovies,
  52. isCategoryTVShows,
  53. isCategoryGames,
  54. isCategoryMusic,
  55. isCategorySoftware,
  56. isCategoryNonPorn;
  57.  
  58. // This logic normalizes RARBG's inconsistent URL parameter types (e.g. category=movies, category%5B%5D=48, category=1;18;41;49;, and category[]=42)
  59. if (nonStandardUrlParams) {
  60. currentUrlNormal = new RegExp(/[\?&]category%5B%5D=([^]*)/).exec(window.location.href); // Grab all URL parameters %5B%5D
  61. currentUrlAbnormal = new RegExp(/[\\?&]category\[[^\[\]]*\]=([^]*)/).exec(window.location.href); // Grab all URL parameters []
  62. if (currentUrlNormal === null && currentUrlAbnormal === null) { // If neither unique parameter exists, then stop this logic, and return nothing
  63. return null;
  64. } else { // Otherwise...
  65. if (currentUrlAbnormal !== null) // If URL parameters is [] (abnormal)
  66. currentUrlParams = String(currentUrlAbnormal).match(/(=)\w+/g).map(String); // Create an array of values separated by the equal sign
  67. else // Otherwise conclude URL parameters are normal (%5B%5D)
  68. currentUrlParams = String(currentUrlNormal).match(/(=)\w+/g).map(String); // Create an array of values separated by the equal sign
  69.  
  70. for (i = 0; i < currentUrlParams.length; i++) { // Iterate through array look for equal signs
  71. currentUrlParams[i] = currentUrlParams[i].replace('=', ''); // Remove the equal sign from the array
  72. }
  73. }
  74. }
  75. else if (getParameterByName('category') !== null) { // Otherwise this is a standard URL parameter
  76. currentUrlParams = getParameterByName('category').split(';').map(String); // Create an array of values separated by the semicolon
  77. }
  78.  
  79. // Compares current url parameters with known RARBG categories. If the value is greater than -1 we have at least one match.
  80. // Navigate through each array to find and set the match to true. For now there can only be one match.
  81. if (getParameterByName('category') !== null || currentUrlParams.length > -1) {
  82. isCategoryMovies = MOVIES.some(item => currentUrlParams.includes(item));
  83. isCategoryTVShows = TV_SHOWS.some(item => currentUrlParams.includes(item));
  84. isCategoryGames = GAMES.some(item => currentUrlParams.includes(item));
  85. isCategoryMusic = MUSIC.some( item => currentUrlParams.includes(item) );
  86. isCategorySoftware = SOFTWARE.some(item => currentUrlParams.includes(item));
  87. isCategoryNonPorn = NON_PORN.some(item => currentUrlParams.includes(item));
  88. }
  89.  
  90. // Method to grab the Parameter name and value (Note: single use only. See line 60 for multiple URL parameters and if needed move to function.)
  91. function getParameterByName(name, url) {
  92. // credit: https://stackoverflow.com/a/901144 (Modified by Kxmode)
  93. // Used under StackOverflow's standard CC BY-SA 3.0 license
  94. if (!url) url = window.location.href;
  95. name = name.replace(/[\[\]]/g, '\\$&');
  96. let regex = '[?&]' + name + '(=([^&#]*)|&|#|$|((%\d\D)*\D\d*))'; // deepscan-disable-line BAD_ESCAPE_AT_REGEXP_CONSTRUCTOR
  97. regex = new RegExp(regex);
  98. let results = regex.exec(url);
  99. if (!results) return null;
  100. if (!results[2]) return '';
  101. return decodeURIComponent(results[2].replace(/\+/g, ' '));
  102. }
  103.  
  104. // Method to activate and deactive filters inside the Advanced Filter's HTML box
  105. function toggleFilter(target, data, bool, optional) {
  106. optional = (optional !== undefined) ? true : false;
  107. let targetID = target.replace('#','');
  108. if (bool) {
  109. if (!optional) {
  110. $(target).find('i').removeClass('fa-eye-slash').addClass('fa-eye');
  111. $(target).removeClass('disabled');
  112. }
  113. $(target).attr(data, 'true');
  114. window.localStorage.setItem(targetID, 'true');
  115. } else {
  116. if (!optional) {
  117. $(target).find('i').removeClass('fa-eye').addClass('fa-eye-slash');
  118. $(target).addClass('disabled');
  119. }
  120. $(target).attr(data, 'false');
  121. window.localStorage.setItem(targetID, 'false');
  122. }
  123. }
  124.  
  125. // Method to show and hide the Advanced Filter's HTML box
  126. function toggleAdvancedFilters(bool, isClicked) {
  127. isClicked = (isClicked !== undefined) ? true : false;
  128. let parentTarget = $('.new-search form');
  129. let target = $('.advanced-search');
  130. if (getParameterByName('category') !== null && isClicked === false) {
  131. if (bool) {
  132. window.localStorage.setItem('shadvbutton', 'true');
  133. parentTarget.removeAttr('style');
  134. parentTarget.removeClass('disabled');
  135. target.show();
  136. $('#shadvbutton').text('«');
  137. } else {
  138. parentTarget.attr('style', 'width: 100%; border-right: 1px solid #9faabc;');
  139. target.hide();
  140. $('#shadvbutton').text('»');
  141. }
  142. } else if (getParameterByName('category') === null && isClicked === false) {
  143. $('#shadvbutton').attr('data-shadvbutton', 'false');
  144. window.localStorage.setItem('shadvbutton', 'false');
  145. parentTarget.attr('style', 'width: 100%; border-right: 1px solid #9faabc;');
  146. target.hide();
  147. $('#shadvbutton').text('»');
  148. } else {
  149. if (bool) {
  150. if (typeof showhideadvsearch !== 'undefined') { showhideadvsearch('show'); } // jshint ignore:line
  151. parentTarget.removeAttr('style');
  152. parentTarget.removeClass('disabled');
  153. target.show();
  154. $('#shadvbutton').text('«');
  155. } else {
  156. parentTarget.attr('style', 'width: 100%; border-right: 1px solid #9faabc;');
  157. target.hide();
  158. $('#shadvbutton').text('»');
  159. }
  160. }
  161. }
  162.  
  163. $('#searchTorrent').parent().addClass('new-search');
  164.  
  165. // Removes extra space between Recommended torrents and search bar
  166. $('#searchTorrent').parent().parent().find('div:nth-of-type(2)').remove();
  167. for(i = 1; i <= 4; i++) {
  168. $('#searchTorrent').parent().parent().find('br:nth-of-type(1)').remove();
  169. }
  170.  
  171. // Fixes a bug in this script affecting the formatting of IMDB searches (?imdb=tt0448115) in darkred's 'RARBG - various tweaks';
  172. if ($('.new-search').next().attr('class') === undefined) {
  173. $('.new-search').next().find('table tr td:last-child').addClass('advanced-search-formatting-fix');
  174. $('<br>').insertBefore('.advanced-search-formatting-fix b:nth-of-type(-n+5)');
  175. }
  176.  
  177. // Attaches FontAwesome script to display active and inactive 'eye' icons. fontawesome.io for more info.
  178. $('head').append( '<script src="https://kit.fontawesome.com/515872dda2.js" crossorigin="anonymous"></script>');
  179.  
  180. // Attaches CSS for the custom Advanced Filters HTML box.
  181. $("head").append( `<style>
  182. .content-rounded .new-search,
  183. .content-rounded div.new-search div { margin-left: auto; }
  184. .new-search { width: 1200px; display: flex; display: -webkit-flex; display: -moz-flex; margin: 30px auto; }
  185. .new-search div { -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; }
  186. .new-search div { border-radius: 0; -moz-border-radius: 0; -webkit-border-radius: 0; }
  187. .new-search form { width: 70%; border-radius: 0; -moz-border-radius: 0; -webkit-border-radius: 0; }
  188. .new-search form { border: 0; border-top: 1px solid #9faabc; border-bottom: 1px solid #9faabc; border-left: 1px solid #9faabc; }
  189. .new-search .divadvscat { width: 157px; display: inline-block; height: auto; padding: 7px; float: none; }
  190. .new-search .divadvclearcats { padding: 10px; }
  191. .new-search .advanced-search { width: 31%; background: #e7f3fb; font-size: 110%; padding: 5px; border: 1px solid #9faabc; float: left; }
  192. .new-search .advanced-search { border: 0; border-top: 1px solid #9faabc; border-bottom: 1px solid #9faabc; border-right: 1px solid #9faabc; }
  193. .new-search .advanced-search h4 { padding: 0; margin: 0 0 10px 0; text-align: center; }
  194. .advanced-search .section-wrapper { border: 1px dotted #9faabc; padding: 10px; }
  195. .advanced-search .section-wrapper:first-child { border-bottom: 0; }
  196. .advanced-search .no-border { border: 0; }
  197. .advanced-search .divadvscat { width: auto; border: 1px solid transparent; cursor: pointer; }
  198. .advanced-search .divadvscat i { padding-right: 2px; }
  199. .advanced-search .disabled { border: 1px solid #DDD; background-color: #f5f5f5; color: #999; }
  200. .advanced-search .centered { text-align: center; }
  201. .section-wrapper .imdb-rating-search { width: 155px; }
  202. .section-wrapper .genre-search { width: auto; }
  203. .section-wrapper .gaming-group-search { width: auto; }
  204. .section-wrapper .imdb-rating-search input { width: 30%; }
  205. .section-wrapper .gaming-group-search input { width: 50%; }
  206. .section-wrapper input { border: 0; margin-left: 10px; border: 1px solid #9faabc; text-align: center; }
  207. .clearfix:before, .clearfix:after { display: table; content: ""; line-height: 0;}
  208. .section-wrapper input.text-left { text-align: left; }
  209. td.header6:hover { background: #3860bb; cursor: default;; }
  210. td.header6 span { text-decoration: underline; cursor: pointer; }
  211. td.header6 span:hover { text-decoration: none; }
  212. .resize { width: 65%; }
  213. </style>`);
  214.  
  215. // Creates the HTML for category specific filters
  216. if (getParameterByName("category") === null || isCategorySoftware)
  217. genreFilter = '<div class="section-wrapper no-border" style="border-top: 1px dotted #9faabc;">\n';
  218. else
  219. genreFilter = '<div class="section-wrapper">\n';
  220.  
  221. // TODO: Handle for: if (GetParameterByName("category") !== null || arrayCurrentUrlParams.length > -1 || nonStandardUrlParams) ----------
  222. if (getParameterByName('category') !== null || nonStandardUrlParams) {
  223. if (isCategoryMovies || isCategoryTVShows) {
  224. genreFilter += `<div id="jQIMDB" class="divadvscat imdb-rating-search centered">Min Rating <input name="minprice" type="text" /></div>
  225. <div id="jQKORSUB" class="divadvscat" title="Hides low-quality KORSUB torrents"><i class="fa fa-eye fa-1x"></i> KORSUB</div>
  226. <div id="jQ720p" class="divadvscat" title="Hides 720p torrents"><i class="fa fa-eye fa-1x"></i> 720p</div>
  227. <div id="jQgenre" class="divadvscat genre-search">Genre <input name="mediagenre" type="text" class="text-left" /></div>`;
  228. } else if (isCategoryGames) {
  229. genreFilter += '<div id="jQGamingGroup" class="divadvscat gaming-group-search centered">Torrent Group <input name="gamegroup" class="text-left" type="text" /></div>\n';
  230. } else if (isCategoryMusic) {
  231. genreFilter += '<div id="jQMusicGenre" class="divadvscat music-group-genre centered">Genre <input name="musicgenre" class="text-left" type="text" /></div>\n';
  232. } else if (isCategorySoftware) {
  233. // genreFilter += '<div id="jQcategoryFilter" class="divadvscat centered">Software Filters Coming Soon</div>\n'; // Not enough to warrant this for now
  234. } else if (isCategoryNonPorn) {
  235. genreFilter += '<div id="jQcategoryFilter" class="divadvscat centered">Non Porn Filters Coming Soon</div>\n';
  236. }
  237. } else {
  238. // genreFilter += '<div id="jQcategoryFilter" class="divadvscat centered">All Filters Coming Soon</div>\n'; // Not enough to warrant this for now
  239. }
  240. genreFilter += '</div>\n';
  241.  
  242. // Creates the Advanced Filter HTML box
  243. let AdvancedFiltersHTML = `<div class="advanced-search">
  244. <div class="section-wrapper">
  245. <div id="jQIcon" class="divadvscat"><i class="fa fa-eye fa-1x"></i> Category Icons</div>
  246. <div id="jQTorrentThumbnail" class="divadvscat"><i class="fa fa-eye fa-1x"></i> Torrent Images</div>
  247. <div id="jQShowPorn" class="divadvscat"><i class="fa fa-eye fa-1x"></i> Porn</div>
  248. </div>
  249. ${ genreFilter }
  250. <div class="section-wrapper no-border">
  251. <span class="jQUpdateFilters btn btn-primary btn-mini">Update Page with Filters</span>
  252. <span class="jQResetFilters btn btn-mini">Reset Filters</span>
  253. </div>
  254. <div class="clearfix"></div>
  255. </div>`;
  256.  
  257. // Attaches Advanced Filters HTML box to RARBG
  258. $('#searchTorrent').parent().append(AdvancedFiltersHTML);
  259.  
  260. // TODO: Likely going to need to move the ToggleFilter and ToggleAdvancedFilters method calls into this gated logic
  261. if (nonStandardUrlParams) {
  262. toggleFilter('#shadvbutton', 'data-shadvbutton', showAdvancedOptions, true);
  263. toggleAdvancedFilters(true, true);
  264. } else {
  265. showAdvancedOptions = ((window.localStorage.getItem('shadvbutton') == 'true') ? true : false);
  266. toggleFilter('#shadvbutton', 'data-shadvbutton', showAdvancedOptions, true);
  267. toggleAdvancedFilters(showAdvancedOptions);
  268. }
  269.  
  270. // Logic for HTML box icons
  271. showIcon = ((window.localStorage.getItem('jQIcon') == 'false') ? false : true);
  272. toggleFilter('#jQIcon', 'data-icon', showIcon);
  273.  
  274. showTorrentThumbnail = ((window.localStorage.getItem('jQTorrentThumbnail') == 'false') ? false : true);
  275. toggleFilter('#jQTorrentThumbnail', 'data-torrent-thumbs', showTorrentThumbnail);
  276.  
  277. showPorn = ((window.localStorage.getItem('jQShowPorn') == 'false') ? false : true);
  278. toggleFilter('#jQShowPorn', 'data-porn', showPorn);
  279.  
  280. showKORSUB = ((window.localStorage.getItem('jQKORSUB') == 'false') ? false : true);
  281. toggleFilter('#jQKORSUB', 'data-korsub', showKORSUB);
  282.  
  283. show720p = ((window.localStorage.getItem('jQ720p') == 'false') ? false : true);
  284. toggleFilter('#jQ720p', 'data-720p', show720p);
  285.  
  286. $('#shadvbutton').on('click', function() {
  287. showAdvancedOptions = ($(this).attr('data-shadvbutton') == 'false') ? true : false;
  288. toggleFilter('#shadvbutton', 'data-shadvbutton', showAdvancedOptions, true);
  289. toggleAdvancedFilters(showAdvancedOptions, true);
  290. });
  291.  
  292. $('#jQIcon').on('click', function() {
  293. showIcon = ($(this).attr('data-icon') == 'false') ? true : false;
  294. toggleFilter('#jQIcon', 'data-icon', showIcon);
  295. });
  296. $('#jQTorrentThumbnail').on('click', function() {
  297. showTorrentThumbnail = ($(this).attr('data-torrent-thumbs') == 'false') ? true : false;
  298. toggleFilter('#jQTorrentThumbnail', 'data-torrent-thumbs', showTorrentThumbnail);
  299. });
  300. $('#jQShowPorn').on('click', function() {
  301. showPorn = ($(this).attr('data-porn') == 'false') ? true : false;
  302. toggleFilter('#jQShowPorn', 'data-porn', showPorn);
  303. });
  304. $('#jQKORSUB').on('click', function() {
  305. showKORSUB = ($(this).attr('data-korsub') == 'false') ? true : false;
  306. toggleFilter('#jQKORSUB', 'data-korsub', showKORSUB);
  307. });
  308. $('#jQ720p').on('click', function() {
  309. show720p = ($(this).attr('data-720p') == 'false') ? true : false;
  310. toggleFilter('#jQ720p', 'data-720p', show720p);
  311. });
  312.  
  313. // Movies and TV Shows only
  314. if (isCategoryMovies || isCategoryTVShows) {
  315. if (window.localStorage.getItem('minimum-rating') > 0) {
  316. let mr = window.localStorage.getItem('minimum-rating');
  317. $('#jQIMDB').find('input').attr('value', mr);
  318. minRating = mr;
  319. } else {
  320. $('#jQIMDB').find('input').attr('value', 0);
  321. }
  322.  
  323. if (window.localStorage.getItem('media-genre') !== null) {
  324. let gen = window.localStorage.getItem('media-genre');
  325. $('#jQgenre').find('input').attr('value', gen);
  326. searchGenre = gen.toLowerCase();
  327. }
  328. }
  329.  
  330. // Games only
  331. if (isCategoryGames) {
  332. if(window.localStorage.getItem('game-group') !== undefined) {
  333. let gg = window.localStorage.getItem('game-group');
  334. $('#jQGamingGroup').find('input').attr('value', gg);
  335. gameGroup = gg;
  336. } else {
  337. $('#jQGamingGroup').find('input').removeAttr('value');
  338. }
  339. }
  340.  
  341. // Music only
  342. if (isCategoryMusic) {
  343. if(window.localStorage.getItem('music-genre') !== undefined) {
  344. let mg = window.localStorage.getItem('music-genre');
  345. $('#jQMusicGenre').find('input').attr('value', mg);
  346. musicGenre = mg;
  347. } else {
  348. $('#jQMusicGenre').find('input').removeAttr('value');
  349. }
  350. }
  351.  
  352. // Input click event
  353. /*
  354. document.querySelectorAll('#jQIMDB input, #jQGamingGroup input, #jQMusicGenre input, #jQgenre input').forEach( selector => {
  355. selector.addEventListener('blur', e => { console.log(e.key) });
  356. });
  357. */
  358. $('#jQIMDB input, #jQGamingGroup input, #jQMusicGenre input, #jQgenre input').on('keydown', function() {
  359. if (event.which == 13 || event.keyCode == 13) $('.jQUpdateFilters').click();
  360. });
  361.  
  362. // Events for the 'Update Filters' button
  363. $('.jQUpdateFilters').on('click', function () {
  364. if (isCategoryMovies || isCategoryTVShows) {
  365. let minRating = $('#jQIMDB').parent().find('input').val();
  366. window.localStorage.setItem('minimum-rating', minRating);
  367.  
  368. let genre = $('#jQgenre').find('input').val();
  369. window.localStorage.setItem('media-genre', genre);
  370. }
  371. if (isCategoryGames) {
  372. let gameGroup = $('#jQGamingGroup').parent().find('input').val();
  373. window.localStorage.setItem('game-group', gameGroup);
  374. }
  375. if (isCategoryMusic) {
  376. let musicGenre = $('#jQMusicGenre').parent().find('input').val();
  377. window.localStorage.setItem('music-genre', musicGenre);
  378. }
  379. location.reload();
  380. });
  381.  
  382. // Events for the 'Reset Filters' button
  383. $('.jQResetFilters').on('click', function() {
  384. window.localStorage.removeItem('jQIcon');
  385. window.localStorage.removeItem('jQTorrentThumbnail');
  386. window.localStorage.removeItem('jQKORSUB');
  387. window.localStorage.removeItem('jQ720p');
  388. window.localStorage.removeItem('jQShowPorn');
  389. window.localStorage.removeItem('media-genre');
  390. window.localStorage.removeItem('minimum-rating');
  391. window.localStorage.removeItem('game-group');
  392. window.localStorage.removeItem('music-genre');
  393. location.reload();
  394. });
  395.  
  396. // Removes Movie filters after clicking the 'View all' link
  397. $('.tdlinkfull2').on('click', function() {
  398. if ($(this).text() === 'View all') {
  399. window.localStorage.removeItem('jQKORSUB');
  400. window.localStorage.removeItem('jQ720p');
  401. window.localStorage.removeItem('minimum-rating');
  402. window.localStorage.removeItem('game-group');
  403. window.localStorage.removeItem('music-genre');
  404. window.localStorage.removeItem('media-genre');
  405. }
  406. });
  407.  
  408. // CATEGORY SPECIFIC =================================================================================================
  409.  
  410. // Hides torrents with seeders equal to or lower than a number [TODO: make this a form input filter]
  411. // use inArray method from work (Configurator height normalizer)
  412. /*
  413. if (parseInt(title.indexOf('720p')) > 0)
  414. {
  415. $(this).parents('.lista2').remove();
  416. }
  417. */
  418.  
  419. // Logic to hide porn
  420. if (!showPorn) {
  421. $.each($('.tdlinkfull2'), function() {
  422. const TARGET_TEXT = $(this).text().toLowerCase();
  423. if (TARGET_TEXT == 'xxx') $(this).parent().parent().remove();
  424. });
  425. $.each($('.divadvscat a'), function() {
  426. const TARGET_TEXT = $(this).text().toLowerCase();
  427. if(TARGET_TEXT == 'xxx (18+)') $(this).parent().remove();
  428. });
  429. }
  430.  
  431. // Loops through all torrents looking at each span tag
  432. $.each($('.lista span'), function(index, value) {
  433. const GENRE = $(this).text().toLowerCase();
  434. if (GENRE !== undefined)
  435. // Creates the logic for category specific filters
  436. if (getParameterByName('category') !== null || nonStandardUrlParams)
  437. if (isCategoryMovies || isCategoryTVShows)
  438. if (GENRE.search(searchGenre) == -1)
  439. $(this).parents('.lista2').remove();
  440. });
  441.  
  442. // Loops through all torrents looking at each anchor tag
  443. $.each($('.lista a'), function(index, value) {
  444. let title = $(this).attr('title');
  445. let icon = $(this).find('img').attr('src');
  446.  
  447. if (title !== undefined) {
  448. // Logic to hide KORSUB torrents
  449. if (!showKORSUB)
  450. if (parseInt(title.indexOf('KORSUB')) > 0)
  451. $(this).parents('.lista2').remove();
  452.  
  453. // Logic to hide 720p torrents
  454. if (!show720p)
  455. if (parseInt(title.indexOf('720p')) > 0)
  456. $(this).parents('.lista2').remove();
  457.  
  458. // Creates the logic for category specific filters
  459. if (getParameterByName('category') !== null || nonStandardUrlParams) {
  460. if (isCategoryMovies || isCategoryTVShows) {
  461. // IMDB Ratings
  462. $.each($('.lista:nth-child(2)'), function(index, value) {
  463. if ($(this).children('span').length) {
  464. const RATINGS = $(this).children('span').text();
  465. const IMDB = RATINGS.indexOf('IMDB: ') + 6;
  466. const SCOPE_MIN_RATING = $('#jQIMDB').parent().find('input').val();
  467. if (SCOPE_MIN_RATING > 0) {
  468. if (RATINGS !== '' && IMDB !== -1) {
  469. minRating = parseFloat(minRating);
  470. const RATE_VALUE = parseFloat(RATINGS.substring(IMDB,RATINGS.length-3));
  471. if (!isNaN(RATE_VALUE)) {
  472. if (RATE_VALUE <= minRating) $(this).parents('.lista2').remove();
  473. } else {
  474. $(this).parents('.lista2').remove();
  475. }
  476. }
  477. }
  478. }
  479. });
  480. }
  481. // Game Torrent Group
  482. else if (isCategoryGames) {
  483. $.each($('.lista2t a'), function(index, value) {
  484. if ($(this).attr('title') !== undefined) {
  485. const TORRENT_TITLE = $(this).attr('title');
  486. const SEARCH_VALUE = TORRENT_TITLE.toLowerCase().indexOf(gameGroup);
  487. if (SEARCH_VALUE === -1 && gameGroup !== null)
  488. $(this).parents('.lista2').remove();
  489. }
  490. });
  491. }
  492. else if (isCategoryMusic) {
  493. $.each($('.lista2t .lista span:last-child'), function(index, value) {
  494. const GENRE_TITLE = $(this).text();
  495. if (GENRE_TITLE !== undefined) {
  496. const SEARCH_VALUE = GENRE_TITLE.toLowerCase().indexOf(musicGenre);
  497. if (SEARCH_VALUE === -1 && musicGenre !== null)
  498. $(this).parents('.lista2').remove();
  499. }
  500. });
  501. }
  502. // Coming soon
  503. // else if (categorySoftwareArray) { }
  504. // else if (categoryNonPornArray) { }
  505. }
  506. }
  507.  
  508. // Logic to hide porn
  509. if (!showPorn) {
  510. if (title !== undefined) {
  511. title = title.indexOf('XXX');
  512. if (title >= 0) $(this).parents('.lista2').remove();
  513. }
  514. if (icon !== undefined) {
  515. icon = icon.indexOf('cat_new4.gif');
  516. if (icon >= 0) $(this).parents('.lista2').remove();
  517. }
  518. }
  519. });
  520.  
  521. // NON-CATEGORY SPECIFIC =================================================================================================
  522.  
  523. // Logic to hide icons
  524. if (!showIcon) {
  525. $('.lista2t tr td:nth-of-type(1)').attr('style','display:none;');
  526. } else {
  527. // TODO: Make child of showIcon (=true)
  528. // Logic to show torrent thumbnails
  529. if (showTorrentThumbnail) {
  530. const LOCAL_STORAGE_SETTING = 'RARBG-Advanced-Filters-Large-Thumbnails';
  531. window.isLargeThumb = ( window.localStorage.getItem(LOCAL_STORAGE_SETTING) == 'true' ) ? true : false;
  532.  
  533. if (window.isLargeThumb)
  534. $('.lista2t').find('tr:first-child td:first-child').html('Thumbnail (<span class="jQlargeThumbs"><i class="fas fa-compress-arrows-alt"></i></span>)');
  535. else
  536. $('.lista2t').find('tr:first-child td:first-child').html('Thumbnail (<span class="jQlargeThumbs"><i class="fas fa-expand-arrows-alt"></i></span>)');
  537.  
  538. $.each($('.lista2t .lista2'), function() {
  539. const ANCHOR = $(this);
  540. $.each(ANCHOR.find('.lista'), function() {
  541. const IMAGE = $(this).find('a');
  542. const TARGET = ANCHOR.find(':nth-child(1) a');
  543. if (IMAGE.attr('onmouseover') !== undefined) {
  544. const HREF = IMAGE.attr('href');
  545. const SOURCE_THUMB = IMAGE.attr('onmouseover');
  546. let val1 = SOURCE_THUMB.match(/(?:[a-z0-9](?:[a-z0-9-]{0,61}[a-z0-9])?\.)+[a-z0-9][a-z0-9-]{0,61}[a-z0-9]/g).map(String)[0];
  547. val1 = SOURCE_THUMB.lastIndexOf(val1);
  548. const VAL2 = SOURCE_THUMB.indexOf("\' border=0>')")-1;
  549. let imageID = SOURCE_THUMB.substring(val1,VAL2);
  550.  
  551. if (window.isLargeThumb) {
  552. if (imageID.includes('static/over')) {
  553. let pvid = imageID.substring(22,23);
  554. imageID = imageID.replace('static/over','posters2/' + pvid);
  555. }
  556.  
  557. if (imageID.includes('over_opt'))
  558. imageID = imageID.replace('over_opt','poster_opt');
  559.  
  560. if (imageID.includes('_small'))
  561. imageID = imageID.replace('_small','_banner_optimized');
  562.  
  563. }
  564.  
  565. let thumbnailImage = "<img class='thumbnail' src=\'//" + imageID + "' />";
  566.  
  567. if (window.isLargeThumb)
  568. if (imageID.includes('posters2/') || imageID.includes('poster_opt') || imageID.includes('_banner_optimized'))
  569. $('.thumbnail').addClass('resize');
  570.  
  571. IMAGE.removeAttr('onmouseover').removeAttr('onmouseout');
  572. TARGET.find('img').replaceWith(thumbnailImage);
  573. TARGET.attr('href', HREF);
  574. ANCHOR.find('td:nth-child(1)').attr( 'align', 'center' );
  575. }
  576. });
  577. });
  578.  
  579. $(document).on('click', '.jQlargeThumbs', function() {
  580. if (window.isLargeThumb)
  581. window.localStorage.setItem(LOCAL_STORAGE_SETTING, 'false');
  582. else
  583. window.localStorage.setItem(LOCAL_STORAGE_SETTING, 'true');
  584. window.location.href = window.location.href;
  585. });
  586. }
  587. }
  588.  
  589. // Is Grid active?
  590. const SHOW_GRID = ((window.localStorage.getItem('advanced-search-grid-view') == 'true') ? true : false);
  591.  
  592. // Creates the Grid button toggle
  593. const GRID_ICON = SHOW_GRID ? '<i class=\'fas fa-list\'></i>' : '<i class=\'fas fa-th\'></i>';
  594. const TOOL_TIP = SHOW_GRID ? 'Show list view' : 'Show grid view';
  595. $('#searchTorrent table tbody tr').prepend('<td><span class=\'btn btn-primary jQGridButton\' title=\'' + TOOL_TIP + '\'>' + GRID_ICON + '</a></td>');
  596.  
  597. // Grid button toggle logic
  598. $(document).on('click', '.jQGridButton', function() {
  599. if (SHOW_GRID)
  600. window.localStorage.setItem('advanced-search-grid-view', 'false');
  601. else
  602. window.localStorage.setItem('advanced-search-grid-view', 'true');
  603. location.reload();
  604. });
  605.  
  606. if (SHOW_GRID) {
  607.  
  608. let isTorrentMagnetLinksScriptActive = false;
  609.  
  610. // Determines if the torrent and magnet links script is installed
  611. $.each($('.lista2t tbody tr:first-child td'), function(index) {
  612. const CONTENT = $(this).html();
  613. switch (CONTENT) {
  614. case 'DL&nbsp;ML':
  615. isTorrentMagnetLinksScriptActive = true;
  616. break;
  617. }
  618. });
  619.  
  620. // Creates the grid
  621. let gridTemplate = `#TorrentGrid .grid-lista2 { grid-template-areas: "thumb thumb"
  622. "file file"
  623. "added added"
  624. "size size"
  625. "seeders leechers"
  626. "comments uploader"; }`;
  627. if (isTorrentMagnetLinksScriptActive) {
  628. gridTemplate = `#TorrentGrid .grid-lista2 { grid-template-areas: "thumb thumb"
  629. "file file"
  630. "mldl mldl"
  631. "added added"
  632. "size size"
  633. "seeders leechers"
  634. "comments uploader"; }`;
  635. }
  636.  
  637. // Creates the CSS for the grid
  638. $('<div id="TorrentGrid"/>').insertBefore('.lista2t').prepend(`<style>
  639. ${ gridTemplate }
  640. #TorrentGrid .grid-lista2 .thumb { grid-area: thumb; }
  641. #TorrentGrid .grid-lista2 .file { grid-area: file; }
  642. #TorrentGrid .grid-lista2 .mldl { grid-area: mldl; }
  643. #TorrentGrid .grid-lista2 .added { grid-area: added; }
  644. #TorrentGrid .grid-lista2 .size { grid-area: size; margin-bottom: 10px; }
  645. #TorrentGrid .grid-lista2 .seeders { grid-area: seeders; justify-self: right; margin-right: 5px; }
  646. #TorrentGrid .grid-lista2 .leechers { grid-area: leechers; justify-self: left; margin-left: 5px; }
  647. #TorrentGrid .grid-lista2 .comments { grid-area: comments; margin-top: 10px; }
  648. #TorrentGrid .grid-lista2 .uploader { grid-area: uploader; margin-top: 10px; }
  649. #TorrentGrid .grid-lista2 { display: grid; grid-template-rows: 220px 60px 45px 27px; }
  650. #TorrentGrid .grid-lista2 { width: 20%; background-color: #e7f3fa; border: 10px solid #fff; margin: 0 !important; padding: 20px; text-align: center; float: left; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; box-sizing: border-box; }
  651. #TorrentGrid .grid-lista2 .lista { margin: 0; }
  652. #TorrentGrid .alt-layout { display:block; min-height: 30px; }
  653. #TorrentGrid .grid-lista2 .alt-darker { background: #222; font-weight: bold; color: #fff; padding: 5px; margin: 5px 0; }
  654. #TorrentGrid .grid-lista2 .alt-deco { border-bottom: 1px solid #CCC; padding-bottom: 5px; margin-bottom: 5px; }
  655. #TorrentGrid .grid-lista2 .lista:first-child img { width: 100%; height: 200px; }
  656. #TorrentGrid .grid-lista2 .alt-size { font-weight: bold; }
  657. #TorrentGrid .grid-lista2 .badge { width: 75%; background-color: #17a2b8; color: #fff; display: inline-block; padding: .75em .4em; font-weight: 700; line-height: 1; text-align: center; white-space: nowrap; vertical-align: baseline; border-radius: .25rem; }
  658. #TorrentGridControls { background: #d3dde7; text-align: center; margin: 0 14px 20px 14px; padding: 10px; border: 1px solid #9faabc; }
  659. #TorrentGridControls h3 { margin: 0 0 10px 0; }
  660. #TorrentGridControls span { margin: 0 5px; }
  661. </style>`);
  662.  
  663. $.each($('.lista2t .lista2'), function(index) {
  664. let parentIndex = index + 1;
  665. $('#TorrentGrid').append('<div class="grid-lista2"/>');
  666. $.each($(this).find('td'), function(index) {
  667. let childIndex = index + 1;
  668. let target = $(this).closest('table').prev().find('div.grid-lista2:nth-of-type('+parentIndex+')');
  669. target.append('<div class="lista"/>');
  670. let currentElement = target.find('.lista:nth-of-type('+childIndex+')').eq(0);
  671. let fileName;
  672. currentElement.html($(this).html());
  673. if (isTorrentMagnetLinksScriptActive) {
  674. switch (childIndex) {
  675. case 1: // thumbnail TD
  676. currentElement.addClass('thumb');
  677. break;
  678. case 2: // file TD
  679. currentElement.addClass('file');
  680. currentElement.find('a:first-child').addClass('alt-layout');
  681. currentElement = currentElement.find('a:first-child');
  682. fileName = currentElement.text().replace(/\./g,' ');
  683. currentElement.text(fileName);
  684. break;
  685. case 3: // DL ML TD - belongs to the torrent and magnet links script
  686. currentElement.addClass('mldl alt-darker');
  687. currentElement.prepend('DL ML: ');
  688. break;
  689. case 4: // Added TD
  690. currentElement.addClass('added alt-deco');
  691. currentElement.prepend('Added: ');
  692. break;
  693. case 5: // Size TD
  694. currentElement.addClass('size alt-size');
  695. currentElement.prepend('Size: ');
  696. break;
  697. case 6: // Seed TD
  698. currentElement.addClass('seeders badge');
  699. currentElement.prepend('Seeds: ');
  700. currentElement.find('font').removeAttr('color');
  701. break;
  702. case 7: // Leecher TD
  703. currentElement.addClass('leechers badge');
  704. currentElement.prepend('Leechers: ');
  705. currentElement.find('font').removeAttr('color');
  706. break;
  707. case 8: // Comments TD
  708. currentElement.addClass('comments');
  709. currentElement.prepend('# Comments: ');
  710. break;
  711. case 9: // Uploader TD
  712. currentElement.addClass('uploader');
  713. currentElement.prepend('# Uploader: ');
  714. break;
  715. }
  716. } else {
  717. switch (childIndex) {
  718. case 1: // thumbnail TD
  719. currentElement.addClass('thumb');
  720. break;
  721. case 2: // file TD
  722. currentElement.addClass('file');
  723. currentElement.find('a:first-child').addClass('alt-layout');
  724. currentElement = currentElement.find('a:first-child');
  725. fileName = currentElement.text().replace(/\./g,' ');
  726. currentElement.text(fileName);
  727. break;
  728. case 3: // Added TD
  729. currentElement.addClass('added alt-deco');
  730. currentElement.prepend('Added: ');
  731. break;
  732. case 4: // Size TD
  733. currentElement.addClass('size alt-size');
  734. currentElement.prepend('Size: ');
  735. break;
  736. case 5: // Seed TD
  737. currentElement.addClass('seeders badge');
  738. currentElement.prepend('Seeds: ');
  739. currentElement.find('font').removeAttr('color');
  740. break;
  741. case 6: // Leecher TD
  742. currentElement.addClass('leechers badge');
  743. currentElement.prepend('Leechers: ');
  744. currentElement.find('font').removeAttr('color');
  745. break;
  746. case 7: // Comments TD
  747. currentElement.addClass('comments');
  748. currentElement.prepend('# Comments: ');
  749. break;
  750. case 8: // Uploader TD
  751. currentElement.addClass('uploader');
  752. currentElement.prepend('# Uploader: ');
  753. break;
  754. }
  755. }
  756. });
  757. });
  758.  
  759. // Sorting Buttons
  760. $('<div id="TorrentGridControls"/>').insertBefore('#TorrentGrid');
  761. $.each($('.lista2t tbody tr:first-child td'), function(index) {
  762. const CONTENT = $(this).html();
  763. if (CONTENT.match('tdlinkfull3')) {
  764. const HREF = $(this).find('.tdlinkfull3').attr('href');
  765. const BUTTON_ID = HREF.substring(HREF.lastIndexOf('order=')+6,HREF.indexOf('&by='));
  766. let buttonName = BUTTON_ID.charAt(0).toUpperCase() + BUTTON_ID.substr(1).toLowerCase();
  767. if (buttonName === 'Data') buttonName = 'Added';
  768. $('#TorrentGridControls').append('<span href="' + HREF + '" class="btn btn-primary jQGridSort">Sort ' + buttonName + '</span>');
  769. }
  770. });
  771.  
  772. // Sorting title logic
  773. const URL = window.location.href;
  774. let sorting_by = URL.substring(URL.lastIndexOf('&by=')+4,URL.indexOf('&page='));
  775. if (URL.indexOf('&page=') === -1) sorting_by = URL.substring(URL.lastIndexOf('&by=')+4);
  776. const BUTTON_ID = URL.substring(URL.lastIndexOf('order=')+6,URL.indexOf('&by='));
  777. if (BUTTON_ID === 'https') {
  778. $('#TorrentGridControls').prepend('<h3>Not Sorted</h3>');
  779. } else {
  780. let buttonName = BUTTON_ID.charAt(0).toUpperCase() + BUTTON_ID.substr(1).toLowerCase();
  781. if (buttonName === 'Data') buttonName = 'Added';
  782. $('#TorrentGridControls').prepend('<h3>' + sorting_by + ' Sorted by ' + buttonName + '</h3>');
  783. }
  784.  
  785. // Event trigger for sorting buttons
  786. $(document).on('click', '.jQGridSort', function (){
  787. location.href = $(this).attr('href');
  788. });
  789.  
  790. // Removes the list from the DOM
  791. $('.lista2t').remove();
  792.  
  793. }
  794.  
  795. });

QingJ © 2025

镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址