From 8161763bf98b7f396ecc349ccd4670b8de592f40 Mon Sep 17 00:00:00 2001 From: Radek Czajka Date: Thu, 22 Sep 2022 16:03:22 +0200 Subject: [PATCH 1/1] More data in catalogue --- src/catalogue/admin.py | 36 +++- src/catalogue/constants.py | 3 + src/catalogue/locale/pl/LC_MESSAGES/django.mo | Bin 3607 -> 4068 bytes src/catalogue/locale/pl/LC_MESSAGES/django.po | 162 +++++++++++------- ...e_remove_author_place_of_birth_and_more.py | 83 +++++++++ ...or_place_of_birth_author_place_of_death.py | 24 +++ ...s_author_year_of_birth_inexact_and_more.py | 27 +++ src/catalogue/models.py | 45 ++++- src/catalogue/translation.py | 10 +- src/catalogue/wikidata.py | 45 +++-- 10 files changed, 344 insertions(+), 91 deletions(-) create mode 100644 src/catalogue/migrations/0035_place_remove_author_place_of_birth_and_more.py create mode 100644 src/catalogue/migrations/0036_author_place_of_birth_author_place_of_death.py create mode 100644 src/catalogue/migrations/0037_alter_place_options_author_year_of_birth_inexact_and_more.py diff --git a/src/catalogue/admin.py b/src/catalogue/admin.py index 47152ebb..213e9ca7 100644 --- a/src/catalogue/admin.py +++ b/src/catalogue/admin.py @@ -16,7 +16,7 @@ from .wikidata import WikidataAdminMixin class NotableBookInline(OrderableAdmin, admin.TabularInline): model = models.NotableBook - raw_id_fields = ['book'] + autocomplete_fields = ['book'] ordering_field_hide_input = True @@ -45,8 +45,35 @@ class AuthorAdmin(WikidataAdminMixin, TabbedTranslationAdmin): ] list_per_page = 10000000 search_fields = ["first_name", "last_name", "wikidata"] + readonly_fields = ["wikidata_link"] + + fieldsets = [ + (None, {"fields": [("wikidata", "wikidata_link")]}), + ( + _("Identification"), + { + "fields": [ + ("first_name", "last_name"), + "slug", + "gender", + "nationality", + ("date_of_birth", "year_of_birth", "year_of_birth_inexact", "year_of_birth_range", "place_of_birth"), + ("date_of_death", "year_of_death", "year_of_death_inexact", "year_of_death_range", "place_of_death"), + "description", + "status", + "collections", + "priority", + + "notes", + "gazeta_link", + "culturepl_link", + ] + }, + ), + ] + prepopulated_fields = {"slug": ("first_name", "last_name")} - autocomplete_fields = ["collections"] + autocomplete_fields = ["collections", "place_of_birth", "place_of_death"] inlines = [ NotableBookInline, ] @@ -316,3 +343,8 @@ class WorkTypeAdmin(admin.ModelAdmin): admin.site.register(models.WorkType, WorkTypeAdmin) + + +@admin.register(models.Place) +class PlaceAdmin(WikidataAdminMixin, TabbedTranslationAdmin): + search_fields = ['name'] diff --git a/src/catalogue/constants.py b/src/catalogue/constants.py index 9134e2d3..0f961b9d 100644 --- a/src/catalogue/constants.py +++ b/src/catalogue/constants.py @@ -2,10 +2,13 @@ # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information. # class WIKIDATA: + PLACE_OF_BIRTH = 'P19' + PLACE_OF_DEATH = 'P20' GENDER = "P21" AUTHOR = "P50" CREATOR = "P170" LANGUAGE = "P407" + DATE_OF_BIRTH = "P569" DATE_OF_DEATH = "P570" LAST_NAME = "P734" GIVEN_NAME = "P735" diff --git a/src/catalogue/locale/pl/LC_MESSAGES/django.mo b/src/catalogue/locale/pl/LC_MESSAGES/django.mo index 3dbf04bec5bdaef81f356104f7704cb34ebdbb8f..39239f881d2b50e2719f557197b2a02ac0521480 100644 GIT binary patch literal 4068 zcmZvdU2I%O6~|9$3&jnk4TY9c!ZeW7PQ32!Iwr{`PMXAV>&8x;$iWptZO8YH*W-J4 zW_9PTH+NN})KVx<6_qGz8a3h}^Z}_4RVxvozyn_O0jUxnLRE!|$O9D;-%=$IQpNw= zJL}!3x!N)9RRn2JpLqjGx#`&A@mK9*9$=QvjPr*2E>mt zG(7GZuYVh4Ki>g)-bIk-UH0}XAkTjl{497C{0#UucsqCv{51G?@KfN2o?Eae_umKd zdOJb(I|^puc{y)MY} ze+6<}e+%-wcR*hMk08h6FCdTqH^}4v2uL0*3c z$m4eT{)*T4gS_vDLB8i1kiU=e(W(dHjQ3-{*N4Mj%2%=fE$5 z-}3e=AlJLsK+e0jL8RU0v(vv-z_Nemb%!A}$T0}Vou7vxpNDW9#vxqiIF^IYJ}7)H zemIV&@;B5KPre&IFF*SW&f)&LiR%VnSyYh^O?Q^;j=yn;fM3^ zQOF_4S0Nma9T0vVf*|Cy8&ZNyL-?se<{*5R$03hExL!{}z6|L-0xu(wlaO5yu8|y1 zzMJ0j1^@CT@BzqSuO9(9w~j*ijydnRw)UPe|1t~CK=9W@d%TTy3ylj{^m zM`FFE=t$9Z)Y^!S$yCO+-cmHBWJuFWrmaLddQ{g}XeLx9)yq1NskVk@mPKY;Vnwbg zA;qGObcoqvW@=Q#I#Oc$>B{){-tD6Tvs5Bvb8o6?gB8kKN6MwTfr+6o zt;P~UV3$R(A`=-P9yjh@LkG6EtP__CBO8jA6Q!_+KpCf~E;|Y#&bL%oCR7Ol2|BoS zq>Va<)xm4$U!h2wFmD_ovh|j%E4=g;jxFCK?!Td()3^?6#Jr8Ik(4{;Mhu5)Bv-|7 zobnr=QpP&X$k-Gfn=--mQWK{$Hff-%gY!1o72ERjP&1YRbZ$8YMG!aDB8s_+^%89p zUfu=B0O4#a!PEjgw--}KE=6uSO4YfvH!RI_C*|B3qa1k(IcnP^5(%!N|K^Qp*7Qbx zbCfBW-&3*2>$Fjrg>0l3J0i(YPni1mG_sbRZ*F!P3+xWu9nL~ zv$)q%|Es~wS%2lF1tl8;dQCLrp}Cp4<9+9qvGUL{i?7sR4TPa4II0ifO0+qUr>s-y z|4_5(0trVWL%m?GPs&B&0KYpdk(-Y_e>6($;pa1 zEXtxLhRu#j`Osul?A$5%_2A^55q{6@<%5-~c>3wQqkO1>p2MPoN#+5}?+rRMS?*7+ zjPQ8B=tSSXzi)>(tm@stU$JZz%Z`s67<#<)h%yR^Vv`y^29%{#jE|MaDntFsIaoz) z^2^uTgI%mr_ovya;(CRlk<%L&x^G63P86k;zTS{YcRizHDp<*AF>^N3MQP2JbtHpT zNsp=SrC5uGbRD6&=;l3G&R1EJ1uJ4ytjb7SJAXMZv)9hQJSy5ztX4(c3N1RasajSdyJg^vf^TS}9tI4LizU`CRQ@ zYG{=N8k^FnqfLwOa;wR8WMJFUaE%N)OH$w{5nswjI@;RA-8=~o W?I|}L*>>s1g{J1T;>4Spr~d;0w6KE! delta 1652 zcmY+ETWpL$6vwBvYIj@Pi`A;Gw(eE8ZnZ@fRT|NF15JoTBK-b!ns74z`F&@;nKLtI=KJ229FHVl=J`4t z)`%i#MY?k_xXnj}eI4oCcsK|tE-S-1ip!%?mqHkT#pahmKmKg~tJtDtti1u9@0%z}rZ0;Qn(UxXTe+5B#(h4onbZKws`huZmL zmkNMqad-2uy6KVnBP4L+`2o?7SWN$8w zRfvI1&R-pKY0yFnpe87WO>ma^d!YL5hZ=YYD#adD;1iHFxU*3GI-&YqwfEPJca8nV z=b7YR1K-e)2R|8qLAB?Q#{yUgHDMHLf*NBT9EaavTyO2WppIrA)Dawn+TdxZg`GEE zO4^HVYv?imF4O`ZK;71-P!qp}WYK*zeuEVEn@WMRNS`JO!+cl-)m{m8>1tsPTn&}E zd=yg$i&Os$+-w7mQs{1G~+?W$cAo$V1}*q`3Fye}lR!X{3d#GPEe5`|sQw zG!xB76{sA|KnszA=m@INzgBCGK2cfWU$|cGbt#fX(cGb@ztuFLOS=r|a_W3#IyUa_e>MegI^yr{8W6u;QdHLL-OT9nwvRgE z75UpETjPmMPSsAgEtY869c$Ul!_Hl$iCC-m!XNim2F80^0v%p{Fyt)`uJK0~mPV^< vtE#V^4A!T6ud_~g9i!X4@=%GlHk9!CLJ{vvDCO@>wZ=E^XpVdR*#&<9M@Esg diff --git a/src/catalogue/locale/pl/LC_MESSAGES/django.po b/src/catalogue/locale/pl/LC_MESSAGES/django.po index ad827e5e..044f9605 100644 --- a/src/catalogue/locale/pl/LC_MESSAGES/django.po +++ b/src/catalogue/locale/pl/LC_MESSAGES/django.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" "Report-Msgid-Bugs-To: \n" -"PO-Revision-Date: 2022-09-19 15:45+0200\n" +"PO-Revision-Date: 2022-09-22 15:57+0200\n" "Last-Translator: \n" "Language-Team: \n" "Language: pl\n" @@ -19,29 +19,27 @@ msgstr "" "n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n" "X-Generator: Poedit 3.0.1\n" -#: catalogue/admin.py:176 +#: catalogue/admin.py:53 catalogue/admin.py:203 msgid "Identification" msgstr "Identyfikacja" -#: catalogue/admin.py:190 +#: catalogue/admin.py:217 msgid "Features" msgstr "Cechy" -#: catalogue/admin.py:200 +#: catalogue/admin.py:227 msgid "Plan" msgstr "Plan" -#: catalogue/admin.py:242 -#, fuzzy -#| msgid "title" +#: catalogue/admin.py:269 msgid "Title" msgstr "tytuł" -#: catalogue/admin.py:248 +#: catalogue/admin.py:275 msgid "Book" msgstr "książka" -#: catalogue/admin.py:258 catalogue/models.py:139 +#: catalogue/admin.py:285 catalogue/models.py:160 msgid "scans source" msgstr "źródło skanów" @@ -73,217 +71,253 @@ msgstr "narodowość" msgid "year of birth" msgstr "rok urodzenia" -#: catalogue/models.py:24 +#: catalogue/models.py:24 catalogue/models.py:33 +msgid "inexact" +msgstr "niedokładny" + +#: catalogue/models.py:25 +msgid "year of birth, range end" +msgstr "rok urodzenia, koniec zakresu" + +#: catalogue/models.py:26 +msgid "date_of_birth" +msgstr "data urodzenia" + +#: catalogue/models.py:29 msgid "place of birth" msgstr "miejsce urodzenia" -#: catalogue/models.py:25 +#: catalogue/models.py:32 msgid "year of death" msgstr "rok śmierci" -#: catalogue/models.py:26 +#: catalogue/models.py:34 +msgid "year of death, range end" +msgstr "rok śmierci, koniec zakresu" + +#: catalogue/models.py:35 +msgid "date_of_death" +msgstr "data śmierci" + +#: catalogue/models.py:38 msgid "place of death" msgstr "miejsce śmierci" -#: catalogue/models.py:28 +#: catalogue/models.py:42 msgid "status" msgstr "status" -#: catalogue/models.py:32 +#: catalogue/models.py:46 msgid "Alive" msgstr "Żyje" -#: catalogue/models.py:33 +#: catalogue/models.py:47 msgid "Dead" msgstr "Zmarły" -#: catalogue/models.py:34 +#: catalogue/models.py:48 msgid "Long dead" msgstr "Dawno zmarły" -#: catalogue/models.py:35 +#: catalogue/models.py:49 msgid "Unknown" msgstr "Nieznany" -#: catalogue/models.py:38 catalogue/models.py:141 catalogue/models.py:207 -#: catalogue/models.py:225 +#: catalogue/models.py:52 catalogue/models.py:162 catalogue/models.py:228 +#: catalogue/models.py:246 msgid "notes" msgstr "notatki" -#: catalogue/models.py:39 catalogue/models.py:147 +#: catalogue/models.py:53 catalogue/models.py:168 msgid "gazeta link" msgstr "link do bazy gazety" -#: catalogue/models.py:40 +#: catalogue/models.py:54 msgid "culture.pl link" msgstr "link do bazy culture.pl" -#: catalogue/models.py:42 +#: catalogue/models.py:56 msgid "description" msgstr "opis" -#: catalogue/models.py:47 catalogue/models.py:143 catalogue/models.py:275 +#: catalogue/models.py:59 catalogue/models.py:164 catalogue/models.py:296 msgid "priority" msgstr "priorytet" -#: catalogue/models.py:48 catalogue/models.py:144 +#: catalogue/models.py:60 catalogue/models.py:165 msgid "Low" msgstr "Niski" -#: catalogue/models.py:48 catalogue/models.py:144 +#: catalogue/models.py:60 catalogue/models.py:165 msgid "Medium" msgstr "Średni" -#: catalogue/models.py:48 catalogue/models.py:144 +#: catalogue/models.py:60 catalogue/models.py:165 msgid "High" msgstr "Wysoki" -#: catalogue/models.py:50 catalogue/models.py:148 catalogue/models.py:230 -#: catalogue/models.py:282 +#: catalogue/models.py:62 catalogue/models.py:169 catalogue/models.py:251 +#: catalogue/models.py:303 msgid "collections" msgstr "kolekcje" -#: catalogue/models.py:53 +#: catalogue/models.py:65 msgid "author" msgstr "autor" -#: catalogue/models.py:54 catalogue/models.py:122 +#: catalogue/models.py:66 catalogue/models.py:143 msgid "authors" msgstr "autorzy" -#: catalogue/models.py:93 catalogue/models.py:205 catalogue/models.py:222 -#: catalogue/models.py:255 +#: catalogue/models.py:114 catalogue/models.py:226 catalogue/models.py:243 +#: catalogue/models.py:276 catalogue/models.py:329 msgid "name" msgstr "nazwa" -#: catalogue/models.py:104 +#: catalogue/models.py:125 msgid "epoch" msgstr "epoka" -#: catalogue/models.py:105 catalogue/models.py:130 catalogue/models.py:279 +#: catalogue/models.py:126 catalogue/models.py:151 catalogue/models.py:300 msgid "epochs" msgstr "epoki" -#: catalogue/models.py:110 +#: catalogue/models.py:131 msgid "genre" msgstr "gatunek" -#: catalogue/models.py:111 catalogue/models.py:132 catalogue/models.py:281 +#: catalogue/models.py:132 catalogue/models.py:153 catalogue/models.py:302 msgid "genres" msgstr "gatunki" -#: catalogue/models.py:116 +#: catalogue/models.py:137 msgid "kind" msgstr "rodzaj" -#: catalogue/models.py:117 catalogue/models.py:131 catalogue/models.py:280 +#: catalogue/models.py:138 catalogue/models.py:152 catalogue/models.py:301 msgid "kinds" msgstr "rodzaje" -#: catalogue/models.py:128 +#: catalogue/models.py:149 msgid "translators" msgstr "tłumacze" -#: catalogue/models.py:133 +#: catalogue/models.py:154 msgid "title" msgstr "tytuł" -#: catalogue/models.py:134 +#: catalogue/models.py:155 msgid "language" msgstr "język" -#: catalogue/models.py:137 +#: catalogue/models.py:158 msgid "based on" msgstr "oparte na" -#: catalogue/models.py:140 +#: catalogue/models.py:161 msgid "text source" msgstr "źródło tekstu" -#: catalogue/models.py:146 +#: catalogue/models.py:167 msgid "year of entry into PD" msgstr "rok wstąpienia do DP" -#: catalogue/models.py:150 +#: catalogue/models.py:171 msgid "estimated number of characters" msgstr "szacowana liczba znaków" -#: catalogue/models.py:151 +#: catalogue/models.py:172 msgid "estimated number of verses" msgstr "szacowana liczba wersów" -#: catalogue/models.py:152 +#: catalogue/models.py:173 msgid "source of estimates" msgstr "źródło szacunków" -#: catalogue/models.py:154 +#: catalogue/models.py:175 msgid "free license" msgstr "wolna licencja" -#: catalogue/models.py:155 +#: catalogue/models.py:176 msgid "missing on Polona" msgstr "brak na Polonie" -#: catalogue/models.py:159 +#: catalogue/models.py:180 msgid "book" msgstr "książka" -#: catalogue/models.py:160 +#: catalogue/models.py:181 msgid "books" msgstr "książki" -#: catalogue/models.py:190 +#: catalogue/models.py:211 msgid "Author" msgstr "autor" -#: catalogue/models.py:195 +#: catalogue/models.py:216 msgid "Translator" msgstr "tłumacze" -#: catalogue/models.py:206 +#: catalogue/models.py:227 msgid "parent" msgstr "rodzic" -#: catalogue/models.py:211 +#: catalogue/models.py:232 msgid "collection category" msgstr "kategoria kolekcji" -#: catalogue/models.py:212 +#: catalogue/models.py:233 msgid "collection categories" msgstr "kategorie kolekcji" -#: catalogue/models.py:224 +#: catalogue/models.py:245 msgid "category" msgstr "kategoria" -#: catalogue/models.py:229 +#: catalogue/models.py:250 msgid "collection" msgstr "kolekcja" -#: catalogue/models.py:259 catalogue/models.py:278 +#: catalogue/models.py:280 catalogue/models.py:299 msgid "work type" msgstr "rodzaj pracy" -#: catalogue/models.py:260 +#: catalogue/models.py:281 msgid "work types" msgstr "rodzaje prac" -#: catalogue/models.py:276 +#: catalogue/models.py:297 msgid "per normalized page" msgstr "za stronę maszynopisu" -#: catalogue/models.py:277 +#: catalogue/models.py:298 msgid "per verse" msgstr "za wers" -#: catalogue/models.py:286 +#: catalogue/models.py:307 msgid "work rate" msgstr "stawka" -#: catalogue/models.py:287 +#: catalogue/models.py:308 msgid "work rates" msgstr "stawki" +#: catalogue/models.py:330 +msgid "locative" +msgstr "miejscownik" + +#: catalogue/models.py:330 +msgid "in…" +msgstr "w…" + +#: catalogue/models.py:333 +msgid "place" +msgstr "miejsce" + +#: catalogue/models.py:334 +msgid "places" +msgstr "miejsca" + #: catalogue/templates/catalogue/author_detail.html:7 #: catalogue/templates/catalogue/author_detail.html:13 #: catalogue/templates/catalogue/book_detail.html:7 diff --git a/src/catalogue/migrations/0035_place_remove_author_place_of_birth_and_more.py b/src/catalogue/migrations/0035_place_remove_author_place_of_birth_and_more.py new file mode 100644 index 00000000..339af8f6 --- /dev/null +++ b/src/catalogue/migrations/0035_place_remove_author_place_of_birth_and_more.py @@ -0,0 +1,83 @@ +# Generated by Django 4.0.6 on 2022-09-22 14:57 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('catalogue', '0034_notablebook'), + ] + + operations = [ + migrations.CreateModel( + name='Place', + fields=[ + ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('wikidata', models.CharField(blank=True, help_text='If you have a Wikidata ID, like "Q1337", enter it and save.', max_length=255)), + ('name', models.CharField(blank=True, max_length=255, verbose_name='name')), + ('name_pl', models.CharField(blank=True, max_length=255, null=True, verbose_name='name')), + ('name_de', models.CharField(blank=True, max_length=255, null=True, verbose_name='name')), + ('name_lt', models.CharField(blank=True, max_length=255, null=True, verbose_name='name')), + ('locative', models.CharField(blank=True, help_text='in…', max_length=255, verbose_name='locative')), + ('locative_pl', models.CharField(blank=True, help_text='in…', max_length=255, null=True, verbose_name='locative')), + ('locative_de', models.CharField(blank=True, help_text='in…', max_length=255, null=True, verbose_name='locative')), + ('locative_lt', models.CharField(blank=True, help_text='in…', max_length=255, null=True, verbose_name='locative')), + ], + options={ + 'abstract': False, + }, + ), + migrations.RemoveField( + model_name='author', + name='place_of_birth', + ), + migrations.RemoveField( + model_name='author', + name='place_of_birth_de', + ), + migrations.RemoveField( + model_name='author', + name='place_of_birth_lt', + ), + migrations.RemoveField( + model_name='author', + name='place_of_birth_pl', + ), + migrations.RemoveField( + model_name='author', + name='place_of_death', + ), + migrations.RemoveField( + model_name='author', + name='place_of_death_de', + ), + migrations.RemoveField( + model_name='author', + name='place_of_death_lt', + ), + migrations.RemoveField( + model_name='author', + name='place_of_death_pl', + ), + migrations.AddField( + model_name='author', + name='date_of_birth', + field=models.DateField(blank=True, null=True, verbose_name='date_of_birth'), + ), + migrations.AddField( + model_name='author', + name='date_of_death', + field=models.DateField(blank=True, null=True, verbose_name='date_of_death'), + ), + migrations.AddField( + model_name='author', + name='year_of_birth_range', + field=models.SmallIntegerField(blank=True, null=True, verbose_name='year of birth, range end'), + ), + migrations.AddField( + model_name='author', + name='year_of_death_range', + field=models.SmallIntegerField(blank=True, null=True, verbose_name='year of death, range end'), + ), + ] diff --git a/src/catalogue/migrations/0036_author_place_of_birth_author_place_of_death.py b/src/catalogue/migrations/0036_author_place_of_birth_author_place_of_death.py new file mode 100644 index 00000000..b72e4ba0 --- /dev/null +++ b/src/catalogue/migrations/0036_author_place_of_birth_author_place_of_death.py @@ -0,0 +1,24 @@ +# Generated by Django 4.0.6 on 2022-09-22 14:57 + +from django.db import migrations, models +import django.db.models.deletion + + +class Migration(migrations.Migration): + + dependencies = [ + ('catalogue', '0035_place_remove_author_place_of_birth_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='author', + name='place_of_birth', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='authors_born', to='catalogue.place', verbose_name='place of birth'), + ), + migrations.AddField( + model_name='author', + name='place_of_death', + field=models.ForeignKey(blank=True, null=True, on_delete=django.db.models.deletion.PROTECT, related_name='authors_died', to='catalogue.place', verbose_name='place of death'), + ), + ] diff --git a/src/catalogue/migrations/0037_alter_place_options_author_year_of_birth_inexact_and_more.py b/src/catalogue/migrations/0037_alter_place_options_author_year_of_birth_inexact_and_more.py new file mode 100644 index 00000000..e5c5629b --- /dev/null +++ b/src/catalogue/migrations/0037_alter_place_options_author_year_of_birth_inexact_and_more.py @@ -0,0 +1,27 @@ +# Generated by Django 4.0.6 on 2022-09-22 15:47 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('catalogue', '0036_author_place_of_birth_author_place_of_death'), + ] + + operations = [ + migrations.AlterModelOptions( + name='place', + options={'verbose_name': 'place', 'verbose_name_plural': 'places'}, + ), + migrations.AddField( + model_name='author', + name='year_of_birth_inexact', + field=models.BooleanField(default=False, verbose_name='inexact'), + ), + migrations.AddField( + model_name='author', + name='year_of_death_inexact', + field=models.BooleanField(default=False, verbose_name='inexact'), + ), + ] diff --git a/src/catalogue/models.py b/src/catalogue/models.py index d0698808..d671425d 100644 --- a/src/catalogue/models.py +++ b/src/catalogue/models.py @@ -21,9 +21,23 @@ class Author(WikidataMixin, models.Model): gender = models.CharField(_("gender"), max_length=255, blank=True) nationality = models.CharField(_("nationality"), max_length=255, blank=True) year_of_birth = models.SmallIntegerField(_("year of birth"), null=True, blank=True) - place_of_birth = models.CharField(_('place of birth'), max_length=255, blank=True) + year_of_birth_inexact = models.BooleanField(_("inexact"), default=False) + year_of_birth_range = models.SmallIntegerField(_("year of birth, range end"), null=True, blank=True) + date_of_birth = models.DateField(_("date_of_birth"), null=True, blank=True) + place_of_birth = models.ForeignKey( + 'Place', models.PROTECT, null=True, blank=True, + verbose_name=_('place of birth'), + related_name='authors_born' + ) year_of_death = models.SmallIntegerField(_("year of death"), null=True, blank=True) - place_of_death = models.CharField(_('place of death'), max_length=255, blank=True) + year_of_death_inexact = models.BooleanField(_("inexact"), default=False) + year_of_death_range = models.SmallIntegerField(_("year of death, range end"), null=True, blank=True) + date_of_death = models.DateField(_("date_of_death"), null=True, blank=True) + place_of_death = models.ForeignKey( + 'Place', models.PROTECT, null=True, blank=True, + verbose_name=_('place of death'), + related_name='authors_died' + ) status = models.PositiveSmallIntegerField( _("status"), null=True, @@ -55,10 +69,19 @@ class Author(WikidataMixin, models.Model): class Wikidata: first_name = WIKIDATA.GIVEN_NAME last_name = WIKIDATA.LAST_NAME + date_of_birth = WIKIDATA.DATE_OF_BIRTH + year_of_birth = WIKIDATA.DATE_OF_BIRTH + place_of_birth = WIKIDATA.PLACE_OF_BIRTH + date_of_death = WIKIDATA.DATE_OF_DEATH year_of_death = WIKIDATA.DATE_OF_DEATH + place_of_death = WIKIDATA.PLACE_OF_DEATH gender = WIKIDATA.GENDER notes = "description" + def _supplement(obj): + if not obj.first_name and not obj.last_name: + yield 'first_name', 'label' + def __str__(self): name = f"{self.first_name} {self.last_name}" if self.year_of_death is not None: @@ -169,10 +192,10 @@ class Book(WikidataMixin, models.Model): txt = self.title astr = self.authors_str() if astr: - txt = f"{astr} – {txt}" + txt = f"{txt}, {astr}" tstr = self.translators_str() if tstr: - txt = f"{txt} (tłum. {tstr})" + txt = f"{txt}, tłum. {tstr}" return txt def get_absolute_url(self): @@ -301,3 +324,17 @@ class WorkRate(models.Model): if book.estimated_chars: return (decimal.Decimal(book.estimated_chars) / 1800 * self.per_normpage).quantize(decimal.Decimal('1.00'), rounding=decimal.ROUND_HALF_UP) + +class Place(WikidataMixin, models.Model): + name = models.CharField(_('name'), max_length=255, blank=True) + locative = models.CharField(_('locative'), max_length=255, blank=True, help_text=_('in…')) + + class Meta: + verbose_name = _('place') + verbose_name_plural = _('places') + + class Wikidata: + name = 'label' + + def __str__(self): + return self.name diff --git a/src/catalogue/translation.py b/src/catalogue/translation.py index 0ee80711..9637e55d 100644 --- a/src/catalogue/translation.py +++ b/src/catalogue/translation.py @@ -7,7 +7,13 @@ class AuthorTranslationOptions(TranslationOptions): fields = ( 'first_name', 'last_name', - 'place_of_birth', - 'place_of_death', 'description', ) + + +@register(models.Place) +class PlaceTranslationOptions(TranslationOptions): + fields = ( + 'name', + 'locative', + ) diff --git a/src/catalogue/wikidata.py b/src/catalogue/wikidata.py index 4fc8bbd8..610245d5 100644 --- a/src/catalogue/wikidata.py +++ b/src/catalogue/wikidata.py @@ -21,6 +21,28 @@ class WikidataMixin(models.Model): class Meta: abstract = True + def wikidata_populate(self, client, entity, attname, wd): + model_field = self._meta.get_field(attname) + if isinstance(model_field, models.ManyToManyField): + if getattr(self, attname).all().exists(): + return + else: + if getattr(self, attname): + return + + wdvalue = None + if wd == "description": + wdvalue = entity.description.get("pl", str(entity.description)) + elif wd == "label": + wdvalue = entity.label.get("pl", str(entity.label)) + else: + try: + wdvalue = entity.get(client.get(wd)) + except DatavalueError: + pass + + self.set_field_from_wikidata(attname, wdvalue) + def save(self, **kwargs): super().save() if self.wikidata and hasattr(self, "Wikidata"): @@ -33,26 +55,11 @@ class WikidataMixin(models.Model): continue wd = getattr(Wikidata, attname) - model_field = self._meta.get_field(attname) - if isinstance(model_field, models.ManyToManyField): - if getattr(self, attname).all().exists(): - continue - else: - if getattr(self, attname): - continue - - wdvalue = None - if wd == "description": - wdvalue = entity.description.get("pl", str(entity.description)) - elif wd == "label": - wdvalue = entity.label.get("pl", str(entity.label)) - else: - try: - wdvalue = entity.get(client.get(wd)) - except DatavalueError: - pass + self.wikidata_populate(client, entity, attname, wd) + if hasattr(Wikidata, '_supplement'): + for attname, wd in Wikidata._supplement(self): + self.wikidata_populate(client, entity, attname, wd) - self.set_field_from_wikidata(attname, wdvalue) kwargs.update(force_insert=False, force_update=True) super().save(**kwargs) -- 2.20.1