User:Tpt/slurpInterwiki.js

Note: After publishing, you may have to bypass your browser's cache to see the changes.

  • Firefox / Safari: Hold Shift while clicking Reload, or press either Ctrl-F5 or Ctrl-R (⌘-R on a Mac)
  • Google Chrome: Press Ctrl-Shift-R (⌘-Shift-R on a Mac)
  • Internet Explorer / Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Press Ctrl-F5.
/**
* This version of the script is only here to allow people to keep using it without any change. Please, use the gadget version: MediaWiki:Gadget-slurpInterwiki.js .
*/
( function ( mw, $ ) {

	var i18nData = {
		'en': {
			'box-title': 'Import interwiki',
			'box-warning': 'Warning: This script automatically imports languages links from one wiki without a check of conflicts. You have to check all the interwikis in the page of the chosen wiki before uploading them to Wikidata!',
			'box-lang': 'from: ',
			'box-updateLabels': 'Auto-complete empty labels with the name of the related link.',
			'import': 'Import',
			'error-api': 'Communication error with the API!',
			'error-wiki': 'The selected wiki is unknown!',
			'error-page': 'The page does not exist!',
			'error-pageNotFound': 'No link found for the selected wiki!',
			'error-save': 'Save error: ',
			'success': 'Links imported!',
			'nolinkstoupdate': 'All the links are already imported. Nothing to do!'
		},
		'ca': {
			'box-title': 'Importació d\'interwikis',
			'box-warning': 'Atenció: aquest script importa automàticament els enllaços interwiki des d\'una wiki sense verificar si hi ha conflictes. Heu de verificar-los tots abans de fer la importació a Wikidata!',
			'box-lang': 'origen: ',
			'import': 'Importa',
			'error-api': 'Error de comunicació amb l\'API!',
			'error-wiki': 'La wiki seleccionada és desconeguda!',
			'error-page': 'La pàgina no existeix!',
			'error-pageNotFound': 'No s\'ha trobat cap enllaç per a la wiki seleccionada!',
			'error-save': 'Error en desar: ',
			'success': 'S\'han importat els enllaços!',
			'nolinkstoupdate': 'Ja s\'han importat tots els enllaços. Res més a fer!'
		},
		'cs': {
			'box-title': 'Import interwiki',
			'box-warning': 'Varování: Tento skript automaticky naimportuje jazykové odkazy z jedné wiki bez kontroly případných konfliktů. Raději zkontroluj odkazy před nahráním na Wikidata!',
			'box-lang': 'z: ',
			'import': 'Import',
			'error-api': 'Chyba při komunikaci s API!',
			'error-wiki': 'Neznámá wiki!',
			'error-page': 'Stránka neexistuje!',
			'error-pageNotFound': 'Nenalezen žádný odkaz pro zvolenou wiki!',
			'error-save': 'Chyba při ukládání: ',
			'success': 'Odkazy naimportovány!',
			'nolinkstoupdate': 'Všechny odkazy již jsou naimportovány.'
		},
		'de': {
 			'box-title': 'Interwiki importieren',
			'box-warning': 'Achtung: Dieses Skript importiert die Interwiki-Links einer Sprachversion, ohne auf mögliche Konflikte zu prüfen. Du musst alle Links überprüfen, bevor du sie nach Wikidata überträgst!',
 			'box-lang': 'von: ',
 			'import': 'Importieren',
 			'error-api': 'Fehler bei der Kommunikation mit der API!',
 			'error-wiki': 'Das ausgewählte Wiki ist unbekannt!',
 			'error-page': 'Die Seite existiert nicht!',
 			'error-pageNotFound': 'Keinen Link im gewählten Wiki gefunden!',
			'error-save': 'Fehler beim Speichern: ',
 			'success': 'Links importiert!',
			'nolinkstoupdate': 'Alle Links wurden schon importiert.'
 		},
		'es': {
			'box-title': 'Importar interwikis',
			'box-warning': '¡Atención: este script importa automáticamente las interwikis de una wiki sin comprobar si existen conflictos; hay que comprobar todas las interwikis de la página de la wiki elegida antes de subirlas a Wikidata!',
			'box-lang': 'desde: ',
			'import': 'Importar',
			'error-api': '¡Error de comunicación con la API!',
			'error-wiki': 'La wiki seleccionada es desconocida',
			'error-page': 'La página no existe',
			'error-pageNotFound': 'No hay enlaces para la wiki seleccionada',
			'error-save': 'Error al guardar: ',
			'success': 'Enlaces importados',
			'nolinkstoupdate': 'Ya están importados todos los enlaces. ¡No es necesario hacer nada!'
		},
		'fa': {
			'box-title': 'دریافت میان‌ویکی',
			'box-warning': 'هشدار:این ابزار پیوندها را بدون تشخیص تداخل میان‌ویکی‌ها درون‌ریزی می‌کند . تشخیص و اصلاح میان‌ویکی‌های اشتباه به عهدهٔ کاربر است!',
			'box-lang': 'از: ',
			'import': 'دریافت',
			'error-api': 'خطا در ارتباط با ای‌پی‌آی!',
			'error-wiki': 'ویکی مورد نظر ناشناس است!',
			'error-page': 'صفحهٔ مورد نظر وجود ندارد!',
			'error-pageNotFound': 'برای ویکی انتخاب شده پیوندی یافت نشد!',
			'error-save': 'خطای ذخیره : ',
			'success': 'پیوندها درون‌ریزی شد!',
			'nolinkstoupdate': 'همه میان‌ویکی‌ها موجود هستند چیزی برای افزودن نمانده‌است!'
		},
		'fi': {
			'box-title': 'Tuo kieltenväliset linkit',
			'box-warning': 'Varoitus: Tämä skripti tuo automaattisesti kieltenväliset linkit yhdestä wikistä ilman tarkistuksia. Sinun pitää ensin tarkistaa kaikki kieltenväliset linkit wikistä, josta tuot linkit Wikidataan !',
			'box-lang': 'mistä: ',
			'import': 'Tuo',
			'error-api': 'Virhe kommunikoidessa API:n kanssa !',
			'error-wiki': 'Valittu wiki on tuntematon !',
			'error-page': 'Sivu ei löydy !',
			'error-pageNotFound': 'Valittuun wikiin ei löytynyt linkkejä !',
			'error-save': 'Tallenna virhe: ',
			'success': 'Linkit tuotu !',
			'nolinkstoupdate': 'Kaikki linkit on jo tuotu. Mitään ei tehty !'
		},
		'fr': {
			'box-title': 'Importer les interwikis',
			'box-warning': 'Attention : Ce script importe automatiquement les liens interlangues depuis le wiki choisi sans faire attention au possibles conflits. Vous devez vérifier tous les interwikis avant de les verser sur Wikidata !',
			'box-lang': 'depuis : ',
			'box-updateLabels': 'Compléter automatiquement les libellés vides avec le nom des liens correspondants.',
			'import': 'Importer',
			'error-api': 'Erreur de communication avec l\'API !',
			'error-wiki': 'Le wiki sélectionné est inconnu !',
			'error-page': 'La page n\'existe pas !',
			'error-pageNotFound': 'Aucun lien n\'a été trouvé pour la wiki sélectionné !',
			'error-save': 'Save error: ',
			'success': 'Liens importés !',
			'nolinkstoupdate': 'Tout les liens ont déjà été importés, le script ne change rien !'
		},
		'it': {
			'box-title': 'Importa gli interwiki',
			'box-warning': 'Attenzione: Questo script importa automaticamente gli interwiki da una wiki senza controllare possibili conflitti di edizione. Verifica che tutti gli interwiki della pagina scelta siano presenti su Wikidata !',
			'box-lang': 'da : ',
			'import': 'Importa',
			'error-api': 'Errore di comunicazione con le API !',
			'error-wiki': 'La wiki selezionata è inesistente!',
			'error-page': 'La pagina selezionata non esiste!',
			'error-pageNotFound': 'Non è stato trovato alcun collegamento verso la wiki selezionata!',
			'error-save': 'Errore durante il salvataggio: ',
			'success': 'Collegamenti importati!',
			'nolinkstoupdate': 'Tutti i link sono già stati importati. Nessuna modifica da fare!'
		},
		'nb': {
			'box-title': 'Importer interwiki',
			'box-warning': 'Advarsel: Dette skriptet importerer språklenker fra én wiki automatisk, uten å sjekke konflikter. Du må sjekke alle interwiki-lenkene på siden til den valgte wikien før du laster dem opp til Wikidata !',
			'box-lang': 'fra: ',
			'import': 'Importer',
			'error-api': 'Feil ved kommunikasjon med API !',
			'error-wiki': 'Den valgte wikien er ukjent !',
			'error-page': 'Siden finnes ikke !',
			'error-pageNotFound': 'Ingen lenke funnet for den valgte wikien !',
			'error-save': 'Lagringsfeil: ',
			'success': 'Lenker importert !',
			'nolinkstoupdate': 'Alle lenkene er allerede importert. Ingenting å gjøre !'
		},
		'nl': {
			'box-title': 'Importeer interwikis',
			'box-warning': 'Waarschuwing: dit script importeert automatisch taalverwijzingen zonder hiervoor op de eventuele conflicten te letten. Het is verstandig ze eerst te controleren voordat je ze automatisch laat toevoegen op Wikidata',
			'box-lang': 'van: ',
			'import': 'Importeren',
			'error-api': 'Kan niet met de API verbinding maken !',
			'error-wiki': 'De geselecteerde wiki is niet bekend !',
			'error-page': 'De pagina bestaat niet !',
			'error-pageNotFound': 'Geen link gevonden voor de geselecteerde wiki !',
			'error-save': 'Fout tijdens opslaan: ',
			'success': 'Links geïmporteerd !',
			'nolinkstoupdate': 'Alle links zijn al geïmporteerd. Er niks om uit te voeren !'
		},
		'pl': {
			'box-title': 'Importuj interwiki',
			'box-warning': 'Uwaga: Ten skrypt importuje automatycznie łącza językowe z jednej wiki bez sprawdzania konfliktów. Musisz sprawdzić wszystkie interwiki na stronie wybranej wiki przed wgraniem ich do Wikidata!',
			'box-lang': 'z: ',
			'import': 'Importuj',
			'error-api': 'Problem w komunikacji z API!',
			'error-wiki': 'Wybrana wiki jest nieznana!',
			'error-page': 'Strona nie istnieje!',
			'error-pageNotFound': 'Nie znaleziono linku dla wybranej wiki!',
			'error-save': 'Błąd zapisu: ',
			'success': 'Linki zaimportowane!',
			'nolinkstoupdate': 'Wszystkie linki są już zaimportowane. Nie ma nic do zrobienia!'
		},
		'pt': {
			'box-title': 'Importar interwikis',
			'box-warning': 'Aviso: Este script importa automaticamente os links para outros idiomas a partir de uma wiki sem conferir se existem conflitos. Você precisa verificar todos os links na página da wiki escolhida antes de importá-los para o Wikidata!',
			'box-lang': 'de: ',
			'import': 'Importar',
			'error-api': 'Erro de comunicação com a API !',
			'error-wiki': 'A wiki escolhida é desconhecida!',
			'error-page': 'A página não existe!',
			'error-pageNotFound': 'Nenhum link foi encontrado na wiki escolhida!',
			'error-save': 'Erro ao salvar: ',
			'success': 'Os links foram importados!',
			'nolinkstoupdate': 'Todos os links já foram importados. Nada a ser feito!'
		},
		'ru': {
			'box-title': 'Импорт интервики ',
			'box-warning': 'Warning: This script import automatically languages links from one wiki without check of conflicts. You have to check all the interwikis in the page of the chosen wiki before uploading them to Wikidata !',
			'box-lang': 'откуда : ',
			'import': 'Импорт',
			'error-api': 'Проблема с API !',
			'error-wiki': 'Выбранный раздел Википедии',
			'error-page': 'Страница не существует!',
			'error-pageNotFound': 'Нет интервик в указанном разделе',
			'error-save': 'Save error: ',
			'success': 'Интервики импортированы.',
			'nolinkstoupdate': 'All the links are already imported. Nothing to do !'
		},
		'zh': {
			'box-title': '導入跨語言連結',
			'box-warning': '警告:此程式將於未檢查跨語言連結衝突的情況下導入。你應於導入前檢查頁面中所有跨語言連結!',
			'box-lang': '取自: ',
			'import': '導入',
			'error-api': '使用API出現錯誤!',
			'error-wiki': '選取了未知Wiki!',
			'error-page': '該頁並不存在!',
			'error-pageNotFound': '該頁沒有跨語言連結!',
			'error-save': '儲存錯誤:',
			'success': '跨語言連結已導入!',
			'nolinkstoupdate': '所有連結已導入!'
		}
	};
	i18nData.no = i18nData.nb;

	var parts = mw.user.options.get( 'language' ).split("-");
	if( i18nData[parts[0]] ) {
		var lang = parts[0];
	} else {
		var lang = 'en';
	}

	var notification = mw.util.getParamValue( 'slurpnotif' );
	if ( notification !== null ) {
		mw.notify( i18n( notification ) );
	};

	var itemId = mw.config.get( 'wbItemId' );
 	if( !itemId ) {
		return;
	}

	/**
	 * Return the localized version of a message
	 */
	function i18n( key ) {
		if( i18nData[ lang ][ key ] ) {
			return i18nData[ lang ][ key ];
		} else {
			return i18nData[ 'en' ][ key ];
		}
	}

	/**
	 * Return the language code from the ID of the Wiki
	 */
	function getLanguageCodeFromWikiId( wiki ) {
		var splited = wiki.match( /^(.*)wiki$/i );
		if( !splited[1] ) {
			return '';
		} else {
			return splited[1].replace(/_/g, '-');
		}
	}

	/**
	 * Create the dialog and add a link in toolBox
	 */
	function init() {
		mw.loader.using( ['jquery.ui'], function() {
			var formFind = '<div id="slurpInterwiki" title="' + i18n( 'box-title' ) + '"><form>';
			formFind += '<p><label for="slurpInterwiki-lang">' + i18n( 'box-lang' ) + '</label><select name="slurpInterwiki-lang" id="slurpInterwiki-lang"></select></p>';
			formFind += '<p><input type="checkbox" name="slurpInterwiki-updateLabels" id="slurpInterwiki-updateLabels" /> <label for="slurpInterwiki-updateLabels">' + i18n( 'box-updateLabels' ) + '</label></p>';
			formFind += '<p>' + i18n( 'box-warning' ) + '</p>';
			formFind += '</form></div>';
			var messageFind = $( formFind ).appendTo( '#content' );
			messageFind.dialog( {
				autoOpen: false,
				modal: true,
				width: 500,
				buttons: [ {
					id: 'slurpInterwiki-button-import',
					text: i18n( 'import' ),
					click: function() {
						work();
					}
				} ]
			} );

			var portletLink = mw.util.addPortletLink( 'p-tb', '#', i18n( 'box-title' ), 't-slurpInterwiki', i18n( 'box-title' ) );
			$(portletLink).click( show );
		} );
	}

	/**
	 * Show the dialog
	 */
	function show() {
		getItemLinks( function( links ) {
			formFind = $( '#slurpInterwiki-lang' );
			formFind.empty();
			var languagesLabel = mw.config.get('wgULSLanguages') || {};
			for( var i in links ) {
				var languageCode = getLanguageCodeFromWikiId( links[i].site );
				var label = links[i].site;
				if( languageCode !== '' ) {
					label = languageCode;
					if( languagesLabel[languageCode] ) {
						label += ' (' + languagesLabel[languageCode] + ')';
					}
				}
				formFind.append( '<option value="' + links[i].site + '">' + label + '</option>' );
			}
			$( 'div#slurpInterwiki' ).dialog( 'open' );
		} );
	}

	/**
	 * Called on error
	 */
	function onError() {
		$.removeSpinner( 'slurpInterwiki' );
		$( '#slurpInterwiki-button-import' ).button( 'option', 'disabled', false );
	}

	/**
	 * Called on API error
	 */
	function onApiError( jqXHR, textStatus, errorThrown ) {
		alert( i18n( 'error-api' ) );
		onError();
	}

	/**
	 * @param msg message to show
	 * Called on success
	 */
	function onSuccess() {
		location.href = mw.util.getUrl( mw.config.get( 'wgPageName' ) ) + '?slurpnotif=success';
	}

	/**
	 * Update interLanguages links from the wiki selected in the box. Works only for Wikipedias.
	 */
	function work() {
		mw.loader.using( ['jquery.spinner'], function() {
			$.createSpinner( {
				size: 'large',
				type: 'block',
				id: 'slurpInterwiki'
			} ).appendTo( 'div#slurpInterwiki' );
			$( '#slurpInterwiki-button-import' ).button( 'option', 'disabled', true );

			getItem( function( item ) {
				if( item.sitelinks ) {
					links = item.sitelinks;
				} else {
					links = {};
				}

				var wiki = $( '#slurpInterwiki-lang' ).val();
				if( !links[wiki] ) {
					alert( i18n( 'error-pageNotFound' ) );
					onError();
					return;
				}
				var page = links[wiki].title;
				getLanguageLinks( wiki, page, function( interlangLinks ) {
					getItem( function( item ) {
						var itemValue = {};
						var changed = [];

						var itemLinks = {};
						if( item.sitelinks ) {
							itemLinks = item.sitelinks;
						}
						var linkChanged = false;
						for( var i in interlangLinks ) {
							var regex = /^(.*)old$/i;
							if( regex.test( interlangLinks[i].lang ) ) {
								mw.log( 'Refused wiki: ' + interlangLinks[i].lang );
							} else {
								var site = interlangLinks[i].lang.replace(/-/g, '_')  + 'wiki';
								if( !itemLinks[site] ) {
									itemLinks[site] = {
										'site': site,
										'title': interlangLinks[i]['*']
									};
									linkChanged = true;
								}
							}
						}
						if( linkChanged ) {
							itemValue.sitelinks = itemLinks;
							changed.push( 'sitelinks' );
						}

						//Update labels
						if( $( '#slurpInterwiki-updateLabels' ).attr( 'checked' ) ) {
							var labels = {};
							if( item.labels ) {
								labels = item.labels;
							}
							var labelChanged = false;
							for( var site in itemLinks ) {
								var lang = getLanguageCodeFromWikiId( itemLinks[site].site );
								if( lang == 'simple' ) {
									continue;
								}
								if( !labels[lang] ) {
									labels[lang] = {
										'language': lang,
										'value': itemLinks[site].title.replace(/\(.*\)/g, '')
									};
									labelChanged = true;
								}
							}
							if( labelChanged ) {
								itemValue.labels = labels;
								changed.push( 'labels' );
							}
						}

						//Push changes
						if( changed.length != 0 ) {
							setItem( itemValue, changed, onSuccess, 'Update of interwikis from ' + wiki );
						} else {
							mw.notify( i18n( 'nolinkstoupdate' ) );
							$( 'div#slurpInterwiki' ).dialog( 'close' );
							onError();
						}
					} );
				} );
			} );
		} );
	}

	/**
	 * Update the item
	 * @param success function called on success
	 */
	function updateItem( links ) {
	}

	/**
	 * Return the item
	 * @param success function called on success
	 */
	function getItem( success ) {
		$.ajax( {
  			url: mw.util.wikiScript( 'api' ),
			data: {
				'format': 'json',
				'action': 'wbgetitems',
				'ids': itemId
			}
		} )
		.done(function( data ) {
			if( data.success && data.items[itemId] ) {
				success( data.items[itemId] );
			} else {
				onApiError();
			}
		} )
		.fail(onApiError);
	}

	/**
	 * Return the existings links of a wiki
	 * @param success function called on success
	 */
	function getItemLinks( success ) {
		getItem( function( item ) {
			if( item.sitelinks ) {
				success( item.sitelinks );
			} else {
				success( {} );
			}
		} );
	}

	/**
	 * Return the existings links in a page of a wiki
	 * @param wiki string id of the wiki. Warning: Currently only Wikipedias are supported.
	 * @param page string name of the page
	 * @param success function called on success
	 */
	function getLanguageLinks( wiki, page, success ) {
		var langCode = getLanguageCodeFromWikiId( wiki );
		if( !langCode === '' ) {
			alert( i18n( 'error-wiki' ) );
			onError();
			return [];
		}
		$.ajax( {
  			url: '//' + langCode + '.wikipedia.org/w/api.php',
			data: {
				'format': 'json',
				'action': 'query',
				'titles': page,
				'prop': 'langlinks',
				'lllimit': 400
			},
			dataType: 'jsonp'
		} )
		.done(function( data ) {
			if( data.query.pages ) {
				for( var id in data.query.pages ) {
					if( id == -1 ) {
						alert( i18n( 'error-page' ) );
						onError();
					} else {
						if( data.query.pages[id].langlinks ) {
							success( data.query.pages[id].langlinks );
						} else {
							success( [] );
						}
					}
				}
			} else {
				onApiError();
			}
		} )
		.fail(onApiError);
	}

	/**
	 * Set the item links
	 * @param item array the item
	 * @param include array of type of changed information (labels, aliases....)
	 * @param success function called on success
	 * @param summary string
	 */
	function setItem( item, include, success, summary ) {
		var exclude = ['pageid', 'ns', 'title', 'lastrevid', 'touched', 'aliases', 'labels', 'descriptions', 'sitelinks'];
		for( var i in include ) {
			exclude.splice( $.inArray(include[i], exclude), 1 );
		}
		$.ajax( {
			type: 'POST',
  			url: mw.util.wikiScript( 'api' ),
			data: {
				'format': 'json',
				'action': 'wbsetitem',
				'id': itemId,
				'type': 'item',
				'token': mw.user.tokens.get( 'csrfToken' ),
				'data': $.toJSON( item ),
				'summary': summary,
				'exclude': exclude.join('|')
			}
		} )
		.done(function( data ) {
			if( data.error && data.error.info ) {
				alert( i18n( 'error-save' )  + data.error.info );
				onError();
			} else {
				success(); //TODO Manage possibles errors
			}
		} )
		.fail(onApiError);
	}

	$( document ).ready( init );
} ( mediaWiki, jQuery ) );