User:Ash Crow/dataDrainer.js

From Wikidata
Jump to navigation Jump to search

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)
  • Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
/**********************************************************************************
***********************************************************************************
**                _       _        _____            _                            **
**               | |     | |      |  __ \          (_)                           **
**             __| | __ _| |_ __ _| |  | |_ __ __ _ _ _ __   ___ _ __            **
**            / _` |/ _` | __/ _` | |  | | '__/ _` | | '_ \ / _ \ '__|           **
**           | (_| | (_| | || (_| | |__| | | | (_| | | | | |  __/ |              **
**            \__,_|\__,_|\__\__,_|_____/|_|  \__,_|_|_| |_|\___|_|    v2.0      **
**                                                                               **
** ----------------------------------------------------------------------------- **
**  How to use:                                                                  **
**   Add to your common.js [[Special:MyPage/common.js]],                         **
**   importScript( 'MediaWiki:Gadget-dataDrainer.js' );                          **
**                                                                               **
**                                                                               **
**  Read me:                                                                     **
**   -This tool allows you to delete the data of an item.                        **
**   -You can choose what you want to delete: labels and/or descriptions and/or  **
**    aliases and or sitelinks                                                   **
**   -When you have chosen your options type the verification code to prevent    **
**    vandalism then click on the "Empty" button.                                **
**   -If you have checked the sitelinks option a dialog ask you if you're really **
**    sure to delete all sitelinks because they can only be once on Wikidata.    **
**   -Then a checklist will show you again the selected options.                 **
**   -Finally a prompt ask you the reason of this deletion.                      **
**                                                                               **
**  Permissions:                                                                 **
**   +----------------------------------------------------------------------+    **
**   |     Groups     |  Labels  |  Descriptions  |  Aliases  |  Sitelinks  |    **
**   +----------------+----------+----------------+-----------+-------------+    **
**   |  sysop         |    OK    |       OK       |    OK     |     OK      |    **
**   |  autoconfirmed |    OK    |       OK       |    OK     |     XX      |    **
**   |  user          |    XX    |       XX       |    XX     |     XX      |    **
**   +----------------------------------------------------------------------+    **
**                                                                               **
***********************************************************************************
**********************************************************************************/

function group() {
  if ( mw.config.get( 'wgUserGroups' ).indexOf( 'sysop' ) !== -1 ) { return 'sysop'; }
  else if ( mw.config.get( 'wgUserGroups' ).indexOf( 'autoconfirmed' ) !== -1 ) { return 'patroller'; }
  else { return ''; }
}


if (( mw.config.get( 'wgNamespaceNumber') === 0 ) 
    && ( group() )){
  mw.loader.using( [ 'mediawiki.util' , 'oojs-ui', 'mediawiki.api'], function() {
    var itemId = mw.config.get( 'wbEntityId' );
    if ( !itemId ) {
      return;
    }

    /*
	** Localization
	*/
    var messages = {
      'en': {
        'link-title': 'Empty',
        'box-title': 'Empty the item',
        'action-cancel': 'Cancel',
        'action-save': 'Empty',
        'canceled': 'Deletion canceled',
        'notif-done':  'Action done.',
        'notif-fail': 'Action failed.',
        'warning-message': 'Caution! You will fully drain this item. Only administrators and autoconfirmed can use this feature. Please check and verify what you want to clear and do not repurpose the item.',
        'labels': 'Labels',
        'descriptions': 'Descriptions',
        'aliases': 'Aliases',
        'sitelinks': 'Sitelinks',
        'locked-option': 'This option is locked. Ask an administrator!',
        'nothing-check': 'There is nothing to do!',
      },
      'el': {
      	'link-title': 'Άδειο',
      	'box-title': 'Άδειασε τたうοおみくろん αντικείμενο',
      	'action-cancel': 'Άκυρο',
      	'action-save': 'Άδειο',
      	'canceled': 'Ηいーた διαγραφή ακυρώθηκε',
      	'notif-done':  'Ηいーた ενέργεια έγινε.',
      	'notif-fail': 'Ηいーた ενέργεια απέτυχε.',
      	'warning-message': 'Προσοχή! Θしーたαあるふぁ αδειάσετε πλήρως αυτό τたうοおみくろん αντικείμενο. Μόνο οおみくろんιいおた διαχειριστές κかっぱαあるふぁιいおた οおみくろんιいおた αυτοεπιβεβαιωμένοι χρήστες μπορούν νにゅーαあるふぁ χρησιμοποιήσουν αυτήν τたうηいーた δυνατότητα. Ελέγξτε κかっぱαあるふぁιいおた επαληθεύστε τたうιいおた θέλετε νにゅーαあるふぁ αδειάσετε κかっぱαあるふぁιいおた μみゅーηいーたνにゅー επανατοποθετήσετε τたうοおみくろん αντικείμενο.',
      	'labels': 'Ετικέτες',
      	'descriptions': 'Περιγραφές',
      	'aliases': 'Αλλώνυμα',
      	'sitelinks': 'Διασύνδεσμοι',
      	'locked-option': 'Αυτή ηいーた επιλογή είναι κλειδωμένη. Ρωτήστε έναν διαχειριστή!',
      	'nothing-check': 'Δでるたεいぷしろんνにゅー υπάρχει τίποτα νにゅーαあるふぁ κάνει!',
      },
      'fi': {
        'link-title': 'Tyhjennä',
        'box-title': 'Tyhjennä kohde',
        'action-cancel': 'Peruuta',
        'action-save': 'Tyhjennä',
        'canceled': 'Poisto peruutettu',
        'notif-done':  'Toiminto suoritettu.',
        'notif-fail': 'Toiminto epäonnistui.',
        'warning-message': 'Huomio! Olet tyhjentämässä tätä kohdetta. Vain ylläpitäjät ja palauttajat voivat käyttää tätä toimintoa. Tarkista ja vahvista mitä haluat tyhjentää äläkä uudelleenkäytä tätä kohdetta eri tarkoitukseen.',
        'labels': 'Nimet',
        'descriptions': 'Kuvaukset',
        'aliases': 'Aliakset',
        'sitelinks': 'Sivustolinkit',
        'locked-option': 'Tämä valinta on lukittu. Kysy ylläpitäjää!',
        'nothing-check': 'Mitään ei tehty!',
      },
      'fr': {
        'link-title': 'Vider',
        'box-title': 'Vider l\'élément',
        'action-cancel': 'Annuler',
        'action-save': 'Vider',
        'notif-done':  'Action effectuée.',
        'notif-fail': 'Échec de l’action.',
        'warning-message': 'Attention! Vous allez entièrement vider cet élément. Seuls les administrateurs et les utilisateurs autoconfirmés peuvent utiliser cette fonctionnalité. Veuillez vérifier et cocher ce que vous voulez vider, et ne pas transformer l’élément en autre chose	.',
        'labels': 'Libellés',
        'descriptions': 'Descriptions',
        'aliases': 'Alias',
        'sitelinks': 'Liens',
        'locked-option': 'Cette option est verrouillée. Demander à un administrateur !',
        'nothing-check': 'Il n\'y a aucune action de cochée !',
      },
      'it': {
        'link-title': 'Svuota',
        'box-title': 'Svuota l\'elemento',
        'action-cancel': 'Annulla',
        'action-save': 'Svuota',
        'canceled': 'Cancellazione annullata',
        'notif-done':  'Cancellazione eseguita.',
        'notif-fail': 'Cancellazione fallita.',
        'warning-message': 'Attenzione! Stai per svuotare completamente questo elemento. Questa funzionalità è riservata ad amministratori e autoconfirmed. Per favore, verifica ciò che intendi rimuovere.',
        'labels': 'Etichette',
        'descriptions': 'Descrizioni',
        'aliases': 'Alias',
        'sitelinks': 'Collegamenti',
        'locked-option': 'Questa opzione è bloccata. Contatta un amministratore!',
        'nothing-check': 'Non hai selezionato alcuna opzione!',
      },
    };

    mw.messages.set( messages[ 'en' ] );
    var lang = mw.config.get( 'wgUserLanguage' );
    if ( lang && lang != 'en' && lang in messages ) {
    	mw.messages.set( messages[ lang ] );
    }

    // Link
    var dataDrainerNode = mw.util.addPortletLink(
    	'p-cactions',
    	'#',
    	mw.msg('link-title')
    );
    $( dataDrainerNode ).on( 'click', function ( e ) {
    	windowManager.openWindow( processDialog );
    	e.preventDefault();
    } );

    // Subclass ProcessDialog.
    function ProcessDialog( config ) {
    	ProcessDialog.super.call( this, config );
    }
    OO.inheritClass( ProcessDialog, OO.ui.ProcessDialog );

    // Specify a name for .addWindows()
    ProcessDialog.static.name = 'dataDrainerDialog';
    // Specify a static title and actions.
    ProcessDialog.static.title = mw.msg('box-title');
    ProcessDialog.static.actions = [
    	{ action: 'save',
    	  label: mw.msg('action-save'),
    	  flags: [ 'primary', 'destructive' ] },
    	{ label: mw.msg('action-cancel'), flags: 'safe' }
    ];

    // Use the initialize() method to add content to the dialog's $body, 
    // to initialize widgets, and to set up event handlers. 
    ProcessDialog.prototype.initialize = function () {
    	ProcessDialog.super.prototype.initialize.apply( this, arguments );
    	
    	this.content = new OO.ui.PanelLayout( { padded: true, expanded: false } );
    	this.content.$element.append(mw.msg('warning-message'));
    	
    	this.checkboxes = new OO.ui.CheckboxMultiselectWidget( {
    		items: [
    			new OO.ui.CheckboxMultioptionWidget( {
    				data: 'labels',
    				label: mw.msg('labels')
    			}),
    			new OO.ui.CheckboxMultioptionWidget( {
    				data: 'descriptions',
    				label: mw.msg('descriptions')
    			}),
    			new OO.ui.CheckboxMultioptionWidget( {
    				data: 'aliases',
    				label: mw.msg('aliases')
    			}),
    			new OO.ui.CheckboxMultioptionWidget( {
    				disabled: ( group() === 'sysop' ? false : true ),
    				data: 'sitelinks',
    				label: mw.msg('sitelinks') + (group() === 'sysop' ? '' : ' — ' + mw.msg('locked-option'))
    			})
    		]
    	});
    	
    	this.content.$element.append(this.checkboxes.$element);
    	this.$body.append( this.content.$element );
    };

    // Use the getActionProcess() method to specify a process to handle the 
    // actions (for the 'save' action, in this example).
    ProcessDialog.prototype.getActionProcess = function ( action ) {
    	var dialog = this;
    	if ( action ) {
    		var selectedTypes = [];
    		if ( action === 'save' ) {
    			var items = this.checkboxes.getItems();
    			for (var i in items ) {
    				if ( items[i].isSelected() ) {
    					selectedTypes.push(items[i]['data']);
    				}
    			}
    		}
    		getValues(selectedTypes.join('|'));
    		
    		// Close the window
    		return new OO.ui.Process( function () {
    			dialog.close( { action: action } );
    		});
    	}
    	
    	// Fallback to parent handler.
    	return ProcessDialog.super.prototype.getActionProcess.call( this, action );
    };

    // Get dialog height.
    ProcessDialog.prototype.getBodyHeight = function () {
    	return 250;
    };

    // Create a new dialog window.
    var processDialog = new ProcessDialog({ });    

    // Create and append the window manager.
    var windowManager = new OO.ui.WindowManager();
    $( 'body' ).append( windowManager.$element );
    windowManager.addWindows( [ processDialog ] );
    
    // Get current content of the item
    var getValues = function(props){
    	if (!props) {
    		mw.notify(mw.msg('nothing-check'));
    	} else {
    		var api = new mw.Api();
	    	api.get({
	    		"action": "wbgetentities",
	    		"format": "json",
	    		"ids": itemId,
	    		"props": props,
	    		"formatversion": "2"
	    	}).done( function ( data ) {
	    		var itemData = data["entities"][itemId];
	    		var payload = {};
	    		for (var type in itemData) {
	    			if (type.match(props)) {
	    				if (!(type in payload)) {
	    					payload[type] = [];
	    				}
	    				for (var langTag in itemData[type]) {
	    					if (type == "sitelinks") {
	    						payload[type].push({
	    							"site": langTag,
	    							"remove": ""
	    						});
	    					} else if (type == "aliases") {
	    						for (var alias in itemData[type][langTag]) {
	    							payload[type].push({
	    								"language": langTag,
	    								"value": itemData[type][langTag][alias]["value"],
	    								"remove": ""
	    							});
	    						}
	    					} else {
	    						payload[type].push({
	    							"language": langTag,
	    							"remove": ""
	    						});
	    					}
	    				}
	    			}
	    		}
	    		api.postWithEditToken({
	    			'action': "wbeditentity",
	    			'id': itemId,
	    			'data': JSON.stringify(payload),
	    			'summary': '[[User:Ash Crow/dataDrainer.js|dataDrainer]] Delete all ' + props,
	    		}).done( function() {
	    			mw.notify(mw.msg('notif-done'));
	    			setTimeout(window.location.reload(), 3000);
	    		}).fail( function() {
	    			console.log('Failed edit.');
	    			console.log('id: '+ itemId);
	    			console.log('data:');
	    			console.log(JSON.stringify(payload));
	    			mw.notify(mw.msg('notif-fail'));
	    		});
	    	});
	    }
    };
  }); // End mw.loader.using
}