Skip to content

Instantly share code, notes, and snippets.

@d-s-x
Forked from koteq/mal_sort_plan2watch.js
Last active April 26, 2022 07:01
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save d-s-x/7379d7292d5267729afea24bf450a03a to your computer and use it in GitHub Desktop.
Save d-s-x/7379d7292d5267729afea24bf450a03a to your computer and use it in GitHub Desktop.
myanimelist.net sort plan to wach by rank #mal
// ==UserScript==
// @name MAL PTW Fetch Sort
// @description This script adds "Fetch Sort" button to the "Plan to watch" page. The button sorts the list by MAL's avg. score
// @namespace d-s-x
// @version 1.0
// @author d-s-x
// @match https://myanimelist.net/animelist/*status=6*
// @grant none
// ==/UserScript==
(function() {
if (document.querySelector('#fetch-sort-button')) return;
const stats = document.querySelector('.stats');
stats.innerHTML = '<a href="javascript: void(0);" id="fetch-sort-button"><i class="fa-solid fa-sort"></i> Fetch Sort</a>' + stats.innerHTML;
document.querySelector('#fetch-sort-button').onclick = () => {
const titles = Array.from(document.querySelectorAll('.list-item .title a[href^="/anime/"]:not(.icon-watch)'));
console.log(`titles: ${titles.length}`);
const retryDelay = 1000; // ms
const requestDocument = (url, callback) => {
const request = new XMLHttpRequest();
request.open('GET', url);
request.responseType = 'document';
request.onload = () => {
if (request.status === 429) {
setTimeout(requestDocument, retryDelay, url, callback);
} else {
callback(request.status === 200 && request.response);
}
};
request.onerror = () => {
callback();
};
request.send();
}
let downloaded = 0;
const parseResponse = (title, page) => {
const item = title.closest('.list-item');
if (page) {
const score = page.querySelector('[itemprop="ratingValue"]');
//const users = page.querySelector('[itemprop="ratingCount"]');
item._weigth = score && parseFloat(score.textContent);
}
scoreHTML = `<span>${item._weigth && item._weigth.toFixed(2) || 'N/A'}</span>`
item.querySelector('td.score').innerHTML = scoreHTML;
if (++downloaded === titles.length) {
console.log('fetch done');
const container = title.closest('.list-table');
const rows = Array.from(container.querySelectorAll('.list-item'));
rows.sort((a, b) => b._weigth - a._weigth);
for (let row of rows) {
container.append(row);
}
}
};
for (const title of titles) {
const url = title.href;
title.closest('.list-item').querySelector('td.score').innerHTML = `<span>...</span>`;
requestDocument(url, (d) => parseResponse(title, d));
}
};
})();
@yarushi
Copy link

yarushi commented May 20, 2018

Really good, thanks <3

@lord-ne
Copy link

lord-ne commented Aug 5, 2018

Not working currently. Button appears but does nothing when pressed

@sarthaka1310
Copy link

Thanks, works!

@3allak
Copy link

3allak commented Aug 12, 2021

can I add this to as part of a theme instead of running it in console every time?

@d-s-x
Copy link
Author

d-s-x commented Aug 12, 2021

@3allak

can I add this to as part of a theme instead of running it in console every time?

You poor soul! This is supposed to be used with greasemonkey/tampermonkey.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment