Utente:MauroBot/BotCancellazioni/core.js/sandbox.js

Da Wikipedia, l'enciclopedia libera.
Vai alla navigazione Vai alla ricerca

Questa pagina definisce alcuni parametri di aspetto e comportamento generale di tutte le pagine. Per personalizzarli vedi Aiuto:Stile utente.


Nota: dopo aver salvato è necessario pulire la cache del proprio browser per vedere i cambiamenti (per le pagine globali è comunque necessario attendere qualche minuto). Per Mozilla / Firefox / Safari: fare clic su Ricarica tenendo premuto il tasto delle maiuscole, oppure premere Ctrl-F5 o Ctrl-R (Command-R su Mac); per Chrome: premere Ctrl-Shift-R (Command-Shift-R su un Mac); per Konqueror: premere il pulsante Ricarica o il tasto F5; per Opera può essere necessario svuotare completamente la cache dal menù Strumenti → Preferenze; per Internet Explorer: mantenere premuto il tasto Ctrl mentre si preme il pulsante Aggiorna o premere Ctrl-F5.

'use strict';

var DelBot = DelBot             || {};
DelBot.classes = DelBot.classes || {};

/**
 * La classe rappresenta lo stato della funzione di scrittura di una pagina. La richiesta AJAX
 * è terminata quando this.done=true. L'esito della scrittura è riportato in this.ok. In caso
 * di errore (this.ok=false), il testo è riportato in this.error
 */
DelBot.classes.WriteStatus = function () {
	this.done = false;
	this.ok = true;
	this.error = '';
};

/**
 * La classe rappresenta lo stato della funzione che si occupa della lettura delle procedure di
 * cancellazione.
 */
DelBot.classes.ReadStatus = function () {
	this.done = false;
	this.qcontinue = false;
	this.ok = false;
	this.finish = false;
	this.error = '';
	this.gcmcontinue = false;
	this.clcontinue = false;
	this.rawData = [];
};

/**
 * La classe rappresenta una procedura di cancellazione.
 */
DelBot.classes.PDC = function () {
	this.pdc = {
		'pageid':          0,
		'titolo-pdc':      '',
		'titolo-voce':     '',
		'multipla':        0,
		'len':             0,
		'temperatura':     0,
		'protezione':      false,
		'data-apertura':   false,
		'ultima-modifica': false,
		'errors':          []
	};
	this.isconsensuale = false; // Categorizzata in Categoria:Cancellazioni consensuali del XX
	this.isprorogata   = false; // Categorizzata in Categoria:Cancellazioni consensuali prorogate del XX
	this.isvotazione   = false; // Categorizzata in Categoria:Cancellazioni con votazione del XX
	this.incorso       = false; // Procedura di cancellazione in fase di discussione
	this.incompleta    = true;  // Indica se la lettura della categorizzazione è completa
};

/**F
 * Get the PDC category prefix from its PDC type
 *
 * @param {string} e.g. 'semplificate'
 * @return {string} e.g. 'Categoria:Cancellazioni del '
 */
DelBot.getCategoryPrefixFromType = function ( type ) {
	var conf = DelBot.config;
	switch( type ) {
		case 'semplificate':  return conf.catSemplificataPrefix;
		case 'consensuali':   return conf.catConsensualePrefix;
		case 'consprorogate': return conf.catConsensualeProrogataPrefix;
		case 'ordinarie':     return conf.catOrdinariaPrefix;
		case 'votazioni':     return conf.catVotazionePrefix;
	}
	throw 'unexpected type' + type;
};

/**
 * La funzione avvia la lettura (invia la richiesta all'API) delle procedure di cancellazione
 * contenute nella categoria individuata dai parametri tipo e data, cioè se tipo=semplificate e
 * data=2013/01/01, verrà letto in contenuto di Categoria:Cancellazioni semplificate del 1 gennaio 2013.
 *
 * @param type {string} e.g. 'semplificate'
 * @param date {Date}
 * @param status {DelBot.classes.ReadStatus}
 */
DelBot.startReadingPDCCategory = function ( type, date, status ) {
	status.done = false;

	// Converto la data in formato giorno mese anno (testuale)
	var dateTxt = DelBot.date2CategoryName( date );

	// Genero il nome della categoria da scansionare in funzione del tipo di procedure da caricare
	// (semplificata, consensuale, consensuale prorogata, ordinaria)
	var categoria = DelBot.getCategoryPrefixFromType( type ) += dateTxt;

	// Richiesta da inviare all'API
	//
	// prop=info
	// inprop=protection
	// https://it.wikipedia.org/w/api.php?action=help&modules=query%2Binfo
	//
	// prop=categories
	// clprop=sortkey
	// https://it.wikipedia.org/w/api.php?action=help&modules=query%2Bcategories
	//
	// prop=revisions
	// rvprop=timestamp
	// https://it.wikipedia.org/w/api.php?action=help&modules=query%2Brevisions
	//
	// generator=categorymembers
	// gcmtitle=
	// gcmtype=page
	// gcmsort=timestamp
	// gcmdir=asc
	// Note: Generator parameter names must be prefixed with a "g", see examples.
	// https://it.wikipedia.org/w/api.php?action=help&modules=query%2Bcategorymembers
	var request = {
		format: 'json',
		action: 'query',
		generator: 'categorymembers',             // Legge le voci nella categoria
		gcmtitle: categoria,
		gcmtype: 'page',
		gcmsort: 'timestamp',                     // Ordinamento per data di inserimento nella categoria
		gcmdir: 'asc',
		prop: 'info|categories|revisions',        // Per ogni voce carico info, categorie e ultima revisione
		inprop: 'protection',
		clprop: 'sortkey',
		rvprop: 'timestamp'
		// rawcontinue: '1' // TODO: perchè non basta il default?
	};

	// Gestione della prosecuzione della query
	if( status.continue ) {
		for( var k in status.continue ) {
			request[ k ] = status.continue[ k ];
		}
	}

	$.ajax( {
		url: mw.util.wikiScript( 'api' ),
		data: request,
		dataType: 'json',
		type: 'GET',
		timeout: 5000,
		success: function( data ) {
			DelBot.processRawData( type, date, status );
		},
		error: function( xhr, textStatus, errorThrown ) {
			var d = new Date();
			status.error = '['+d.toISOString()+'] [JQuery/AJAX Error] Errore durante la lettura delle procedure \"'+type+'" del '+dateTxt+' ('+textStatus+')';
			status.ok = false;
			status.done = true;
		 }
	} );
};

/**
 * La funzione analizza la risposta dell'API, estraendo le informazioni delle PDC
 *
 * @param tipo {string}
 * @param data
 * @param status
 */
DelBot.processRawData = function ( tipo, data, status ) {
	// La richiesta ha avuto esito positivo?
	if ( data && data.query && data.query.pages ) {
		/* gestito in DelBot.startReadingPDCCategory

		var idcontinue = 0;

		// Gestione del query-continue
		if ( data['query-continue'] ) {
			// La query non è completata
			status.qcontinue = true;
			if( data['query-continue'].categories ) {
				status.clcontinue = data['query-continue'].categories.clcontinue;
				s = status.clcontinue.split('|');
				idcontinue = parseInt(s[0]);
			} else {
				status.clcontinue = false;
				if ( data['query-continue'].categorymembers ) {
					status.gcmcontinue = data['query-continue'].categorymembers.gcmcontinue;
				}
			}
		} else {
			status.qcontinue = false;
		}
		*/

		// per ogni PDC
		for( var pageid in data.query.pages ) {
			// La pdc è già stata processata?
			var i;
			for( i = 0; i < status.rawData.length; i++ ) {
				if( status.rawData[i]['pdc'].pageid == parseInt(pageid) ) {
					break;
				}
			}

			// La pdc non è ancora stata processata!
			if( i == status.rawData.length ) {
				// Leggo i dati di base
				titoloPDC = data.query.pages[pageid].title;

				// Controllo la correttezza del prefisso della PDC
				if( titoloDelBot.indexOf(DelBot.config.pdcPrefix) != 0 ) {
					continue;
				}

				// Creo un nuovo oggetto per la pdc
				status.rawData.push( new DelBot.classes.PDC() );
				status.rawData[i]['pdc'].pageid = parseInt(pageid);
				status.rawData[i]['pdc']['titolo-pdc'] = titoloPDC;
				status.rawData[i]['pdc']['len'] = data.query.pages[pageid]['length'];

				// Controllo se la procedura è multipla
				if( titoloDelBot.indexOf(DelBot.config.pdcMultiplePrefix) == 0 ) {
					status.rawData[i]['pdc']['multipla'] = 1;
				}
			}

			// Verifico se ho devo processare le categorie
			if( status.rawData[i].incompleta && data.query.pages[pageid].categories ) {
				// Le categorie della pdc devono essere lette
				for( var index in data.query.pages[pageid].categories ) {
					var cat = data.query.pages[pageid].categories[index].title;
					if( cat.indexOf(DelBot.config.catSemplificataPrefix) == 0 ) {
						// Converto la data dal formato giorno mesetxt anno in un oggetto Date
						status.rawData[i]['pdc']['data-apertura'] = DelBot.categoryName2Date( cat.substring( DelBot.config.catSemplificataPrefix.length ) );
						status.rawData[i]['pdc']['titolo-voce'] = data.query.pages[pageid].categories[index].sortkeyprefix;
					} else if( cat.indexOf(DelBot.config.catConsensualePrefix) == 0  ) {
						status.rawData[i].isconsensuale = true;
					} else if ( cat.indexOf(DelBot.config.catConsensualeProrogataPrefix) == 0 ) {
						status.rawData[i].isprorogata = true;
					} else if ( cat.indexOf(DelBot.config.catOrdinariaPrefix) == 0 ) {
						status.rawData[i].isvotazione = true;
					} else if ( cat.indexOf(DelBot.config.catVotazionePrefix) == 0 ) {
						status.rawData[i].isvotazione = true;
					} else if ( cat.indexOf(DelBot.config.CatRunning) == 0 ) {
						status.rawData[i].incorso = true;
					}
				}

				if( pageid != idcontinue) {
					status.rawData[i].incompleta = false;
					var titoloPDC = data.query.pages[pageid].title;

					// Il titolo della voce da cancellare è contenuto nell'ordinamento {{DEFAULTSORT}}
					//titolo = data.query.pages[pageid].categories[0].sortkeyprefix;
					var titolo = status.rawData[i]['pdc']['titolo-voce'];

					// Controllo validità del titolo della pdc

					// Rimuovo il prefisso della PDC. Esempio:
					// Wikipedia:Pagine da cancellare/titolo/2 -> titolo/2
					var titolo1 = status.rawData[i]['pdc']['multipla'] == 1
						? titoloPDC.substring(DelBot.config.pdcMultiplePrefix.length)
						: titoloPDC.substring(DelBot.config.pdcPrefix.length);

					// Se il titolo della voce da cancellare è differente da quello della PDC si tratta
					// di una procedura con precedenti
					if( titolo != titolo1 ) {
						// Il titolo della procedura multipla è lungo, come minimo, 2 caratteri più del
						// titolo della PDC: i caratteri sono '/' e il numero progressivo
						if( titolo1.length < titolo.length+2 ) {
							status.rawData[i]['pdc']['errors'].push('title-error');
						} else {
							if( titolo1[titolo.length] != '/' || isNaN( Number( titolo1.substring( titolo.length+1 ) ) ) ) {
								status.rawData[i]['pdc']['errors'].push('title-error');
							}
						}
					}


					//status.rawData[i]['pdc']['titolo-voce'] = titolo;
					rev_timestamp = data.query.pages[pageid].revisions[0].timestamp;
					// rev_timestamp -> YYYY-MM-DD
					anno = Number(rev_timestamp.substr(0,4));
					mese = Number(rev_timestamp.substr(5,2))-1;
					giorno = Number(rev_timestamp.substr(8,2));
					status.rawData[i]['pdc']['ultima-modifica'] = new Date(anno, mese, giorno);

					if( data.query.pages[pageid].protection.length > 0 ) {
						for( var ip = 0; ip < data.query.pages[pageid].protection.length; ip++ ) {
							var v = data.query.pages[pageid].protection[ip];
							if( v["type"]=="edit" ) {
								if( v["level"]=="sysop" ) {
									status.rawData[i]['pdc']['protezione'] = true;
								}
								break;
							}
						}
					}
				}
			}
		} //fine ciclo lettura pdc
		status.ok = true;
		status.done = true;
	} else if ( data && data.error ) {
		// Will this ever happen??
		var d = new Date();
		// TODO: datatxt undefined?
		status.error = '['+d.toISOString()+'] [API Error] Errore durante la lettura delle procedure \"'+tipo+'" del '+ datatxt+' (Errore"'+data.error.code + '": ' + data.error.info+')';
		status.ok = false;
		status.done = true;
	} else {
		status.ok = true;
		status.done = true;
	}
};

/**
 * La funzione analizza le procedure lette con la funzione PDC.processRawData e restituisce
 * una struttura con la seguente forma:
 * 
 * pdc['incorso']{array di pdc}
 * pdc['concluse']{array di pdc}
 * pdc['errate']{array di pdc}
 *
 * @param tipo {string}
 * @param rawData {Object}
 */
DelBot.processLetturaCategoriaPDC = function( tipo, rawData ) {
	var pdc = {
		incorso: [],
		concluse: [],
		errate: []
	};
	for( var i=0; i < rawData.length; i++ ) {
		// Individuo il tipo di PDC analizzando le categorie presenti nella PDC
		var inserisciPDC = false;
		switch( tipo ) {
			case 'semplificate':
				if ( !rawData[i].isconsensuale && !rawData[i].isprorogata && !rawData[i].isvotazione ) {
					inserisciPDC = true;
				}
				break;
			case 'consensuali':
				if ( rawData[i].isconsensuale && !rawData[i].isprorogata && !rawData[i].isvotazione ) {
					inserisciPDC = true;
				}
				break;
			case 'consprorogate':
				if ( rawData[i].isconsensuale && rawData[i].isprorogata && !rawData[i].isvotazione ) {
					inserisciPDC = true;
				}
				break;
			case 'ordinarie':
			case 'votazioni':
				if ( rawData[i].isconsensuale && rawData[i].isvotazione ) {
					inserisciPDC = true;
				}
				break;
			throw 'unexpected type';
		}

		// Controllo eventuali errori di categorizzazione
		if(  !rawData[i].isconsensuale && ( rawData[i].isprorogata || rawData[i].isvotazione ) ) {
			rawData[i]['pdc']['errors'].push( 'category-error' );
		}

		// Controllo la presenza di errori nella pdc
		if( rawData[i]['pdc']['errors'].length == 0 ) {
			if( inserisciPDC ) {
				rawData[i]['pdc']['temperatura'] = DelBot.calculateTemperature(tipo, rawData[i]['pdc']['len']);
				if ( rawData[i].incorso && !rawData[i]['pdc']['protezione'] ) {
					pdc['incorso'].push(rawData[i]['pdc']);
				} else {
					pdc['concluse'].push(rawData[i]['pdc']);
				}
			}
		} else {
			// con errori
			pdc['errate'].push(rawData[i]['pdc']);
		}
	}
	return pdc;
};

/**
 *La funzione analizza le procedure passate come argomento:
 * 
 * procedure['semplificate']['incorso']{array di pdc}
 * procedure['semplificate']['concluse']{array di pdc}
 * procedure['consensuali']['incorso']{array di pdc}
 * procedure['consensuali']['concluse']{array di pdc}
 * procedure['consprorogate']['incorso']{array di pdc}
 * procedure['consprorogate']['concluse']{array di pdc}
 * procedure['votazioni']['incorso']{array di pdc}
 * procedure['votazioni']['concluse']{array di pdc}
 *
 * e individua le errate, rimuovendo eventuali doppioni
 *
 * @param procedure {Object}
 */
DelBot.processPDCErrate = function (procedure) {
	var errate = [];
	for(var i=0; i < DelBot.config.tipologie.length; i++ ) {
		var tipo = DelBot.config.tipologie[i];
		if ( procedure[tipo] ) {
			// Loop sulle pdc errate
			for(var j=0; j<procedure[tipo]['errate'].length;j++ ) {
				pdc = procedure[tipo]['errate'][j];

				// Verifico che la PDC non sia già stata inserita
				var k;
				for( k=0; k < errate.length; k++ ) {
					if( errate[k].pageid == pdc.pageid ) {
						break;
					}
				}
				if( k == errate.length ) {
					errate.push(pdc);
				}
			}
		}
	}
	procedure['errate'] = errate;
};

/**
 * Funzione DelBot.generateDailyLog(data, procedure)
 *
 * La funzione genera il testo del Log giornaliero
 *
 * @param data
 * @param procedure
 */
DelBot.generateDailyLog = function ( data, procedure ) {
	var txt = '<noinclude>{{paginecancellare}}</noinclude>\n';
	    txt += '== '+data.getDate()+' '+convertiMeseToTxt(data.getMonth()+1)+' ==\n';
	    txt += '{{'+DelBot.config.pdcCountPrefix+convertiDateToLogTxt(data)+'}}\n';

	// Procedure errate
	if( procedure['errate'].length > 0) {
		txt += '\n<!--inizio procedure con errori-->\n';
	}
	for( var j=0; j<procedure['errate'].length; j++ ) {
		txt += '{{'+procedure['errate'][j]['titolo-pdc']+'}}\n';
	}

	// Procedure in corso
	for( var i=0; i < DelBot.config.tipologie.length; i++ ) {
		var tipo = DelBot.config.tipologie[i];
		if( ! procedure[tipo] ) {
			continue;
		}
		if( procedure[tipo]['incorso'].length > 0 ) {
			switch( tipo ) {
				case 'ordinarie':
				case 'votazioni':
					txt += '\n<!--inizio procedure con votazione-->\n';
					break;
				case 'consprorogate':
					txt += '\n<!--inizio procedure consensuali prorogate-->\n';
					break;
				case 'consensuali':
					txt += '\n<!--inizio procedure consensuali-->\n';
					break;
				case 'semplificate':
					txt += '\n<!--inizio procedure semplificate-->\n';
					break;
			}
			for(var j=0; j<procedure[tipo]['incorso'].length;j++ ) {
				txt += '{{'+procedure[tipo]['incorso'][j]['titolo-pdc']+'}}\n';
			}
		}
	}

	// Procedure concluse
	var concluse = false;
	for( var i=0; i < DelBot.config.tipologie.length; i++ ) {
		tipo = DelBot.config.tipologie[i];
		if( !procedure[tipo] ) {
			continue;
		}
		if( procedure[tipo]['concluse'].length > 0 && !concluse ) {
			txt += '\n<!--inizio procedure concluse/annullate-->\n';
			concluse = true;
		}
		for(var j=0; j<procedure[tipo]['concluse'].length; j++ ) {
			txt += '{{'+procedure[tipo]['concluse'][j]['titolo-pdc']+'}}\n';
		}
	}

	return txt;
};

/**
 *
 * La funzione genera il testo della la tabella di conteggio. 
 *
 * @param data
 * @param procedure {Object}
 * @return string
 */
DelBot.generaTabellaConteggio = function ( data, procedure ) {
	var tabella_InCorso='';
	var tabella_Concluse='';
	var tabella_Errate='';
	var Log_name = DelBot.config.pdcLogPrefix + convertiDateToLogTxt( data );

	// Procedure errate
	var n = 0
	for( var j=0; j<procedure['errate'].length; j++ ) {
		var pdc = procedure['errate'][j];
		n++;
		var riga = DelBot.templates.CPErrateRow;
		riga = riga.replace( '__n__', n );
		riga = riga.replace( '__SP_name__', pdc['titolo-pdc'] );
		riga = riga.replace( '__SP_name__', pdc['titolo-pdc'] );
		riga = riga.replace( '__bgcolor__', '#f6f6f6' );

		var errors = '';
		if( pdc['errors'].length == 1) {
			errors = DelBot.l10n.errorMessages[pdc['errors'][0]];
		} else {
			var e = [];
			for( var i=0; i < pdc['errors'].length; i++ ) {
				e.push( (i+1)+') '+DelBot.l10n.errorMessages[pdc['errors'][i]] );
			}
			errors = '<div style="padding-left:10px;">'+e.join('<br />')+'</div>';
		}

		riga = riga.replace( '__note__', errors );

		tabella_Errate = tabella_Errate + riga;
	}

	// Procedure in corso
	var n = 0;
	for( var i=0; i < DelBot.config.tipologie.length; i++ ) {
		var tipo = DelBot.config.tipologie[i];
		if( ! procedure[tipo] ) {
			continue;
		}

		for( var j=0; j < procedure[tipo]['incorso'].length; j++ ) {
			var pdc = procedure[tipo]['incorso'][j];
			n++;
			var riga = DelBot.templates.CPRunningRow;
			riga = riga.replace('__n__', n);
			riga = riga.replace('__temperatura__', pdc['temperatura']);
			riga = riga.replace(/__title__/g, pdc['titolo-voce']);
			if( pdc['multipla'] == 1 ) {
				riga = riga.replace('__title_link__', pdc['titolo-voce']);
			} else {
				riga = riga.replace('__title_link__', '[[:'+pdc['titolo-voce']+']]');
			}

			riga = riga.replace('__SP_name__', pdc['titolo-pdc']);
			riga = riga.replace('__LP_name__', Log_name);
			if( pdc['multipla'] == 1 ) {
				riga = riga.replace('__note__', DelBot.l10n.notesMessages['multipla']);
			} else {
				riga = riga.replace('__note__', ''); 
			}

			switch( tipo ) {
				case 'semplificate':
					riga = riga.replace('__modalita__', 'semplificata');
					riga = riga.replace('__azione__', 'commenta');
					riga = riga.replace('__vai_alla__', 'proposta di cancellazione');
					riga = riga.replace('__bgcolor__', '#e5ffe5');
					break;
				case 'consensuali':
					riga = riga.replace('__modalita__', 'consensuale');
					riga = riga.replace('__azione__', 'commenta');
					riga = riga.replace('__vai_alla__', 'discussione');
					riga = riga.replace('__bgcolor__', '#fffccc');
					break;
				case 'consprorogate':
					riga = riga.replace('__modalita__', 'consensuale prorogata');
					riga = riga.replace('__azione__', 'commenta');
					riga = riga.replace('__vai_alla__', 'discussione');
					riga = riga.replace('__bgcolor__', '#fffccc');
					break;
				case 'ordinarie':
				case 'votazioni':
					riga = riga.replace('__modalita__', 'votazione');
					riga = riga.replace('__azione__', 'vota');
					riga = riga.replace('__vai_alla__', 'votazione');
					riga = riga.replace('__bgcolor__', '#ffe2df');
					break;
				default:
					throw 'unexpected type';
			}

			tabella_InCorso = tabella_InCorso + riga;
		}
	}

	// Procedure concluse
	var n = 0;
	for(var i=0; i < DelBot.config.tipologie.length; i++ ) {
		var tipo = DelBot.config.tipologie[i];
		if( !procedure[tipo] ) {
			continue;
		}

		for( var j = 0; j < procedure[tipo]['concluse'].length; j++ ) {
			var pdc = procedure[tipo]['concluse'][j];
			n++;
			var riga = DelBot.templates.CPEndedRow;
			riga = riga.replace('__n__', n);
			riga = riga.replace('__temperatura__', pdc['temperatura']);
			riga = riga.replace(/__title__/g, pdc['titolo-voce']);
			if( pdc['multipla'] == 1 ) {
				riga = riga.replace('__title_link__', pdc['titolo-voce']);
			} else {
			riga = riga.replace('__title_link__', '[[:'+pdc['titolo-voce']+']]');
			}
			riga = riga.replace('__SP_name__', pdc['titolo-pdc']);
			riga = riga.replace('__LP_name__', Log_name);
			if( pdc['multipla'] == 1 ) {
				riga = riga.replace('__note__', DelBot.l10n.notesMessages['multipla']); 
			} else {
				riga = riga.replace('__note__', '');
			}
			if( pdc.protezione ) {
				d = pdc['ultima-modifica']-pdc['data-apertura'];
				d = Math.ceil(d/1000/3600/24);
				if (d > 1) {
					riga = riga.replace('__durata__', d+' giorni');
				} else if ( d==1 ) {
					riga = riga.replace('__durata__', '1 giorno');
				} else {
					riga = riga.replace('__durata__', '< 1 giorno');
				}
			} else {
				riga = riga.replace('__durata__', 'non protetta');
			}
			riga = riga.replace('__SP_name__', pdc['titolo-pdc']);

			switch( tipo ) {
				case 'semplificate':
					riga = riga.replace('__modalita__', 'semplificata');
					riga = riga.replace('__bgcolor__', '#e5ffe5');
					break;
				case 'consensuali':
					riga = riga.replace('__modalita__', 'consensuale');
					riga = riga.replace('__bgcolor__', '#fffccc');
					break;
				case 'consprorogate':
					riga = riga.replace('__modalita__', 'consensuale prorogata');
					riga = riga.replace('__bgcolor__', '#fffccc');
					break;
				case 'ordinarie':
				case 'votazioni':
					riga = riga.replace('__modalita__', 'votazione');
					riga = riga.replace('__bgcolor__', '#ffe2df');
					break;
				default:
					throw 'unexpected type';
			}

			tabella_Concluse = tabella_Concluse + riga;
		}
	}

	var tabella = '';
	if( tabella_Errate.length > 0 ) {
		var header = DelBot.templates.CPErrateHeader.replace('__last_update_errate__', '<small>Ultimo aggiornamento: 14:12, 9 apr 2018 (CEST)</small>');
		tabella = header + tabella_Errate + DelBot.templates.CPErrateFooter;
	}

	if( tabella_InCorso.length > 0 ) {
		if( tabella.length == 0 ) {
			var header = DelBot.templates.CPRunningHeader.replace('__last_update_incorso__', '<small>Ultimo aggiornamento: 14:12, 9 apr 2018 (CEST)</small>');
			tabella = header + tabella_InCorso + DelBot.templates.CPRunningFooter;
		} else  {
			var header = DelBot.templates.CPRunningHeader.replace('__last_update_incorso__', '');
			tabella = tabella + header + tabella_InCorso + DelBot.templates.CPRunningFooter;
		}
	}

	if( tabella_Concluse.length > 0) {
		if( tabella.length == 0 ) {
			var header = DelBot.templates.CPEndedHeader.replace('__last_update_concluse__', '<small>Ultimo aggiornamento: 14:12, 9 apr 2018 (CEST)</small>');
			tabella = header + tabella_Concluse + DelBot.templates.CPEndedFooter;
		} else {
			var header = DelBot.templates.CPEndedHeader.replace('__last_update_concluse__', '');
			tabella = tabella + header + tabella_Concluse + DelBot.templates.CPEndedFooter;
		}
	}

	var CP_avvisi_1 = DelBot.templates.CPAvvisi.replace(/__giorno__/g, data.getDate() );
	CP_avvisi_1 = CP_avvisi_1.replace(/__mese_num__/g, data.getMonth()+1 );
	CP_avvisi_1 = CP_avvisi_1.replace(/__anno__/g, data.getFullYear() );

	if( tabella.length > 0 ) {
		return CP_avvisi_1 + tabella + DelBot.templates.CPFooter;
	}
	return CP_avvisi_1 + DelBot.templates.CPEmpty + DelBot.templates.CPFooter;
};

/**
 * La funzione calcola la temperatura della discussione in funzione della tipologia.
 * La temperatura è calcolata come interpolazione lineare tra il decimo e il novantesimo percentile
 * della lunghezza della PDC
 *
 * @param tipo {string}
 * @param len {int}
 * @return float
 */
DelBot.calculateTemperature = function ( type, len ) {
	var slope, offset;
	switch( type ) {
		case 'semplificate':
			slope  =  0.0365;
			offset = -24.0;
			break;
		case 'consensuali':
			slope  =  0.0075;
			offset = -12.81;
			break;
		case 'consprorogate':
			slope  =  0.0035;
			offset = -9.76;
			break;
		case 'ordinarie':
		case 'votazioni':
			slope  =  0.0025;
			offset = -16.43;
			break;
		default:
			throw 'unexpected type';
	}

	var temp = Math.round( slope * len + offset );
	if (temp > 100) {
		temp = 100;
	} else if (temp < 0) {
		temp = 0;
	}
	return temp;
};

/**
 * La funzione scrive una pagina wiki.
 *
 * @param titolo {string}
 * @param contenuto {string}
 * @param summary {string}
 * @param editToken {string}
 * @param status
 */
DelBot.writePage = function (titolo, contenuto, summary, editToken, status) {
	status.done = false;
	$.ajax( {
		url: mw.util.wikiScript( 'api' ),
		timeout: 5000,
		data: {
			format: 'json',
			action: 'edit',
			bot: true,
			title: titolo,
			summary: summary,
			text: contenuto,
			token: editToken
		},
		dataType: 'json',
		type: 'POST',
		success: function( data ) {
			if ( data && data.edit && data.edit.result == 'Success' ) {
				status.ok = true;
				status.done = true;
			} else if ( data && data.error ) {
				status.done = true;
				status.ok = false;
				var d = new Date();
				status.error = '['+d.toISOString()+'] [API Error] Errore durante la scrittura di \"'+titolo+'"' + ' (Errore"'+data.error.code + '": ' + data.error.info+')';
			} else {
				status.done = true;
				status.ok = false;
				var d = new Date();
				status.error = '['+d.toISOString()+'] [API Error] Errore durante la scrittura di \"'+titolo+'"' + ' (Errore sconosciuto)';
			}
		},
		error: function( xhr, status ) {
			status.done = true;
			status.ok = false;
			var d = new Date();
			status.error = '['+d.toISOString()+'] [JQuery/AJAX Error] Errore durante la scrittura \"'+titolo+'" ('+status+')'; 
		}
	} );
};

/**
 * La funzione si occupa della gestione dell'aggiornamento dei contenuti della categoria
 * Categoria:Procedure di cancellazione in corso. La categorizzazione viene fatta per mezzo di 
 * template e quindi, alla protezione della pdc, l'aggiornamento non è immediato. 
 * Per aggiornarne il contenuto è necessario modificare la pagina DelBot.config.pageLastCategoryUpdate in modo da 
 * forzare l'aggiormento della tabella categorylinks
 *
 * @param statusReq
 * @param statusLastUpd
 */
DelBot.leggiStatoCatInCorso = function ( statusReq, statusLastUpd ) {
	// Leggo timestamp dell'ultima richiesta di aggiornamento
	$.ajax( {
		url: mw.util.wikiScript( 'api' ),
		timeout: 5000,
		data: {
			format: 'json',
			action: 'query',
			titles: DelBot.config.pageLastCategoryUpdate,
			prop: 'revisions',
			rvprop: 'content',
			rvlimit: '1'
		},
		dataType: 'json',
		type: 'GET',
		success: function( data ) {
			if ( data && data.query && data.query.pages )  {
				var t = undefined;
				for( var pageid in data.query.pages ) {
					t = data.query.pages[pageid].revisions[0]['*'];
				}
				if( t === undefined ) {
					throw 'missing text';
				}

				statusReq.done = true;
				if( t.length >= 14 ) {
					statusReq.timestamp = convertiTimestampToDate( t.substr(0, 14) );
					statusReq.ok = true;
				} else {
					statusReq.ok = false;
					var d = new Date();
					statusReq.error = '['+d.toISOString()+'] Errore durante la lettura di '+DelBot.config.pageLastCategoryUpdate+': formato non valido';
				}
			} else if ( data && data.error ) {
				statusReq.done = true;
				statusReq.ok = false;
				var d = new Date();
				statusReq.error = '['+d.toISOString()+'] [API Error] Errore durante la lettura di Utente:Mauro742/DeletionBot/LastCatUpd"'+
					' (Errore"'+data.error.code + '": ' + data.error.info+')';
			} else {
				statusReq.done = true;
				statusReq.ok = false;
				var d = new Date();
				statusReq.error = '['+d.toISOString()+'] [API Error] Errore durante la lettura di '+DelBot.config.pageLastCategoryUpdate+
				' (Errore sconosciuto)';
			}
		},
		error: function( xhr, status ) {
			statusReq.done = true;
			statusReq.ok = false;
			var d = new Date();
			statusReq.error = '['+d.toISOString()+'] [JQuery/AJAX Error] Errore durante la lettura di '+DelBot.config.pageLastCategoryUpdate+' ('+status+')'; 
		}
	} );

	// Leggo ultimo aggiornamento effettuato
	$.ajax( {
		url: mw.util.wikiScript( 'api' ),
		timeout: 5000,
		data: {
			format: 'json',
			action: 'query',
			list: 'categorymembers',
			cmtitle: DelBot.config.CatRunning,
			cmsort: 'timestamp',
			cmdir: 'asc',
			cmprop: 'title|sortkeyprefix',
			cmlimit: '1'
		},
		dataType: 'json',
		type: 'GET',
		success: function( data ) {
			if ( data && data.query && data.query.categorymembers ) {
				var t = data.query.categorymembers[0]['sortkeyprefix'];

				statusLastUpd.done = true;
				if( t.length > 14 ) {
					statusLastUpd.timestamp = convertiTimestampToDate( t.substr(t.length-14, 14) );
					statusLastUpd.ok = true;
				} else {
					statusLastUpd.ok = false;
					var d = new Date();
					statusLastUpd.error = '['+d.toISOString()+'] Errore durante la lettura di '+DelBot.config.CatRunning;
				}
			} else if ( data && data.error ) {
				statusLastUpd.done = true;
				statusLastUpd.ok = false;
				var d = new Date();
				statusLastUpd.error = '['+d.toISOString()+'] [API Error] Errore durante la lettura di '+DelBot.config.CatRunning+
				' (Errore"'+data.error.code + '": ' + data.error.info+')';
			} else {
				statusLastUpd.done = true;
				statusLastUpd.ok = false;
				d = new Date();
				statusLastUpd.error = '['+d.toISOString()+'] [API Error] Errore durante la lettura di '+DelBot.config.CatRunning+
				' (Errore sconosciuto)';
			}
		},
		error: function( xhr, status ) {
			statusLastUpd.done = true;
			statusLastUpd.ok = false;
			var d = new Date();
			statusLastUpd.error = '['+d.toISOString()+'] [JQuery/AJAX Error] Errore durante la lettura di '+DelBot.config.CatRunning+' ('+status+')'; 
		}
	} );
};