/*
* Cat Usage
*
* Author : [[User:0x010C]]
*/
//<nowiki>
mw.loader.using( [ 'mediawiki.util', 'oojs-ui', 'mediawiki.widgets.CategoryMultiselectWidget' ], function () {
var CatUsage = function () {
this.booklet = undefined;
this.basePage = undefined;
this.resultPage = undefined;
this.api = new mw.Api();
this.totalCats = 0;
this.totalFiles = 0;
this.countedFiles = 0;
this.fileUploaded = {};
this.uniqFileUsage = {};
this.fileUsage = {};
this.globalUsage = {};
this.fileUsageMainNamespace = {};
this.globalUsageMainNamespace = {};
this.files = [];
this.categories = [];
this.semaphor = 0;
this.step = 0;
var catusage = this;
this.generateInterface = function () {
var self = this;
this.booklet = new OO.ui.BookletLayout( {
outlined: true
} );
this.basePage = new BasePageLayout( this, 'base' );
this.resultPage = new ResultPageLayout( this, 'result' );
this.booklet.addPages ( [ this.basePage, this.resultPage ] );
var mainContainer = $( '<div>' ).css('height', '500px').css( 'border', '1px solid #a2a9b1' ).css( 'border-radius', '2px' ).css( 'position', 'relative' ).append( this.booklet.$element );
$( '#mw-content-text' ).prepend( mainContainer );
};
this.run = function( depth, categories ) {
while ( categories.length > 0 ) {
var category = 'Category:' + categories.pop();
this.categories.push( category );
this.exploreAllCategories( category, depth );
}
};
this.nextStep = function() {
console.log( 'step: ' + this.step + ' - semaphor: ' + this.semaphor );
if ( this.semaphor === 0 ) {
this.step++;
switch ( this.step ) {
case 1:
this.totalCats = this.categories.length;
for ( var i = 0; i < 5; i++ ) {
if ( this.categories.length > 0 ) {
this.getFilesInCat( this.categories.pop() );
}
}
break;
case 2:
this.totalFiles = this.files.length;
for ( var i = 0; i < 5; i++ ) {
if ( this.files.length > 0 ) {
this.usageRequest( this.files.splice( 0,50 ) )
}
}
break;
}
}
switch ( this.step ) {
case 0:
this.resultPage.setHeader( '<i>Listing recursively all categories to analyse ; ' + catusage.categories.length + ' found so far.</i><br><br>' );
break;
case 1:
this.resultPage.setHeader( '<i>Exploring the categories to list all files to work on ; ' + catusage.categories.length + ' remaining out of ' + catusage.totalCats + ' ; ' + catusage.files.length + ' files found so far.</i><br><br>' );
break;
case 2:
this.resultPage.setHeader( '<i>Analysing file usage ; ' + catusage.countedFiles + ' medias out of ' + catusage.totalFiles + ' fetched so far.</i><br><br>' );
break;
case 3:
this.resultPage.setHeader( '<i>Done ; ' + catusage.countedFiles + ' files successfully analysed.</i><br><br>' );
break;
}
};
this.exploreAllCategories = function( category, depth ) {
if ( depth >= 0 ) {
catusage.semaphor++;
//Explore the subcategories
this.api.post( {
"action": "query",
"format": "json",
"generator": "categorymembers",
"formatversion": "2",
"gcmtitle": category,
"gcmtype": "subcat",
"gcmlimit": "500",
} ).then( function( data ) {
if ( data.query !== undefined ) {
var categoriesToExplore = [];
$.each( data.query.pages, function( _, page ) {
if ( ! ( page.title in catusage.categories ) ) {
catusage.categories.push( page.title );
categoriesToExplore.push( page.title );
}
} );
while ( categoriesToExplore.length > 0 ) {
catusage.exploreAllCategories( categoriesToExplore.pop(), depth - 1 );
}
}
catusage.semaphor--;
catusage.nextStep();
} ).fail( function( data ) {
console.log( data );
catusage.semaphor--;
catusage.exploreAllCategories( category, depth );
} );
}
};
this.getFilesInCat = function( category, gcmcontinue ) {
gcmcontinue = gcmcontinue || '';
if ( category === undefined ) {
return;
}
this.semaphor++;
catusage.api.post( {
"action": "query",
"format": "json",
"generator": "categorymembers",
"formatversion": "2",
"gcmtitle": category,
"gcmtype": "file",
"gcmlimit": "500",
"gcmcontinue": gcmcontinue
} ).then( function( data ) {
if ( data.query !== undefined ) {
$.each( data.query.pages, function( _, page ) {
if ( ! ( page.title in catusage.files ) ) {
catusage.files.push( page.title );
}
} );
}
catusage.semaphor--;
if ( data.continue !== undefined ) {
catusage.getFilesInCat( category, data.continue.gcmcontinue );
}
else {
catusage.getFilesInCat( catusage.categories.pop() );
catusage.nextStep();
}
} ).fail( function( data ) {
console.log( data );
catusage.semaphor--;
catusage.getFilesInCat( category, gcmcontinue );
} );
};
this.usageRequest = function( titles, fucontinue, gucontinue ) {
if ( titles.length === 0 ) {
return;
}
fucontinue = fucontinue || '';
gucontinue = gucontinue || '';
this.semaphor++;
var payload = {
"action": "query",
"format": "json",
"prop": "fileusage|globalusage|imageinfo",
"titles": titles.join( '|' ),
"formatversion": "2",
"fuprop": "title",
"fulimit": "500",
"guprop": "url|namespace",
"gulimit": "500"
};
if ( fucontinue !== '' ) {
payload[ 'fucontinue' ] = fucontinue;
}
if ( gucontinue !== '' ) {
payload[ 'gucontinue' ] = gucontinue;
}
this.api.post( payload ).then( function( data ) {
var isContinue = false;
if ( fucontinue !== '' || gucontinue !== '' ) {
isContinue = true;
}
catusage.analyseUsage( data.query.pages, isContinue );
if ( data.continue === undefined ) {
catusage.generateOutput();
catusage.usageRequest( catusage.files.splice( 0,50 ) );
}
else {
var next_fucontinue = "";
var next_gucontinue = "";
if ( data.continue.fucontinue ) {
next_fucontinue = data.continue.fucontinue;
}
if ( data.continue.gucontinue ) {
next_gucontinue = data.continue.gucontinue;
}
catusage.usageRequest( titles, next_fucontinue, next_gucontinue );
}
catusage.semaphor--;
catusage.nextStep();
} ).fail( function( data ) {
console.log( data );
catusage.semaphor--;
catusage.usageRequest( titles, fucontinue, gucontinue );
} );
};
this.analyseUsage = function( pages, isContinue ) {
$.each( pages, function( _, page ) {
var timestamp = page.imageinfo[0].timestamp.substring(0,7);
if ( catusage.fileUploaded[ timestamp ] === undefined ) {
catusage.fileUploaded[ timestamp ] = 0;
catusage.uniqFileUsage[ timestamp ] = 0;
catusage.fileUsage[ timestamp ] = 0;
catusage.fileUsageMainNamespace[ timestamp ] = 0;
catusage.globalUsage[ timestamp ] = 0;
catusage.globalUsageMainNamespace[ timestamp ] = 0;
}
if ( !isContinue ) {
catusage.countedFiles++;
catusage.fileUploaded[timestamp]++;
if ( page.globalusage.length > 0 ) {
catusage.uniqFileUsage[timestamp]++;
}
}
if ( page.fileusage !== undefined ) {
catusage.fileUsage[timestamp] += page.fileusage.length;
$.each( page.fileusage, function( _, localPage ) {
if ( localPage.ns === 0 ) {
catusage.fileUsageMainNamespace[timestamp]++;
}
} );
}
catusage.globalUsage[timestamp] += page.globalusage.length;
$.each( page.globalusage, function( _, globalPage ) {
if ( globalPage.ns === 0 ) {
catusage.globalUsageMainNamespace[timestamp]++;
}
} );
} );
};
this.generateOutput = function() {
var table = $( '<table>' ).addClass( 'wikitable' );
var header = $( '<tr>' );
header.append( $( '<th>' ).text( 'Date' ) );
header.append( $( '<th>' ).text( 'nb files uploaded' ) );
header.append( $( '<th>' ).text( 'nb files used' ) );
header.append( $( '<th>' ).text( 'nb pages using thoose files on Commons' ) );
header.append( $( '<th>' ).text( 'nb pages using thoose files on Commons in the main namespace' ) );
header.append( $( '<th>' ).text( 'nb pages using thoose files on an other wiki' ) );
//header.append( $( '<th>' ).text( 'globalUsageMainNamespace' ) );
table.append( $( '<thead>' ).append( header ) );
var body = $( '<tbody>' );
$.each( catusage.fileUploaded, function( date,_ ) {
var line = $( '<tr>' );
line.append( $( '<th>' ).text( date ) );
line.append( $( '<th>' ).text( ( catusage.fileUploaded[ date ] > 0 ? catusage.fileUploaded[ date ] : '' ) ) );
line.append( $( '<th>' ).text( ( catusage.uniqFileUsage[ date ] > 0 ? catusage.uniqFileUsage[ date ] : '' ) ) );
line.append( $( '<th>' ).text( ( catusage.fileUsage[ date ] > 0 ? catusage.fileUsage[ date ] : '' ) ) );
line.append( $( '<th>' ).text( ( catusage.fileUsageMainNamespace[ date ] > 0 ? catusage.fileUsageMainNamespace[ date ] : '' ) ) );
line.append( $( '<th>' ).text( ( catusage.globalUsage[ date ] > 0 ? catusage.globalUsage[ date ] : '' ) ) );
//line.append( $( '<th>' ).text( catusage.globalUsageMainNamespace[ date ] ) );
body.prepend( line );
} );
table.append( body );
this.resultPage.setContent( table );
};
return this.generateInterface();
};
var BasePageLayout = function( catusage, name, config ) {
var page = this;
BasePageLayout.super.call( this, name, config );
this.catusage = catusage;
this.depthInput = new OO.ui.NumberInputWidget( { min: 0, value: 0 } );
this.categoriesInput = new mw.widgets.CategoryMultiselectWidget( {
searchTypes: [
mw.widgets.CategoryMultiselectWidget.SearchType.OpenSearch,
mw.widgets.CategoryMultiselectWidget.SearchType.InternalSearch
]
} );
this.categoriesInput.addTag( mw.config.get( 'wgTitle' ) );
var saveButton = new OO.ui.ButtonWidget( {
label: 'Do it!',
icon: 'next',
iconTitle: 'Do it!',
flags: [ 'primary', 'progressive' ]
} );
saveButton.on( 'click', function() {
saveButton.setDisabled( true );
page.catusage.run( page.depthInput.getValue(), page.categoriesInput.getValue() );
} );
// Create a Fieldset layout.
var fieldset = new OO.ui.FieldsetLayout( {
label: 'Parameters',
} );
fieldset.addItems( [
new OO.ui.FieldLayout( this.depthInput, {
label: 'Depth:',
align: 'left',
} ),
new OO.ui.FieldLayout( this.categoriesInput, {
label: 'Categories:',
align: 'left',
} ),
new OO.ui.FieldLayout( saveButton, {
label: ' ',
align: 'left',
} ),
] );
this.$element.append( fieldset.$element );
};
OO.inheritClass( BasePageLayout, OO.ui.PageLayout );
BasePageLayout.prototype.setupOutlineItem = function () {
this.outlineItem.setLabel( 'Parameters' );
};
var ResultPageLayout = function( autotranslateHelper, name, config ) {
ResultPageLayout.super.call( this, name, config );
this.header = $( '<div>' );
this.content = $( '<div>' );
this.$element.append( this.header ).append( this.content );
};
OO.inheritClass( ResultPageLayout, OO.ui.PageLayout );
ResultPageLayout.prototype.setupOutlineItem = function () {
this.outlineItem.setLabel( 'Result' );
};
ResultPageLayout.prototype.setHeader = function( node ) {
this.header.empty().append( node );
};
ResultPageLayout.prototype.setContent = function( node ) {
this.content.empty().append( node );
};
if ( mw.config.get( 'wgNamespaceNumber' ) === 14 ) {
mw.loader.using( 'mediawiki.util', function() {
var node = mw.util.addPortletLink(
'p-cactions',
'#',
'Files usage'
);
$( node ).on( 'click', function ( e ) {
cu = new CatUsage();
window.catusage = cu;
e.preventDefault();
} );
} );
}
});