Export Your Anime/Manga XML List On Any Page + Wayback Machine Your Profile.

This script adds a button on any anime/manga page, click on this button to download your Anime/Manga XML list. There's a button that's added on your profile only and Backups Your Profile using the Wayback Machine services.

Встановити цей скрипт?
Скрипт запропонований Автором

Вам також може сподобатись Better Buttons To Edit Anime/Manga Information.

Встановити цей скрипт
// ==UserScript==
// @name         Export Your Anime/Manga XML List On Any Page + Wayback Machine Your Profile.
// @namespace    http://tampermonkey.net/
// @version      25
// @description  This script adds a button on any anime/manga page, click on this button to download your Anime/Manga XML list. There's a button that's added on your profile only and Backups Your Profile using the Wayback Machine services.
// @author       hacker09
// @match        https://myanimelist.net/profile/*
// @exclude      https://myanimelist.net/profile/*/*
// @match        https://myanimelist.net/editprofile.php
// @match        https://myanimelist.net/panel.php?go=export
// @include      /^https:\/\/myanimelist\.net\/(anime|manga)(id=)?(\.php\?id=)?\/?\d+\/?(?!.*\/).*(\?q=.*&cat=anime|manga)?$/
// @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        window.close
// @grant        GM_setValue
// @grant        GM_getValue
// ==/UserScript==

(function() {
  'use strict';
  const $ = jQuery; //Defines That The Symbol $ Is A jQuery
  const username = document.querySelector('a.header-profile-link').innerText; //Save the user name to a variable

  if (location.href === 'https://myanimelist.net/panel.php?go=export') { //If the user is on the export MAL page
    document.querySelector("input.inputButton").defaultValue = "Export My List Now"; //Change the export button text
  }
  //*****************************************************************************************************************************************************
  if (location.href.match(/^https:\/\/myanimelist\.net\/anime\/[\d]+(\/.*)?/) || location.href.match(/^https:\/\/myanimelist\.net\/manga\/[\d]+(\/.*)?/)) { //If the user is on a manga/anime page
    var type, downtype; //Make these variables global
    const token = document.head.querySelector("[name='csrf_token']").content; //Save the user csrf_token to a variable

    location.pathname.split('/')[1] === 'anime' ? (type = 'anime', downtype = 'type=1') : (type = 'manga', downtype = 'type=2'); //Set the page and download types
    const XMLBackupBTN = document.createElement("a"); //Creates the backup button element
    type === 'anime' ? XMLBackupBTN.innerHTML = "Backup My AnimeList" : XMLBackupBTN.innerHTML = "Backup My MangaList"; //Add the correct text to the button
    document.querySelector("span.information.type").parentElement.appendChild(XMLBackupBTN); //Add the button to the page
    XMLBackupBTN.setAttribute("id", "XMLBackupBTN"); //Adds an id to the button
    XMLBackupBTN.setAttribute("style", "cursor: pointer;margin-left: 15px;font-size: 10px;"); //Sets the CSS style of the button
    document.querySelector("#XMLBackupBTN").addEventListener("click", function() { //Add a click advent listener to the button
      (async function() { //Starts the async function
        const response = await fetch("https://myanimelist.net/panel.php?go=export2", { //Fetch the export MAL page
          "headers": { //Adds the header to the request
            "content-type": "application/x-www-form-urlencoded" //Set the content type
          }, //Ends the fetch request headers
          "body": downtype + "&subexport=Export+My+List&csrf_token=" + token, //Define the download type
          "method": "POST" //Fetch as POST
        }); //Finishes the fetch request
        const filename = response.headers.get('Content-Disposition').split(';')[1].split('=')[1].split('"')[1]; //Store the file name
        const blob = await response.blob(); //Gets the fetch response //Store the file bytes
        const link = document.createElement("a"); //Creates a new link element
        link.href = URL.createObjectURL(blob); //Add the file bytes as a blob link in the link element
        link.download = filename; //Add the file name and download to the link element
        link.click(); //Click on the link element
      }()); //Finishes the async function
    }, false); //Finishes the advent listener
  } //Finishes the if condition
  //*****************************************************************************************************************************************************
  if (location.href === 'https://myanimelist.net/editprofile.php') { //If the user is on the edit profile page
    document.querySelectorAll("textarea")[1].parentNode.insertAdjacentHTML('beforeend', '<a style="cursor: pointer;" id="Import"> Import Previous Profile BBCodes</a>'); //Append the Import btn below the textarea
    document.querySelector("#Import").onclick = function() //Detect the mouse click on the import button
    { //Starts the onclick function
      document.querySelectorAll("textarea")[1].value = GM_getValue("ProfileBBCodes"); //When the import btn is clicked return the previous ProfileBBCodes
    }; //Finishes the onclick function
  } //Finishes the if condition
  //*****************************************************************************************************************************************************
  if (location.href.match('profile/' + username) !== null) { //If the user is on his profile page
    const BackupProfileBTN = document.createElement("a"); //Creates the backup profile button element
    BackupProfileBTN.innerHTML = "Backup My Profile"; //Adds a text to the button
    document.querySelector("a.header-right.mt4.mr0").parentElement.appendChild(BackupProfileBTN); //Add the button to the page
    BackupProfileBTN.setAttribute("id", "BackupProfileBTN"); //Set an id to the button
    BackupProfileBTN.setAttribute("style", "cursor: pointer;margin-left: 15px;font-size: 10px;"); //Set the button css style
    document.querySelector("#BackupProfileBTN").addEventListener("click", saveprofileonarchiveorg, false); //Add a click advent listener to the button

    function saveprofileonarchiveorg() { //Starts the function to backup the user profile
      function iFrameLoaded(id, src) { //Creates a function
        const deferred = $.Deferred(),
          iframe = $("<iframe id='iframe'></iframe>").attr({ //Creates the iframe
            "id": id, //Sets the iframe id
            "src": src //Sets the iframe source
          }); //Finishes the attrib

        iframe.load(deferred.resolve); //Load the page and wait to be fully loaded
        iframe.appendTo("body"); //Add the iframe to the actual page body

        deferred.done(function() { //When the iframe finished loading
          console.log("iframe loaded: " + id); //Show a message on the browser console for dev purposes
        }); //Finishes the function

        return deferred.promise();
      } //Finishes the IframeLoaded function
      $.when(iFrameLoaded("Update MALGraph", "https://anime.plus/" + username + "/queue-add"),
          iFrameLoaded("Update Badges", "https://www.mal-badges.net/users/" + username + "/update"),
          iFrameLoaded("Currently Watching", "https://web.archive.org/save/https://myanimelist.net/animelist/" + username + "?status=1"),
          iFrameLoaded("Completed", "https://web.archive.org/save/https://myanimelist.net/animelist/" + username + "?status=2"),
          iFrameLoaded("On Hold", "https://web.archive.org/save/https://myanimelist.net/animelist/" + username + "?status=3"),
          iFrameLoaded("Dropped", "https://web.archive.org/save/https://myanimelist.net/animelist/" + username + "?status=4"),
          iFrameLoaded("Plan to Watch", "https://web.archive.org/save/https://myanimelist.net/animelist/" + username + "?status=6"),
          iFrameLoaded("Topics in Forum Replied To", "https://web.archive.org/save/https://myanimelist.net/forum/search?u=" + username + "&q=&uloc=1&loc=-1"),
          iFrameLoaded("MAL History", "https://web.archive.org/save/https://myanimelist.net/history/" + username + "/anime"),
          iFrameLoaded("Profile texts/statistics/Favorites/Comments and 12 Friends", "https://web.archive.org/save/https://myanimelist.net/profile/" + username + "#statistics"),
          iFrameLoaded("Clubs", "https://web.archive.org/save/https://myanimelist.net/profile/" + username + "/clubs"),
          iFrameLoaded("Recommendations", "https://web.archive.org/save/https://myanimelist.net/profile/" + username + "/recommendations"),
          iFrameLoaded("Reviews", "https://web.archive.org/save/https://myanimelist.net/profile/" + username + "/reviews"))
        .then(function() { //After all iframes finished loading

          (async () => { //Creates a function to get the ProfileBBCpdes and Starts the function
            const response = await (await fetch('https://myanimelist.net/editprofile.php')).text(); //Fetch
            const newDocument = new DOMParser().parseFromString(response, 'text/html'); //Parses the fetch response
            GM_setValue("ProfileBBCodes", newDocument.querySelectorAll("textarea")[1].value); //Store the ProfileBBCodes
            close(); //Close the actual tab
          })(); //Finishes the async function
        }); //Finishes the "then" function
    } //Finishes the saveprofileonarchiveorg function
  } //Finishes the if condition
})();