Mediux Titlecards Fix

Inserts Season #s into Titlecard YAML and fixes errors where no posters are available

目前为 2024-10-10 提交的版本。查看 最新版本

// ==UserScript==
// @name         Mediux Titlecards Fix
// @license      MIT
// @version      1.0
// @description  Inserts Season #s into Titlecard YAML and fixes errors where no posters are available
// @author       azuravian
// @require      https://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js
// @match        https://mediux.pro/*
// @grant        none
// @run-at       document-end
// @namespace    https://greasyfork.org/users/1025348
// ==/UserScript==

waitForKeyElements(
    "code.whitespace-pre-wrap",
    start);

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

function get_posters() {
  const regexpost = /posterCheck/g
  var scriptlist = document.querySelectorAll('script')
  for (let i = scriptlist.length - 1; i >= 0; i--) {
    const element = scriptlist[i];
    if (regexpost.test(element.textContent)) {
      var str1 = element.textContent.replace('self.__next_f.push(', '');
      var str1 = str1.substring(0, str1.length - 1);
      var jsonString = JSON.parse(str1)[1].split('{"set":')[1];
      var fullJson = `{"set":${jsonString}`;
      var parsedObject = JSON.parse(fullJson.substring(0, fullJson.length - 2));
      return parsedObject.set.files;
    }
  }
}

function color_change(button) {
  button.classList.remove('bg-gray-500');
  button.classList.add('bg-green-500');

  // After 2 seconds, change it back to bg-gray-500
  setTimeout(() => {
    button.classList.remove('bg-green-500');
    button.classList.add('bg-gray-500');
  }, 2000); // 2000 milliseconds = 2 seconds
}

function fix_posters(codeblock) {
  const button = document.querySelector('#fpbutton');
  var yaml = codeblock.textContent;
  var posters = get_posters();
  var seasons = posters.filter((poster) => poster.title.includes("Season"));
  for (i in seasons) {
    var current = seasons.filter((season) => season.title.includes(`Season ${i}`));
    yaml = yaml + `      ${i}:\n        url_poster: https://api.mediux.pro/assets/${current[0].id}\n`;
  }
  yaml = yaml.substring(0, yaml.length - 1);
  codeblock.innerText = yaml;
  navigator.clipboard.writeText(yaml);
  color_change(button);
}

function fix_cards(codeblock) {
  const button = document.querySelector('#fcbutton');
  const str = codeblock.innerText;
  const regextest = /(seasons:\n)(        episodes:)/g;
  const regex = /(        episodes:)/g;
  let counter = 1;
  if (regextest.test(str)) {
    const modifiedStr = str.replace(regex, (match) => {
      const newLine = `      ${counter++}:\n`; // Create the new line with the counter
      return `${newLine}${match}`; // Return the new line followed by the match
    });
    codeblock.innerText = modifiedStr;
    navigator.clipboard.writeText(modifiedStr);
    color_change(button);
  }
}

function start() {
  const codeblock = document.querySelector('code.whitespace-pre-wrap');
  var fpbutton = $('<button id="fpbutton" class="absolute duration-500 top-1 right-1 text-xs py-1 px-2 bg-gray-500 text-white rounded flex items-center justify-center" style="margin-top:30px"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-gallery-horizontal-end w-5 h-5"><path d="M2 7v10"></path><path d="M6 5v14"></path><rect width="12" height="18" x="10" y="3" rx="2"></rect></svg></button>');
    // Set the onclick event to call the runner function
    fpbutton.on('click', () => fix_posters(codeblock));

    // Insert the button after the code element with class "whitespace-pre-wrap"
    $('.whitespace-pre-wrap').after(fpbutton);

  var fcbutton = $('<button id="fcbutton" class="absolute duration-500 top-1 right-1 text-xs py-1 px-2 bg-gray-500 text-white rounded flex items-center justify-center" style="margin-top:60px"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-gallery-vertical-end w-5 h-5"><path d="M7 2h10"></path><path d="M5 6h14"></path><rect width="18" height="12" x="3" y="10" rx="2"></rect></svg></button>');
    // Set the onclick event to call the runner function
    fcbutton.on('click', () => fix_cards(codeblock));

    // Insert the button after the fpbutton
    $('#fpbutton').after(fcbutton);
}


/*--- waitForKeyElements():  A utility function, for Greasemonkey scripts,
    that detects and handles AJAXed content.
    Usage example:
        waitForKeyElements (
            "div.comments"
            , commentCallbackFunction
        );
        //--- Page-specific function to do what we want when the node is found.
        function commentCallbackFunction (jNode) {
            jNode.text ("This comment changed by waitForKeyElements().");
        }
    IMPORTANT: This function requires your script to have loaded jQuery.
*/
function waitForKeyElements (
    selectorTxt,    /* Required: The jQuery selector string that
                        specifies the desired element(s).
                    */
    actionFunction, /* Required: The code to run when elements are
                        found. It is passed a jNode to the matched
                        element.
                    */
    bWaitOnce,      /* Optional: If false, will continue to scan for
                        new elements even after the first match is
                        found.
                    */
    iframeSelector  /* Optional: If set, identifies the iframe to
                        search.
                    */
) {
    var targetNodes, btargetsFound;

    if (typeof iframeSelector == "undefined")
        targetNodes     = jQuery(selectorTxt);
    else
        targetNodes     = jQuery(iframeSelector).contents ()
                                           .find (selectorTxt);

    if (targetNodes  &&  targetNodes.length > 0) {
        btargetsFound   = true;
        /*--- Found target node(s).  Go through each and act if they
            are new.
        */
        targetNodes.each ( function () {
            var jThis        = jQuery(this);
            var alreadyFound = jThis.data ('alreadyFound')  ||  false;

            if (!alreadyFound) {
                //--- Call the payload function.
                var cancelFound     = actionFunction (jThis);
                if (cancelFound)
                    btargetsFound   = false;
                else
                    jThis.data ('alreadyFound', true);
            }
        } );
    }
    else {
        btargetsFound   = false;
    }

    //--- Get the timer-control variable for this selector.
    var controlObj      = waitForKeyElements.controlObj  ||  {};
    var controlKey      = selectorTxt.replace (/[^\w]/g, "_");
    var timeControl     = controlObj [controlKey];

    //--- Now set or clear the timer as appropriate.
    if (btargetsFound  &&  bWaitOnce  &&  timeControl) {
        //--- The only condition where we need to clear the timer.
        clearInterval (timeControl);
        delete controlObj [controlKey]
    }
    else {
        //--- Set a timer, if needed.
        if ( ! timeControl) {
            timeControl = setInterval ( function () {
                    waitForKeyElements (    selectorTxt,
                                            actionFunction,
                                            bWaitOnce,
                                            iframeSelector
                                        );
                },
                300
            );
            controlObj [controlKey] = timeControl;
        }
    }
    waitForKeyElements.controlObj   = controlObj;
}