From 4b200d823f0ec79279da035a46d0d888693ca2fe Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Tue, 27 Sep 2022 10:14:48 +0200 Subject: [PATCH] Author photos and nicer Wikidata imports. --- requirements/requirements.txt | 2 +- src/catalogue/admin.py | 2 + src/catalogue/constants.py | 1 + ...photo_author_photo_attribution_and_more.py | 33 +++++++++ src/catalogue/models.py | 10 +++ .../static/catalogue/wikidata_admin.css | 23 ++++-- .../static/catalogue/wikidata_admin.js | 50 ++++++++++--- src/catalogue/urls.py | 1 + src/catalogue/views.py | 66 ++++++++++++++--- src/catalogue/wikidata.py | 69 +++++++++++++----- src/catalogue/wikimedia.py | 70 +++++++++++++++++++ 11 files changed, 286 insertions(+), 41 deletions(-) create mode 100644 src/catalogue/migrations/0039_author_photo_author_photo_attribution_and_more.py create mode 100644 src/catalogue/wikimedia.py diff --git a/requirements/requirements.txt b/requirements/requirements.txt index eba62b92..519d5745 100644 --- a/requirements/requirements.txt +++ b/requirements/requirements.txt @@ -8,7 +8,7 @@ oauth2 httplib2 # oauth2 dependency python-slugify python-docx==0.8.11 -Wikidata==0.6.1 +Wikidata==0.7 librarian==2.4.8 diff --git a/src/catalogue/admin.py b/src/catalogue/admin.py index 087bfd74..f00e7fc9 100644 --- a/src/catalogue/admin.py +++ b/src/catalogue/admin.py @@ -67,6 +67,8 @@ class AuthorAdmin(WikidataAdminMixin, TabbedTranslationAdmin): "notes", "gazeta_link", "culturepl_link", + "plwiki", + "photo", "photo_source", "photo_attribution", ] }, ), diff --git a/src/catalogue/constants.py b/src/catalogue/constants.py index 0acc116a..1faee93a 100644 --- a/src/catalogue/constants.py +++ b/src/catalogue/constants.py @@ -2,6 +2,7 @@ # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # class WIKIDATA: + IMAGE = 'P18' PLACE_OF_BIRTH = 'P19' PLACE_OF_DEATH = 'P20' GENDER = "P21" diff --git a/src/catalogue/migrations/0039_author_photo_author_photo_attribution_and_more.py b/src/catalogue/migrations/0039_author_photo_author_photo_attribution_and_more.py new file mode 100644 index 00000000..2f94a562 --- /dev/null +++ b/src/catalogue/migrations/0039_author_photo_author_photo_attribution_and_more.py @@ -0,0 +1,33 @@ +# Generated by Django 4.0.6 on 2022-09-26 16:21 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('catalogue', '0038_book_original_year'), + ] + + operations = [ + migrations.AddField( + model_name='author', + name='photo', + field=models.ImageField(blank=True, null=True, upload_to='catalogue/author/'), + ), + migrations.AddField( + model_name='author', + name='photo_attribution', + field=models.CharField(blank=True, max_length=255), + ), + migrations.AddField( + model_name='author', + name='photo_source', + field=models.CharField(blank=True, max_length=255), + ), + migrations.AddField( + model_name='author', + name='plwiki', + field=models.CharField(blank=True, max_length=255), + ), + ] diff --git a/src/catalogue/models.py b/src/catalogue/models.py index 92275ecf..db840da5 100644 --- a/src/catalogue/models.py +++ b/src/catalogue/models.py @@ -9,6 +9,7 @@ from admin_ordering.models import OrderableModel from wikidata.client import Client from .constants import WIKIDATA from .wikidata import WikidataModel +from .wikimedia import WikiMedia class Author(WikidataModel): @@ -51,8 +52,13 @@ class Author(WikidataModel): ], ) notes = models.TextField(_("notes"), blank=True) + gazeta_link = models.CharField(_("gazeta link"), max_length=255, blank=True) culturepl_link = models.CharField(_("culture.pl link"), max_length=255, blank=True) + plwiki = models.CharField(blank=True, max_length=255) + photo = models.ImageField(blank=True, null=True, upload_to='catalogue/author/') + photo_source = models.CharField(blank=True, max_length=255) + photo_attribution = models.CharField(max_length=255, blank=True) description = models.TextField(_("description"), blank=True) @@ -78,6 +84,10 @@ class Author(WikidataModel): place_of_death = WIKIDATA.PLACE_OF_DEATH gender = WIKIDATA.GENDER notes = "description" + plwiki = "plwiki" + photo = WikiMedia.download(WIKIDATA.IMAGE) + photo_source = WikiMedia.descriptionurl(WIKIDATA.IMAGE) + photo_attribution = WikiMedia.attribution(WIKIDATA.IMAGE) def _supplement(obj): if not obj.first_name and not obj.last_name: diff --git a/src/catalogue/static/catalogue/wikidata_admin.css b/src/catalogue/static/catalogue/wikidata_admin.css index 92ac69d9..24e27de0 100644 --- a/src/catalogue/static/catalogue/wikidata_admin.css +++ b/src/catalogue/static/catalogue/wikidata_admin.css @@ -1,13 +1,26 @@ .wikidata-hint { background-image: url('https://www.wikidata.org/static/favicon/wikidata.ico'); background-repeat: no-repeat; - background-position: 2px 50%; + background-position: 5px 50%; background-size: 16px auto; - padding: 2px 2px 2px 20px; + padding: 5px 5px 5px 26px; cursor: pointer; - color: black; - background-color: white; + background-color: black; + color: white; border-radius: 10px; + display: inline-block; + overflow: hidden; + vertical-align: middle; +} +@media (prefers-color-scheme: dark) { + .wikidata-hint { + color: black; + background-color: white; + } +} +.wikidata-hint img { + height: 48px; + margin: -5px -5px -5px 5px; } #id_wikidata { @@ -21,3 +34,5 @@ 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 a8aa51ee..f13510bc 100644 --- a/src/catalogue/static/catalogue/wikidata_admin.js +++ b/src/catalogue/static/catalogue/wikidata_admin.js @@ -18,25 +18,44 @@ 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_value_from_wikidata_id( - $input, val.model, val.wd, - function() { - $(this).remove(); - } + set_file_from_url( + $input, val.download, + () => {$(this).remove();} ); }); - el.text(val.label); } else { + // A plain literal. el.on('click', function() { $input.val(val); $(this).remove(); }); el.text(val); } - $input.parent().append(el); + if (!already_set) { + $input.parent().append(el); + } } }; @@ -55,10 +74,25 @@ csrfmiddlewaretoken: $('[name=csrfmiddlewaretoken]').val(), }, success: function(result) { - $input.val(result.id); + $input.append($('