Created
December 18, 2014 23:17
-
-
Save jdlrobson/7af95ce2c09e49634c23 to your computer and use it in GitHub Desktop.
WikiDataApiTest
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
( function ( M, $ ) { | |
var api = M.require( 'api' ), | |
Api = api.Api, | |
WikiDataApi; | |
/** | |
* Gets claims and labels from the WikiData API | |
* @class WikiDataApi | |
* @extends Api | |
*/ | |
WikiDataApi = Api.extend( { | |
apiUrl: 'https://www.wikidata.org/w/api.php', | |
useJsonp: true, | |
language: mw.config.get( 'wgUserLanguage' ), | |
// Avoids loading token from cache. | |
getCentralAuthToken: function( type ) { | |
var data = { | |
action: 'tokens', | |
type: 'centralauth' | |
}; | |
return api.get( data ).then( function( resp ) { | |
return resp.tokens.centralauthtoken; | |
} ); | |
}, | |
getToken: function( type, centralAuthToken ) { | |
var data = { | |
action: 'tokens', | |
origin: this.getOrigin(), | |
centralauthtoken: centralAuthToken, | |
type: type | |
}; | |
return this.get( data ).then( function( resp ) { | |
return resp.tokens[type + 'token'].replace( '+\\', '' ); | |
} ); | |
}, | |
// FIXME: Remove this when dev finished. | |
ajax: function ( data, options ) { | |
var key, request, self = this; | |
options = options || {}; | |
if ( this.useJsonp ) { | |
options.url = this.apiUrl; | |
// new line | |
if ( data.action !== 'tokens' ) { | |
options.dataType = 'jsonp'; | |
} | |
} | |
if ( typeof data !== 'string' ) { | |
for ( key in data ) { | |
if ( data[key] === false ) { | |
delete data[key]; | |
} else if ( $.isArray( data[key] ) ) { | |
data[key] = data[key].join( '|' ); | |
} | |
} | |
} | |
// FIXME: move to mw.Api (although no EventEmitter in core)? | |
options.xhr = function () { | |
var xhr = $.ajaxSettings.xhr(); | |
if ( xhr.upload && ( mw.config.get( 'wgMFAjaxUploadProgressSupport' ) ) ) { | |
// need to bind this event before we open the connection (see note at | |
// https://developer.mozilla.org/en-US/docs/DOM/XMLHttpRequest/Using_XMLHttpRequest#Monitoring_progress) | |
xhr.upload.addEventListener( 'progress', function ( ev ) { | |
if ( ev.lengthComputable ) { | |
self.emit( 'progress', request, ev.loaded / ev.total ); | |
} | |
} ); | |
} | |
return xhr; | |
}; | |
request = mw.Api.prototype.ajax.call( this, data, options ); | |
this.requests.push( request ); | |
return request; | |
}, | |
post: function( data ) { | |
var self = this, | |
d = $.Deferred(); | |
// first let's sort out the token | |
self.getCentralAuthToken().done( function ( centralAuthTokenOne ) { | |
self.getToken( 'edit', centralAuthTokenOne ).done( function ( editToken ) { | |
self.getCentralAuthToken().done( function ( centralAuthTokenTwo ) { | |
data.format = 'json'; | |
data.centralauthtoken = centralAuthTokenTwo; | |
data.token = editToken; | |
data.origin = self.getOrigin(); | |
$.post( self.apiUrl, data ).done( function ( resp ) { | |
d.resolve( resp ); | |
} ); | |
} ); | |
} ) | |
} ); | |
return d; | |
}, | |
initialize: function ( options ) { | |
this.subjectId = options.itemId; | |
Api.prototype.initialize.apply( this, arguments ); | |
}, | |
getClaims: function () { | |
var self = this, | |
id = this.subjectId; | |
return this.ajax( { | |
action: 'wbgetentities', | |
ids: id, | |
languages: this.language, | |
props: [ 'descriptions', 'claims' ], | |
format: 'json' | |
} ).then( function ( data ) { | |
var description, instanceClaims, entityClaims, instanceOf, | |
claims = {}; | |
// See if the page has any 'instance of' claims. | |
if ( | |
data.entities !== undefined && | |
data.entities[id].claims !== undefined && | |
data.entities[id].claims.P31 !== undefined | |
) { | |
entityClaims = data.entities[id].claims; | |
instanceClaims = entityClaims.P31; | |
// Examine claims closely | |
$.each( instanceClaims, function ( i, claim ) { | |
instanceOf = claim.mainsnak.datavalue.value['numeric-id']; | |
if ( instanceOf === 5 ) { | |
claims.isHuman = true; | |
} else if ( instanceOf === 515 ) { | |
claims.isCity = true; | |
} else if ( instanceOf === 6256 ) { | |
claims.isCountry = true; | |
} else if ( instanceOf === 16521 ) { | |
claims.isTaxon = true; | |
} else if ( instanceOf === 11424 ) { | |
claims.isMovie = true; | |
} else if ( instanceOf === 5398426 ) { | |
claims.isTVSeries = true; | |
} | |
// Note: bands are subclassed as rock band, punk band etc.. not sure how we want | |
// to include them here. | |
} ); | |
// set some claims | |
claims.hasOccupation = entityClaims.P106 ? true : false; | |
claims.hasCountryOfCitizenship = entityClaims.P27 ? true : false; | |
claims.hasDateOfBirth = entityClaims.P569 ? true : false; | |
claims.hasDateOfDeath = entityClaims.P570 ? true : false; | |
claims.entities = entityClaims; | |
description = data.entities[ id ]; | |
if ( description && description.descriptions !== undefined ) { | |
if ( description.descriptions[ self.language ] ) { | |
claims.description = description.descriptions[ self.language ].value; | |
} | |
} | |
return claims; | |
} else { | |
// FIXME: logError does not exist | |
// self.logError( 'no-impression-cannot-fetch-claims' ); | |
return false; | |
} | |
} ).fail( function () { | |
// FIXME: logError does not exist | |
// self.logError( 'no-impression-cannot-fetch-claims' ); | |
} ); | |
}, | |
/** | |
* Get labels for an item from Wikidata | |
* See: https://www.wikidata.org/wiki/Help:Label | |
* | |
* @param {Array} itemIds for items in Wikidata | |
* @return {jQuery.Deferred} Object returned by ajax call | |
*/ | |
getLabels: function ( itemIds ) { | |
var lang = this.language; | |
return this.ajax( { | |
action: 'wbgetentities', | |
props: 'labels', | |
languages: lang, | |
ids: itemIds | |
} ).then( function ( data ) { | |
var map = {}; | |
$.each( itemIds, function ( i, itemId ) { | |
if ( data.entities[ itemId ].labels && | |
data.entities[ itemId ].labels[ lang ] !== undefined | |
) { | |
map[ itemId ] = data.entities[ itemId ].labels[ lang ].value; | |
} else { | |
map[ itemId ] = null; | |
} | |
} ); | |
return map; | |
} ); | |
}, | |
/** | |
* Store description. | |
* | |
* @param {string} value of new description | |
* @return {jQuery.Deferred} Object returned by ajax call | |
*/ | |
saveDescription: function ( value ) { | |
var self = this, | |
d = $.Deferred(); | |
this.getInfo().done( function ( info ) { | |
self.post( { | |
action: 'wbsetdescription', | |
id: this.subjectId, | |
value: value, | |
language: self.language, | |
baserevid: info.lastrevid, | |
bot: 1 | |
} ).done( function ( resp ) { | |
d.resolve( resp ); | |
} ); | |
} ); | |
return d; | |
}, | |
/** | |
* Get information about current wikidata entity | |
* | |
* FIXME: add error handling. | |
* @inheritdoc | |
*/ | |
getInfo: function () { | |
var id = this.subjectId; | |
return this.get( { | |
action: 'wbgetentities', | |
ids: id, | |
props: 'info' | |
} ).then( function ( resp ) { | |
return resp.entities[id]; | |
} ); | |
}, | |
/** | |
* Expand item ids to find associated data such as labels and urls | |
* for the wikidata entities for the current sitename. | |
* | |
* @param {Array} itemIds for items in Wikidata | |
* @return {jQuery.Deferred} Object returned by ajax call | |
*/ | |
getExpandedItemsData: function ( itemIds ) { | |
var lang = this.language, | |
wiki = mw.config.get( 'wgDBname' ) || 'enwiki'; | |
return this.ajax( { | |
action: 'wbgetentities', | |
sites: wiki, | |
props: [ 'labels', 'sitelinks/urls' ], | |
languages: lang, | |
ids: itemIds | |
} ).then( function ( data ) { | |
var map = {}; | |
$.each( itemIds, function ( i, itemId ) { | |
var item, sitelink; | |
if ( data.entities[ itemId ].labels && | |
data.entities[ itemId ].labels[ lang ] !== undefined | |
) { | |
item = data.entities[ itemId ]; | |
if ( item.sitelinks && item.sitelinks[wiki] ) { | |
sitelink = item.sitelinks[wiki]; | |
} | |
map[ itemId ] = { | |
label: sitelink ? sitelink.title : item.labels[ lang ].value | |
}; | |
if ( sitelink && sitelink.url ) { | |
map[ itemId ].url = sitelink.url; | |
} | |
} else { | |
map[ itemId ] = null; | |
} | |
} ); | |
return map; | |
} ); | |
} | |
} ); | |
M.define( 'modules/wikigrok/WikiDataApi', WikiDataApi ); | |
var w = new WikiDataApi( { itemId: 'Q2323140' } ); | |
w.saveDescription( 'test' ); | |
}( mw.mobileFrontend, jQuery ) ); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment