From 4b6300daffdd6e22340ae46c20bcdddab3e38bfe Mon Sep 17 00:00:00 2001 From: Antonin Delpeuch Date: Fri, 31 May 2019 09:09:24 +0100 Subject: [PATCH 1/2] Update available language codes in Wikidata extension. Closes #1933. --- .../wikidata/module/scripts/langsuggest.js | 57 ++++++++++++------- 1 file changed, 37 insertions(+), 20 deletions(-) diff --git a/extensions/wikidata/module/scripts/langsuggest.js b/extensions/wikidata/module/scripts/langsuggest.js index b8a1061ba..d830fd095 100644 --- a/extensions/wikidata/module/scripts/langsuggest.js +++ b/extensions/wikidata/module/scripts/langsuggest.js @@ -3,28 +3,45 @@ * LANGUAGE SUGGEST * ********************/ -// This list was manually copied from https://www.wikidata.org/w/api.php?action=paraminfo&modules=wbsetlabel on 2017-10-06 +// This list was manually copied from Wikidata on 2019-05-31. It can be updated with the following command: +// +// curl "https://www.wikidata.org/w/api.php?action=query&meta=wbcontentlanguages&wbclcontext=monolingualtext&format=json&formatversion=2" | jq ".query.wbcontentlanguages[].code" | tr '\n' ',' +// +// See https://stackoverflow.com/questions/46507037/how-to-get-all-allowed-languages-for-wikidata/46562061#46562061 // I don't think it is worth making every OpenRefine client perform this query at every startup, because it typically does // not change very often. -// See https://stackoverflow.com/questions/46507037/how-to-get-all-allowed-languages-for-wikidata/46562061#46562061 -WIKIDATA_LANGUAGES = [ "aa", "ab", "ace", "ady", "ady-cyrl", "aeb", "aeb-arab", "aeb-latn", "af", "ak", "aln", "als", "am", "an", "ang", "anp", "ar", "arc", "arn", "arq", "ary", "arz", -"as", "ase", "ast", "atj", "av", "avk", "awa", "ay", "az", "azb", "ba", "ban", "bar", "bat-smg", "bbc", "bbc-latn", "bcc", "bcl", "be", "be-tarask", "be-x-old", "bg", "bgn", "bh", "bho", -"bi", "bjn", "bm", "bn", "bo", "bpy", "bqi", "br", "brh", "bs", "bto", "bug", "bxr", "ca", "cbk-zam", "cdo", "ce", "ceb", "ch", "cho", "chr", "chy", "ckb", "co", "cps", "cr", "crh", -"crh-cyrl", "crh-latn", "cs", "csb", "cu", "cv", "cy", "da", "de", "de-at", "de-ch", "de-formal", "din", "diq", "dsb", "dtp", "dty", "dv", "dz", "ee", "egl", "el", "eml", "en", "en-ca", -"en-gb", "eo", "es", "et", "eu", "ext", "fa", "ff", "fi", "fit", "fiu-vro", "fj", "fo", "fr", "frc", "frp", "frr", "fur", "fy", "ga", "gag", "gan", "gan-hans", "gan-hant", "gd", "gl", -"glk", "gn", "gom", "gom-deva", "gom-latn", "gor", "got", "grc", "gsw", "gu", "gv", "ha", "hak", "haw", "he", "hi", "hif", "hif-latn", "hil", "ho", "hr", "hrx", "hsb", "ht", "hu", "hy", -"hz", "ia", "id", "ie", "ig", "ii", "ik", "ike-cans", "ike-latn", "ilo", "inh", "io", "is", "it", "iu", "ja", "jam", "jbo", "jut", "jv", "ka", "kaa", "kab", "kbd", "kbd-cyrl", "kbp", -"kea", "kg", "khw", "ki", "kiu", "kj", "kk", "kk-arab", "kk-cn", "kk-cyrl", "kk-kz", "kk-latn", "kk-tr", "kl", "km", "kn", "ko", "ko-kp", "koi", "kr", "krc", "kri", "krj", "krl", "ks", -"ks-arab", "ks-deva", "ksh", "ku", "ku-arab", "ku-latn", "kv", "kw", "ky", "la", "lad", "lb", "lbe", "lez", "lfn", "lg", "li", "lij", "liv", "lki", "lmo", "ln", "lo", "loz", "lrc", "lt", -"ltg", "lus", "luz", "lv", "lzh", "lzz", "mai", "map-bms", "mdf", "mg", "mh", "mhr", "mi", "min", "mk", "ml", "mn", "mo", "mr", "mrj", "ms", "mt", "mus", "mwl", "my", "myv", "mzn", "na", -"nah", "nan", "nap", "nb", "nds", "nds-nl", "ne", "new", "ng", "niu", "nl", "nl-informal", "nn", "no", "nod", "nov", "nrm", "nso", "nv", "ny", "nys", "oc", "olo", "om", "or", "os", "ota", -"pa", "pag", "pam", "pap", "pcd", "pdc", "pdt", "pfl", "pi", "pih", "pl", "pms", "pnb", "pnt", "prg", "ps", "pt", "pt-br", "qu", "qug", "rgn", "rif", "rm", "rmy", "rn", "ro", "roa-rup", -"roa-tara", "ru", "rue", "rup", "ruq", "ruq-cyrl", "ruq-latn", "rw", "rwr", "sa", "sah", "sat", "sc", "scn", "sco", "sd", "sdc", "sdh", "se", "sei", "ses", "sg", "sgs", "sh", "shi", -"shi-latn", "shi-tfng", "shn", "si", "simple", "sje", "sk", "skr", "skr-arab", "sl", "sli", "sm", "sma", "smj", "sn", "so", "sq", "sr", "sr-ec", "sr-el", "srn", "srq", "ss", "st", "stq", -"su", "sv", "sw", "szl", "ta", "tay", "tcy", "te", "tet", "tg", "tg-cyrl", "tg-latn", "th", "ti", "tk", "tl", "tly", "tn", "to", "tokipona", "tpi", "tr", "tru", "ts", "tt", "tt-cyrl", -"tt-latn", "tum", "tw", "ty", "tyv", "tzm", "udm", "ug", "ug-arab", "ug-latn", "uk", "ur", "uz", "uz-cyrl", "uz-latn", "ve", "vec", "vep", "vi", "vls", "vmf", "vo", "vot", "vro", "wa", -"war", "wo", "wuu", "xal", "xh", "xmf", "yi", "yo", "yue", "za", "zea", "zh", "zh-classical", "zh-cn", "zh-hans", "zh-hant", "zh-hk", "zh-min-nan", "zh-mo", "zh-my", "zh-sg", "zh-tw", -"zh-yue", "zu" ] +// +// This is the list of language codes accepted for monolingualtext values. The language codes for terms are more restrictive. +// TODO: in the future, store different lists for term languages and monolingual text languages. +WIKIDATA_LANGUAGES = [ +"aa","ab","abs","ace","ady","ady-cyrl","aeb","aeb-arab","aeb-latn","af","ak","aln","als","am","an","ang","anp", +"ar","arc","arn","arq","ary","arz","as","ase","ast","atj","av","avk","awa","ay","az","azb","ba","ban","bar", +"bbc","bbc-latn","bcc","bcl","be","be-tarask","bg","bgn","bh","bho","bi","bjn","bm","bn","bo","bpy","bqi","br", +"brh","bs","btm","bto","bug","bxr","ca","cbk-zam","cdo","ce","ceb","ch","cho","chr","chy","ckb","co","cps","cr", +"crh","crh-cyrl","crh-latn","cs","csb","cu","cv","cy","da","de","de-at","de-ch","din","diq","dsb","dtp","dty", +"dv","dz","ee","egl","el","eml","en","en-ca","en-gb","eo","es","es-419","et","eu","ext","fa","ff","fi","fit", +"fj","fo","fr","frc","frp","frr","fur","fy","ga","gag","gan","gan-hans","gan-hant","gcr","gd","gl","glk","gn", +"gom","gom-deva","gom-latn","gor","got","grc","gsw","gu","gv","ha","hak","haw","he","hi","hif","hif-latn","hil", +"ho","hr","hrx","hsb","ht","hu","hy","hyw","hz","ia","id","ie","ig","ii","ik","ike-cans","ike-latn","ilo","inh", +"io","is","it","iu","ja","jam","jbo","jut","jv","ka","kaa","kab","kbd","kbd-cyrl","kbp","kea","kg","khw","ki", +"kiu","kj","kjp","kk","kk-arab","kk-cn","kk-cyrl","kk-kz","kk-latn","kk-tr","kl","km","kn","ko","ko-kp","koi", +"kr","krc","kri","krj","krl","ks","ks-arab","ks-deva","ksh","ku","ku-arab","ku-latn","kum","kv","kw","ky","la", +"lad","lb","lbe","lez","lfn","lg","li","lij","liv","lki","lmo","ln","lo","loz","lrc","lt","ltg","lus","luz","lv", +"lzh","lzz","mai","map-bms","mdf","mg","mh","mhr","mi","min","mk","ml","mn","mni","mnw","mo","mr","mrj","ms","mt", +"mus","mwl","my","myv","mzn","na","nah","nan","nap","nb","nds","nds-nl","ne","new","ng","niu","nl","nn","no","nod", +"nov","nqo","nrm","nso","nv","ny","nys","oc","olo","om","or","os","ota","pa","pag","pam","pap","pcd","pdc","pdt", +"pfl","pi","pih","pl","pms","pnb","pnt","prg","ps","pt","pt-br","qu","qug","rgn","rif","rm","rmy","rn","ro", +"roa-tara","ru","rue","rup","ruq","ruq-cyrl","ruq-latn","rw","rwr","sa","sah","sat","sc","scn","sco","sd","sdc", +"sdh","se","sei","ses","sg","sgs","sh","shi","shi-latn","shi-tfng","shn","shy-latn","si","sje","sk","skr","skr-arab", +"sl","sli","sm","sma","smj","smn","sms","sn","so","sq","sr","sr-ec","sr-el","srn","srq","ss","st","stq","sty","su", +"sv","sw","szl","ta","tay","tcy","te","tet","tg","tg-cyrl","tg-latn","th","ti","tk","tl","tly","tn","to","tpi","tr", +"tru","ts","tt","tt-cyrl","tt-latn","tum","tw","ty","tyv","tzm","udm","ug","ug-arab","ug-latn","uk","ur","uz","uz-cyrl", +"uz-latn","ve","vec","vep","vi","vls","vmf","vo","vot","vro","wa","war","wo","wuu","xal","xh","xmf","xsy","yi","yo", +"yue","za","zea","zgh","zh","zh-cn","zh-hans","zh-hant","zh-hk","zh-mo","zh-my","zh-sg","zh-tw","zu","und","mis", +"mul","zxx","abe","abq","ami","bnn","brx","chn","cnr","cop","el-cy","ett","eya","fkv","fos","fr-ca","frm","fro", +"fuf","gez","gmy","hai","haz","hbo","kjh","koy","lag","lkt","lld","mid","mnc","moe","non","nr","nxm","ood","otk", +"pjt","ppu","pwn","pyu","quc","qya","rar","shy","sia","sjd","sjk","sjn","sjt","sju","ssf","syc","tlb","trv","tzl", +"uga","umu","uun","xpu","yap","zun" ] $.suggest("langsuggest", { _init: function() { From 03fef3d7b43e3b5461599e2487483a3fd026fbb4 Mon Sep 17 00:00:00 2001 From: Antonin Delpeuch Date: Thu, 6 Jun 2019 21:00:03 +0100 Subject: [PATCH 2/2] Switch to own language code validation in backend, for #1933 --- .../wikidata/schema/WbLanguageConstant.java | 10 +- .../wikidata/utils/LanguageCodeStore.java | 529 ++++++++++++++++++ .../schema/WbLanguageConstantTest.java | 1 + 3 files changed, 537 insertions(+), 3 deletions(-) create mode 100644 extensions/wikidata/src/org/openrefine/wikidata/utils/LanguageCodeStore.java diff --git a/extensions/wikidata/src/org/openrefine/wikidata/schema/WbLanguageConstant.java b/extensions/wikidata/src/org/openrefine/wikidata/schema/WbLanguageConstant.java index a6259b30d..9ce06c629 100644 --- a/extensions/wikidata/src/org/openrefine/wikidata/schema/WbLanguageConstant.java +++ b/extensions/wikidata/src/org/openrefine/wikidata/schema/WbLanguageConstant.java @@ -25,6 +25,7 @@ package org.openrefine.wikidata.schema; import org.apache.commons.lang.Validate; import org.openrefine.wikidata.schema.exceptions.SkipSchemaExpressionException; +import org.openrefine.wikidata.utils.LanguageCodeStore; import org.wikidata.wdtk.datamodel.interfaces.WikimediaLanguageCodes; import com.fasterxml.jackson.annotation.JsonCreator; @@ -59,10 +60,13 @@ public class WbLanguageConstant implements WbExpression { */ public static String normalizeLanguageCode(String lang) { try { - WikimediaLanguageCodes.getLanguageCode(lang); - return WikimediaLanguageCodes.fixLanguageCodeIfDeprecated(lang); + if (LanguageCodeStore.ALLOWED_LANGUAGE_CODES.contains(lang)) { + return WikimediaLanguageCodes.fixLanguageCodeIfDeprecated(lang); + } else { + return null; + } } catch (IllegalArgumentException e) { - return null; + return null; } } diff --git a/extensions/wikidata/src/org/openrefine/wikidata/utils/LanguageCodeStore.java b/extensions/wikidata/src/org/openrefine/wikidata/utils/LanguageCodeStore.java new file mode 100644 index 000000000..168930e92 --- /dev/null +++ b/extensions/wikidata/src/org/openrefine/wikidata/utils/LanguageCodeStore.java @@ -0,0 +1,529 @@ +package org.openrefine.wikidata.utils; + +import java.util.Arrays; +import java.util.Set; +import java.util.stream.Collectors; + +/** + * A store for the allowed language code for terms and monolingual text values + * in Wikidata. + * + * @todo generalize for other Wikibase instances (fetch it dynamically via + * https://stackoverflow.com/questions/46507037/how-to-get-all-allowed-languages-for-wikidata/46562061) + * @todo separate the languages allowed for terms from the ones allowed for monolingual text. + * Currently the list is for monolingual texts (which is larger). + * + * Query to update this list: + * curl "https://www.wikidata.org/w/api.php?action=query&meta=wbcontentlanguages&wbclprop=code&wbclcontext=monolingualtext&format=json" | jq ".query.wbcontentlanguages[].code" | sed -e "s/$/,/" + * + * @author Antonin Delpeuch + * + */ +public class LanguageCodeStore { + public static Set ALLOWED_LANGUAGE_CODES = Arrays.asList( + "aa", + "ab", + "abs", + "ace", + "ady", + "ady-cyrl", + "aeb", + "aeb-arab", + "aeb-latn", + "af", + "ak", + "aln", + "als", + "am", + "an", + "ang", + "anp", + "ar", + "arc", + "arn", + "arq", + "ary", + "arz", + "as", + "ase", + "ast", + "atj", + "av", + "avk", + "awa", + "ay", + "az", + "azb", + "ba", + "ban", + "bar", + "bbc", + "bbc-latn", + "bcc", + "bcl", + "be", + "be-tarask", + "bg", + "bgn", + "bh", + "bho", + "bi", + "bjn", + "bm", + "bn", + "bo", + "bpy", + "bqi", + "br", + "brh", + "bs", + "btm", + "bto", + "bug", + "bxr", + "ca", + "cbk-zam", + "cdo", + "ce", + "ceb", + "ch", + "cho", + "chr", + "chy", + "ckb", + "co", + "cps", + "cr", + "crh", + "crh-cyrl", + "crh-latn", + "cs", + "csb", + "cu", + "cv", + "cy", + "da", + "de", + "de-at", + "de-ch", + "din", + "diq", + "dsb", + "dtp", + "dty", + "dv", + "dz", + "ee", + "egl", + "el", + "eml", + "en", + "en-ca", + "en-gb", + "eo", + "es", + "es-419", + "et", + "eu", + "ext", + "fa", + "ff", + "fi", + "fit", + "fj", + "fo", + "fr", + "frc", + "frp", + "frr", + "fur", + "fy", + "ga", + "gag", + "gan", + "gan-hans", + "gan-hant", + "gcr", + "gd", + "gl", + "glk", + "gn", + "gom", + "gom-deva", + "gom-latn", + "gor", + "got", + "grc", + "gsw", + "gu", + "gv", + "ha", + "hak", + "haw", + "he", + "hi", + "hif", + "hif-latn", + "hil", + "ho", + "hr", + "hrx", + "hsb", + "ht", + "hu", + "hy", + "hyw", + "hz", + "ia", + "id", + "ie", + "ig", + "ii", + "ik", + "ike-cans", + "ike-latn", + "ilo", + "inh", + "io", + "is", + "it", + "iu", + "ja", + "jam", + "jbo", + "jut", + "jv", + "ka", + "kaa", + "kab", + "kbd", + "kbd-cyrl", + "kbp", + "kea", + "kg", + "khw", + "ki", + "kiu", + "kj", + "kjp", + "kk", + "kk-arab", + "kk-cn", + "kk-cyrl", + "kk-kz", + "kk-latn", + "kk-tr", + "kl", + "km", + "kn", + "ko", + "ko-kp", + "koi", + "kr", + "krc", + "kri", + "krj", + "krl", + "ks", + "ks-arab", + "ks-deva", + "ksh", + "ku", + "ku-arab", + "ku-latn", + "kum", + "kv", + "kw", + "ky", + "la", + "lad", + "lb", + "lbe", + "lez", + "lfn", + "lg", + "li", + "lij", + "liv", + "lki", + "lmo", + "ln", + "lo", + "loz", + "lrc", + "lt", + "ltg", + "lus", + "luz", + "lv", + "lzh", + "lzz", + "mai", + "map-bms", + "mdf", + "mg", + "mh", + "mhr", + "mi", + "min", + "mk", + "ml", + "mn", + "mni", + "mnw", + "mo", + "mr", + "mrj", + "ms", + "mt", + "mus", + "mwl", + "my", + "myv", + "mzn", + "na", + "nah", + "nan", + "nap", + "nb", + "nds", + "nds-nl", + "ne", + "new", + "ng", + "niu", + "nl", + "nn", + "no", + "nod", + "nov", + "nqo", + "nrm", + "nso", + "nv", + "ny", + "nys", + "oc", + "olo", + "om", + "or", + "os", + "ota", + "pa", + "pag", + "pam", + "pap", + "pcd", + "pdc", + "pdt", + "pfl", + "pi", + "pih", + "pl", + "pms", + "pnb", + "pnt", + "prg", + "ps", + "pt", + "pt-br", + "qu", + "qug", + "rgn", + "rif", + "rm", + "rmy", + "rn", + "ro", + "roa-tara", + "ru", + "rue", + "rup", + "ruq", + "ruq-cyrl", + "ruq-latn", + "rw", + "rwr", + "sa", + "sah", + "sat", + "sc", + "scn", + "sco", + "sd", + "sdc", + "sdh", + "se", + "sei", + "ses", + "sg", + "sgs", + "sh", + "shi", + "shi-latn", + "shi-tfng", + "shn", + "shy-latn", + "si", + "sje", + "sk", + "skr", + "skr-arab", + "sl", + "sli", + "sm", + "sma", + "smj", + "smn", + "sms", + "sn", + "so", + "sq", + "sr", + "sr-ec", + "sr-el", + "srn", + "srq", + "ss", + "st", + "stq", + "sty", + "su", + "sv", + "sw", + "szl", + "ta", + "tay", + "tcy", + "te", + "tet", + "tg", + "tg-cyrl", + "tg-latn", + "th", + "ti", + "tk", + "tl", + "tly", + "tn", + "to", + "tpi", + "tr", + "tru", + "ts", + "tt", + "tt-cyrl", + "tt-latn", + "tum", + "tw", + "ty", + "tyv", + "tzm", + "udm", + "ug", + "ug-arab", + "ug-latn", + "uk", + "ur", + "uz", + "uz-cyrl", + "uz-latn", + "ve", + "vec", + "vep", + "vi", + "vls", + "vmf", + "vo", + "vot", + "vro", + "wa", + "war", + "wo", + "wuu", + "xal", + "xh", + "xmf", + "xsy", + "yi", + "yo", + "yue", + "za", + "zea", + "zgh", + "zh", + "zh-cn", + "zh-hans", + "zh-hant", + "zh-hk", + "zh-mo", + "zh-my", + "zh-sg", + "zh-tw", + "zu", + "und", + "mis", + "mul", + "zxx", + "abe", + "abq", + "ami", + "bnn", + "brx", + "chn", + "cnr", + "cop", + "el-cy", + "ett", + "eya", + "fkv", + "fos", + "fr-ca", + "frm", + "fro", + "fuf", + "gez", + "gmy", + "hai", + "haz", + "hbo", + "kjh", + "koy", + "lag", + "lkt", + "lld", + "mid", + "mnc", + "moe", + "non", + "nr", + "nxm", + "ood", + "otk", + "pjt", + "ppu", + "pwn", + "pyu", + "quc", + "qya", + "rar", + "shy", + "sia", + "sjd", + "sjk", + "sjn", + "sjt", + "sju", + "ssf", + "syc", + "tlb", + "trv", + "tzl", + "uga", + "umu", + "uun", + "xpu", + "yap", + "zun" + ).stream().collect(Collectors.toSet()); +} diff --git a/extensions/wikidata/tests/src/org/openrefine/wikidata/schema/WbLanguageConstantTest.java b/extensions/wikidata/tests/src/org/openrefine/wikidata/schema/WbLanguageConstantTest.java index eab2d72ed..7248bbb31 100644 --- a/extensions/wikidata/tests/src/org/openrefine/wikidata/schema/WbLanguageConstantTest.java +++ b/extensions/wikidata/tests/src/org/openrefine/wikidata/schema/WbLanguageConstantTest.java @@ -50,6 +50,7 @@ public class WbLanguageConstantTest extends WbExpressionTest { assertEquals("de", WbLanguageConstant.normalizeLanguageCode("de")); assertEquals("nb", WbLanguageConstant.normalizeLanguageCode("no")); assertEquals("nb", WbLanguageConstant.normalizeLanguageCode("nb")); + assertEquals("mul", WbLanguageConstant.normalizeLanguageCode("mul")); assertNull(WbLanguageConstant.normalizeLanguageCode("non-existent language code")); assertNull(WbLanguageConstant.normalizeLanguageCode(null)); }