From 3f7228b204d935f82de397313e58989c738f2f47 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Thu, 10 Nov 2022 10:54:09 +0100 Subject: [PATCH] Enhancements for wikidata imports. --- src/catalogue/models.py | 2 +- .../static/catalogue/wikidata_admin.css | 2 +- .../static/catalogue/wikidata_admin.js | 103 +++++++++++------- src/catalogue/views.py | 1 + src/catalogue/wikidata.py | 7 +- src/catalogue/wikimedia.py | 14 +++ 6 files changed, 89 insertions(+), 40 deletions(-) diff --git a/src/catalogue/models.py b/src/catalogue/models.py index d3766d5a..92b27651 100644 --- a/src/catalogue/models.py +++ b/src/catalogue/models.py @@ -83,7 +83,7 @@ class Author(WikidataModel): year_of_death = WIKIDATA.DATE_OF_DEATH place_of_death = WIKIDATA.PLACE_OF_DEATH gender = WIKIDATA.GENDER - notes = "description" + notes = WikiMedia.append("description") plwiki = "plwiki" photo = WikiMedia.download(WIKIDATA.IMAGE) photo_source = WikiMedia.descriptionurl(WIKIDATA.IMAGE) diff --git a/src/catalogue/static/catalogue/wikidata_admin.css b/src/catalogue/static/catalogue/wikidata_admin.css index 24e27de0..b205523d 100644 --- a/src/catalogue/static/catalogue/wikidata_admin.css +++ b/src/catalogue/static/catalogue/wikidata_admin.css @@ -30,7 +30,7 @@ background-repeat: no-repeat; background-position: -64px 50%; } -#id_wikidata.wikidata-processing { +#id_wikidata.wikidata-processing, .wikidata-hint.wikidata-processing { background-position: 100% 50%; transition: 10s background-position; } diff --git a/src/catalogue/static/catalogue/wikidata_admin.js b/src/catalogue/static/catalogue/wikidata_admin.js index f13510bc..d2af5f70 100644 --- a/src/catalogue/static/catalogue/wikidata_admin.js +++ b/src/catalogue/static/catalogue/wikidata_admin.js @@ -4,6 +4,67 @@ let model = $('body').attr('class').match(/model-([^\s]*)/)[1]; $("#id_wikidata").each(show_wikidata_hints).on('change', show_wikidata_hints); + function add_wikidata_hint($input, val) { + if (val && val != $input.val()) { + let already_set = false; + let el = $(''); + + if (val.wd) { + let iv = $input.val(); + if (val.id) { + if (Array.isArray(iv)) { + if (iv.indexOf(val.id.toString()) != -1) { + already_set = true; + } + } else if (val.id == iv) { + already_set = true; + } + } + + if (!already_set) { + // A representation of a WD Entity. + el.on('click', function() { + $(this).addClass('wikidata-processing'); + set_value_from_wikidata_id( + $input, val.model, val.wd, + () => {$(this).remove();} + ); + }); + el.text(val.label); + } + } else if (val.img) { + // A downloadable remote image. + let img = $(''); + img.attr('src', val.img); + el.append(img); + el.on('click', function() { + set_file_from_url( + $input, val.download, + () => {$(this).remove();} + ); + }); + } else if (val.action == 'append') { + el.on('click', function() { + $input.val( + $input.val() + '\n' + val.value + ); + $(this).remove(); + }); + el.text('+ ' + val.value); + } else { + // A plain literal. + el.on('click', function() { + $input.val(val); + $(this).remove(); + }); + el.text(val); + } + if (!already_set) { + $input.parent().append(el); + } + } + } + function show_wikidata_hints() { $(".wikidata-hint").remove(); $wdinput = $(this); @@ -17,45 +78,13 @@ for (att in result) { let val = result[att]; let $input = $("#id_" + att); - if (val && val != $input.val()) { - let already_set = false; - let el = $(''); - if (val.wd) { - if (val.id && val.id == $input.val()) { - already_set = true; - } else { - // A representation of a WD Entity. - el.on('click', function() { - set_value_from_wikidata_id( - $input, val.model, val.wd, - () => {$(this).remove();} - ); - }); - el.text(val.label); - } - } else if (val.img) { - // A downloadable remote image. - let img = $(''); - img.attr('src', val.img); - el.append(img); - el.on('click', function() { - set_file_from_url( - $input, val.download, - () => {$(this).remove();} - ); - }); - } else { - // A plain literal. - el.on('click', function() { - $input.val(val); - $(this).remove(); - }); - el.text(val); - } - if (!already_set) { - $input.parent().append(el); + if (Array.isArray(val)) { + for (singleValue of val) { + add_wikidata_hint($input, singleValue); } + } else { + add_wikidata_hint($input, val); } }; diff --git a/src/catalogue/views.py b/src/catalogue/views.py index 95f33fd0..889a8321 100644 --- a/src/catalogue/views.py +++ b/src/catalogue/views.py @@ -178,6 +178,7 @@ class WikidataView(APIView): d[fieldname] = [ { "model": type(item)._meta.model_name, + "id": item.pk, "wd": item.wikidata, "label": str(item) or item._wikidata_label } for item in d[fieldname].all() diff --git a/src/catalogue/wikidata.py b/src/catalogue/wikidata.py index 90f1a5cb..b5ce07b1 100644 --- a/src/catalogue/wikidata.py +++ b/src/catalogue/wikidata.py @@ -159,7 +159,12 @@ class WikidataModel(models.Model): wdvalue = wdvalue.label.get(language, str(wdvalue.label)) if not skip_set: - setattr(self, attname, wdvalue) + try: + wdvalue = model_field.to_python(wdvalue) + except: + pass + else: + setattr(self, attname, wdvalue) def wikidata_link(self): if self.wikidata: diff --git a/src/catalogue/wikimedia.py b/src/catalogue/wikimedia.py index 534ca17a..fe6b1c6d 100644 --- a/src/catalogue/wikimedia.py +++ b/src/catalogue/wikimedia.py @@ -50,7 +50,21 @@ class WikiMedia: return Downloadable(download_url) return transform + @classmethod + def append(cls, arg): + def transform(get_value): + value = get_value(arg) + return Appendable(value) + return transform + +class Appendable(str): + def as_hint_json(self): + return { + 'value': self, + 'action': 'append', + } + class Downloadable: def __init__(self, url): self.url = url -- 2.20.1