Greasy Fork is available in English.

Ps4Trainer JSON Downloader

Descarga archivos JSON de la página de juegos ps4trainer.com

// ==UserScript==
// @name         Ps4Trainer JSON Downloader
// @namespace    https://greasyfork.org/es/scripts/466743
// @version      1.1
// @description  Descarga archivos JSON de la página de juegos ps4trainer.com
// @description  Download JSON files from the ps4trainer.com games page
// @author       Shu2Ouma
// @icon         http://ps4trainer.com/Trainer/favicon.png
// @match        http://ps4trainer.com/Trainer/index.html
// @grant        none
// ==/UserScript==

(function() {
  'use strict';

  // Declaración de variables
  // Variable declaration
  let links = {};
  let counter = 0;
  let showOnlyNew = false;
  let searchText = '';

  // Crear contenedor de lista de enlaces
  // Create links list container
  const listContainer = document.createElement('div');
  listContainer.style.cssText = 'display: none; position: fixed; top: 30px; right: 10px; width: 300px; max-height: 500px; overflow-y: scroll; background-color: #333; color: #fff; padding: 10px; border-radius: 5px; z-index: 999;';
  document.body.appendChild(listContainer);

  // Crear botón de alternancia para mostrar/ocultar la lista
  // Create toggle button to show/hide the list
  const toggleButton = document.createElement('button');
  toggleButton.textContent = 'Archivos JSON: ' + counter;
  toggleButton.style.cssText = 'position: fixed; top: 0; right: 0; padding: 5px; font-size: 16px; background-color: #333; color: #fff; border: none; cursor: pointer; border-radius: 5px;';
  document.body.appendChild(toggleButton);

  // Crear botón para descargar todos los archivos
  // Create button to download all files
  const downloadAllButton = document.createElement('button');
  downloadAllButton.textContent = 'Descargar Todo';
  downloadAllButton.style.cssText = 'margin-top: 5px; padding: 5px; font-size: 16px; background-color: #377dff; color: #fff; border: none; border-radius: 5px; cursor: pointer;';
  listContainer.appendChild(downloadAllButton);

  // Crear contenedor de interruptor para mostrar solo nuevos enlaces
  // Create switch container to show only new links
  const switchContainer = document.createElement('div');
  switchContainer.classList.add('switch-container');
  listContainer.appendChild(switchContainer);

  // Crear entrada de interruptor
  // Create switch input
  const switchInput = document.createElement('input');
  switchInput.type = 'checkbox';
  switchInput.id = 'switch';
  switchContainer.appendChild(switchInput);

  // Crear etiqueta para el interruptor
  // Create label for the switch
  const switchLabel = document.createElement('label');
  switchLabel.setAttribute('for', 'switch');
  switchLabel.classList.add('lbl');
  switchContainer.appendChild(switchLabel);

  // Agregar evento clic al botón "Descargar Todo"
  // Add click event to "Download All" button
  downloadAllButton.addEventListener('click', function(event) {
    event.preventDefault();
    const linkElements = listContainer.querySelectorAll('a');
    for (const linkElement of linkElements) {
      if (!linkElement.hasAttribute('data-downloaded') || !showOnlyNew) {
        downloadFile(linkElement);
      }
    }
  });

  // Agregar evento cambio al interruptor para mostrar solo nuevos enlaces
  // Add change event to the switch to show only new links
  switchInput.addEventListener('change', function(event) {
    event.preventDefault();
    showOnlyNew = !showOnlyNew;
    filterList();
    switchInput.classList.toggle('active');
    updateDownloadAllButtonText();
  });

  // Agregar evento clic al botón de alternancia para mostrar/ocultar la lista
  // Add click event to the toggle button to show/hide the list
  toggleButton.addEventListener('click', function(event) {
    event.preventDefault();
    listContainer.style.display = listContainer.style.display === 'none' ? 'block' : 'none';
  });

  // Crear entrada de búsqueda de enlaces
  // Create link search input
  const searchInput = document.createElement('input');
  searchInput.type = 'text';
  searchInput.placeholder = 'Buscar';
  searchInput.classList.add('search-input');
  searchInput.style.cssText = 'color: #fff; background-color: #333; border: none; padding: 5px;';
  listContainer.appendChild(searchInput);

  // Agregar evento de entrada al campo de búsqueda de enlaces
  // Add input event to the link search field
  searchInput.addEventListener('input', function(event) {
    searchText = event.target.value.toLowerCase();
    filterList();
  });

  // Estilos CSS
  // CSS Styles
  const style = document.createElement('style');
  style.textContent = `
    .lbl {
      display: inline-block;
      width: 48px;
      height: 16px;
      background: #979797;
      border-radius: 16px;
      cursor: pointer;
      position: relative;
      transition: .2s;
      padding: 0;
      line-height: 16px;
      font-size: 12px;
      color: #fff;
      font-size: 12px;
      transform: scale(0.75);
      margin-top: 5px;
    }

    .lbl::after {
      content: '';
      display: block;
      width: 12px;
      height: 12px;
      background: #eee;
      border-radius: 100%;
      position: absolute;
      top: 2px;
      left: 2px;
      transition: .2s;
    }

    #switch:checked + .lbl {
      background: #09cc85;
    }

    #switch:checked + .lbl::after {
      left: calc(100% - 2px);
      transform: translateX(-100%);
    }

    .new {
      color: #6ab8ff; /* Color azul claro para enlaces sin descargar */
    }

    .downloaded {
      color: #ccc; /* Color gris claro para enlaces descargados */
    }
  `;
  document.head.appendChild(style);

  // Filtrar y mostrar/ocultar enlaces en la lista
  // Filter and show/hide links in the list
  function filterList() {
    const linkElements = listContainer.querySelectorAll('a');
    const sortedLinks = Array.from(linkElements).sort((a, b) =>
      a.textContent.toLowerCase().localeCompare(b.textContent.toLowerCase())
    );

    for (const linkElement of sortedLinks) {
      const linkText = linkElement.textContent.toLowerCase();
      const linkMatchesSearch = linkText.includes(searchText);

      if (showOnlyNew && !linkElement.classList.contains('new')) {
        linkElement.style.display = 'none';
      } else if (searchText && !linkMatchesSearch) {
        linkElement.style.display = 'none';
      } else {
        linkElement.style.display = 'block';
      }
    }
  }

  // Actualizar el texto del botón "Descargar Todo"
  // Update "Download All" button text
  function updateDownloadAllButtonText() {
    downloadAllButton.textContent = showOnlyNew ? 'Descargar Solo Nuevos' : 'Descargar Todo';
  }

  // Descargar un archivo cuando se hace clic en el enlace correspondiente
  // Download a file when the corresponding link is clicked
  function downloadFile(linkElement) {
    const downloadUrl = linkElement.href;
    const fileName = linkElement.download;

    fetch(downloadUrl)
      .then((response) => response.blob())
      .then((blob) => {
        const url = URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = fileName;
        a.click();
        URL.revokeObjectURL(url);

        linkElement.setAttribute('data-downloaded', 'true');
        linkElement.classList.add('downloaded');
        linkElement.textContent += ' ✓';

        localStorage.setItem(fileName, 'true');

        filterList();
      });
  }

  // Actualizar la lista de enlaces y el contador periódicamente
  // Periodically update the links list and the counter
  setInterval(function() {
    const trainerCards = document.querySelectorAll('div.col.col.s12.m6.x4.xl5ths.trainer-card.animate__animated.animate__zoomIn');

    for (const trainerCard of trainerCards) {
      const source = trainerCard.getAttribute('source');

      if (source && !links[source]) {
        links[source] = true;
        counter++;

        const linkElement = document.createElement('a');
        linkElement.textContent = source.split('/').pop();
        linkElement.style.cssText = 'display: block; margin-bottom: 5px; text-decoration: none;';
        linkElement.href = source;
        linkElement.download = source.split('/').pop();

        const fileName = linkElement.download;
        const isDownloaded = localStorage.getItem(fileName) === 'true';
        if (isDownloaded) {
          linkElement.setAttribute('data-downloaded', 'true');
          linkElement.classList.add('downloaded');
          linkElement.textContent += ' ✓';
        } else {
          linkElement.classList.add('new');
        }

        // Agregar evento clic para descargar el archivo
        // Add click event to download the file
        linkElement.addEventListener('click', function(event) {
          event.preventDefault();
          downloadFile(linkElement);
        });

        listContainer.appendChild(linkElement);
      }
    }

    toggleButton.textContent = 'Archivos JSON: ' + counter;

    filterList();
    updateDownloadAllButtonText();
  }, 5000);
})();