User:Ash Crow/dataDrainer.js

From Wikidata
Jump to navigation Jump to search

Note: After saving, 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: Hold Ctrl while clicking Refresh, or press Ctrl-F5
  • Opera: Go to Menu → Settings (Opera → Preferences on a Mac) and then to Privacy & security → Clear browsing data → Cached images and files.
/**********************************************************************************
***********************************************************************************
**                _       _        _____            _                            **
**               | |     | |      |  __ \          (_)                           **
**             __| | __ _| |_ __ _| |  | |_ __ __ _ _ _ __   ___ _ __            **
**            / _` |/ _` | __/ _` | |  | | '__/ _` | | '_ \ / _ \ '__|           **
**           | (_| | (_| | || (_| | |__| | | | (_| | | | | |  __/ |              **
**            \__,_|\__,_|\__\__,_|_____/|_|  \__,_|_|_| |_|\___|_|    v2.0      **
**                                                                               **
** ----------------------------------------------------------------------------- **
**  How to use:                                                                  **
**   Add to your common.js [[Special:MyPage/common.js]],                         **
**   importScript( 'User:Ash Crow/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      |    **
**   |  rollbacker    |    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( 'rollbacker' ) !== -1 ) { return 'patroller'; }
  else { return ''; }
}


if (( mw.config.get( 'wgNamespaceNumber') === 0 ) 
    && ( group() )){
  mw.loader.using( [ 'mediawiki.util' , 'oojs-ui', 'mediawiki.api.edit'], 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 rollbackers 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!',
      },
      '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 révocateurs 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 rollbacker. 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),
	    			'tags': 'datadrainer',
	    			'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() {
	    			mw.notify(mw.msg('notif-fail'));
	    		});
	    	});
	    }
    };
  }); // End mw.loader.using
}