Iwara Custom Sort

Automatically sort video results in a page on /videos, /images, /subscriptions, and sidebars using customizable sort function.

当前为 2019-02-08 提交的版本,查看 最新版本

  1. // ==UserScript==
  2. // @name Iwara Custom Sort
  3. // @version 0.112
  4. // @grant GM.setValue
  5. // @grant GM.getValue
  6. // @grant GM.deleteValue
  7. // @match https://ecchi.iwara.tv/*
  8. // @match https://www.iwara.tv/*
  9. // @match http://ecchi.iwara.tv/*
  10. // @match http://www.iwara.tv/*
  11. // @description Automatically sort video results in a page on /videos, /images, /subscriptions, and sidebars using customizable sort function.
  12. // @namespace https://gf.qytechs.cn/users/245195
  13. // ==/UserScript==
  14.  
  15. /* jshint esversion: 6 */
  16.  
  17. const logDebug = (...args) => {
  18. const debugging = true;
  19. if (debugging) {
  20. console.log(...args);
  21. }
  22. }
  23.  
  24. logDebug('Parsed.');
  25.  
  26. const sortValueInput = document.createElement('input');
  27.  
  28. const parsePrefixed = (str) => {
  29. return Number.parseFloat(str) * (str.includes('k') ? 1000 : 1);
  30. }
  31.  
  32. const sortVideos = (videosContainer) => {
  33. const videoDivs = Array.from(videosContainer.querySelectorAll('.clearfix'));
  34. const views = videoDivs.map(div => div.querySelector('.glyphicon-eye-open'))
  35. .map(div => div ? parsePrefixed(div.parentElement.textContent) : 0);
  36. const likes = videoDivs.map(div => div.querySelector('.glyphicon-heart'))
  37. .map(div => div ? parsePrefixed(div.parentElement.textContent) : 0);
  38. const videoEntries = Object.entries(videoDivs);
  39. GM.setValue('sortValue', sortValueInput.value);
  40. const evalSortValue = (views, likes) => {
  41. const ratio = Math.min(likes / Math.max(1, views), 1);
  42. return eval(sortValueInput.value);
  43. }
  44. videoEntries.sort((entryA, entryB) => {
  45. return evalSortValue(views[entryB[0]], likes[entryB[0]]) - evalSortValue(views[entryA[0]], likes[entryA[0]]);
  46. });
  47. videoDivs.map(div => div.parentElement)
  48. .forEach((div, index) => {
  49. div.append(videoEntries[index][1]);
  50. });
  51. };
  52.  
  53. const sortAllVideos = () => {
  54. let gridCount = 0;
  55. document.querySelectorAll('.views-responsive-grid').forEach((grid) => {
  56. sortVideos(grid);
  57. gridCount++;
  58. });
  59. logDebug(`${gridCount}grids sorted.`);
  60. };
  61.  
  62. const requestMorePages = (URL, pageCount) => {
  63. const params = URL.searchParams;
  64. const page = params.has('page') ? params.get('page') : 0;
  65. logDebug(page, pageCount);
  66. }
  67.  
  68. (async () => {
  69. const currentURL = new URL(location);
  70. if (/\/(videos|images|subscriptions)/.test(currentURL.pathname)) {
  71. const additionalPageCount = 2;
  72. requestMorePages(currentURL, additionalPageCount);
  73. }
  74. sortValueInput.type = 'text';
  75. sortValueInput.value = await GM.getValue('sortValue', '100 * ratio + Math.sqrt(likes) / 25');
  76. const uiContainer = (() => {
  77. const temp = document.querySelector('.list-inline');
  78. if (temp) {
  79. return temp;
  80. } else {
  81. return document.querySelector('#user-links');
  82. }
  83. })();
  84. uiContainer.insertAdjacentElement('afterbegin', sortValueInput);
  85. const sortButton = document.createElement('button');
  86. sortButton.innerHTML = 'Sort';
  87. uiContainer.insertAdjacentElement('afterbegin', sortButton);
  88. sortButton.addEventListener('click', sortAllVideos);
  89. sortAllVideos();
  90. })();

QingJ © 2025

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