Automatically sort video results in a page on /videos, /images, /subscriptions, /users, and sidebars using customizable sort function.
当前为
// ==UserScript==
// @name Iwara Custom Sort
// @version 0.117
// @grant GM.setValue
// @grant GM.getValue
// @grant GM.deleteValue
// @match https://ecchi.iwara.tv/*
// @match https://www.iwara.tv/*
// @match http://ecchi.iwara.tv/*
// @match http://www.iwara.tv/*
// @description Automatically sort video results in a page on /videos, /images, /subscriptions, /users, and sidebars using customizable sort function.
// @namespace https://greasyfork.org/users/245195
// ==/UserScript==
/* jshint esversion: 6 */
const logDebug = (...args) => {
const debugging = true;
if (debugging) {
console.log(...args);
}
}
logDebug('Parsed.');
const parsePrefixed = (str) => {
return Number.parseFloat(str) * (str.includes('k') ? 1000 : 1);
}
const sortVideos = (container, sortValueExpression) => {
const videoDivs = Array.from(container.querySelectorAll('.clearfix'));
const views = videoDivs.map(div => div.querySelector('.glyphicon-eye-open'))
.map(div => div ? parsePrefixed(div.parentElement.textContent) : 0);
const likes = videoDivs.map(div => div.querySelector('.glyphicon-heart'))
.map(div => div ? parsePrefixed(div.parentElement.textContent) : 0);
const videoEntries = Object.entries(videoDivs);
GM.setValue('sortValue', sortValueExpression);
const evalSortValue = (views, likes) => {
const ratio = Math.min(likes / Math.max(1, views), 1);
return eval(sortValueExpression);
}
videoEntries.sort((entryA, entryB) => {
return evalSortValue(views[entryB[0]], likes[entryB[0]]) - evalSortValue(views[entryA[0]], likes[entryA[0]]);
});
videoDivs.map(div => div.parentElement)
.forEach((div, index) => {
div.append(videoEntries[index][1]);
});
};
const sortAllVideos = (containers, sortValueExpression) => {
let containerCount = 0;
try {
containers.forEach((container) => {
sortVideos(container, sortValueExpression);
containerCount++;
});
} catch (message) {
alert(message);
}
logDebug(`${containerCount} containers sorted.`);
};
const requestMorePages = async (URL, pageCount) => {
/*
const params = URL.searchParams;
const page =params.has('page') ? Number.parseInt(params.get('page')) : 0;
params.set('page', page + 1);
try {
const newPage = await fetch(URL);
logDebug(page, pageCount, URL, new DOMParser().parseFromString(await newPage.text(), 'text/html'));
} catch (message) {
logDebug(message);
}
*/
}
(async () => {
const videoContainers = Array.from(document.querySelectorAll('.views-responsive-grid'));
if (videoContainers.length === 0) {
return;
}
const currentURL = new URL(location);
if (/\/(videos|images|subscriptions)/.test(currentURL.pathname)) {
const additionalPageCount = 2;
requestMorePages(currentURL, additionalPageCount);
}
const sortValueInput = document.createElement('input');
sortValueInput.type = 'text';
sortValueInput.value = await GM.getValue('sortValue', '100 * ratio + Math.sqrt(likes) / 25');
const UIDiv = document.createElement('div');
UIDiv.style.display = 'inline';
UIDiv.style.margin = '5px';
UIDiv.append(sortValueInput);
const sortButton = document.createElement('button');
sortButton.innerHTML = 'Sort';
UIDiv.append(sortButton);
sortValueInput.addEventListener('keyup', (event) => {
if (event.key !== "Enter") {
return;
}
sortButton.click();
event.preventDefault();
});
const temp = document.querySelector('.list-inline');
if (temp) {
temp.append(UIDiv);
} else {
document.querySelector('#user-links').insertAdjacentElement('afterbegin', UIDiv);
}
sortButton.addEventListener('click', () => sortAllVideos(videoContainers, sortValueInput.value));
sortAllVideos(videoContainers, sortValueInput.value);
})();