Utilisateur:Seudo/wikidatafy.js
Apparence
[[File:|10px|link=Catégorie:{{{1}}}|alt=]]
(Redirigé depuis Utilisateur:Seudo/auteur.js)
Note : après avoir enregistré vos modifications, il se peut que vous deviez forcer le rechargement complet du cache de votre navigateur pour voir les changements.
- Firefox / Safari : Maintenez la touche Maj (Shift) en cliquant sur le bouton Actualiser ou pressez Ctrl-F5 ou Ctrl-R (⌘-R sur un Mac) ;
- Google Chrome : Appuyez sur Ctrl-Maj-R (⌘-Shift-R sur un Mac) ;
- Internet Explorer : Maintenez la touche Ctrl en cliquant sur le bouton Actualiser ou pressez Ctrl-F5 ;
- Opera : Allez dans Menu → Settings (Opera → Préférences sur un Mac) et ensuite à Confidentialité & sécurité → Effacer les données d'exploration → Images et fichiers en cache.
// @english: In case you saw a modification made by this tool in Wikidata, this is an experimental tool
// to enhance information about Wikisource documents at Wikidata. It is not a bot but a Javascript gadget,
// so it should not cause a major disruptance. However it may contain bugs or not be used properly.
// In case you notice something really wrong, feel free to modify this page and remove everything to
// limit the damage (but please send me a message...)
//
// ////////////////////////////////////////////////////////////////
// Outil permettant de :
// - récupérer de Wikidata la liste des œuvres et éditions d'un auteur
// qui ne sont pas déjà mentionnées dans la page Auteur => cette
// fonctionnalité est pour l'instant désactivée, car les données de
// Wikidata sont rarement d'une qualité suffisante pour que ce soit
// utile ;
// - corriger les données Wikidata des œuvres d'un auteur, via une
// interface qu'on peut lancer depuis la page de l'auteur (en mode
// édition uniquement, pour des raisons techniques) ;
// - afficher en haut d'une page de l'espace principal (transclusion),
// le cas échéant, une liste de propositions d'améliorations de la fiche
// Wikidata correspondant à cette page. Pour les cas les plus simples,
// la correction peut être faite directement, sans avoir à aller sur Wikidata.
//
// Mode d'emploi :
// - inclure ce fichier dans common.js :
// importScript('User:Seudo/wikidatafy.js')
// 1) Ouvrir une page Auteur en mode édition.
// - Dans le menu « Plus » , cliquer sur « (WDfy) Cohérence des données ».
// - Une fenêtre suggère des améliorations à faire le cas échéant dans Wikidata.
// Dans certains cas elles peuvent être faites en cliquant sur
// « Mettre à jour Wikidata » (sous votre responsabilité !), la plupart du temps un lien
// vers Wikidata est fourni.
// 2) Ouvrir une page de l'espace principal contenant la transclusion d'un
// ouvrage.
// - Si l'outil détecte des problèmes potentiels dans la fiche Wikidata
// (absence totale de fiche Wikidata, données importantes non renseignées...)
// il affiche un cadre rouge en haut de la page avec l'indication de ces problèmes
// et, dans les cas les plus simples, un bouton permettant de corriger directement
// Wikidata.
//
// Si on ne souhaite pas que le cadre rouge apparaisse à chaque chargement d'une page de l'espace principal,
// charger le script de la manière suivante (avec le paramètre « auto=non ») :
// mw.loader.load( '/w/index.php?title=User:Seudo/wikidatafy.js&auto=non&action=raw&ctype=text/javascript' );
//
// Numéro de version (qui peut être cherché dans l'historique)
version = 0.3
mw.loader.using( [ 'oojs', 'oojs-ui', 'mediawiki.util' ] ).done( function () {
WIKIDATAFY_WIKISOURCE_URL = "https://fr.wikisource.org"; // Valeur par défaut
const script_name = "wikidatafy.js";
// User Agent envoyé pour les requêtes à l'API
const api_user_agent = `Seudo/${script_name} ${version} ([[s:fr:User:Seudo/${script_name}]]; https://fr.wikisource.org/wiki/User_talk:Seudo)`
// Pour ne pas surcharger le serveur
const maxCountFS = 50;
// Hauteur des boutons d'édition Wikidata
const g_btn_height = "1.6em";
// Mise en forme pour un message de succès
const css_successmsg = "font-weight: bold;";
// Mise en forme pour un message d'erreur
const css_errormsg = "font-weight: bold; color: red;";
const WD_API_URL = "https://www.wikidata.org/w/api.php";
// Fin de la configuration
///////////////////////////////////////////////////////////
// Renvoit un message dans une langue plus ou moins adaptée
const WIKIDATAFY_WIKISOURCE_URL_FR = "https://fr.wikisource.org";
const i18n_messages = {
"Accédez à l'élément Wikidata": { "en": "Go to the Wikidata element" },
"chargez le gadget WEF": { "en": "load the WEF gadget" },
"Il manque une référence à l'œuvre correspondant à cette édition (propriété {1} : « {2} »)": {
"en": "A reference is missing to the work this edition refers to (property {1} : '{2}')"
},
"édition ou traduction de": {
"en": "edition or translation of"
},
"ou bien": {
"en": "or"
},
"puis cliquez sur WEF: FRBR Edition pour éditer l'élément Wikidata sans sortir de Wikisource": {
"en": "then clic on WEF: FRBR Edition to edit the Wikidata element without leaving Wikisource"
}
};
function i18n(msg, params=[]) {
// On ne gère que deux langues
var lang = (WIKIDATAFY_WIKISOURCE_URL == WIKIDATAFY_WIKISOURCE_URL_FR ? "fr" : "en");
if(msg in i18n_messages) {
if(lang != "fr")
msg = i18n_messages[msg][lang];
for(i = 0; i < params.length; i++)
msg = msg.replace("{" + (i+1) + "}", params[i]);
}
return msg;
}
// Lancement automatique au chargement d'une page
var getScriptURL = (function() {
var scripts = document.getElementsByTagName('script');
for(s of scripts) {
let src = s.src;
if(src && src.includes("/" + script_name + "&"))
return function() { return src; };
}
return function() { return null; };
})();
var automatique = true;
///////////////////////////////////////////////////////////
// Fonctions utilitaires générales
function escapeHtml(unsafe) {
return unsafe
.replace(/&/g, "&")
.replace(/</g, "<")
.replace(/>/g, ">")
.replace(/"/g, """)
.replace(/'/g, "'");
}
function url_last_part(url) {
if (typeof(url) != "string")
throw new Error("" + url + " devrait être une chaîne");
return url.replace(/.*\//, "");
}
function getAjax(url, settings={}) {
settings['Api-User-Agent'] = api_user_agent;
return $.ajax(url, settings);
}
function escape_regex(s) {
return s.replaceAll('(', '\\\(')
.replaceAll(')', '\\\)')
.replaceAll('|', '\\\|')
.replaceAll('*', '\\\*')
.replaceAll('?', '\\\?');
}
function pluriel(nb) {
return (nb >= 2 ? "s" : "");
}
// Renvoit une version "canonique" des chaînes de
// caractères pour des comparaisons
function canonique(s) {
return s.replaceAll(' ', ' ')
.replaceAll(/\s+/g, ' ')
.trim();
}
///////////////////////////////////////////////////////////
// Constantes et fonctions utilitaires pour Wikidata.
var wdproperties = {};
const p_nature = "P31";
wdproperties[p_nature] = "nature de l'élément"
const p_auteur = "P50";
wdproperties[p_auteur] = "auteur ou autrice";
const p_traducteur = "P655";
wdproperties[p_traducteur] = "traducteur ou traductrice";
const p_editeur = "P123";
wdproperties[p_editeur] = "publié par";
const p_langue = "P407";
wdproperties[p_langue] = "langue de l'œuvre, du nom ou du terme";
const p_edition_de = "P629";
wdproperties[p_edition_de] = "édition ou traduction de";
const p_edition = "P747";
wdproperties[p_edition] = "édition";
const p_facsimile = "P996";
wdproperties[p_facsimile] = "fac-similé";
const p_titre = "P1476";
wdproperties[p_titre] = "titre";
function get_property_label(prop) {
if (prop in wdproperties)
return wdproperties[prop];
else
throw new Error(`Erreur interne : ${prop} est une propriété inconnue`);
}
var wdentities = {};
const q_francais = "Q150";
wdentities[q_francais] = "français";
const q_edition = "Q3331189";
wdentities[q_edition] = "version, édition ou traduction";
const q_traduction = "Q39811647"; // traduction (sous-classe du précédent)
wdentities[q_traduction] = "traduction";
// Codes des langues considérées comme relevant du français
// (cf. Module:Œuvre/Langue française)
const langues_fr_wdids = [
q_francais, // français
"Q35222", // ancien français
"Q1473289", // moyen français
"Q3100376" // français classique
];
function get_entity_label(entity) {
if (entity in wdentities)
return wdentities[entity];
else
throw new Error(`Erreur interne : ${entity} est une entité inconnue`);
}
var badges_avancement = {
"Q28064618": 1, // document numérique
"Q20748094": 1, // texte incomplet
"Q20748091": 2, // texte non corrigé
"Q20748092": 4, // texte relu et corrigé
"Q20748093": 5 // texte validé
}
// Renvoi la qualité indiquée dans une page de transclusion (via le modèle TextQuality, qui insère une catégorie)
function get_quality_in_page() {
let res = null;
if(RLCONF && RLCONF["wgCategories"]) {
RLCONF["wgCategories"].forEach(categorie => {
if(Avancement.hasQuality(categorie))
res = categorie;
});
}
return res;
}
function get_mw_api() {
return new mw.Api({
ajax: {
headers: { 'Api-User-Agent': api_user_agent }
}
});
}
function get_wikidata_id() {
// Plusieurs méthodes, selon le type de page, la skin, etc.
let wd_id = mw.config.get("wgWikibaseItemId");
if(wd_id)
return wd_id;
const re = new RegExp("https://www.wikidata.org/wiki/Special:EntityPage/(.*)");
let lien = $("#t-wikibase a");
if(lien.length > 0) {
wd_id = $("#t-wikibase a").attr("href").match(re)[1];
return wd_id;
}
return null;
}
// Envoie une requête SPARQL et passe le résultat à une fonction
// sous forme d'objet JSON
function send_sparql(query, callback) {
console.log(query);
let url = "https://query.wikidata.org/sparql?format=json&query=" + encodeURIComponent(query);
fetch(url, {
method: 'POST' // Juste pour éviter le cache : cf. https://www.wikidata.org/wiki/Wikidata:SPARQL_query_service/query_optimization#Dealing_with_cached_queries
})
.then(response => response.json())
.then(data => callback(data));
}
// Renvoit la valeur d'une donnée renvoyée par SPARQL,
// qui présente des structures diverses
function get_value(x) {
if (typeof(x) == "string")
return x;
else if ("value" in x)
return x["value"];
else {
console.log(x);
throw new Error("Valeur non reconnue : " + x);
}
}
// Cherche à renvoyer la "valeur" d'un snak (ex: mainsnak = {...}) en fonction de son type
function snak_value(snak) {
// snaktype peut valoir "value", "somevalue" (valeur inconnue) ou "novalue".
if(snak.snaktype == "value") {
if(snak.datatype == "wikibase-item" && snak.datavalue && snak.datavalue.type == "wikibase-entityid"
&& snak.datavalue.value["entity-type"] == "item")
return snak.datavalue.value.id;
else if(snak.datatype == "commonsMedia" && snak.datavalue.type == "string")
return snak.datavalue.value;
else if(snak.datatype == "monolingualtext" && snak.datavalue.type == "monolingualtext")
return snak.datavalue.value.text;
else {
// Autres types à implémenter en tant que de besoin
console.error("Type de snak non reconnu : " + JSON.stringify(snak));
return null;
}
}
else {
console.log("Snak sans valeur ou avec une valeur inconnue : " + JSON.stringify(snak));
return null;
}
}
function nettoyer_sparql_res(bindings) {
let items = {};
const multiples = ["nature", "natureLabel", "editionDe", "langue", "facsimile", "badge"]; // Champs à valeurs multiples
bindings.forEach(item => {
const item_id = url_last_part(get_value(item["item"]));
if (item_id in items) {
const autre = items[item_id];
for (key in item) {
if (!item[key])
continue;
const val = get_value(item[key]);
if (multiples.includes(key)) {
if (key in autre) {
if (!autre[key].includes(val))
autre[key].push(val);
} else
autre[key] = [val];
} else if (!key in autre || !autre[key])
autre[key] = val;
}
} else {
const newitem = {};
for (key in item) {
const val = get_value(item[key]);
if (multiples.includes(key))
newitem[key] = [val];
else
newitem[key] = val;
}
items[item_id] = newitem;
}
});
return items;
}
///////////////////////////////////////////////////////////
// Vérifie la cohérence des informations relatives aux oeuvres dans Wikidata
// et affiche les résultats dans une boîte de dialogue
function verif_wd_oeuvres_auteur(data) {
console.log(data);
if (!data["results"] || !data["results"]["bindings"]) {
OO.ui.alert("Pas de résultats");
return;
}
// D'abord un nettoyage : la requête SPARQL renvoit certains items en plusieurs
// versions, dont certains incomplètes
let items = nettoyer_sparql_res(data["results"]["bindings"]);
// Variables de maintenance de Wikidata
let editions_sans_oeuvre = {};
let oeuvre2editions = {};
let edition2oeuvre = {};
let editions_incompletes = {};
let facsimiles_manquants = {};
// Relie une œuvre à l'avancement le plus élevé de ses éditions
// let avancement_oeuvres = {};
// Pour vérifier qu'il est renseigné dans Wikidata comme dans Wikisource
// let avancement_editions = [];
for (let item_id in items) {
const item = items[item_id];
let nature_ids = item["nature"].map(x => url_last_part(x));
const has_nature_edition = nature_ids.includes(q_edition)
|| nature_ids.includes(q_traduction);
if (has_nature_edition && item["wsname"] && !item["facsimile"])
facsimiles_manquants[item_id] = [item];
if (item["editionDe"]) {
// c'est une édition
let manquants = [];
if(!item["langue"] || item["langue"].length == 0)
manquants.push([p_langue, get_property_label(p_langue)]);
if(manquants.length > 0)
editions_incompletes[item_id] = [item, manquants];
item["editionDe"].forEach(editionDe => {
const oeuvre = url_last_part(editionDe);
if (!edition2oeuvre[item_id])
edition2oeuvre[item_id] = [];
edition2oeuvre[item_id].push(oeuvre);
});
} else {
// c'est une œuvre
let editions = [];
item["editions"].split(/\s+/).forEach(edition => {
if (edition.length > 0)
editions.push(url_last_part(edition));
});
oeuvre2editions[item_id] = editions;
}
}
for (let item_id in items) {
let item = items[item_id];
let msg = [];
let nature_ids = item["nature"].map(x => url_last_part(x));
// On se limite pour l'instant aux œuvres, définies comme
// les éléments qui ont au moins une édition (restrictif : suppose
// que tout est parfait dans Wikidata)
// if(!(item["editions"] && item["editions"].length > 0))
// continue;
// On n'affiche pas un document qui n'a ni transclusion, ni fac-similé
if (!item["wsname"] && !item["facsimile"])
continue;
// On n'affiche pas certains éléments qui ne correspondent manifestement
// pas à des ouvrages intéressant Wikisource
const non_oeuvres = [
"Q7777570" // production théâtrale
];
let keep = true;
non_oeuvres.forEach(id => {
if (nature_ids.includes(id))
keep = false;
});
if (!keep)
continue;
const has_nature_edition = nature_ids.includes(q_edition)
|| nature_ids.includes(q_traduction);
// On n'affiche les éditions non rattachées à une œuvre que
// si elles sont en français
if (has_nature_edition
&& "langue" in item && !(item["langue"].map(url_last_part).includes("Q150")))
continue;
// On recense les éditions en français défectueuses
if (has_nature_edition && !item["editionDe"])
editions_sans_oeuvre[item_id] = item;
};
display_resultats(items, editions_sans_oeuvre,
oeuvre2editions, edition2oeuvre, editions_incompletes,
facsimiles_manquants);
}
// Affiche des données récupérées de SPARQL dans le champ de saisie
function display_oeuvres(data) {
console.log(data);
const editbox = $("#wpTextbox1");
if (!editbox) {
throw new Error("Champ d'édition absent");
}
const content = editbox.val();
if (!data["results"] || !data["results"]["bindings"]) {
OO.ui.alert("Pas de résultats");
return;
}
let documents = [];
let cur_document = null;
// D'abord un nettoyage : la requête SPARQL renvoit certains items en plusieurs
// versions, dont certains incomplètes
let items = nettoyer_sparql_res(data["results"]["bindings"]);
// Relie une œuvre à l'avancement le plus élevé de ses éditions
let avancement_oeuvres = {};
for (let item_id in items) {
const item = items[item_id];
let nature_ids = item["nature"].map(x => url_last_part(x));
const has_nature_edition = nature_ids.includes(q_edition)
|| nature_ids.includes(q_traduction);
if (item["editionDe"]) {
// c'est une édition
item["editionDe"].forEach(editionDe => {
const oeuvre = url_last_part(editionDe);
if(item["badge"]) {
item["badge"].forEach(badge => {
let badge_id = url_last_part(badge);
if(badge_id in badges_avancement) {
const avancement = badges_avancement[badge_id];
if (!(oeuvre in avancement_oeuvres)
|| avancement_oeuvres[oeuvre] < avancement)
avancement_oeuvres[oeuvre] = avancement;
}
});
}
});
}
}
for (let item_id in items) {
let item = items[item_id];
let msg = [];
let nature_ids = item["nature"].map(x => url_last_part(x));
// On se limite pour l'instant aux œuvres, définies comme
// les éléments qui ont au moins une édition (restrictif : suppose
// que tout est parfait dans Wikidata)
// if(!(item["editions"] && item["editions"].length > 0))
// continue;
// On n'affiche pas un document qui n'a ni transclusion, ni fac-similé
if (!item["wsname"] && !item["facsimile"])
continue;
// On n'affiche pas certains éléments qui ne correspondent manifestement
// pas à des ouvrages intéressant Wikisource
const non_oeuvres = [
"Q7777570" // production théâtrale
];
let keep = true;
non_oeuvres.forEach(id => {
if (nature_ids.includes(id))
keep = false;
});
if (!keep)
continue;
const has_nature_edition = nature_ids.includes(q_edition)
|| nature_ids.includes(q_traduction);
// On n'affiche les éditions non rattachées à une œuvre que
// si elles sont en français
if (has_nature_edition
&& "langue" in item && !(item["langue"].map(url_last_part).includes("Q150")))
continue;
// On recense les éditions en français défectueuses
// if (has_nature_edition && !item["editionDe"])
// editions_sans_oeuvre[item_id] = item;
let label = item["itemLabel"];
// S'il y a une page sur Wikisource, on regarde si l'élément est présent
// dans un appel à Document ou L2S. Sinon, on l'affiche sans lien.
let doc = null;
if (item["wsname"]) {
const wsname = item["wsname"];
const wsname_regexp = escape_regex(wsname);
const regex1 = new RegExp('{{Document\\s*\\\|([^}]*\\\||)\\s*(titre|éditions)=' + wsname_regexp + "(\\\||})", "i");
const regex2 = new RegExp('{{Document\\s*\\\|([^}]*\\\||)\\s*(titre|éditions)=\\\[\\\[' + wsname_regexp + "(\\\||\\\]\\\])", "i");
const regex3 = new RegExp('{{(L2S|Livre2Scanné)\\s*\\\|\\s*' + wsname_regexp + "(\\\||})", "i");
if (content.search(regex1) < 0 && content.search(regex2) < 0 && content.search(regex3) < 0) {
// Document non encore mentionné dans la page : on le rajoute
doc = {
"wsname": wsname
};
}
} else
doc = {};
if (doc) {
doc["_type"] = has_nature_edition ? "édition" : "œuvre";
doc["id"] = item_id;
doc["titre"] = label;
let forme;
if (item["formeDeLOeuvreLabel"]) {
const s = item["formeDeLOeuvreLabel"];
forme = s[0].toUpperCase() + s.substr(1);
} else
forme = null;
if (item["yearPublication"])
doc["date"] = item["yearPublication"];
else if (item["yearFondation"])
doc["date"] = item["yearFondation"];
else if (item["yearPremiereRepresentation"])
doc["date"] = item["yearPremiereRepresentation"];
// Attention, SPARQL renvoit l'année suivante si elle est négative !
if(doc["date"] && doc["date"][0] == "-")
doc["date"] = "-" + (1 + parseInt(doc["date"].substring(1)));
doc["nature"] = item["natureLabel"].join(", ");
doc["genre"] = forme;
if(item["facsimile"]) {
// On fait un lien seulement vers le premier fac-similé
const uri = decodeURI(item["facsimile"][0]);
doc["livre"] = url_last_part(uri);
}
if(item["badge"]) {
item["badge"].forEach(badgeurl => {
let badge_id = url_last_part(badgeurl);
if(badge_id in badges_avancement) {
doc["avancement"] = badges_avancement[badge_id];
}
});
}
doc["_msg"] = msg;
documents.push(doc);
}
};
// Tri
documents.sort((a, b) => {
if (a["_type"] == "œuvre" && b["_type"] != "œuvre")
return false;
else if (a["_type"] != "œuvre" && b["_type"] == "œuvre")
return true;
else {
for (let critere in["nature", "genre", "date", "titre"])
if (a[critere] && b[critere] && a[critere] != b[critere])
return (a[critere] < b[critere]);
}
return (a["item"] < b["item"]);
});
// Mise à jour de l'avancement des oeuvres à partir de celui des éditions
documents.forEach(doc => {
if (!doc["avancement"] && (doc["id"]in avancement_oeuvres))
doc["avancement"] = avancement_oeuvres[doc["id"]]; // Avancement de l'édition la plus avancée
});
const LISTE_DEBUT = "{{liste documents début}}\n";
const LISTE_FIN = "{{liste documents fin}}\n";
let in_liste_docs = false;
let count = 0;
let nb_oeuvres = 0;
let nb_editions = 0;
if (documents.length > 0) {
let cur_typ = null;
let wikitxt = "";
documents.forEach(doc => {
let typ = doc["nature"] + (doc["genre"] ? ", " + doc["genre"] : "");
if (typ != cur_typ) {
if (in_liste_docs) {
wikitxt += LISTE_FIN;
in_liste_docs = false;
}
wikitxt += "'''" + typ + "'''\n";
cur_typ = typ;
}
if (doc["_type"] == "édition")
nb_editions += 1;
else if (doc["_type"] == "œuvre")
nb_oeuvres += 1;
else
throw new Error("Type de document inattendu : " + doc["_type"]);
if (!doc["wsname"]) {
if (in_liste_docs) {
wikitxt += LISTE_FIN;
in_liste_docs = false;
}
wikitxt += "* " + doc["titre"];
if ("date" in doc)
wikitxt += " (" + doc["date"] + ")";
wikitxt += " " + lienwiki_wd_edit(doc["id"]);
} else {
if (!in_liste_docs) {
wikitxt += LISTE_DEBUT;
in_liste_docs = true;
}
wikitxt += "* {{Document|";
wikitxt += (doc["_type"] == "édition" ? "titre=" : "éditions=");
if (doc["wsname"] && doc["titre"]) {
if (doc["wsname"] == doc["titre"])
wikitxt += "[[" + doc["titre"] + "]]";
else
wikitxt += "[[" + doc["wsname"] + "|" + doc["titre"] + "]]";
} else if (doc["wsname"])
wikitxt += "[[" + doc["wsname"] + "]]";
else
wikitxt += doc["titre"];
if ("livre" in doc)
wikitxt += "|livre=" + doc["livre"];
if ("date" in doc)
wikitxt += "|date=" + doc["date"];
if ("avancement" in doc)
wikitxt += "|avancement=" + doc["avancement"];
wikitxt += "}}";
}
wikitxt += " <!-- " + doc["id"];
if (doc["_msg"].length > 0)
wikitxt += " : " + doc["_msg"].join(", ");
wikitxt += " -->";
wikitxt += "\n";
count += 1;
});
if (in_liste_docs) {
wikitxt += LISTE_FIN;
in_liste_docs = false;
}
editbox.val(wikitxt + editbox.val());
}
OO.ui.alert("Nombre de résultats insérés au début du champ de saisie : " + count + ". "
+ "Ne cliquez pas sur « Publier » ! Reclassez d'abord les documents à l'endroit approprié.");
}
function wdlink(id, display_id = true) {
// Renvoit un lien vers une propriété ou une entité Wikidata
// répertoriée dans wdproperties ou wdentities
let txt = id;
let complement = null;
let url;
if (wdentities[id]) {
if(display_id)
complement = "(" + wdentities[id] + ")";
else
txt = wdentities[id];
url = "https://www.wikidata.org/wiki/" + id;
} else if (wdproperties[id]) {
if(display_id)
complement = "(" + wdproperties[id] + ")";
else
txt = wdproperties[id];
url = "https://www.wikidata.org/wiki/Property:" + id;
} else if(id && id[0] == "P")
url = "https://www.wikidata.org/wiki/Property:" + id;
else
url = "https://www.wikidata.org/wiki/" + id;
const lien = "<a target=_blank href='" + url + "'>" + escapeHtml(txt) + "</a>";
const res = (complement ?
"<span style='font-size: 90%'>" + lien + "</span>" + (complement ? " " + complement : "")
: lien);
return res;
}
function lienwiki_wd_edit(id) {
// Renvoit un lien vers Wikidata sous forme de crayon
return `[[Image:Blue pencil.svg|10px|link=d:${id}|Voir et modifier les données sur Wikidata]]`;
}
function lienhtml_wd_edit(id) {
// Renvoit un lien vers Wikidata sous forme de crayon
return `<span typeof="mw:File"><a href="https://www.wikidata.org/wiki/${id}" title="Voir et modifier les données sur Wikidata"><img alt="Voir et modifier les données sur Wikidata" src="//upload.wikimedia.org/wikipedia/commons/thumb/7/73/Blue_pencil.svg/10px-Blue_pencil.svg.png" decoding="async" srcset="//upload.wikimedia.org/wikipedia/commons/thumb/7/73/Blue_pencil.svg/15px-Blue_pencil.svg.png 1.5x, //upload.wikimedia.org/wikipedia/commons/thumb/7/73/Blue_pencil.svg/20px-Blue_pencil.svg.png 2x" data-file-width="600" data-file-height="600" width="10" height="10"></a></span>`;
}
function lienhtml_ws(item) {
// Renvoit un lien vers Wikisource le cas échéant
// item peut être un nom de page ou un objet construit à partir d'une requête SPARQL
if(typeof(item) == "string")
return `<a target=_blanc href="${WIKIDATAFY_WIKISOURCE_URL}/wiki/${encodeURIComponent(item)}">${item}</a>`;
else if(item["wsname"])
return `<a target=_blanc href="${WIKIDATAFY_WIKISOURCE_URL}/wiki/${encodeURIComponent(item["wsname"])}">${item["itemLabel"]}</a>`;
else // Pas de page
return item["itemLabel"];
}
function get_centralauthtoken(data = null) {
let promise = getAjax(WIKIDATAFY_WIKISOURCE_URL + "/w/api.php?action=centralauthtoken&format=json")
.then(function(json) {
if(json.centralauthtoken && json.centralauthtoken.centralauthtoken) {
let centralauthtoken = json.centralauthtoken.centralauthtoken;
console.log("central auth token=" + centralauthtoken );
return [centralauthtoken, data];
}
else {
console.log(json);
throw "Token central non renvoyé";
}
}).fail(function(jqXHR, textStatus, errorThrown) {
console.log("" + textStatus + ", " + errorThrown);
alert("Erreur lors de la récupération du token centralisé : " + textStatus);
});
return promise;
}
function get_wikidata_token(centralauthtoken, test=false) {
let url = (test ? "https://test.wikidata.org/w/api.php" : WD_API_URL);
let promise = getAjax(url, {
data: {
"action": "query",
"format": "json",
"origin": WIKIDATAFY_WIKISOURCE_URL,
"meta": "tokens",
"centralauthtoken": centralauthtoken
},
headers: { 'Api-User-Agent': api_user_agent },
xhrFields: {
withCredentials: true
},
datatype: "json"
}).then(function(json) {
if(json.query && json.query.tokens && json.query.tokens.csrftoken) {
let token = json.query.tokens.csrftoken;
console.log("Récupéré de l'API le token : " + token);
return token;
}
else {
console.log(json);
throw "Token non renvoyé";
}
}).fail(function(jqXHR, textStatus, errorThrown) {
console.log("" + textStatus + ", " + errorThrown);
alert("Erreur lors de la récupération du token : " + textStatus);
});
return promise;
}
// Fontion éditant une propriété d'un item de Wikidata
function edit_wikidata(item_id, propriete, valeurs, btneditid) {
if(![p_facsimile, p_langue, p_titre, "badge"].includes(propriete))
throw "Propriété non éditable : " + propriete;
let promise =
get_centralauthtoken()
.then(function(args) {
return get_wikidata_token(args[0]);
})
.then(function(token) {
return get_centralauthtoken(token);
})
.then(function(args) {
// Une fois qu'on a tous les tokens, on peut faire l'édition
let centralauthtoken = args[0];
let token = args[1];
let querydata = null;
let summary = "";
if(propriete == p_facsimile) {
// On accepte un fac-similé ou un array de fac-similés
if(typeof(valeurs) == "string")
valeurs = [valeurs];
if(!typeof(valeurs) == "object") {
console.error(valeurs);
throw "Erreur interne";
}
querydata = { "claims": [] };
valeurs.forEach(val => {
querydata["claims"].push({
"mainsnak": {
"snaktype": "value",
"property": propriete,
"datatype": "commonsMedia",
"datavalue": {
"value": val,
"type":"string"
}
},
"rank":"normal",
"type":"statement"
});
});
summary = "Set [[Property:" + propriete + "]] (" + get_property_label(propriete) + ")";
}
else if(propriete == p_langue) {
// On accepte une langue ou un array de langues
if(typeof(valeurs) == "string")
valeurs = [valeurs];
if(!typeof(valeurs) == "object") {
console.error(valeurs);
throw "Erreur interne";
}
querydata = { "claims": [] };
valeurs.forEach(val => {
let numeric_val = parseInt(val.substr(1));
querydata["claims"].push({
"mainsnak": {
"snaktype": "value",
"property": propriete,
"datatype": "wikibase-item",
"datavalue": {
"value": {
"entity-type": "item",
"numeric-id": numeric_val,
"id": val
},
"type":"wikibase-entityid"
}
},
"rank":"normal",
"type":"statement"
});
});
summary = "Set [[Property:" + propriete + "]] (" + get_property_label(propriete) + ")";
}
else if(propriete == p_titre) {
if(!typeof(valeurs) == "string")
throw "Erreur interne";
let valeur = valeurs; // Une seule
querydata = { "claims": [] };
querydata["claims"].push({
"mainsnak": {
"snaktype": "value",
"property": propriete,
"datatype": "monolingualtext",
"datavalue": {
"type":"monolingualtext",
"value": {
"language": "fr",
"text": valeur
}
}
},
"rank":"normal",
"type":"statement"
});
summary = "Set [[Property:" + propriete + "]] (" + get_property_label(propriete) + ")";
}
else if(propriete == "badge") {
if(!typeof(valeurs) == "string")
throw "Erreur interne";
let valeur = valeurs; // Une seule
// Cette requête, en principe, écrase les badges sur frwikisource mais ne touche pas au reste
querydata = { "sitelinks": { "frwikisource": {
"site": "frwikisource",
"badges": [ valeur ]
}}};
summary = "Set frwikisource badge ([[" + valeur + "]])";
}
else
throw "Propriété non éditable : " + propriete;
summary += " via [[:s:fr:User:Seudo/" + script_name + "]] " + version;
$("#" + btneditid).replaceWith($("<span>", {
id: btneditid, style: "height:" + g_btn_height
}).text("En cours..."));
let url = "https://www.wikidata.org/w/api.php"
+ "?centralauthtoken=" + encodeURIComponent(centralauthtoken)
+ "&origin=" + encodeURIComponent(WIKIDATAFY_WIKISOURCE_URL);
console.log("Appel de l'API Wikidata (" + url + ")");
console.log(querydata);
return $.post({
url: url,
headers: { "Api-User-Agent": api_user_agent },
data: {
action: "wbeditentity",
format: "json",
origin: WIKIDATAFY_WIKISOURCE_URL,
centralauthtoken: centralauthtoken,
data: JSON.stringify(querydata),
summary: summary,
id: item_id,
token: token
}
});
}).then(function(json) {
console.log("Réponse de l'API Wikidata : ")
console.log(json);
if(json.entity && json.entity.lastrevid) {
let lastrevid = json.entity.lastrevid;
let url_rev = `https://www.wikidata.org/w/index.php?title=${item_id}&diff=prev&oldid=${lastrevid}`;
let img = '<span><img src="//upload.wikimedia.org/wikipedia/commons/thumb/f/f6/OOjs_UI_icon_check-constructive.svg/20px-OOjs_UI_icon_check-constructive.svg.png" decoding="async" srcset="//upload.wikimedia.org/wikipedia/commons/thumb/f/f6/OOjs_UI_icon_check-constructive.svg/30px-OOjs_UI_icon_check-constructive.svg.png 1.5x, //upload.wikimedia.org/wikipedia/commons/thumb/f/f6/OOjs_UI_icon_check-constructive.svg/40px-OOjs_UI_icon_check-constructive.svg.png 2x" data-file-width="20" data-file-height="20" width="20" height="20"></span>';
$("#" + btneditid).replaceWith($("<span>", {
id: btneditid,
style: "white-space: nowrap; height:" + g_btn_height
}).html("Fait " + img + " (<a target=_blank href='" + url_rev + "'>révision</a>)"));
}
else if(json.error && json.error.info) {
msg = "";
if(json.error.messages && json.error.messages.length == 1
&& json.error.messages[0].name == "wikibase-validator-no-such-media"
&& propriete == "P996")
msg = "Il semble que le fac-similé ait été versé sur Wikisource uniquement, "
+ "de sorte qu'il ne peut pas être renseigné sur Wikidata. ";
msg += "La modification a échoué avec le message suivant :\n" + json.error.info;
alert(msg); // OO.ui.alert() ne fonctionne pas depuis une boîte de dialogue
$("#" + btneditid).replaceWith($("<span>", { style: "height: " + g_btn_height})
.text("Échec de la modification."));
}
else {
alert("Wikidata a renvoyé un contenu inattendu. Veuillez vérifier le "
+ "contenu de vos dernières modifications sur Wikidata et "
+ "prévenir l'auteur de ce gadget de l'erreur indiquée ci-dessous : \n"
+ JSON.stringify(json));
$("#" + btneditid).replaceWith($("<span>", { style: "height: " + g_btn_height })
.text("Échec de la modification."));
}
}).fail(function(jqXHR, textStatus, errorThrown) {
console.log("" + textStatus + ", " + errorThrown);
$("#" + btneditid).replaceWith($("<span>", { style: "height: " + g_btn_height})
.text("Échec de la modification."));
alert("Erreur lors de la mise à jour : " + textStatus);
});
return promise;
}
// Crée une oeuvre dans Wikidata
function creer_oeuvre_pour_edition(item_id, item, btnid) {
$("#" + btnid).replaceWith($("<div>", {
id: btnid, style: "clear: right; margin-top: 1em;"
}));
let div = $("#" + btnid);
div.html("Recherche d'éléments similaires sur Wikidata...");
let url = "https://www.wikidata.org";
let itemLabel = item["itemLabel"];
if(!itemLabel)
itemLabel = "";
getAjax("https://www.wikidata.org/w/api.php", {
data: { action: "wbsearchentities", language: "fr", uselang: "fr", search: itemLabel,
format: "json", origin: WIKIDATAFY_WIKISOURCE_URL }
}).done(function(data) {
console.log(data);
let btn_label = "Confirmer la création";
if(data.search && data.search.length > 0) {
div.html("");
let htmls = [];
data.search.forEach(elem => {
if(elem.id == item_id)
return;
let html = (elem.label ? elem.label : "<libellé non renseigné>")
+ " " + lienhtml_wd_edit(elem.id);
if(elem.description)
html += " (" + elem.description + ")";
htmls.push(html);
});
if(htmls.length > 0) {
div.append($("<p>").text("Éléments approchants trouvés sur Wikidata :"));
let ul = div.append($("<ul>"));
htmls.forEach(html => { ul.append($("<li>").html(html)); });
div.append($("<p>").html("Si AUCUN de ces éléments ne correspond à l'œuvre recherchée, alors cliquez "
+ "sur « " + btn_label + " »."));
}
else {
div.html($("<p>").html("Aucun élément approchant n'a été trouvé dans Wikidata. "
+ "Cliquez sur « " + btn_label + " » pour créer l'élément dans Wikidata."));
}
}
else {
div.html($("<p>").text("Aucun élément approchant n'a été trouvé dans Wikidata. "
+ "Cliquez sur « " + btn_label + " » pour créer l'élément dans Wikidata."));
}
let wdeditbtn_id = "wdeditbtn_" + item_id;
let wdeditbtn = $("<input>", {
type: "button", value: btn_label, id: wdeditbtn_id,
style: "height:" + g_btn_height + "; float:right;"
});
wdeditbtn.on("click", function(e) {
let USE_TEST = false;
$("#" + wdeditbtn_id).text("En cours...");
// Champs à inclure lors de la création de l'œuvre (idéal : reprendre l'interface de WEF) :
// - label : demander (par défaut : même que l'édition)
// - nature : à demander (liste déroulante des plus fréquentes)
// - description : à demander (facultatif
// - auteur : demander (par défaut : même que l'édition)
// - langue : demander (par défaut : même que l'édition)
let wd_data = {
labels: {
fr: { language: "fr", value: itemLabel}
},
claims: [{
"mainsnak": {
"snaktype": "value",
"property": "P31",
"datavalue": {
"value": {
"entity-type": "item",
"numeric-id": 7725634,
"id": "Q7725634"
},
"type": "wikibase-entityid"
},
"datatype": "wikibase-item"
},
"type": "statement",
"rank": "normal"
}]
};
getAjax(WD_API_URL, {
data: { action: "wbgetentities", ids: encodeURIComponent(item_id),
format: "json", origin: WIKIDATAFY_WIKISOURCE_URL }
})
.then(function(json) {
if(!json.entities || !json.entities[item_id] || !json.entities[item_id].sitelinks)
throw new Error("L'élément Wikidata n'a pas été créé");
for(let sitelink in json.entities[item_id].sitelinks) {
let wikiidx = sitelink.indexOf("wiki");
if(wikiidx > 0 && wikiidx == sitelink.length - 4 && wikiidx <= 3)
throw new Error("L'élément Wikidata comprend un lien Wikipédia, "
+ "ce qui est suspect pour un élément de type édition. "
+ "En conséquence, je préfère ne pas créer automatiquement "
+ "l'œuvre.");
};
return get_centralauthtoken();
})
.then(function(args) {
return get_wikidata_token(args[0], USE_TEST);
})
.then(function(token) {
return get_centralauthtoken(token);
})
.then(function(args) {
// Une fois qu'on a tous les tokens, on peut faire l'édition
let centralauthtoken = args[0];
let token = args[1];
let url = (USE_TEST ? "https://test.wikidata.org/w/api.php" : WD_API_URL)
+ "?centralauthtoken=" + encodeURIComponent(centralauthtoken)
+ "&origin=" + encodeURIComponent(WIKIDATAFY_WIKISOURCE_URL);
let summary = " via [[:s:fr:User:Seudo/" + script_name + "]] " + version;
return $.post({
url: url,
headers: { "Api-User-Agent": api_user_agent },
data: {
action: "wbeditentity",
new: "item",
format: "json",
origin: WIKIDATAFY_WIKISOURCE_URL,
centralauthtoken: centralauthtoken,
data: JSON.stringify(wd_data),
summary: summary,
token: token
}
});
})
.then(function(args) {
console.log(args);
if(args.error) {
if(args.error.info) {
let msg = "";
if(args.error.code == "modification-failed")
msg = "La modification a échoué. ";
throw new Error(msg + args.error.info);
}
else
throw new Error(JSON.stringify(args.error));
}
let msg = "L'élément a été créé avec succès.";
$("#" + wdeditbtn_id).replaceWith($("<div>", {"style": css_succesmsg}).text(msg));
})
.catch(function(jqXHR, textStatus, errorThrown) {
console.error(jqXHR);
let msg = jqXHR.message;
$("#" + wdeditbtn_id).replaceWith($("<div>", {"style": css_errormsg}).text(msg));
});
});
div.append($("<div>").append(wdeditbtn));
});
}
// Avancement :
// quality : paramètre de {{TextQuality}}, qui correspond au nom de la catégorie (00%, ..., 100%, Textes validés)
// avancement :
var Avancement = {};
// Table de correspondance récupérée dans {{TextQuality}}
Avancement.info = [
// qualité, image, avancement, badge, libellé badge
["Textes validés", "https://upload.wikimedia.org/wikipedia/commons/7/79/Mozilla.svg",
"Texte validé", "Q20748093", "texte validé"],
["100%", "https://upload.wikimedia.org/wikipedia/commons/2/24/100_percent.svg",
"À valider", "Q20748092", "texte relu et corrigé"],
["75%", "https://upload.wikimedia.org/wikipedia/commons/6/62/75_percent.svg",
"À relire", "Q20748091", "texte non corrigé"],
["50%", "https://upload.wikimedia.org/wikipedia/commons/e/eb/50_percent.svg",
"À formater", "Q20748091", "texte non corrigé"],
["25%", "https://upload.wikimedia.org/wikipedia/commons/c/ce/25_percent.svg",
"À compléter", "Q20748094", "texte incomplet"],
["00%", "https://upload.wikimedia.org/wikipedia/commons/6/60/00_percent.svg",
"À rechercher", "Q20748094", "texte incomplet"]
];
Avancement.qualityInfo = Object.fromEntries(Avancement.info.map(x => [x[0], x]));
Avancement.badgeInfo = Object.fromEntries(Avancement.info.map(x => [x[3], x]));
Avancement.hasQuality = function(quality) {
return (Avancement.qualityInfo[quality] ? true : false);
}
Avancement.hasBadge = function(badge) {
return (Avancement.badgeInfo[badge] ? true : false);
}
Avancement.to_info = function(arr, cle, idx) {
if(arr[cle])
return arr[cle][idx];
else
throw "Valeur inconnue : " + cle;
};
Avancement.quality2image = function(quality) { return Avancement.to_info(Avancement.qualityInfo, quality, 1) };
Avancement.quality2avancement = function(quality) { return Avancement.to_info(Avancement.qualityInfo, quality, 2) };
Avancement.quality2badge = function(quality) { return Avancement.to_info(Avancement.qualityInfo, quality, 3) };
Avancement.quality2badgelib = function(quality) { return Avancement.to_info(Avancement.qualityInfo, quality, 4) };
Avancement.badge2quality = function(badge) { return Avancement.to_info(Avancement.badgeInfo, badge, 0) };
Avancement.badge2image = function(badge) { return Avancement.to_info(Avancement.badgeInfo, badge, 1) };
Avancement.badge2lib = function(badge) { return Avancement.to_info(Avancement.badgeInfo, badge, 4) };
SampleTabPanel = function DemoSampleTabPanel(name, config) {
OO.ui.TabPanelLayout.call(this, name, config);
if (this.$element.is(':empty')) {
this.$element.text(this.label);
}
};
OO.inheritClass(SampleTabPanel, OO.ui.TabPanelLayout);
IndexedDialog = function DemoIndexedDialog(args, config) {
IndexedDialog.super.call(this, config);
this.args = args;
};
OO.inheritClass(IndexedDialog, OO.ui.ProcessDialog);
IndexedDialog.static.title = 'Analyse des résultats';
IndexedDialog.static.name = 'Unnom';
IndexedDialog.static.actions = [{
action: 'save',
label: 'Fermer',
flags: ['primary', 'progressive']
}, {
action: 'cancel',
label: 'Cancel',
flags: ['safe', 'close']
}
];
IndexedDialog.prototype.getBodyHeight = function() {
return 500;
};
IndexedDialog.prototype.getBodyWidth = function() {
return 900;
};
IndexedDialog.prototype.initializeEditionsSansOeuvre = function(editions_sans_oeuvre) {
if (Object.keys(editions_sans_oeuvre).length >= 1) {
let pl = (Object.keys(editions_sans_oeuvre).length >= 2);
const entete = (pl ? "Les documents suivants sont" : "Le document suivant est") + " de nature <b>"
+ wdlink(q_edition) + " ou " + wdlink(q_traduction) + "</b>, donc "
+ (pl ? "ils devraient être <b>reliés" : "il devrait être <b>relié") + " à une œuvre</b> "
+ "au moyen de la propriété " + wdlink("P747", true) + ".";
let contenu = $("<div>").append($("<p>").html(entete));
for (let item_id in editions_sans_oeuvre) {
const item = editions_sans_oeuvre[item_id];
let desc = $("<div>", { style: "clear:right; margin-top: 0.9em;" })
.append(lienhtml_ws(item) + " " + lienhtml_wd_edit(item_id) + " ");
/* On ne rajoute pas ce bouton, trop complexe et risqué */
/*
let btneditid = item_id +"_editoeuvrebtn";
let wdeditbtn = $("<input>", {
id: btneditid, type: "button",
style: "height:" + g_btn_height + "; float:right;",
value: "Créer l'œuvre dans Wikidata"
});
wdeditbtn.on("click", function(e) { creer_oeuvre_pour_edition(item_id, item, btneditid) });
desc.append(wdeditbtn);
*/
contenu.append(desc);
};
this.tabPanels.push(new SampleTabPanel('tab' + this.tabPanels.length, {
label: 'Éditions sans œuvre',
content: [contenu]
}));
}
};
IndexedDialog.prototype.initializeEditionsIncompletes = function(editions_incompletes) {
if (Object.keys(editions_incompletes).length >= 1) {
let pl = (Object.keys(editions_incompletes).length >= 2);
const entete =
"<p>Certains <b>champs relatifs aux éditions</b> devraient probablement être remplis dans "
+ (pl ? "les documents suivants" : "le document suivant") + ".</p>\n";
let desc = "";
for (let item_id in editions_incompletes) {
const item = editions_incompletes[item_id][0];
const manquants = editions_incompletes[item_id][1];
desc += `<div>${lienhtml_ws(item)} ${lienhtml_wd_edit(item_id)} : `;
manquants.forEach((x, idx) => {
desc += (idx > 0 ? ", " : "") + wdlink(x[0], true); // `${x[0]} (${x[1]}), `;
});
desc += ".</div>\n";
}
this.tabPanels.push(new SampleTabPanel('tab' + this.tabPanels.length, {
label: 'Champs manquants',
content: [$(`${entete}${desc}`)]
}));
}
};
IndexedDialog.prototype.initializeFacsimilesManquants = function(facsimiles_manquants) {
if(Object.keys(facsimiles_manquants).length >= 1) {
let pl = (Object.keys(facsimiles_manquants).length >= 2);
let entete = (pl ? "" + Object.keys(facsimiles_manquants).length + " documents, de type édition, sont reliés" : "Le document suivant est relié")
+ " à une page de Wikisource, "
+ `mais <b>la propriété ${wdlink(p_facsimile, true)} n'est pas renseignée</b> :`
+ " <b>attention</b> en cliquant sur « mettre à jour Wikidata », ce module est expérimental et il est indispensable "
+ "de vérifier sur Wikidata ce qui a été fait.";
let desc =
$("<table>", {"style": "border-collapse: collapse"})
.append($("<thead>").append($("<th>").text("Wikisource"))
.append($("<th>").text("Fac-similé trouvé"))
.append($("<th>").text("Action")));
let tdstyle = "border-top: 1px solid #a2a9b1; border-bottom: 1px solid #a2a9b1";
let tbody = $("<tbody>");
desc.append(tbody);
let countFS = 0;
for(let item_id in facsimiles_manquants) {
if(countFS >= maxCountFS) {
entete += " Seules " + maxCountFS + " requêtes sont envoyées."
break;
}
let item = facsimiles_manquants[item_id][0];
let div_id = "fsmanquant_" + countFS;
// desc += `<div style="margin-top: 0.5em;" id="${div_id}">${lienhtml_ws(item)} ${lienhtml_wd_edit(item_id)}</div>`;
desc.append($("<tr>", {id: div_id})
.append($("<td>", {style: tdstyle}).html(lienhtml_ws(item) + " " + lienhtml_wd_edit(item_id))));
countFS += 1;
}
this.tabPanels.push(new SampleTabPanel('tab' + this.tabPanels.length, {
label: 'Fac-similé manquant',
content: [$("<div>").append($("<p>").html(entete)).append(desc)]
}));
countFS = 0;
let tab_fsids = {};
// Pour ne pas trop charger le serveur je mets un intervalle entre deux requêtes
const intervalle = 200;
const fsmanquants_count = Object.keys(facsimiles_manquants).length;
let fsmanquants_idx = 0;
const intervalid = setInterval(function(x) {
if(fsmanquants_idx >= fsmanquants_count) {
clearInterval(intervalid);
return;
}
let item_id = Object.keys(facsimiles_manquants)[fsmanquants_idx];
fsmanquants_idx += 1;
if(countFS >= maxCountFS) {
clearInterval(intervalid);
return;
}
let item = facsimiles_manquants[item_id][0];
let div_id = "fsmanquant_" + countFS; // même définition que ci-dessus
const wsname = item["wsname"];
// desc += `<div style="margin-top: 0.5em;" id="${div_id}">${lienhtml_ws(item)} ${lienhtml_wd_edit(item_id)}</div>`;
// On essaie de récupérer la valeur du fac-similé
if(wsname) {
tab_fsids[wsname] = div_id;
let facsimiles = [];
// Peut-être plus simple : récupérer mw.config.values.prpSourceIndexPage
getAjax(`${WIKIDATAFY_WIKISOURCE_URL}/api/rest_v1/page/html/${encodeURIComponent(wsname)}`)
.then(function(html) {
// On récupère le ou les fac-similés dans le code HTML de la page
let elem = document.createElement("html");
elem.innerHTML = html;
let prpPagesOutput = elem.getElementsByClassName("prp-pages-output");
for(let elem of prpPagesOutput) {
data = JSON.parse(elem.getAttribute("data-mw"));
if(data.attrs && data.attrs.index && ! facsimiles.includes(data.attrs.index))
facsimiles.push(data.attrs.index);
};
if(facsimiles.length > 0)
return getAjax("https://www.wikidata.org/w/rest.php/wikibase/v0/entities/items/" + item_id);
else
return null;
})
.then(function(wd_info) {
let fsedit_fs = $("<td>", {style: tdstyle});
let fsedit_action = $("<td>", {style: tdstyle});
// On vérifie que le fac-similé n'est pas déjà renseigné dans Wikidata
// (au cas où il ait été modifié depuis l'appel SPARQL)
if(wd_info && wd_info.statements && wd_info.statements.P996
&& wd_info.statements.P996.length > 0) {
let wd_facsimiles = wd_info.statements.P996.map(x => x.value.content);
if(wd_facsimiles.sort().join("/") == facsimiles.sort().join("/"))
fsedit_fs.html("Le fac-similé est déjà renseigné sur Wikidata");
else
fsedit_fs.html("Le fac-similé est déjà renseigné sur Wikidata avec une valeur différente.");
}
else {
if(facsimiles.length > 0) {
let btneditid = item_id +"_editbtn";
let wdeditbtn = $("<input>", {
type: 'button', style: "height:" + g_btn_height,
id: btneditid, value: "Mettre à jour Wikidata"
});
wdeditbtn.on("click", function(e) {
edit_wikidata(item_id, 'P996', facsimiles, btneditid);
});
let html = facsimiles.map(s => lienhtml_ws("Index:" + s))
.join(", ");
fsedit_fs.html(html);
fsedit_action.append(wdeditbtn);
}
else
fsedit_fs.html("Fac-similé non trouvé sur Wikisource");
}
$("#" + tab_fsids[wsname]).append(fsedit_fs)
.append(fsedit_action);
})
.catch(function(error) {
console.error(error);
let fsedit_fs = $("<td>", {style: tdstyle}).text("Impossible de récupérer le fac-similé");
let fsedit_action = $("<td>", {style: tdstyle});
$("#" + tab_fsids[wsname]).append(fsedit_fs)
.append(fsedit_action);
});
}
countFS += 1;
}, intervalle, 42);
console.log("Interval id pour la recherche de fac-similés : " + intervalid);
}
};
IndexedDialog.prototype.initializeAvancementTab = function(items) {
/* Panel comparant l'avancement des éditions dans Wikidata et dans Wikisource */
let tabPanelAvancement = new SampleTabPanel('tab' + this.tabPanels.length, {
label: 'Avancement',
content: [$("<div>Rien à indiquer sur l'état d'avancement pour l'instant.</div>")]
});
let avancement_load = function() {
let first_in_tabavancement = true;
let desc =
$("<table>", {"style": "border-collapse: collapse"})
.append($("<thead>").append($("<th>").text("Wikisource"))
.append($("<th>").text("Avancement trouvé"))
.append($("<th>").text("Action")));
let tdstyle = "border-top: 1px solid #a2a9b1; border-bottom: 1px solid #a2a9b1";
let tbody = $("<tbody>");
desc.append(tbody);
let get_avancementpaneltr = function(item_id, item, badge) {
let avancementitemid = "tabavancement_" + item_id + "_" + badge;
let tr = $("<tr>", {id: avancementitemid})
.append($("<td>", {style: tdstyle}).html(lienhtml_ws(item) + " " + lienhtml_wd_edit(item_id)));
tbody.append(tr);
if(first_in_tabavancement) {
tabPanelAvancement.$element.text("");
tabPanelAvancement.$element.append(desc);
first_in_tabavancement = false;
}
return tr;
};
let items_withwsname = Object.fromEntries(Object.entries(items).filter(([item_id, item]) => item["wsname"] ? true : false));
let intervalle = 200;
let item_idx = 0;
let count_api_call = 0;
let max_api_call = 100;
const item_count = Object.keys(items_withwsname).length;
const intervalid = setInterval(function(x) {
if(item_idx >= item_count) {
clearInterval(intervalid);
return;
}
let item_id = Object.keys(items_withwsname)[item_idx];
item_idx += 1;
const item = items_withwsname[item_id];
const wsname = item["wsname"];
if(count_api_call >= max_api_call) {
// TODO : rien n'est affiché si l'avancement est correct sur maxCountFS.
tabPanelAvancement.$element.prepend($("<div>").text("Seules "
+ maxCountFS + " requêtes sont envoyées."));
clearInterval(intervalid);
return;
}
count_api_call += 1;
// On essaie de récupérer l'avancement dans la page Wikisource
let api = get_mw_api(); // new mw.Api();
api.get( {
action: "query",
titles: wsname,
prop: "categories"
}).done(function(data) {
if(data.query && data.query.pages) {
let categories = data.query.pages[Object.keys(data.query.pages)[0]].categories;
console.log("Catégories pour la page " + wsname + " : " + categories);
if(!categories)
return;
let avancement = null;
categories.forEach(function(cat) {
if(!cat.title || !cat.title.startsWith("Catégorie:"))
throw "Catégorie inattendue : " + cat;
let categorie = cat.title.substring(10);
if(Avancement.hasQuality(categorie)) {
let badge = Avancement.quality2badge(categorie);
let badge_trouve = false;
let btneditid = null;
let wdeditbtn = null;
let item_autresbadges = [];
if(item["badge"]) {
item["badge"].forEach(function(b) {
const badge_id = url_last_part(b);
if(Avancement.hasBadge(badge_id)) {
if(badge_id == badge)
badge_trouve = true;
else
item_autresbadges.push(badge_id);
}
});
}
if(!badge_trouve) {
const badge = Avancement.quality2badge(categorie);
btneditid = item_id +"_editavancementbtn";
wdeditbtn = $("<input>" , {
type: "button", id: btneditid,
value: "Mettre à jour Wikidata"
});
wdeditbtn.on("click", function(e) {
edit_wikidata(item_id, "badge", badge, btneditid);
});
let avancementtr = get_avancementpaneltr(item_id, item, badge);
let td = $("<td>", { style: tdstyle })
.append("L'avancement est ")
.append($("<img>", {
width: "10px", src: Avancement.quality2image(categorie)
}))
.append(" (")
.append($("<i>").text(categorie))
.append(") dans Wikisource");
if(item_autresbadges.length > 0) {
td.append(" mais vaut ")
.append(item_autresbadges.map(badge_id =>
"<img width=10px src='" + encodeURI(Avancement.badge2image(badge_id)) + "'>"
).join(", "))
.append(" dans Wikidata");
}
td.append($("<br>"))
.append("→ il faudrait poser le badge « ")
.append($("<i>").text(Avancement.quality2badgelib(categorie)))
.append(" » dans Wikidata");
avancementtr.append(td);
let td2 = $("<td>", {style: tdstyle});
if(wdeditbtn)
td2.append(wdeditbtn);
avancementtr.append(td2);
}
}
});
}
});
}, intervalle);
console.log("Intervalle pour la recherche de l'état d'avancement : " + intervalid);
}
let avancement_load_btn = $("<input>", {
type: "button",
value: "Charger l'état d'avancement"
});
avancement_load_btn.on("click", avancement_load);
tabPanelAvancement.$element.append(avancement_load_btn);
this.tabPanels.push(tabPanelAvancement);
};
IndexedDialog.prototype.initializeDivers = function(items, edition2oeuvre, oeuvre2editions) {
msg = "";
for (oeuvre_id in oeuvre2editions) {
const editions = oeuvre2editions[oeuvre_id];
let malreliees = [];
let editions_inconnues = [];
editions.forEach(edition => {
// On vérifie que l'édition a bien été renvoyée par la requête SPARQL,
// car sinon c'est normal qu'on ne l'ait pas
if(edition in items) {
if(!edition in edition2oeuvre)
editions_inconnues.push(edition);
else if(!edition2oeuvre[edition] || !edition2oeuvre[edition].includes(oeuvre_id))
malreliees.push(edition);
}
});
if (editions_inconnues.length > 0) {
const pluriel = editions_inconnues.length >= 2 ? "s" : "";
msg += `<li>L'œuvre ${wdlink(oeuvre_id)} est reliée `
+ (pluriel ? "aux éditions " : "à l'édition ")
+ editions_inconnues.map(item => wdlink(item)).join(", ")
+ ` par la propriété ${wdlink("P747", true)}, mais `
+ (pluriel ? "ces dernières n'ont pas été récupérées"
: "cette dernière n'a pas été récupérée")
+ ".</li>";
}
if (malreliees.length > 0) {
const pluriel = malreliees.length >= 2 ? "s" : "";
msg += `<li>L'œuvre ${wdlink(oeuvre_id)} est reliée `
+ (pluriel ? "aux éditions " : "à l'édition ")
+ malreliees.map(item => wdlink(item)).join(", ")
+ ` par la propriété ${wdlink("P747", true)}, mais `
+ (pluriel ? "celles-ci ne sont pas reliées " : "cette dernière n'est pas reliée ")
+ `à l'œuvre par la propriété ${wdlink("P629", true)}.</li>`;
}
};
};
IndexedDialog.prototype.initialize = function()
{
let [items, editions_sans_oeuvre,
oeuvre2editions, edition2oeuvre, editions_incompletes, facsimiles_manquants] = this.args;
IndexedDialog.super.prototype.initialize.apply(this/*, arguments*/);
this.indexLayout = new OO.ui.IndexLayout();
this.tabPanels = [];
// Message général
let msg = "<p>Cette boîte de dialogue recense des insuffisances constatées dans les fiches de Wikidata "
+ "consacrées aux ouvrages de cet auteur. Si aucun onglet n'apparaît à droite de celui-ci, "
+ "aucune insuffisance n'a été constatée.</p>";
this.tabPanels.push(new SampleTabPanel('tab' + this.tabPanels.length, {
label: 'Résultats',
content: [$(msg)]
}));
// Champs optionnels, selon les problèmes rencontrés dans les éléments
// Wikidata
this.initializeEditionsSansOeuvre(editions_sans_oeuvre);
this.initializeEditionsIncompletes(editions_incompletes);
this.initializeFacsimilesManquants(facsimiles_manquants);
this.initializeAvancementTab(items);
this.initializeDivers(items, edition2oeuvre, oeuvre2editions);
if (msg.length > 0) {
// this.content.$element.append("<p>Analyse du lien entre les œuvres et les éditions sur Wikidata :</p><ul>" + msg + "</ul></p>");
this.tabPanels.push(new SampleTabPanel('tab' + this.tabPanels.length, {
label: 'Analyse',
content: [$(msg)]
}));
}
this.indexLayout.addTabPanels(this.tabPanels);
this.$body.append(this.indexLayout.$element);
};
IndexedDialog.prototype.getActionProcess = function (action) {
if (action) {
return new OO.ui.Process(function () {
this.close({
action: action
});
}, this);
}
return IndexedDialog.super.prototype.getActionProcess.call(this, action);
};
IndexedDialog.prototype.getTeardownProcess = function (data) {
return IndexedDialog.super.prototype.getTeardownProcess.call(this, data)
.next(function () {
this.indexLayout.resetScroll();
}, this);
};
function display_resultats(items, editions_sans_oeuvre,
oeuvre2editions, edition2oeuvre, editions_incompletes, facsimiles_manquants) {
let undialogue = new IndexedDialog([items, editions_sans_oeuvre,
oeuvre2editions, edition2oeuvre, editions_incompletes, facsimiles_manquants],
{ size: 'medium' });
// Create and append a window manager, which opens and closes the window.
let idWM = "auteur-window-manager";
if($("#" + idWM).length)
$("#" + idWM).remove();
let unwindowManager = new OO.ui.WindowManager({ id: idWM});
$(document.body).append(unwindowManager.$element);
unwindowManager.addWindows([undialogue]);
// Open the window
unwindowManager.openWindow(undialogue);
return;
}
function get_oeuvres_auteur(itemAuteur, callback) {
// Récupère la liste des oeuvres de Wikidata et appelle une callback avec le résultat
const query = `
SELECT DISTINCT
?item ?itemLabel ?nature ?natureLabel ?formeDeLOeuvreLabel
?facsimile ?langue
?datePublication ?yearPublication
?dateFondation ?yearFondation
?datePremiereRepresentation ?yearPremiereRepresentation
?wsname ?badge ?revision
?editionDe (GROUP_CONCAT(?edition) AS ?editions)
WHERE {
{ # Soit l'item est une édition en langue française
# d'une œuvre qui a X pour auteur
?item wdt:${p_langue} wd:${q_francais};
wdt:P629 ( wdt:P50 wd:Q535 ). }
UNION
{ # Si ce n'est pas le cas, l'item doit avoir X directement pour auteur
?item wdt:${p_auteur} wd:${itemAuteur}. }
OPTIONAL { # On récupère les éditions en français de l'item, le cas échéant
?item wdt:P747 ?edition.
?edition wdt:${p_langue} wd:${q_francais}. }
OPTIONAL { # On récupère le lien vers Wikisource-fr, le cas échéant
?wsLien schema:isPartOf <${WIKIDATAFY_WIKISOURCE_URL}/>;
schema:inLanguage "fr";
schema:name ?wsname;
schema:about ?item.
OPTIONAL { ?wsLien wikibase:badge ?badge. }
}
# Et puis les autres propriétés intéressantes
?item wdt:P31 ?nature. # nature de l'élément
?item schema:version ?revision .
OPTIONAL { ?item wdt:${p_edition_de} ?editionDe. }
OPTIONAL { ?item wdt:${p_langue} ?langue. }
OPTIONAL { ?item wdt:P7937 ?formeDeLOeuvre. }
OPTIONAL { ?item wdt:P996 ?facsimile. }
OPTIONAL { ?item wdt:P577 ?datePublication. }
BIND(YEAR(?datePublication) AS ?yearPublication)
OPTIONAL { ?item wdt:P571 ?dateFondation. }
BIND(YEAR(?dateFondation) AS ?yearFondation)
OPTIONAL { ?item wdt:P1191 ?datePremiereRepresentation. }
BIND(YEAR(?datePremiereRepresentation) AS ?yearPremiereRepresentation)
SERVICE wikibase:label { bd:serviceParam wikibase:language "[AUTO_LANGUAGE],fr,en". }
}
GROUP BY
?item ?itemLabel ?nature ?natureLabel ?formeDeLOeuvreLabel
?facsimile ?langue
?datePublication ?yearPublication
?dateFondation ?yearFondation
?datePremiereRepresentation ?yearPremiereRepresentation
?wsname ?badge ?revision
?editionDe
ORDER BY ?natureLabel ?editions ?editionDe ?formeDeLOeuvreLabel ?yearPublication ?yearFondation ?yearPremiereRepresentation
`;
send_sparql(query, callback);
}
/////////////////////////////////////
// Vérifie l'ensemble des oeuvres d'un auteur
function wdverif_auteur(e) {
e.preventDefault();
try {
let wdid = get_wikidata_id(true);
if(wdid)
get_oeuvres_auteur(wdid, verif_wd_oeuvres_auteur);
else
OO.ui.alert("Apparemment, cette page n'a pas encore été reliée à un élément Wikidata. Utilisez par exemple le gadget WEF: FRBR Edition.");
} catch (exc) {
OO.ui.alert("Erreur lors de la vérification d'un auteur : " + exc);
return;
}
}
function get_page_info() {
// Renvoit les infos trouvées dans la page même, sans appel à Wikidata
let info = {
item_id: mw.config.get("wgWikibaseItemId"),
categories: mw.config.get("wgCategories"),
prpSourceIndexPage: mw.config.get("prpSourceIndexPage")
};
return info;
}
function get_page_ws_data() {
// Renvoit les informations compris dans l'élément HTML div#ws_data
let res = {
"title": $("#ws-data .ws-title").text(),
"author": $("#ws-data .ws-author").text(),
"translator": $("#ws-data .ws-translator").text(),
"publisher": $("#ws-data .ws-publisher").text(),
"year": $("#ws-data .ws-year").text(),
"progress": $("#ws-data .ws-progress").text(),
"scan": $("#ws-data .ws-scan").text(),
"cover": $("#ws-data .ws-cover").text(),
"pages": $("#ws-data .ws-pages").text()
};
return res;
}
class ApiError {
constructor(json_error) {
this.json_error = json_error;
}
get_message() {
let json_error = this.json_error;
if(json_error.code == "no-such-entity")
return("Entité inconnue : " + json_error.id);
else if(json_error.info)
return(json_error.info);
else
return("Erreur inconnue : " + JSON.stringify(json.error));
}
}
function display_erreurs(erreurs_elem) {
let err_style = "margin: 1em 1em 1em 1em; padding: 0em 0em 0.5em; border: 2px solid red; font-weight bold;";
let div_id = "wd_erreur_msg";
if($("#" + div_id).length > 0)
$("#" + div_id).remove();
let jsclose = "$('#" + div_id + "').hide()";
$("#bodyContent").prepend($("<div>", { "id": div_id, style: err_style })
.append($("<a>", { "style": "float: right; border-left: 1px solid gray; border-bottom: 1px solid gray; margin: 0px 0px 5px 5px; padding: 3px 3px 3px 3px; font-size: smaller;",
"href": "#",
"onclick": jsclose })
.text("Fermer ce message"))
.append(erreurs_elem));
}
class Item {
constructor(item_id, data) {
this.id = item_id;
this.data = data;
}
get_label() {
if(this.data.labels.fr)
return this.data.labels.fr.value;
return null;
}
get(property_id) {
return this.data.claims[property_id];
}
// Renvoit la valeur unique
get_value(property_id) {
const prop = this.data.claims[property_id];
if(!prop)
return null;
else if(prop.length >= 2)
throw new Error("Plusieurs valeurs pour " + property_id + " : " + JSON.stringify(prop));
else
return snak_value(prop[0]);
}
get_values(property_id) {
const prop = this.data.claims[property_id];
if(!prop)
return null;
else
return prop.map(elem => snak_value(elem.mainsnak));
}
get_auteur() { return this.get_values(p_auteur) }
get_traducteur() { return this.get_values(p_traducteur) }
get_editeur() { return this.get_values(p_editeur) }
get_facsimiles() { return this.get_values(p_facsimile) }
get_langues() { return this.get_values(p_langue) }
get_nature() { return this.get_values(p_nature) }
get_editionOuTraductionDe() { return this.get_values(p_edition_de) }
get_editions() { return this.get_values(p_edition) }
get_titre() { return this.get_values(p_titre) }
is_edition() {
let natures = this.get_nature();
if(!natures)
return false;
let res = false;
natures.forEach(nature => {
if(nature == q_edition)
res = true;
});
return res;
}
/* Vérifier les données et émet des alertes en cas de problème */
check_donnees(page_info, page_ws_data, dans_lancement=false) {
let erreurs = [];
if(this.get_nature() == null)
erreurs.push("Il manque la nature (propriété P31).");
if(this.is_edition()) {
this.check_edition(page_info, page_ws_data, erreurs);
}
let url = "https://www.wikidata.org/wiki/" + this.id;
let divacceswd = ($("<div>", { style: "text-align: center" })
.append($("<a>", { "href": url, target: "_blank" })
.text("⇒ " + i18n("Accédez à l'élément Wikidata"))));
if(this.is_edition()) {
if($("#p-wef").length >= 1)
divacceswd.append(" ou utilisez le gadget WEF: FRBR Edition");
else {
let wefbtn = $("<a>", { href: "#" })
.text(i18n("chargez le gadget WEF"));
wefbtn.on("click", function(e) {
mw.loader.load('https://ru.wikipedia.org/w/index.php?title=MediaWiki:WEF AllEditors.js&action=raw&ctype=text/javascript');
});
divacceswd.append(" " + i18n("or") + " ")
.append(wefbtn)
.append(" " + i18n("puis cliquez sur WEF: FRBR Edition pour éditer l'élément Wikidata sans sortir de Wikisource"));
}
}
if(erreurs.length >= 1) {
let msg = $("<ul>");
erreurs.forEach(erreur => {
if(typeof(erreur) == "string")
msg.append($("<li>").text(erreur));
else
msg.append($("<li>").append(erreur));
});
msg.append(divacceswd);
display_erreurs(msg);
}
else {
if(!dans_lancement) {
let msg = $("<div>").text("Aucun problème particulier n'a été détecté dans l'élément Wikidata. N'hésitez toutefois pas à le vérifier directement.");
msg.append(divacceswd);
display_erreurs(msg);
}
}
}
/* Vérifier les données pour une édition*/
check_edition(page_info, page_ws_data, erreurs) {
let oeuvre = this.get_values(p_edition_de);
if(!oeuvre || oeuvre.length == 0)
erreurs.push(i18n("Il manque une référence à l'œuvre correspondant à cette édition (propriété {1} : « {2} »)",
[p_edition_de, i18n(wdproperties[p_edition_de])]));
// erreurs.push("Il manque une référence à l'œuvre correspondant à cette édition (propriété " + p_edition_de
// + " : « " + wdproperties[p_edition_de] + " »)");
this.check_langue(erreurs);
let cur_quality = get_quality_in_page();
if(cur_quality) {
if(! this.data.sitelinks || this.data.sitelinks.frwikisource == 0)
erreurs.push("L'élément Wikidata n'a pas de liens vers des sites Wikimédia.");
else {
let badges = this.data.sitelinks.frwikisource.badges;
if(badges == null || badges.length == 0) {
let msg = $("<p>").append("L'avancement n'est pas indiqué dans la fiche Wikidata. Ajoutez le badge ")
.append($("<img>", { width: "10px", src: Avancement.quality2image(cur_quality) }))
.append(" (")
.append($("<i>").text(Avancement.quality2badgelib(cur_quality)))
.append(").");
const badge = Avancement.quality2badge(cur_quality);
const wdeditbtn = this.make_wdedit_btn("badge", badge);
msg.append($("<span>", { style: "margin-left: 0.5em"})
.text(" "))
.append(wdeditbtn);
erreurs.push(msg);
}
else {
badges.forEach(badge => {
if(Avancement.hasBadge(badge) && badge != Avancement.quality2badge(cur_quality)) {
const badgenew = Avancement.quality2badge(cur_quality);
const wdeditbtn = this.make_wdedit_btn("badge", badgenew);
let msg = $("<p>").append("L'avancement indiqué dans la fiche Wikidata (« "
+ Avancement.badge2lib(badge) + " ») ne correspond pas "
+ " à la qualité indiquée ici (« " + cur_quality + " »). "
+ "Corriger l'avancement dans Wikidata en ")
.append($("<img>", { width: "10px", src: Avancement.quality2image(cur_quality) }))
.append(" (")
.append($("<i>").text(Avancement.badge2lib(badgenew)))
.append(").");
msg.append($("<span>", { style: "margin-left: 0.5em"})
.text(" "))
.append(wdeditbtn);
erreurs.push(msg);
}
});
}
}
}
this.check_facsimile(page_info, erreurs);
// Titre
let page_titre = page_ws_data["title"];
let wd_titre = this.get_titre();
if(!wd_titre || wd_titre.length == 0) {
if(page_titre) {
let msg = $("<p>").append("Le titre n'est pas renseigné dans Wikidata. "
+ "Rajouter le titre « " + page_titre + " » ? ");
const wdeditbtn = this.make_wdedit_btn(p_titre, page_titre);
msg.append($("<span>", { style: "margin-left: 0.5em"})
.text(" "))
.append(wdeditbtn);
erreurs.push(msg);
}
else {
let msg = "Le titre n'est pas renseigné dans Wikidata, "
+ "mais je ne l'ai pas trouvé non plus dans cette page.";
erreurs.push(msg);
}
}
// cf. https://fr.wikisource.org/wiki/Wikisource:Scriptorium/Septembre_2023#Wikidata_et_Wikisource
// else if(page_titre && canonique(page_titre) != canonique(wd_titre[0])) {
// let msg = "Le titre dans Wikidata est « " + wd_titre[0] + " », "
// + "mais j'ai trouvé dans cette page le titre suivant : « " + page_titre + " »";
// erreurs.push(msg);
// }
// Auteur, traducteur, éditeur
let page_auteur = page_ws_data["author"];
let wd_auteur = this.get_auteur();
if(page_auteur && (!wd_auteur || wd_auteur.length == 0))
erreurs.push("L'auteur « " + page_auteur + " » n'est pas mentionné dans Wikidata.");
let page_traducteur = page_ws_data["translator"];
let wd_traducteur = this.get_traducteur();
if(page_traducteur && (!wd_traducteur || wd_traducteur.length == 0))
erreurs.push("Le traducteur « " + page_traducteur + " » n'est pas mentionné dans Wikidata.");
// Pas forcément utile, surtout dans le cas où un item Wikidata est créé pour chaque élément d'un recueil
// let page_editeur = page_ws_data["publisher"];
// let wd_editeur = this.get_editeur();
// if(page_editeur && (!wd_editeur || wd_editeur.length == 0))
// erreurs.push("L'éditeur « " + page_editeur + " » n'est pas mentionné dans Wikidata.");
}
check_langue(erreurs) {
// TODO : handle other languages?
if(WIKIDATAFY_WIKISOURCE_URL != 'https://fr.wikisource.org')
return;
let langues = this.get_langues();
if(!langues || langues.filter(function(n) { return langues_fr_wdids.indexOf(n) !== -1; }).length == 0) {
let msg = $("<p>").append("Rajouter le français comme langue du document ? ");
const wdeditbtn = this.make_wdedit_btn(p_langue, q_francais);
msg.append($("<span>", { style: "margin-left: 0.5em"})
.text(" "))
.append(wdeditbtn);
erreurs.push(msg);
}
}
check_facsimile(page_info, erreurs) {
const prpSourceIndexPage = page_info["prpSourceIndexPage"];
if(prpSourceIndexPage) {
// Internationalisation :
// let main_index = prpSourceIndexPage.substr("Livre:".length);
let main_index = prpSourceIndexPage.substr(prpSourceIndexPage.indexOf(":")+1);
let facsimiles = this.get_facsimiles();
if(!facsimiles || facsimiles.length == 0) {
let msg = $("<p>").append("Rajouter le fac-similé "
+ prpSourceIndexPage
+ " (vérifier que la page transclut bien ce fac-similé et lui seul) ?");
const wdeditbtn = this.make_wdedit_btn(p_facsimile, main_index);
msg.append($("<span>", { style: "margin-left: 0.5em"})
.text(" "))
.append(wdeditbtn);
erreurs.push(msg);
}
}
}
// Crée un bouton d'édition de Wikidata pour une catégorie de donnée
// (qui doit être reconnue par edit_wikidata().
make_wdedit_btn(typ, val) {
const btneditid = ("editbtn_" + Math.random()).replace(".", "");
const wdeditbtn = $("<input>" , {
type: "button", id: btneditid,
style: "margin-left: 1em",
value: "Mettre à jour Wikidata"
});
const item_id = this.id;
wdeditbtn.on("click", function(e) {
edit_wikidata(item_id, typ, val, btneditid);
});
return wdeditbtn;
}
}
/////////////////////////////////////////
// Vérifie une page (transclusion)
function wdverif_page(e=null, dans_lancement=false) {
if(e)
e.preventDefault();
try {
let msgs = ["Résultat"];
let page_info = get_page_info();
let page_ws_data = get_page_ws_data();
let item_id = get_wikidata_id();
if(!item_id) {
display_erreurs([$("<p>").text("Apparemment, cette page n'a pas encore été reliée à un élément Wikidata. Utilisez par exemple le gadget WEF: FRBR Edition.")]);
return;
}
getAjax(WD_API_URL, {
data: { action: "wbgetentities", ids: encodeURIComponent(item_id),
format: "json", origin: WIKIDATAFY_WIKISOURCE_URL }
}).then(function(json) {
if(json.error)
throw new ApiError(json.error);
let item = new Item(item_id, json.entities[item_id]);
item.check_donnees(page_info, page_ws_data, dans_lancement);
}).fail(function(exc) {
if(exc instanceof ApiError)
OO.ui.alert(exc.get_message());
else {
msg = typeof(exc);
OO.ui.alert("Erreur lors de l'appel de wbgetentities : " + msg);
}
})
} catch (exc) {
if(exc instanceof ApiError)
OO.ui.alert(exc.get_message());
else
OO.ui.alert("Erreur lors de la vérification d'une page : " + exc);
return;
}
}
/////////////////////////////////////////
// Insère la liste des oeuvres d'un auteur
function auteur(e) {
e.preventDefault();
try {
const editbox = $("#wpTextbox1");
if (!editbox || !editbox.length) {
OO.ui.alert("Cette page ne contient pas de champ d'édition");
return;
}
const wdid = get_wikidata_id;
if(wdid) {
get_oeuvres_auteur(wdid, display_oeuvres);
};
} catch (exc) {
OO.ui.alert("Erreur lors de l'insertion des œuvres d'un auteur : " + exc);
return;
}
}
function addCommande(libelle, id, desc, fn) {
mw.util.addPortletLink("p-cactions",
"#",
libelle,
id,
desc);
$('#' + id).on('click', function (e) {
fn(e);
});
}
MAIN_NS = 0;
AUTEUR_NS = 102;
// AUTEUR_NS_TALK = 103;
$(function ($) {
WIKIDATAFY_WIKISOURCE_URL = `https://${mw.config.get('wgServerName')}`;
const editbox = $("#wpTextbox1");
const ns = mw.config.get('wgNamespaceNumber');
const script_url = getScriptURL();
// Désactivation de la vérification automatique pour une vérification depuis mobile
// automatique = (script_url != null && script_url.match(/(fr\.m\.wikisource|[\&\?]auto=non(\&|\b))/) ? false : true);
automatique = (location.href.match(/fr\.m\.wikisource/)
|| (script_url != null
&& script_url.match(/[\&\?]auto=non(\&|\b)/))) ? false : true;
if(ns == AUTEUR_NS) {
// Pas sûr que ce soit vraiment utile
// addCommande("(WDfy) Œuvres de l’auteur",
// "sd-auteur",
// "Œuvres de l’auteur",
// auteur);
addCommande("(WDfy) Cohérence des données",
"sd-wdverif",
"Vérifier la qualité des informations dans Wikidata",
wdverif_auteur);
}
else if(ns == MAIN_NS) {
addCommande("(WDfy) Vérifier l'élément Wikidata",
"sd-coherence-page",
"Élément Wikidata d'une transclusion",
wdverif_page);
if(automatique) {
wdverif_page(null, true);
}
}
})
})