User

Difference between revisions of "Nicolas NALLET/bluell.js"

< User:Nicolas NALLET

(vrsion de Seb35)
(nouvelle version avec restriction des sélecteurs)
Line 10: Line 10:
 
mw.loader.using( ['oojs', 'oojs-ui'], function () {
 
mw.loader.using( ['oojs', 'oojs-ui'], function () {
  
var oouiSpeaker, oouiGender, oouiLanguage, oouiProficiency;
+
var oouiSelectors = {
 +
'speaker': null,
 +
'gender': null,
 +
'language': null,
 +
'proficiency': null,
 +
};
 +
var sparqlGlobal = {
 +
'speaker': 'SELECT DISTINCT ?speaker ?speakerLabel WHERE { ?speaker prop:P2 entity:Q3 . ?speaker rdfs:label ?speakerLabel . FILTER( LANG(?speakerLabel) = "en" ) } ORDER BY ?speakerLabel',
 +
'gender': 'SELECT DISTINCT ?gender ?genderLabel WHERE { ?gender prop:P2 entity:Q7 . SERVICE wikibase:label { bd:serviceParam wikibase:language "' + userLanguage + ',fr,en" } } ORDER BY ?gender',
 +
'language': 'SELECT DISTINCT ?language ?languageLabel WHERE { ?language prop:P2 entity:Q4 . SERVICE wikibase:label { bd:serviceParam wikibase:language "' + userLanguage + ',fr,en" } } ORDER BY ?languageLabel',
 +
'proficiency': 'SELECT DISTINCT ?proficiency ?proficiencyLabel WHERE { ?proficiency prop:P2 entity:Q5 . SERVICE wikibase:label { bd:serviceParam wikibase:language "' + userLanguage + ',fr,en" } } ORDER BY ?proficiency',
 +
};
 +
var placeholders = {
 +
'speaker': '👤 Speaker',
 +
'gender': '♀️ ♂️ Speaker\'s gender',
 +
'language': '🏳️ Language',
 +
'proficiency': '🥇 Level of proficiency',
 +
};
 +
var htmlElements = {
 +
'speaker': '#filteruser',
 +
'gender': '#filtergender',
 +
'language': '#filterlanguage',
 +
'proficiency': '#filterlevelofproficiency',
 +
};
 +
var lastRequest = {
 +
'speaker': '',
 +
'gender': '',
 +
'language': '',
 +
'proficiency': '',
 +
};
  
$.getJSON(
+
function updateSelector( type ) {
'https://lingualibre.org/bigdata/namespace/wdq/sparql',
+
return function( values ) {
{
+
console.log( lastRequest );
query: 'SELECT DISTINCT ?speaker ?speakerLabel WHERE { ?speaker prop:P2 entity:Q3 . ?speaker rdfs:label ?speakerLabel . FILTER( LANG(?speakerLabel) = "en" ) } ORDER BY ?speakerLabel'
+
console.log( oouiSelectors['speaker'] ? oouiSelectors['speaker'].getValue() : '' );
}
+
console.log( oouiSelectors['gender'] ? oouiSelectors['gender'].getValue() : '' );
).done( function( speakers ) {
+
console.log( oouiSelectors['language'] ? oouiSelectors['language'].getValue() : '' );
oouiSpeaker = new OO.ui.ComboBoxInputWidget( {
+
console.log( oouiSelectors['proficiency'] ? oouiSelectors['proficiency'].getValue() : '' );
placeholder: '👤 Speaker',
+
if( ( oouiSelectors['speaker'] && oouiSelectors['speaker'].getValue() != lastRequest['speaker'] ) ||
menu: {
+
    ( oouiSelectors['gender'] && oouiSelectors['gender'].getValue() != lastRequest['gender'] ) ||
filterFromInput: true,
+
    ( oouiSelectors['language'] && oouiSelectors['language'].getValue() != lastRequest['language'] ) ||
items: speakers.results.bindings.map( function( x ) {
+
    ( oouiSelectors['proficiency'] && oouiSelectors['proficiency'].getValue() != lastRequest['proficiency'] ) ) {
return new OO.ui.MenuOptionWidget( {
+
return;
data: x.speakerLabel.value + " (" + x.speaker.value.substr( 31 ) + ")",
 
label: x.speakerLabel.value
 
} );
 
} )
 
 
}
 
}
} );
 
  
$( '#filteruser' ).append(
+
oouiSelectors[type] = new OO.ui.ComboBoxInputWidget( {
oouiSpeaker.$element
+
placeholder: placeholders[type],
);
+
menu: {
 +
filterFromInput: true,
 +
items: values.results.bindings.map( function( x ) {
 +
return new OO.ui.MenuOptionWidget( {
 +
data: x[ type + 'Label' ].value + " (" + x[type].value.substr( 31 ) + ")",
 +
label: x[ type + 'Label' ].value
 +
} );
 +
} )
 +
}
 +
} );
 +
 
 +
$( htmlElements[type] ).html('').append(
 +
oouiSelectors[type].$element
 +
);
  
oouiSpeaker.on( 'change', doQuery );
+
oouiSelectors[type].on( 'change', function() { doQuery(); doQuery( 'speaker' ); doQuery( 'gender' ); doQuery( 'language' ); doQuery( 'proficiency' ); } );
  
} );
+
};
 +
}
  
 
$.getJSON(
 
$.getJSON(
 
'https://lingualibre.org/bigdata/namespace/wdq/sparql',
 
'https://lingualibre.org/bigdata/namespace/wdq/sparql',
 
{
 
{
query: 'SELECT DISTINCT ?gender ?genderLabel WHERE { ?gender prop:P2 entity:Q7 . SERVICE wikibase:label { bd:serviceParam wikibase:language "' + userLanguage + ',fr,en" } } ORDER BY ?gender'
+
query: sparqlGlobal['speaker']
 
}
 
}
).done( function( genders ) {
+
).done( updateSelector( 'speaker' ) );
oouiGender = new OO.ui.ComboBoxInputWidget( {
 
placeholder: '♀️ ♂️ Speaker\'s gender',
 
menu: {
 
filterFromInput: true,
 
items: genders.results.bindings.map( function( x ) {
 
return new OO.ui.MenuOptionWidget( {
 
data: x.genderLabel.value + " (" + x.gender.value.substr( 31 ) + ")",
 
label: x.genderLabel.value
 
} );
 
} )
 
}
 
} );
 
  
$( '#filtergender' ).append(
+
$.getJSON(
oouiGender.$element
+
'https://lingualibre.org/bigdata/namespace/wdq/sparql',
);
+
{
 
+
query: sparqlGlobal['gender']
oouiGender.on( 'change', doQuery );
+
}
 
+
).done( updateSelector( 'gender' ) );
} );
 
  
 
$.getJSON(
 
$.getJSON(
 
'https://lingualibre.org/bigdata/namespace/wdq/sparql',
 
'https://lingualibre.org/bigdata/namespace/wdq/sparql',
 
{
 
{
query: 'SELECT DISTINCT ?language ?languageLabel WHERE { ?language prop:P2 entity:Q4 . SERVICE wikibase:label { bd:serviceParam wikibase:language "' + userLanguage + ',fr,en" } } ORDER BY ?languageLabel'
+
query: sparqlGlobal['language']
 
}
 
}
).done( function( languages ) {
+
).done( updateSelector( 'language' ) );
oouiLanguage = new OO.ui.ComboBoxInputWidget( {
 
placeholder: '🏳️ Language',
 
menu: {
 
filterFromInput: true,
 
items: languages.results.bindings.map( function( x ) {
 
return new OO.ui.MenuOptionWidget( {
 
data: x.languageLabel.value + " (" + x.language.value.substr( 31 ) + ")",
 
label: x.languageLabel.value
 
} );
 
} )
 
}
 
} );
 
 
 
$( '#filterlanguage' ).append(
 
oouiLanguage.$element
 
);
 
 
 
oouiLanguage.on( 'change', doQuery );
 
 
 
} );
 
  
 
$.getJSON(
 
$.getJSON(
 
'https://lingualibre.org/bigdata/namespace/wdq/sparql',
 
'https://lingualibre.org/bigdata/namespace/wdq/sparql',
 
{
 
{
query: 'SELECT DISTINCT ?proficiency ?proficiencyLabel WHERE { ?proficiency prop:P2 entity:Q5 . SERVICE wikibase:label { bd:serviceParam wikibase:language "' + userLanguage + ',fr,en" } } ORDER BY ?proficiency'
+
query: sparqlGlobal['proficiency']
 
}
 
}
).done( function( proficiencies ) {
+
).done( updateSelector( 'proficiency' ) );
oouiProficiency = new OO.ui.ComboBoxInputWidget( {
 
placeholder: '🥇 Level of proficiency',
 
menu: {
 
filterFromInput: true,
 
items: proficiencies.results.bindings.map( function( x ) {
 
return new OO.ui.MenuOptionWidget( {
 
data: x.proficiencyLabel.value + " (" + x.proficiency.value.substr( 31 ) + ")",
 
label: x.proficiencyLabel.value
 
} );
 
} )
 
}
 
} );
 
 
 
$( '#filterlevelofproficiency' ).append(
 
oouiProficiency.$element
 
);
 
 
 
oouiProficiency.on( 'change', doQuery );
 
 
 
} );
 
  
 
// Display results
 
// Display results
Line 130: Line 115:
 
return;
 
return;
 
}
 
}
for (var i = 0; i < 100; i++) {
+
var length = data.results.bindings.length < 100 ? data.results.bindings.length : 100;
 +
$( '#audioresults' ).html( '' );
 +
for (var i = 0; i < length; i++) {
 
var box = $( '<div class="audiobox"> <div class="ab-playbutton"><i></i></div> <div> <div class="ab-title">...</div> <div class="ab-metadata">...</div> </div> </div>' );
 
var box = $( '<div class="audiobox"> <div class="ab-playbutton"><i></i></div> <div> <div class="ab-title">...</div> <div class="ab-metadata">...</div> </div> </div>' );
 
var audiobox = new AudioBox( data.results.bindings[ i ].record.value.substr( 31 ), box );
 
var audiobox = new AudioBox( data.results.bindings[ i ].record.value.substr( 31 ), box );
Line 137: Line 124:
 
//$("body").append('<div class="audiobox"> <div class="ab-playbutton"><i></i></div> <div> <div class="ab-title">...</div> <div class="ab-metadata">...</div> </div> </div>');
 
//$("body").append('<div class="audiobox"> <div class="ab-playbutton"><i></i></div> <div> <div class="ab-title">...</div> <div class="ab-metadata">...</div> </div> </div>');
 
}
 
}
//ab1 = new AudioBox( data.query.rwrecords[ 0 ], $( '.audiobox' ).eq( 0 ) );
 
//ab2 = new AudioBox( data.query.rwrecords[ 1 ], $( '.audiobox' ).eq( 1 ) );
 
 
}
 
}
  
 
// Do SPARQL request from filters
 
// Do SPARQL request from filters
function doQuery(){
+
function doQuery( variable ){
+
 
function getQ( text ) {
+
// Do not modify a selector where there is a value
 +
if( variable && oouiSelectors[variable] && oouiSelectors[variable].getValue() ) {
 +
return;
 +
}
 +
 
 +
function getQ( type ) {
 +
if( variable === type ) {
 +
return '?' + type;
 +
}
 +
var text = oouiSelectors[type] ? oouiSelectors[type].getValue() : '';
 
if( !text ) {
 
if( !text ) {
 
return '';
 
return '';
Line 150: Line 144:
 
text = text.trim();
 
text = text.trim();
 
if( /^Q[0-9]+$/.test( text ) ) {
 
if( /^Q[0-9]+$/.test( text ) ) {
return text;
+
return 'entity:' + text;
 
} else if( /\((Q[0-9]+)\)$/.test( text ) ) {
 
} else if( /\((Q[0-9]+)\)$/.test( text ) ) {
return text.replace( /.*\((Q[0-9]+)\)$/, '$1' );
+
return 'entity:' + text.replace( /.*\((Q[0-9]+)\)$/, '$1' );
 
} else {
 
} else {
 
console.warn( 'Bad input “' + text + '”' );
 
console.warn( 'Bad input “' + text + '”' );
Line 159: Line 153:
 
}
 
}
  
var speaker = getQ( oouiSpeaker.getValue() ),
+
var speaker = getQ( 'speaker' ),
    gender = getQ( oouiGender.getValue() ),
+
    gender = getQ( 'gender' ),
    language = getQ( oouiLanguage.getValue() ),
+
    language = getQ( 'language' ),
    proficiency = getQ( oouiProficiency.getValue() ),
+
    proficiency = getQ( 'proficiency' ),
 
    somevalue = false;
 
    somevalue = false;
 +
if( ! variable ) {
 +
lastRequest = {
 +
'speaker': oouiSelectors['speaker'] ? oouiSelectors['speaker'].getValue() : '',
 +
'gender': oouiSelectors['gender'] ? oouiSelectors['gender'].getValue() : '',
 +
'language': oouiSelectors['language'] ? oouiSelectors['language'].getValue() : '',
 +
'proficiency': oouiSelectors['proficiency'] ? oouiSelectors['proficiency'].getValue() : '',
 +
};
 +
}
  
var query = "SELECT ?record WHERE { ?record prop:P2 entity:Q2 ; prop:P4 ?language ; prop:P5 ?speaker . ";
+
var query = "SELECT " + ( variable ? 'DISTINCT ?' + variable + ' ?' + variable + 'Label' : "?record" ) + " WHERE { ?record prop:P2 entity:Q2 ; prop:P4 ?language ; prop:P5 ?speaker . ";
 
if( speaker ) {
 
if( speaker ) {
query += "?record prop:P5 entity:" + speaker + " .";
+
query += "?record prop:P5 " + speaker + " . ";
 
somevalue = true;
 
somevalue = true;
 
}
 
}
 
if( gender ) {
 
if( gender ) {
query += "?record prop:P5 [ prop:P8 entity:" + gender + " ] .";
+
query += "?record prop:P5 [ prop:P8 " + gender + " ] . ";
 
somevalue = true;
 
somevalue = true;
 
}
 
}
 
if( language ) {
 
if( language ) {
query += "?record prop:P4 entity:" + language + " .";
+
query += "?record prop:P4 " + language + " . ";
 
somevalue = true;
 
somevalue = true;
 
}
 
}
 
if( proficiency ) {
 
if( proficiency ) {
query += "?speaker llp:P4 [ llv:P4 ?language ; llq:16 entity:" + proficiency + " ] .";
+
query += "?speaker llp:P4 [ llv:P4 ?language ; llq:P16 " + proficiency + " ] . ";
 
somevalue = true;
 
somevalue = true;
 
}
 
}
query += "SERVICE wikibase:label { bd:serviceParam wikibase:language '[AUTO_LANGUAGE],en,fr' } } LIMIT 100";
+
query += "SERVICE wikibase:label { bd:serviceParam wikibase:language '" + userLanguage + ",en,fr' } } LIMIT 100";
  
$( '#audioresults' ).html( '' );
+
if( variable ) {
 
+
if( !somevalue ) {
if( !somevalue ) {
+
query = sparqlGlobal[variable];
return;
+
}
 +
} else {
 +
if( !variable && !somevalue ) {
 +
return;
 +
}
 +
$( '#audioresults' ).html( '' ); // TODO replace by a spinner
 
}
 
}
  
$.getJSON(
+
// Execute the request
 +
var result = $.getJSON(
 
'https://lingualibre.org/bigdata/namespace/wdq/sparql',
 
'https://lingualibre.org/bigdata/namespace/wdq/sparql',
 
{
 
{
Line 196: Line 204:
 
//Accept: 'application/sparql-results+json'
 
//Accept: 'application/sparql-results+json'
 
}
 
}
).then( createAudioBoxesForSearch, displayError );
+
);
 +
 
 +
// Depending if we want the whole results or update on selector
 +
if( variable ) {
 +
result.then( updateSelector( variable ), displayError );
 +
} else {
 +
result.then( createAudioBoxesForSearch, displayError );
 +
}
 
}
 
}
  

Revision as of 19:34, 6 August 2021

$( function (){
	var userLanguage = mw.config.get( 'wgUserLanguage' );
	var messages = {
		'no-results': {
			en: 'No results.',
			de: 'Keine Ergebnisse.',
			fr: 'Pas de résultat.',
		}
	};
	mw.loader.using( ['oojs', 'oojs-ui'], function () {

		var oouiSelectors = {
			'speaker': null,
			'gender': null,
			'language': null,
			'proficiency': null,
		};
		var sparqlGlobal = {
			'speaker': 'SELECT DISTINCT ?speaker ?speakerLabel WHERE { ?speaker prop:P2 entity:Q3 . ?speaker rdfs:label ?speakerLabel . FILTER( LANG(?speakerLabel) = "en" ) } ORDER BY ?speakerLabel',
			'gender': 'SELECT DISTINCT ?gender ?genderLabel WHERE { ?gender prop:P2 entity:Q7 . SERVICE wikibase:label { bd:serviceParam wikibase:language "' + userLanguage + ',fr,en" } } ORDER BY ?gender',
			'language': 'SELECT DISTINCT ?language ?languageLabel WHERE { ?language prop:P2 entity:Q4 . SERVICE wikibase:label { bd:serviceParam wikibase:language "' + userLanguage + ',fr,en" } } ORDER BY ?languageLabel',
			'proficiency': 'SELECT DISTINCT ?proficiency ?proficiencyLabel WHERE { ?proficiency prop:P2 entity:Q5 . SERVICE wikibase:label { bd:serviceParam wikibase:language "' + userLanguage + ',fr,en" } } ORDER BY ?proficiency',
		};
		var placeholders = {
			'speaker': '👤 Speaker',
			'gender': '♀️ ♂️ Speaker\'s gender',
			'language': '🏳️ Language',
			'proficiency': '🥇 Level of proficiency',
		};
		var htmlElements = {
			'speaker': '#filteruser',
			'gender': '#filtergender',
			'language': '#filterlanguage',
			'proficiency': '#filterlevelofproficiency',
		};
		var lastRequest = {
			'speaker': '',
			'gender': '',
			'language': '',
			'proficiency': '',
		};

		function updateSelector( type ) {
			return function( values ) {
				console.log( lastRequest );
				console.log( oouiSelectors['speaker'] ? oouiSelectors['speaker'].getValue() : '' );
				console.log( oouiSelectors['gender'] ? oouiSelectors['gender'].getValue() : '' );
				console.log( oouiSelectors['language'] ? oouiSelectors['language'].getValue() : '' );
				console.log( oouiSelectors['proficiency'] ? oouiSelectors['proficiency'].getValue() : '' );
				if( ( oouiSelectors['speaker'] && oouiSelectors['speaker'].getValue() != lastRequest['speaker'] ) ||
				    ( oouiSelectors['gender'] && oouiSelectors['gender'].getValue() != lastRequest['gender'] ) ||
				    ( oouiSelectors['language'] && oouiSelectors['language'].getValue() != lastRequest['language'] ) ||
				    ( oouiSelectors['proficiency'] && oouiSelectors['proficiency'].getValue() != lastRequest['proficiency'] ) ) {
					return;
				}

				oouiSelectors[type] = new OO.ui.ComboBoxInputWidget( {
					placeholder: placeholders[type],
					menu: {
						filterFromInput: true,				
						items: values.results.bindings.map( function( x ) {
							return new OO.ui.MenuOptionWidget( {
								data: x[ type + 'Label' ].value + " (" + x[type].value.substr( 31 ) + ")",
								label: x[ type + 'Label' ].value
							} );
						} )
					}
				} );

				$( htmlElements[type] ).html('').append(
					oouiSelectors[type].$element
				);

				oouiSelectors[type].on( 'change', function() { doQuery(); doQuery( 'speaker' ); doQuery( 'gender' ); doQuery( 'language' ); doQuery( 'proficiency' ); } );

			};
		}

		$.getJSON(
			'https://lingualibre.org/bigdata/namespace/wdq/sparql',
			{
				query: sparqlGlobal['speaker']
			}
		).done( updateSelector( 'speaker' ) );

		$.getJSON(
			'https://lingualibre.org/bigdata/namespace/wdq/sparql',
			{
				query: sparqlGlobal['gender']
			}
		).done( updateSelector( 'gender' ) );

		$.getJSON(
			'https://lingualibre.org/bigdata/namespace/wdq/sparql',
			{
				query: sparqlGlobal['language']
			}
		).done( updateSelector( 'language' ) );

		$.getJSON(
			'https://lingualibre.org/bigdata/namespace/wdq/sparql',
			{
				query: sparqlGlobal['proficiency']
			}
		).done( updateSelector( 'proficiency' ) );

		// Display results
		function createAudioBoxesForSearch( data ) {
			if ( data.results === undefined || data.results.bindings === undefined ) {
				displayError( 'error: no result from SPARQL' );
				return;
			}
			if ( data.results.bindings.length < 1 ) {
				$( '#audioresults' ).html( messages['no-results'][userLanguage] ? messages['no-results'][userLanguage] : messages['no-results']['en'] );
				return;
			}
			var length = data.results.bindings.length < 100 ? data.results.bindings.length : 100;
			$( '#audioresults' ).html( '' );
			for (var i = 0; i < length; i++) {
				var box = $( '<div class="audiobox"> <div class="ab-playbutton"><i></i></div> <div> <div class="ab-title">...</div> <div class="ab-metadata">...</div> </div> </div>' );
				var audiobox = new AudioBox( data.results.bindings[ i ].record.value.substr( 31 ), box );
				$( '#audioresults' ).append( box );
				//ab1 = new AudioBox( data.query.rwrecords[ i ], $( '.audiobox' ).eq( i ) );
				//$("body").append('<div class="audiobox"> <div class="ab-playbutton"><i></i></div> <div> <div class="ab-title">...</div> <div class="ab-metadata">...</div> </div> </div>');	
			}
		}

		// Do SPARQL request from filters
		function doQuery( variable ){

			// Do not modify a selector where there is a value
			if( variable && oouiSelectors[variable] && oouiSelectors[variable].getValue() ) {
				return;
			}

			function getQ( type ) {
				if( variable === type ) {
					return '?' + type;
				}
				var text = oouiSelectors[type] ? oouiSelectors[type].getValue() : '';
				if( !text ) {
					return '';
				}
				text = text.trim();
				if( /^Q[0-9]+$/.test( text ) ) {
					return 'entity:' + text;
				} else if( /\((Q[0-9]+)\)$/.test( text ) ) {
					return 'entity:' + text.replace( /.*\((Q[0-9]+)\)$/, '$1' );
				} else {
					console.warn( 'Bad input “' + text + '”' );
					return '';
				}
			}

			var speaker = getQ( 'speaker' ),
			    gender = getQ( 'gender' ),
			    language = getQ( 'language' ),
			    proficiency = getQ( 'proficiency' ),
			    somevalue = false;
			if( ! variable ) {
				lastRequest = {
					'speaker': oouiSelectors['speaker'] ? oouiSelectors['speaker'].getValue() : '',
					'gender': oouiSelectors['gender'] ? oouiSelectors['gender'].getValue() : '',
					'language': oouiSelectors['language'] ? oouiSelectors['language'].getValue() : '',
					'proficiency': oouiSelectors['proficiency'] ? oouiSelectors['proficiency'].getValue() : '',
				};
			}

			var query = "SELECT " + ( variable ? 'DISTINCT ?' + variable + ' ?' + variable + 'Label' : "?record" ) + " WHERE { ?record prop:P2 entity:Q2 ; prop:P4 ?language ; prop:P5 ?speaker . ";
			if( speaker ) {
				query += "?record prop:P5 " + speaker + " . ";
				somevalue = true;
			}
			if( gender ) {
				query += "?record prop:P5 [ prop:P8 " + gender + " ] . ";
				somevalue = true;
			}
			if( language ) {
				query += "?record prop:P4 " + language + " . ";
				somevalue = true;
			}
			if( proficiency ) {
				query += "?speaker llp:P4 [ llv:P4 ?language ; llq:P16 " + proficiency + " ] . ";
				somevalue = true;
			}
			query += "SERVICE wikibase:label { bd:serviceParam wikibase:language '" + userLanguage + ",en,fr' } } LIMIT 100";

			if( variable ) {
				if( !somevalue ) {
					query = sparqlGlobal[variable];
				}
			} else {
				if( !variable && !somevalue ) {
					return;
				}
				$( '#audioresults' ).html( '' ); // TODO replace by a spinner
			}

			// Execute the request
			var result = $.getJSON(
				'https://lingualibre.org/bigdata/namespace/wdq/sparql',
				{
					query: query,
					//Accept: 'application/sparql-results+json'
				}
			);

			// Depending if we want the whole results or update on selector
			if( variable ) {
				result.then( updateSelector( variable ), displayError );
			} else {
				result.then( createAudioBoxesForSearch, displayError );
			}
		}

	} );

} );