Greasy Fork

Greasy Fork is available in English.

Anime list total time - MAL

Shows the total amount of time you will take to watch all entries on your anime list.

当前为 2022-07-30 提交的版本,查看 最新版本

// ==UserScript==
// @name         Anime list total time - MAL
// @namespace    http://greasyfork.icu/en/users/670188-hacker09?sort=daily_installs
// @version      2
// @description  Shows the total amount of time you will take to watch all entries on your anime list.
// @author       hacker09
// @match        https://myanimelist.net/profile/*
// @icon         https://t3.gstatic.com/faviconV2?client=SOCIAL&type=FAVICON&fallback_opts=TYPE,SIZE,URL&url=http://myanimelist.net&size=64
// @run-at       document-end
// @grant        none
// ==/UserScript==

(async function() {
  'use strict';
  document.head.insertAdjacentHTML('beforeend', '<style>.di-ib.fl-r.lh10 {cursor: pointer;}</style>'); //Make each status total entry number look clickable
  document.querySelectorAll(".di-ib.fl-r.lh10").forEach(async function(el, i) { //ForEach status total entry number
    el.onclick = async function() //When the user clicks on the status total entry number
    { //Starts the onclick event listener
      var stats; //Set a global variable
      var EntryIds = []; //Create a new array
      var TotalHrMins = ['0']; //Create a new array
      var nextpagenum = 0; //Create a variable to hold the page number
      var Counter = 0; //Create a variable to hold the Total Entries Number
      var increaseby = 300; //Create a variable to Increase the list page number

      alert(`This process will take about ${(Math.floor(el.innerText.match(/\d+,?\d+/g)[0].replace(',','') * 2 / 60))}:${el.innerText.match(/\d+,?\d+/g)[0].replace(',','') * 2 % 60} minutes to complete\n\nPlease avoid opening any MAL links during that time!`); //Let the user know how log it will take

      switch (i) { //Detect the user choice
        case 0: //If the user clicked on Watching
          stats = 1; //Change the variable value
          document.querySelector("h5").style.backgroundColor = '#2db039'; //Change the bg color to match the selected status
          break; //Stop executing the switch statement
        case 1: //If the user clicked on Completed
          stats = 2; //Change the variable value
          document.querySelector("h5").style.backgroundColor = '#26448f'; //Change the bg color to match the selected status
          break; //Stop executing the switch statement
        case 2: //If the user clicked on On-Hold
          stats = 3; //Change the variable value
          document.querySelector("h5").style.backgroundColor = '#f9d457'; //Change the bg color to match the selected status
          break; //Stop executing the switch statement
        case 3: //If the user clicked on Dropped
          stats = 4; //Change the variable value
          document.querySelector("h5").style.backgroundColor = '#a12f31'; //Change the bg color to match the selected status
          break; //Stop executing the switch statement
        case 4: //If the user clicked on Plan to Watch
          stats = 6; //Change the variable value
          document.querySelector("h5").style.backgroundColor = '#c3c3c3'; //Change the bg color to match the selected status
          break; //Stop executing the switch statement
      } //Finishes the switch statement

      while (true) { //Starts the while condition to get the Total Number of Entries on the user list
        const entries = await (await fetch(`https://myanimelist.net/animelist/${location.href.split('/')[4]}/load.json?status=${stats}&offset=${nextpagenum}`)).json(); //Fetches the user list
        nextpagenum += increaseby; //Increase the next page number
        var TotalEntries = entries.length; //Save the Total Entries Number
        Counter += TotalEntries; //Sum the Total Entries Number to TotalEntries
        entries.forEach(el => EntryIds.push(el.anime_id)); //Save all entry ids
        if (TotalEntries !== 300) //If the next page has less than 300 entries stop looping the while condition
        { //Starts the if condition
          console.log('Finished Getting the Total Entries Number!'); //Shows a console message
          EntryIds.forEach(async function(id, index) { //For each entry id
            setTimeout(async function() { //Starts the settimeout
              const response = await (await fetch("https://myanimelist.net/includes/ajax-no-auth.inc.php?t=6", { //Fetch
                "headers": {
                  "content-type": "application/x-www-form-urlencoded; charset=UTF-8"
                },
                "body": `color=1&id=${id}&memId=${document.querySelector("input[name*=profileMemId]") !== null ? document.querySelector("input[name*=profileMemId]").value : document.querySelector(".mr0").href.match(/\d+/g)[0]}&type=anime&csrf_token=${document.querySelector("meta[name=csrf_token]").content}`,
                "method": "POST",
                "mode": "cors"
              })).text(); //Get each entry individual episode duration times
              const newDocument = new DOMParser().parseFromString(response, 'text/html'); //Parses the fetch response
              const json = await (await fetch(`https://api.jikan.moe/v4/anime/${id}/full`)).json(); //Fetch to get the eps

              var TotalEpisodes = json.data.episodes; //Get the amount of eps
              var TotalMins = TotalEpisodes * newDocument.querySelectorAll("td > div > a:nth-child(2) > small")[0].childNodes[0].data.match(/\d+/g)[1]; //Multiply Extracted Eps By Mins
              var TotalHrs = TotalEpisodes * newDocument.querySelectorAll("td > div > a:nth-child(2) > small")[0].childNodes[0].data.match(/\d+/g)[0] * 60; //Multiply Eps By Hrs
              TotalHrMins.push(TotalHrs, TotalMins); //Add Hrs And Mins To The Array
              var TotalMinsResult = TotalHrMins.filter(Boolean).map(i => Number(i)).reduce((a, b) => a + b); //Sum Hrs in Mins + Total Mins
              var days = Math.floor(TotalMinsResult / 1440); //Get total days amount
              var hours = Math.floor((TotalMinsResult % 1440) / 60); //Get total hours amount
              var minutes = (TotalMinsResult % 1440) % 60; //Get total minutes amount
              document.querySelector("h5").innerText = 'Anime Stats (' + days + ' Days ' + hours + ' Hours ' + minutes + ' Minutes)'; //Show the total time

              if (EntryIds.length - 1 === index) //If it's the last loop
              { //Starts the if condition
                document.querySelector("h5").innerText += ' ✔️'; //Shows a console message
              } //Finishes the if condition

            }, index * 2000); //Finishes the settimeout function
          }); //Finishes the for each condition
          return; //Stop the script if fetched page has less than 300 entries and run the EntryIds.forEach loop
        } //Finishes the if condition
      } //Finishes the while condition
    }; //Finishes the onclick event listener
  }); //Finishes the foreach loop
})();