392 lines
16 KiB
JavaScript
392 lines
16 KiB
JavaScript
// ==UserScript==
|
|
// @name Portaledeltrasporto CON MOD AL DOWNLOAD WORKING2- Full Automation v3.3
|
|
// @namespace http://tampermonkey.net/
|
|
// @version 3.5
|
|
// @description Fix MouseEvent + Remote Hook Integration
|
|
// @author Tu
|
|
// @match *://www.ilportaledeltrasporto.it/nove/gestioneistanzanove/spa/*
|
|
// @grant GM_xmlhttpRequest
|
|
// @connect 192.168.1.33
|
|
// @run-at document-end
|
|
// ==/UserScript==
|
|
|
|
(function() {
|
|
'use strict';
|
|
|
|
let TELAIO = '';
|
|
let VALORE2 = '0';
|
|
let taskAttivo = false;
|
|
let downloadInCorso = false;
|
|
let completatoLocalmente = false; // Flag per evitare loop dopo il completamento
|
|
const ENDPOINT_GET = 'http://192.168.1.33/hook/dati2.php';
|
|
|
|
function fetchDati_veryold() {
|
|
GM_xmlhttpRequest({
|
|
method: "GET",
|
|
url: ENDPOINT_GET,
|
|
onload: function(response) {
|
|
try {
|
|
const data = JSON.parse(response.responseText);
|
|
if (data.tipo === 'DOC_NRAP' && data.task === 'fare') {
|
|
// Se è un nuovo telaio, resettiamo il flag di completamento
|
|
if (TELAIO !== data.valore1) {
|
|
TELAIO = data.valore1;
|
|
VALORE2 = data.valore2;
|
|
completatoLocalmente = false;
|
|
console.log(`[TM] Nuovo task ricevuto per telaio: ${TELAIO}`);
|
|
}
|
|
|
|
if (!completatoLocalmente) {
|
|
taskAttivo = true;
|
|
eseguiAutomazione();
|
|
}
|
|
} else {
|
|
taskAttivo = false;
|
|
completatoLocalmente = false;
|
|
}
|
|
} catch (e) {
|
|
console.error("[TM] Errore parsing dati", e);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function fetchDati_old() {
|
|
GM_xmlhttpRequest({
|
|
method: "GET",
|
|
url: ENDPOINT_GET,
|
|
onload: function(response) {
|
|
try {
|
|
const data = JSON.parse(response.responseText);
|
|
if (data.tipo === 'DOC_NRAP' && data.task === 'fare') {
|
|
|
|
// --- LOGICA DI REINDIRIZZAMENTO ---
|
|
const targetUrl = 'https://www.ilportaledeltrasporto.it/nove/gestioneistanzanove/spa/le-mie-istanze';
|
|
if (!window.location.href.includes('le-mie-istanze') &&
|
|
!window.location.href.includes('dettaglio-istanza') &&
|
|
!window.location.href.includes('/abilitazione/')) {
|
|
|
|
console.log("[TM] Nuovo task rilevato, vado alla pagina di ricerca...");
|
|
window.location.href = targetUrl;
|
|
return; // Interrompiamo l'esecuzione qui, la pagina cambierà
|
|
}
|
|
// ----------------------------------
|
|
|
|
if (TELAIO !== data.valore1) {
|
|
TELAIO = data.valore1;
|
|
VALORE2 = data.valore2;
|
|
completatoLocalmente = false;
|
|
console.log(`[TM] Nuovo task ricevuto per telaio: ${TELAIO}`);
|
|
}
|
|
|
|
if (!completatoLocalmente) {
|
|
taskAttivo = true;
|
|
eseguiAutomazione();
|
|
}
|
|
} else {
|
|
taskAttivo = false;
|
|
completatoLocalmente = false;
|
|
}
|
|
} catch (e) {
|
|
console.error("[TM] Errore parsing dati", e);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function fetchDati() {
|
|
GM_xmlhttpRequest({
|
|
method: "GET",
|
|
url: ENDPOINT_GET,
|
|
onload: function(response) {
|
|
try {
|
|
const data = JSON.parse(response.responseText);
|
|
const targetHome = 'https://www.ilportaledeltrasporto.it/nove/gestioneistanzanove/spa/le-mie-istanze';
|
|
|
|
// --- LOGICA DI RESET SPECIFICA ---
|
|
// if (data.task === 'reset') {
|
|
if (data.tipo === 'RESET_NRAP') {
|
|
console.log("[TM] Ricevuto comando RESET. Ritorno alla home e pulizia variabili.");
|
|
TELAIO = '';
|
|
VALORE2 = '0';
|
|
completatoLocalmente = false;
|
|
taskAttivo = false;
|
|
|
|
// Se non siamo già in home, ci spostiamo
|
|
if (window.location.href !== targetHome) {
|
|
window.location.href = targetHome;
|
|
}
|
|
return; // Esce dalla funzione, non esegue altro
|
|
}
|
|
// ---------------------------------
|
|
|
|
if (data.tipo === 'DOC_NRAP' && data.task === 'fare') {
|
|
// Se il telaio cambia mentre siamo operativi, forziamo il redirect
|
|
if (TELAIO !== '' && TELAIO !== data.valore1) {
|
|
console.log(`[TM] Cambio telaio rilevato (${TELAIO} -> ${data.valore1}). Redirect.`);
|
|
TELAIO = data.valore1;
|
|
window.location.href = targetHome;
|
|
return;
|
|
}
|
|
|
|
// Aggiornamento dati task
|
|
if (TELAIO !== data.valore1) {
|
|
TELAIO = data.valore1;
|
|
VALORE2 = data.valore2;
|
|
completatoLocalmente = false;
|
|
}
|
|
|
|
if (!completatoLocalmente) {
|
|
taskAttivo = true;
|
|
eseguiAutomazione();
|
|
}
|
|
} else {
|
|
taskAttivo = false;
|
|
completatoLocalmente = false;
|
|
}
|
|
} catch (e) {
|
|
console.error("[TM] Errore parsing dati", e);
|
|
}
|
|
}
|
|
});
|
|
}
|
|
|
|
function segnaComeCompletato_old() {
|
|
completatoLocalmente = true;
|
|
taskAttivo = false;
|
|
GM_xmlhttpRequest({
|
|
method: "POST",
|
|
url: ENDPOINT_GET,
|
|
data: JSON.stringify({ task: "completato", valore1: TELAIO }),
|
|
headers: { "Content-Type": "application/json" },
|
|
onload: function() {
|
|
console.log("[TM] Server aggiornato: task completato.");
|
|
downloadInCorso = false;
|
|
}
|
|
});
|
|
}
|
|
|
|
function segnaComeCompletato() {
|
|
completatoLocalmente = true;
|
|
taskAttivo = false;
|
|
|
|
// Prepariamo l'oggetto completo con i valori aggiornati
|
|
const payload = {
|
|
tipo: "DOC_NRAP",
|
|
task: "completato", // Unica variabile che cambia davvero
|
|
valore1: TELAIO,
|
|
valore2: VALORE2,
|
|
valore3: "0"
|
|
};
|
|
|
|
GM_xmlhttpRequest({
|
|
method: "POST",
|
|
url: ENDPOINT_GET,
|
|
data: JSON.stringify(payload),
|
|
headers: { "Content-Type": "application/json" },
|
|
onload: function(response) {
|
|
console.log("[TM] Server aggiornato con tutti i campi. Task: completato.");
|
|
downloadInCorso = false;
|
|
},
|
|
onerror: function(err) {
|
|
console.error("[TM] Errore nell'invio dei dati al server", err);
|
|
}
|
|
});
|
|
}
|
|
|
|
// FIX: Funzione click corretta per evitare l'errore 'view' member
|
|
function clickReactSafe_OLD(element) {
|
|
if (!element) return;
|
|
const opts = { bubbles: true, cancelable: true, view: window.unsafeWindow || window };
|
|
|
|
// Se il costruttore standard fallisce, usiamo il metodo più compatibile
|
|
try {
|
|
element.dispatchEvent(new MouseEvent('mousedown', opts));
|
|
element.dispatchEvent(new MouseEvent('mouseup', opts));
|
|
element.click();
|
|
} catch (e) {
|
|
// Fallback per browser restrittivi
|
|
element.dispatchEvent(new Event('mousedown', { bubbles: true }));
|
|
element.dispatchEvent(new Event('mouseup', { bubbles: true }));
|
|
element.click();
|
|
}
|
|
}
|
|
|
|
function clickReactSafe(element) {
|
|
// Se l'elemento non esiste, esci silenziosamente senza generare errori
|
|
if (!element || typeof element.dispatchEvent !== 'function') {
|
|
console.warn("[TM] Tentativo di click su un elemento non valido o non trovato.");
|
|
return;
|
|
}
|
|
|
|
const opts = { bubbles: true, cancelable: true, view: window.unsafeWindow || window };
|
|
|
|
try {
|
|
element.dispatchEvent(new MouseEvent('mousedown', opts));
|
|
element.dispatchEvent(new MouseEvent('mouseup', opts));
|
|
element.click();
|
|
} catch (e) {
|
|
element.dispatchEvent(new Event('mousedown', { bubbles: true }));
|
|
element.dispatchEvent(new Event('mouseup', { bubbles: true }));
|
|
element.click();
|
|
}
|
|
}
|
|
|
|
function setInputReactSafe(input, value) {
|
|
if (!input) return;
|
|
const setter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, 'value').set;
|
|
input.focus();
|
|
setter.call(input, value);
|
|
input.dispatchEvent(new Event('input', { bubbles: true }));
|
|
input.dispatchEvent(new Event('change', { bubbles: true }));
|
|
}
|
|
|
|
function avviaDownloadDocumenti() {
|
|
if (downloadInCorso) return;
|
|
|
|
const tuttiIBottoni = Array.from(document.querySelectorAll('button.DocumentsSection__file-btn'));
|
|
if (tuttiIBottoni.length === 0) return;
|
|
|
|
downloadInCorso = true;
|
|
const titoliGiaVisti = new Set();
|
|
let delayDoc = 0;
|
|
|
|
tuttiIBottoni.forEach((btn, index, array) => {
|
|
const riga = btn.closest('tr');
|
|
const titolo = riga ? riga.innerText.trim().split('\t')[0] : btn.innerText.trim();
|
|
|
|
if (!titoliGiaVisti.has(titolo)) {
|
|
titoliGiaVisti.add(titolo);
|
|
|
|
setTimeout(() => {
|
|
console.log(`[TM] 1. Avvio Download: ${titolo}`);
|
|
clickReactSafe(btn);
|
|
|
|
// --- SEQUENZA MODALE ---
|
|
|
|
// STEP A: Click Esporta File (dopo 1.2 secondi)
|
|
setTimeout(() => {
|
|
//const btnEsporta = Array.from(document.querySelectorAll('button.btn-primary.btn-xs'))
|
|
const btnEsporta = Array.from(document.querySelectorAll('button.btn-primary.btn-xs'));
|
|
//.find(b => b.textContent.includes('Esporta File'));
|
|
|
|
if (btnEsporta) {
|
|
console.log(`[TM] 2. Click Esporta File per: ${titolo}`);
|
|
clickReactSafe(btnEsporta);
|
|
}
|
|
|
|
// STEP B: Click Chiudi Modale (dopo altri 1.5 secondi dal click esporta)
|
|
setTimeout(() => {
|
|
const btnChiudiModale = document.querySelector('button.ModalContent__header--btn');
|
|
if (btnChiudiModale) {
|
|
console.log(`[TM] 3. Chiusura modale per: ${titolo}`);
|
|
clickReactSafe(btnChiudiModale);
|
|
}
|
|
}, 1500);
|
|
|
|
}, 1200);
|
|
// -----------------------
|
|
|
|
// Se è l'ultimo documento
|
|
if (index === array.length - 1) {
|
|
setTimeout(segnaComeCompletato, 5000); // Aumentato a 5s per sicurezza
|
|
}
|
|
}, delayDoc);
|
|
|
|
// Aumentiamo il delay totale tra un file e l'altro a 5 secondi
|
|
// per coprire l'intera sequenza (Download -> Esporta -> Chiudi)
|
|
delayDoc += 3000;
|
|
}
|
|
});
|
|
}
|
|
|
|
function avviaDownloadDocumenti_old() {
|
|
if (downloadInCorso) return;
|
|
|
|
const tuttiIBottoni = Array.from(document.querySelectorAll('button.DocumentsSection__file-btn'));
|
|
if (tuttiIBottoni.length === 0) return;
|
|
|
|
downloadInCorso = true;
|
|
const titoliGiaVisti = new Set();
|
|
let delayDoc = 0;
|
|
|
|
tuttiIBottoni.forEach((btn, index, array) => {
|
|
const riga = btn.closest('tr');
|
|
const titolo = riga ? riga.innerText.trim().split('\t')[0] : btn.innerText.trim();
|
|
|
|
if (!titoliGiaVisti.has(titolo)) {
|
|
titoliGiaVisti.add(titolo);
|
|
|
|
setTimeout(() => {
|
|
console.log(`[TM] Download: ${titolo}`);
|
|
clickReactSafe(btn);
|
|
|
|
// --- NUOVA LOGICA CHIUSURA MODALE ---
|
|
setTimeout(() => {
|
|
const btnChiudiModale = document.querySelector('button.ModalContent__header--btn');
|
|
if (btnChiudiModale) {
|
|
console.log(`[TM] Chiusura modale per: ${titolo}`);
|
|
clickReactSafe(btnChiudiModale);
|
|
}
|
|
}, 1000); // Aspetta 1 secondo dopo il click di download
|
|
// ------------------------------------
|
|
|
|
// Se è l'ultimo documento unico trovato
|
|
if (index === array.length - 1) {
|
|
setTimeout(segnaComeCompletato, 1500);
|
|
}
|
|
}, delayDoc);
|
|
|
|
// Ho aumentato leggermente il delay tra un file e l'altro (3.5s invece di 2.5s)
|
|
// per dare tempo alla modale di aprirsi, restare aperta 1s e chiudersi.
|
|
delayDoc += 1500;
|
|
}
|
|
});
|
|
}
|
|
|
|
function eseguiAutomazione() {
|
|
if (!taskAttivo || completatoLocalmente) return;
|
|
|
|
const url = window.location.href;
|
|
|
|
// FASE 1: RICERCA
|
|
if (url.includes('le-mie-istanze')) {
|
|
const input = document.getElementById('numeroTelaio');
|
|
const btnCerca = Array.from(document.querySelectorAll('button')).find(b => b.textContent.includes('Cerca'));
|
|
const btnTabella = document.querySelector('button.action-button-table');
|
|
|
|
if (input && TELAIO !== '' && input.value !== TELAIO) {
|
|
setInputReactSafe(input, TELAIO);
|
|
setTimeout(() => { if(btnCerca) clickReactSafe(btnCerca); }, 800);
|
|
}
|
|
if (btnTabella) setTimeout(() => clickReactSafe(btnTabella), 1500);
|
|
}
|
|
|
|
// FASE 2: PROCEDI
|
|
if (url.includes('/abilitazione/') && !url.includes('dettaglio-istanza')) {
|
|
const btnProcedi = Array.from(document.querySelectorAll('button')).find(b => b.textContent.trim() === 'Procedi');
|
|
if (btnProcedi && !btnProcedi.disabled) setTimeout(() => clickReactSafe(btnProcedi), 1000);
|
|
}
|
|
|
|
// FASE 3: DOWNLOAD
|
|
if (url.includes('dettaglio-istanza')) {
|
|
if (parseInt(VALORE2) > 0) {
|
|
if (document.querySelector('button.DocumentsSection__file-btn')) {
|
|
avviaDownloadDocumenti();
|
|
}
|
|
} else {
|
|
console.log("[TM] Valore2 <= 1, chiusura task senza download.");
|
|
segnaComeCompletato();
|
|
}
|
|
}
|
|
}
|
|
|
|
const observer = new MutationObserver(() => {
|
|
if (taskAttivo) eseguiAutomazione();
|
|
});
|
|
observer.observe(document.body, { childList: true, subtree: true });
|
|
|
|
// Polling ogni 4 secondi
|
|
setInterval(fetchDati, 2500);
|
|
fetchDati();
|
|
})(); |