MediaWiki
Gadget-Normalizer.js
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 / Edge: 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.
const sparqlEndpoint = 'https://lingualibre.fr/bigdata/namespace/wdq/sparql';
const allSpeakersQuery = 'SELECT DISTINCT ?qid ?name ?gender ?linkedUser WHERE { ?qid prop:P2 entity:Q3. ?qid rdfs:label ?name. FILTER(LANG(?name) = "en"). ?qid prop:P11 ?linkedUser. ?qid prop:P8 ?genderId. BIND( IF( isBLANK(?genderId), \'\', ?genderId ) as ?gender ). }';
const allowedLicenses = [ 'cc-by-sa-4.0', 'cc-by-sa-3.0', 'cc-by-4.0', 'cc-by-3.0', 'cc-zero' ];
rw = mw.recordWizard;
/**
* MRecord
*/
var MRecord = function( qid ) {
console.log( 'aaa' );
rw.Record.call( this, '' );
this.qid = qid;
console.log( 'bbb' );
this.wbItem = new rw.wikibase.Item( this.qid );
}
OO.inheritClass( MRecord, rw.Record );
MRecord.prototype.setData = function( filename, transcription, qualifier, langQid, speakerQid, date ) {
var word = transcription;
if ( qualifier !== null ) {
word += ' (' + qualifier + ')';
}
this.filename = filename;
this.fileextension = filename.split( '.' ).pop();
this.word = word;
this.transcription = transcription;
this.qualifier = qualifier;
this.langQid = langQid;
this.speakerQid = speakerQid;
this.date = date;
return true;
}
MRecord.prototype.fetchData = async function( api ) {
var filename, langQid, speakerQid, date, transcription, qualifierStatements, qualifier;
await this.wbItem.getFromApi( api );
filename = this.wbItem.getStatements( rw.config.properties.audioRecord )[ 0 ].getValue();
langQid = this.wbItem.getStatements( rw.config.properties.spokenLanguages )[ 0 ].getValue();
speakerQid = this.wbItem.getStatements( rw.config.properties.locutor )[ 0 ].getValue();
date = new Date( this.wbItem.getStatements( rw.config.properties.date )[ 0 ].getValue().time.slice( 1 ) );
transcription = this.wbItem.getStatements( rw.config.properties.transcription )[ 0 ].getValue();
qualifierStatements = this.wbItem.getStatements( rw.config.properties.qualifier );
if ( qualifierStatements !== null ) {
qualifier = qualifierStatements[ 0 ].getValue();
} else {
qualifier = null;
}
this.setData( filename, transcription, qualifier, langQid, speakerQid, date );
};
MRecord.prototype.updateLocalItem = async function( api ) {
// Update local item
this.fillWbItem();
return await this.wbItem.createOrUpdate( api, true ).then(
function() { return true },
function() { return false }
);
};
/**
* LLNormalizer
*/
var LLNormalizer = function () {
this.api = new mw.Api();
this.commonsApi = new mw.ForeignApi( 'https://commons.wikimedia.org/w/api.php', {
anonymous: true,
parameters: { origin: '*' },
ajax: { timeout: 10000 }
} );
};
LLNormalizer.prototype.getAllSpeakers = async function() {
var speaker, qid,
response = await $.post( sparqlEndpoint, { format: 'json', query: allSpeakersQuery } );
this.speakers = {};
for ( i = 0; i < response.results.bindings.length; i++ ) {
speaker = response.results.bindings[ i ];
qid = speaker.qid.value.split( '/' ).pop();
this.speakers[ qid ] = {
qid: qid,
name: speaker.name.value,
gender: speaker.gender.value.split( '/' ).pop(),
linkedUser: speaker.linkedUser.value,
};
}
};
LLNormalizer.prototype.process = async function( qids, updateLocalItem, updateDescriptionOnCommons, renameOnCommons ) {
var i, record;
if ( !Array.isArray( qids ) ) {
qids = [ qids ];
}
for ( i in qids ) {
record = new MRecord( qids[ i ] );
await record.fetchData( this.api );
// Set global variable to the apropriate value
rw.metadatas.language = record.langQid;
rw.metadatas.locutor = this.speakers[ record.speakerQid ];
mw.config.set( 'wgUserName', this.speakers[ record.speakerQid ].linkedUser );
// Get the license from the description on Commons
// If the file description doesn't contain the Lingua Libre template,
// the returned value will be false, blocking any changes on this file
if ( updateDescriptionOnCommons || renameOnCommons ) {
rw.metadatas.license = await this.getLicense( record );
}
if ( updateLocalItem ) {
await record.updateLocalItem( this.api );
}
if ( updateDescriptionOnCommons && rw.metadatas.license !== false ) {
await this.updateDescriptionOnCommons( record );
}
if ( renameOnCommons && rw.metadatas.license !== false ) {
await this.renameOnCommons( record );
}
}
};
LLNormalizer.prototype.getLicense = async function( record ) {
var i, wikitext,
license = false,
response = await this.commonsApi.get( {
"action": "query",
"format": "json",
"prop": "revisions",
"titles": "File:" + record.filename,
"formatversion": "2",
"rvprop": "content",
"rvslots": "main"
} );
wikitext = response.query.pages[ 0 ].revisions[ 0 ].slots.main.content;
if ( wikitext.indexOf( '{{Lingua Libre record' ) === -1 ) {
return false;
}
for ( i in allowedLicenses ) {
if ( wikitext.indexOf( '{{' + allowedLicenses[ i ] ) !== -1 ) {
license = allowedLicenses[ i ];
break;
}
}
return license;
};
LLNormalizer.prototype.updateDescriptionOnCommons = async function( record ) {
var newWikitext = record.getText();
return await this.api.postWithToken( 'csrf', {
action: 'post-to-commons',
request: JSON.stringify( {
"action": "edit",
"format": "json",
"title": 'File:' + record.filename,
"text": newWikitext,
"formatversion": "2"
} )
} );
};
LLNormalizer.prototype.renameOnCommons = async function( record ) {
console.log( record.filename )
console.log( record.getFilename() )
if ( record.filename === record.getFilename() ) {
return false;
}
return await this.api.postWithToken( 'csrf', {
action: 'post-to-commons',
request: JSON.stringify( {
"action": "move",
"format": "json",
"from": 'File:' + record.filename,
"to": 'File:' + record.getFilename(),
"reason": "normalize",
"movetalk": 1,
"ignorewarnings": 1
} )
} );
};
/*
normalizer = new LLNormalizer();
await normalizer.getAllSpeakers();
await normalizer.process( [ 'Q651', 'Q652', 'Q653' ], true, true, true );
*/