User:Tpt/ws2wd.js
< User:Tpt
Note: After publishing, 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)
- Edge: Hold Ctrl while clicking Refresh, or press Ctrl-F5.
mw.loader.using(['mediawiki.widgets', 'mediawiki.util', 'mediawiki.api', 'oojs-ui-core' ], function () {
$(function () {
var wdApi = new mw.Api();
function executeEntityQuery(sparqlWhere) {
var sparql = 'SELECT ?entity ?entityLabel WHERE {' + sparqlWhere + ' SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],en". } }';
return $.ajax({
url: 'https://query.wikidata.org/sparql',
data: {
query: sparql,
format: 'json'
},
dataType: 'json'
}).then(function (result) {
return result.results.bindings.map(function (binding) {
return $('<a>').attr('href', binding.entity.value).text(binding.entityLabel.value);
});
}, function (jqXHR, textStatus) {
OO.ui.alert('Convertion to SPARQL query failed: ' + JSON.stringify(textStatus));
});
}
function itemClaim(propertyId, itemId) {
return {
mainsnak: {
snaktype: 'value',
property: propertyId,
datavalue: {
value: {
id: itemId
},
type: 'wikibase-entityid'
},
datatype: 'wikibase-item'
},
type: 'statement',
rank: 'normal'
};
}
function extractNewClaims(claims) {
return claims.map(function (claim) {
return {
mainsnak: claim.mainsnak,
qualifiers: claim.qualifiers || {},
type: claim.type,
rank: claim.rank
};
});
}
function createWork(item) {
executeEntityQuery('{ wd:' + item.id + ' wdt:P629+ ?entity . }').done(function (results) {
if (results.length > 0) {
OO.ui.alert($('<span>').text('There is already a work item: ').append(results));
} else {
postEntity({
type: 'item',
labels: {},
descriptions: {},
claims: {
P31: [itemClaim('P31', 'Q47461344')],
P50: extractNewClaims(item.claims.P50 || []),
P747: [itemClaim('P747', item.id)],
}
}).then(function (result) {
if ('entity' in result && 'id' in result.entity) {
addItemIdStatement(item.id, 'P629', result.entity.id).then(function () {
mw.notify('Work item created');
window.open('https://www.wikidata.org/entity/' + result.entity.id, '_blank');
}, function (jqXHR, textStatus) {
OO.ui.alert('Addition of the "edition of" statement failed: ' + JSON.stringify(textStatus));
});
} else {
OO.ui.alert('Entity saving done with unexpected result ' + JSON.stringify(result));
}
}, function (jqXHR, textStatus) {
OO.ui.alert('Creation of the work item failed: ' + JSON.stringify(textStatus));
});
}
});
}
function addItemIdStatement(subjectId, propertyId, objectId, qualifiers) {
return wdApi.postWithEditToken({
action: 'wbcreateclaim',
entity: subjectId,
snaktype: 'value',
property: propertyId,
value: JSON.stringify({'id': objectId})
}).then(function(result) {
if(result.claim && result.claim.id) {
mw.notify('Link from the work to this edition item created');
return $.when((qualifiers || []).map(function(qualifier) {
return wdApi.postWithEditToken({
action: 'wbsetqualifier',
claim: result.claim.id,
snaktype: 'value',
property: qualifier.prop,
value: JSON.stringify(qualifier.value)
});
}));
} else {
OO.ui.alert('The saving of the edition claim failed with result: "' + JSON.stringify(result));
return $.Deferred().reject();
}
});
}
function addEditionPropertyToWork(editionItem) {
return $.when((editionItem.claims.P629 || []).map(function(statement) {
if(statement.mainsnak.datavalue && statement.mainsnak.datavalue.value.id) {
return getEntity(statement.mainsnak.datavalue.value.id).then(function(workItem) {
if(!(workItem.claims.P747 || []).some(function(statement) {
return statement.mainsnak.datavalue && statement.mainsnak.datavalue.value.id == editionItem.id;
})) {
var qualifiers = [];
if(editionItem.claims.P407) {
editionItem.claims.P407.forEach(function(statement) {
if(statement.mainsnak.datavalue && statement.mainsnak.datavalue.value) {
qualifiers.push({prop: 'P407', value: statement.mainsnak.datavalue.value});
}
});
}
return addItemIdStatement(workItem.id, 'P747', editionItem.id, qualifiers);
} else {
return $.when();
}
});
} else {
return $.when();
}
}));
}
function convertPage(title) {
return $.ajax({
url: 'https://tptools.toolforge.org/ws2wd.php',
data: {
title: title
},
dataType: 'json'
}).fail(function (jqXHR, textStatus) {
OO.ui.alert('Convertion to Wikidata failed: ' + JSON.stringify(textStatus));
});
}
function getEntity(entityId) {
return wdApi.get({
action: 'wbgetentities',
ids: entityId
}).then(function(content) {
if(entityId in content.entities) {
return content.entities[entityId];
} else {
OO.ui.alert('The Wikidata item ' + entityId + ' does not exists.');
return $.Deferred().reject(content);
}
}, function (jqXHR, textStatus) {
OO.ui.alert('Retrieval of the Wikidata item ' + entityId + ' failed: ' + JSON.stringify(textStatus));
});
}
function postEntity(entity) {
if ('id' in entity) {
return wdApi.postWithEditToken({
action: 'wbeditentity',
id: entity.id,
data: JSON.stringify(entity)
});
} else {
return wdApi.postWithEditToken({
action: 'wbeditentity',
new: entity.type,
data: JSON.stringify(entity)
});
}
}
function addFastImportationButton() {
var $sitelinkElement = $('[data-wb-siteid="frwikisource"]');
var title = $sitelinkElement.find('.wikibase-sitelinkview-page a').attr('title');
if (title !== undefined) {
$sitelinkElement.prepend(
$('<a>')
.append(new OO.ui.IconWidget({
icon: 'download',
iconTitle: 'Import microdata'
}).$element)
.css('float', 'right')
.click(function () {
doImportation(title);
})
);
}
}
function doImportation(title) {
return new OO.ui.Process(convertPage(title.toString()).done(function (item) {
return postEntity(item).then(function (result) {
if ('entity' in result && 'id' in result.entity) {
addEditionPropertyToWork(result.entity).done(function() {
setTimeout(function() {
window.location.href = 'https://www.wikidata.org/entity/' + result.entity.id;
}, 3000); //TODO: bad hack
});
} else {
OO.ui.alert('Entity saving done with result ' + JSON.stringify(result));
}
}, function (jqXHR, textStatus) {
OO.ui.alert('Importation to Wikidata failed: ' + JSON.stringify(textStatus));
});
}));
}
function WS2WDDialog(config) {
WS2WDDialog.super.call(this, config);
}
OO.inheritClass(WS2WDDialog, OO.ui.ProcessDialog);
WS2WDDialog.static.name = 'wd2ws';
WS2WDDialog.static.title = 'Wikisource to Wikidata import tool';
WS2WDDialog.static.size = 'large';
WS2WDDialog.static.actions = [
{action: 'import', label: 'Import', flags: ['primary', 'constructive']},
{label: 'Cancel', flags: 'safe'}
];
WS2WDDialog.prototype.initialize = function () {
WS2WDDialog.super.prototype.initialize.apply(this, arguments);
var pageInput = new mw.widgets.TitleInputWidget({
api: new mw.ForeignApi('https://fr.wikisource.org/w/api.php')
});
this.page = pageInput;
var fieldset = new OO.ui.FieldsetLayout({
label: 'Page on French Wikisource to import'
});
fieldset.addItems([pageInput]);
this.panel = new OO.ui.PanelLayout({
padded: true,
expanded: false
});
this.panel.$element.append(fieldset.$element);
this.$body.append(this.panel.$element);
// We prefill the input
mw.hook('wikibase.entityPage.entityLoaded').add(function (entity) {
if ('sitelinks' in entity && 'frwikisource' in entity.sitelinks) {
pageInput.setValue(entity.sitelinks.frwikisource.title);
}
});
};
WS2WDDialog.prototype.getActionProcess = function (action) {
if (action === 'import') {
var title = this.page.getMWTitle();
if (title === null) {
OO.ui.alert('The provided page title "' + this.page.getValue() + '"is invalid!');
} else {
return doImportation(title);
}
}
return WS2WDDialog.super.prototype.getActionProcess.call(this, action);
};
WS2WDDialog.prototype.getBodyHeight = function () {
return this.panel.$element.outerHeight(true);
};
var windowManager = new OO.ui.WindowManager();
$('body').append(windowManager.$element);
windowManager.addWindows([new WS2WDDialog()]);
var portletLink = mw.util.addPortletLink('p-tb', '#', 'Import Wikisource page');
$(portletLink).click(function () {
windowManager.openWindow('wd2ws');
});
if (mw.config.get('wgNamespaceNumber') === 0) {
var workPortletLink = mw.util.addPortletLink('p-tb', '#', 'Create work item');
$(workPortletLink).click(function () {
mw.hook('wikibase.entityPage.entityLoaded').add(createWork);
});
}
addFastImportationButton();
});
});