Author description generator
authorRadek Czajka <rczajka@rczajka.pl>
Mon, 26 Sep 2022 10:52:02 +0000 (12:52 +0200)
committerRadek Czajka <rczajka@rczajka.pl>
Mon, 26 Sep 2022 10:52:02 +0000 (12:52 +0200)
src/catalogue/admin.py
src/catalogue/constants.py
src/catalogue/locale/pl/LC_MESSAGES/django.mo
src/catalogue/locale/pl/LC_MESSAGES/django.po
src/catalogue/migrations/0038_book_original_year.py [new file with mode: 0644]
src/catalogue/models.py
src/catalogue/templates/catalogue/author_description.html [new file with mode: 0644]
src/catalogue/urls.py
src/catalogue/views.py
src/catalogue/wikidata.py

index 213e9ca..087bfd7 100644 (file)
@@ -45,7 +45,7 @@ class AuthorAdmin(WikidataAdminMixin, TabbedTranslationAdmin):
     ]
     list_per_page = 10000000
     search_fields = ["first_name", "last_name", "wikidata"]
     ]
     list_per_page = 10000000
     search_fields = ["first_name", "last_name", "wikidata"]
-    readonly_fields = ["wikidata_link"]
+    readonly_fields = ["wikidata_link", "description_preview"]
 
     fieldsets = [
         (None, {"fields": [("wikidata", "wikidata_link")]}),
 
     fieldsets = [
         (None, {"fields": [("wikidata", "wikidata_link")]}),
@@ -59,7 +59,7 @@ class AuthorAdmin(WikidataAdminMixin, TabbedTranslationAdmin):
                     "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"),
                     "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",
+                    ("description", "description_preview"),
                     "status",
                     "collections",
                     "priority",
                     "status",
                     "collections",
                     "priority",
@@ -78,6 +78,9 @@ class AuthorAdmin(WikidataAdminMixin, TabbedTranslationAdmin):
         NotableBookInline,
     ]
 
         NotableBookInline,
     ]
 
+    def description_preview(self, obj):
+        return obj.generate_description()
+
 
 admin.site.register(models.Author, AuthorAdmin)
 
 
 admin.site.register(models.Author, AuthorAdmin)
 
@@ -209,6 +212,7 @@ class BookAdmin(WikidataAdminMixin, NumericFilterModelAdmin):
                     "translators",
                     "language",
                     "based_on",
                     "translators",
                     "language",
                     "based_on",
+                    "original_year",
                     "pd_year",
                 ]
             },
                     "pd_year",
                 ]
             },
index 0f961b9..0acc116 100644 (file)
@@ -10,6 +10,7 @@ class WIKIDATA:
     LANGUAGE = "P407"
     DATE_OF_BIRTH = "P569"
     DATE_OF_DEATH = "P570"
     LANGUAGE = "P407"
     DATE_OF_BIRTH = "P569"
     DATE_OF_DEATH = "P570"
+    PUBLICATION_DATE = "P577"
     LAST_NAME = "P734"
     GIVEN_NAME = "P735"
     TRANSLATOR = "P655"
     LAST_NAME = "P734"
     GIVEN_NAME = "P735"
     TRANSLATOR = "P655"
index 39239f8..4502885 100644 (file)
Binary files a/src/catalogue/locale/pl/LC_MESSAGES/django.mo and b/src/catalogue/locale/pl/LC_MESSAGES/django.mo differ
index 044f960..86f4d12 100644 (file)
@@ -7,7 +7,7 @@ msgid ""
 msgstr ""
 "Project-Id-Version: \n"
 "Report-Msgid-Bugs-To: \n"
 msgstr ""
 "Project-Id-Version: \n"
 "Report-Msgid-Bugs-To: \n"
-"PO-Revision-Date: 2022-09-22 15:57+0200\n"
+"PO-Revision-Date: 2022-09-26 11:45+0200\n"
 "Last-Translator: \n"
 "Language-Team: \n"
 "Language: pl\n"
 "Last-Translator: \n"
 "Language-Team: \n"
 "Language: pl\n"
@@ -23,23 +23,23 @@ msgstr ""
 msgid "Identification"
 msgstr "Identyfikacja"
 
 msgid "Identification"
 msgstr "Identyfikacja"
 
-#: catalogue/admin.py:217
+#: catalogue/admin.py:218
 msgid "Features"
 msgstr "Cechy"
 
 msgid "Features"
 msgstr "Cechy"
 
-#: catalogue/admin.py:227
+#: catalogue/admin.py:228
 msgid "Plan"
 msgstr "Plan"
 
 msgid "Plan"
 msgstr "Plan"
 
-#: catalogue/admin.py:269
+#: catalogue/admin.py:270
 msgid "Title"
 msgstr "tytuł"
 
 msgid "Title"
 msgstr "tytuł"
 
-#: catalogue/admin.py:275
+#: catalogue/admin.py:276
 msgid "Book"
 msgstr "książka"
 
 msgid "Book"
 msgstr "książka"
 
-#: catalogue/admin.py:285 catalogue/models.py:160
+#: catalogue/admin.py:286 catalogue/models.py:160
 msgid "scans source"
 msgstr "źródło skanów"
 
 msgid "scans source"
 msgstr "źródło skanów"
 
@@ -123,12 +123,12 @@ msgstr "Dawno zmarły"
 msgid "Unknown"
 msgstr "Nieznany"
 
 msgid "Unknown"
 msgstr "Nieznany"
 
-#: catalogue/models.py:52 catalogue/models.py:162 catalogue/models.py:228
-#: catalogue/models.py:246
+#: catalogue/models.py:52 catalogue/models.py:162 catalogue/models.py:232
+#: catalogue/models.py:250
 msgid "notes"
 msgstr "notatki"
 
 msgid "notes"
 msgstr "notatki"
 
-#: catalogue/models.py:53 catalogue/models.py:168
+#: catalogue/models.py:53 catalogue/models.py:169
 msgid "gazeta link"
 msgstr "link do bazy gazety"
 
 msgid "gazeta link"
 msgstr "link do bazy gazety"
 
@@ -140,7 +140,7 @@ msgstr "link do bazy culture.pl"
 msgid "description"
 msgstr "opis"
 
 msgid "description"
 msgstr "opis"
 
-#: catalogue/models.py:59 catalogue/models.py:164 catalogue/models.py:296
+#: catalogue/models.py:59 catalogue/models.py:164 catalogue/models.py:300
 msgid "priority"
 msgstr "priorytet"
 
 msgid "priority"
 msgstr "priorytet"
 
@@ -156,8 +156,8 @@ msgstr "Średni"
 msgid "High"
 msgstr "Wysoki"
 
 msgid "High"
 msgstr "Wysoki"
 
-#: catalogue/models.py:62 catalogue/models.py:169 catalogue/models.py:251
-#: catalogue/models.py:303
+#: catalogue/models.py:62 catalogue/models.py:170 catalogue/models.py:255
+#: catalogue/models.py:307
 msgid "collections"
 msgstr "kolekcje"
 
 msgid "collections"
 msgstr "kolekcje"
 
@@ -169,8 +169,8 @@ msgstr "autor"
 msgid "authors"
 msgstr "autorzy"
 
 msgid "authors"
 msgstr "autorzy"
 
-#: catalogue/models.py:114 catalogue/models.py:226 catalogue/models.py:243
-#: catalogue/models.py:276 catalogue/models.py:329
+#: catalogue/models.py:114 catalogue/models.py:230 catalogue/models.py:247
+#: catalogue/models.py:280 catalogue/models.py:333
 msgid "name"
 msgstr "nazwa"
 
 msgid "name"
 msgstr "nazwa"
 
@@ -178,7 +178,7 @@ msgstr "nazwa"
 msgid "epoch"
 msgstr "epoka"
 
 msgid "epoch"
 msgstr "epoka"
 
-#: catalogue/models.py:126 catalogue/models.py:151 catalogue/models.py:300
+#: catalogue/models.py:126 catalogue/models.py:151 catalogue/models.py:304
 msgid "epochs"
 msgstr "epoki"
 
 msgid "epochs"
 msgstr "epoki"
 
@@ -186,7 +186,7 @@ msgstr "epoki"
 msgid "genre"
 msgstr "gatunek"
 
 msgid "genre"
 msgstr "gatunek"
 
-#: catalogue/models.py:132 catalogue/models.py:153 catalogue/models.py:302
+#: catalogue/models.py:132 catalogue/models.py:153 catalogue/models.py:306
 msgid "genres"
 msgstr "gatunki"
 
 msgid "genres"
 msgstr "gatunki"
 
@@ -194,7 +194,7 @@ msgstr "gatunki"
 msgid "kind"
 msgstr "rodzaj"
 
 msgid "kind"
 msgstr "rodzaj"
 
-#: catalogue/models.py:138 catalogue/models.py:152 catalogue/models.py:301
+#: catalogue/models.py:138 catalogue/models.py:152 catalogue/models.py:305
 msgid "kinds"
 msgstr "rodzaje"
 
 msgid "kinds"
 msgstr "rodzaje"
 
@@ -219,102 +219,106 @@ msgid "text source"
 msgstr "źródło tekstu"
 
 #: catalogue/models.py:167
 msgstr "źródło tekstu"
 
 #: catalogue/models.py:167
+msgid "original publication year"
+msgstr "rok oryginalnej publikacji"
+
+#: catalogue/models.py:168
 msgid "year of entry into PD"
 msgstr "rok wstąpienia do DP"
 
 msgid "year of entry into PD"
 msgstr "rok wstąpienia do DP"
 
-#: catalogue/models.py:171
+#: catalogue/models.py:172
 msgid "estimated number of characters"
 msgstr "szacowana liczba znaków"
 
 msgid "estimated number of characters"
 msgstr "szacowana liczba znaków"
 
-#: catalogue/models.py:172
+#: catalogue/models.py:173
 msgid "estimated number of verses"
 msgstr "szacowana liczba wersów"
 
 msgid "estimated number of verses"
 msgstr "szacowana liczba wersów"
 
-#: catalogue/models.py:173
+#: catalogue/models.py:174
 msgid "source of estimates"
 msgstr "źródło szacunków"
 
 msgid "source of estimates"
 msgstr "źródło szacunków"
 
-#: catalogue/models.py:175
+#: catalogue/models.py:176
 msgid "free license"
 msgstr "wolna licencja"
 
 msgid "free license"
 msgstr "wolna licencja"
 
-#: catalogue/models.py:176
+#: catalogue/models.py:177
 msgid "missing on Polona"
 msgstr "brak na Polonie"
 
 msgid "missing on Polona"
 msgstr "brak na Polonie"
 
-#: catalogue/models.py:180
+#: catalogue/models.py:181
 msgid "book"
 msgstr "książka"
 
 msgid "book"
 msgstr "książka"
 
-#: catalogue/models.py:181
+#: catalogue/models.py:182
 msgid "books"
 msgstr "książki"
 
 msgid "books"
 msgstr "książki"
 
-#: catalogue/models.py:211
+#: catalogue/models.py:215
 msgid "Author"
 msgstr "autor"
 
 msgid "Author"
 msgstr "autor"
 
-#: catalogue/models.py:216
+#: catalogue/models.py:220
 msgid "Translator"
 msgstr "tłumacze"
 
 msgid "Translator"
 msgstr "tłumacze"
 
-#: catalogue/models.py:227
+#: catalogue/models.py:231
 msgid "parent"
 msgstr "rodzic"
 
 msgid "parent"
 msgstr "rodzic"
 
-#: catalogue/models.py:232
+#: catalogue/models.py:236
 msgid "collection category"
 msgstr "kategoria kolekcji"
 
 msgid "collection category"
 msgstr "kategoria kolekcji"
 
-#: catalogue/models.py:233
+#: catalogue/models.py:237
 msgid "collection categories"
 msgstr "kategorie kolekcji"
 
 msgid "collection categories"
 msgstr "kategorie kolekcji"
 
-#: catalogue/models.py:245
+#: catalogue/models.py:249
 msgid "category"
 msgstr "kategoria"
 
 msgid "category"
 msgstr "kategoria"
 
-#: catalogue/models.py:250
+#: catalogue/models.py:254
 msgid "collection"
 msgstr "kolekcja"
 
 msgid "collection"
 msgstr "kolekcja"
 
-#: catalogue/models.py:280 catalogue/models.py:299
+#: catalogue/models.py:284 catalogue/models.py:303
 msgid "work type"
 msgstr "rodzaj pracy"
 
 msgid "work type"
 msgstr "rodzaj pracy"
 
-#: catalogue/models.py:281
+#: catalogue/models.py:285
 msgid "work types"
 msgstr "rodzaje prac"
 
 msgid "work types"
 msgstr "rodzaje prac"
 
-#: catalogue/models.py:297
+#: catalogue/models.py:301
 msgid "per normalized page"
 msgstr "za stronę maszynopisu"
 
 msgid "per normalized page"
 msgstr "za stronę maszynopisu"
 
-#: catalogue/models.py:298
+#: catalogue/models.py:302
 msgid "per verse"
 msgstr "za wers"
 
 msgid "per verse"
 msgstr "za wers"
 
-#: catalogue/models.py:307
+#: catalogue/models.py:311
 msgid "work rate"
 msgstr "stawka"
 
 msgid "work rate"
 msgstr "stawka"
 
-#: catalogue/models.py:308
+#: catalogue/models.py:312
 msgid "work rates"
 msgstr "stawki"
 
 msgid "work rates"
 msgstr "stawki"
 
-#: catalogue/models.py:330
+#: catalogue/models.py:334
 msgid "locative"
 msgstr "miejscownik"
 
 msgid "locative"
 msgstr "miejscownik"
 
-#: catalogue/models.py:330
+#: catalogue/models.py:334
 msgid "in…"
 msgstr "w…"
 
 msgid "in…"
 msgstr "w…"
 
-#: catalogue/models.py:333
+#: catalogue/models.py:337
 msgid "place"
 msgstr "miejsce"
 
 msgid "place"
 msgstr "miejsce"
 
-#: catalogue/models.py:334
+#: catalogue/models.py:338
 msgid "places"
 msgstr "miejsca"
 
 msgid "places"
 msgstr "miejsca"
 
@@ -341,7 +345,7 @@ msgstr[1] "%(c)s autorów"
 msgstr[2] "%(c)s autorów"
 msgstr[3] ""
 
 msgstr[2] "%(c)s autorów"
 msgstr[3] ""
 
-#: catalogue/wikidata.py:18
+#: catalogue/wikidata.py:21
 msgid "If you have a Wikidata ID, like \"Q1337\", enter it and save."
 msgstr "Jeśli masz identyfikator Wikidanych , jak „Q1337”, wklej go i zapisz."
 
 msgid "If you have a Wikidata ID, like \"Q1337\", enter it and save."
 msgstr "Jeśli masz identyfikator Wikidanych , jak „Q1337”, wklej go i zapisz."
 
diff --git a/src/catalogue/migrations/0038_book_original_year.py b/src/catalogue/migrations/0038_book_original_year.py
new file mode 100644 (file)
index 0000000..d8408dd
--- /dev/null
@@ -0,0 +1,18 @@
+# Generated by Django 4.0.6 on 2022-09-26 11:36
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+    dependencies = [
+        ('catalogue', '0037_alter_place_options_author_year_of_birth_inexact_and_more'),
+    ]
+
+    operations = [
+        migrations.AddField(
+            model_name='book',
+            name='original_year',
+            field=models.IntegerField(blank=True, null=True, verbose_name='original publication year'),
+        ),
+    ]
index b974de1..92275ec 100644 (file)
@@ -2,6 +2,7 @@ from collections import Counter
 import decimal
 from django.apps import apps
 from django.db import models
 import decimal
 from django.apps import apps
 from django.db import models
+from django.template.loader import render_to_string
 from django.urls import reverse
 from django.utils.translation import gettext_lazy as _
 from admin_ordering.models import OrderableModel
 from django.urls import reverse
 from django.utils.translation import gettext_lazy as _
 from admin_ordering.models import OrderableModel
@@ -104,6 +105,12 @@ class Author(WikidataModel):
         else:
             return None
 
         else:
             return None
 
+    def generate_description(self):
+        t = render_to_string(
+            'catalogue/author_description.html',
+            {'obj': self}
+        )
+        return t
 
 class NotableBook(OrderableModel):
     author = models.ForeignKey(Author, models.CASCADE)
 
 class NotableBook(OrderableModel):
     author = models.ForeignKey(Author, models.CASCADE)
@@ -164,6 +171,7 @@ class Book(WikidataModel):
         _("priority"),
         default=0, choices=[(0, _("Low")), (1, _("Medium")), (2, _("High"))]
     )
         _("priority"),
         default=0, choices=[(0, _("Low")), (1, _("Medium")), (2, _("High"))]
     )
+    original_year = models.IntegerField(_('original publication year'), null=True, blank=True)
     pd_year = models.IntegerField(_('year of entry into PD'), null=True, blank=True)
     gazeta_link = models.CharField(_("gazeta link"), max_length=255, blank=True)
     collections = models.ManyToManyField("Collection", blank=True, verbose_name=_("collections"))
     pd_year = models.IntegerField(_('year of entry into PD'), null=True, blank=True)
     gazeta_link = models.CharField(_("gazeta link"), max_length=255, blank=True)
     collections = models.ManyToManyField("Collection", blank=True, verbose_name=_("collections"))
@@ -186,10 +194,13 @@ class Book(WikidataModel):
         title = WIKIDATA.TITLE
         language = WIKIDATA.LANGUAGE
         based_on = WIKIDATA.BASED_ON
         title = WIKIDATA.TITLE
         language = WIKIDATA.LANGUAGE
         based_on = WIKIDATA.BASED_ON
+        original_year = WIKIDATA.PUBLICATION_DATE
         notes = "description"
 
     def __str__(self):
         txt = self.title
         notes = "description"
 
     def __str__(self):
         txt = self.title
+        if self.original_year:
+            txt = f"{txt} ({self.original_year})"
         astr = self.authors_str()
         if astr:
             txt = f"{txt}, {astr}"
         astr = self.authors_str()
         if astr:
             txt = f"{txt}, {astr}"
diff --git a/src/catalogue/templates/catalogue/author_description.html b/src/catalogue/templates/catalogue/author_description.html
new file mode 100644 (file)
index 0000000..934e4b6
--- /dev/null
@@ -0,0 +1,47 @@
+<dl>
+  {% if obj.date_of_birth or obj.place_of_birth %}
+    <dt>Ur.</dt>
+    <dd>
+      {% if obj.date_of_birth %}
+        {{ obj.date_of_birth }}
+      {% endif %}
+      {% if obj.place_of_birth %}
+        w
+        {% if obj.place_of_birth.locative %}
+          {{ obj.place_of_birth.locative }}
+        {% else %}
+          {{ obj.place_of_birth.name }}
+        {% endif %}
+      {% endif %}
+    </dd>
+  {% endif %}
+  {% if obj.date_of_death or obj.place_of_death %}
+    <dt>Zm.</dt>
+    <dd>
+      {% if obj.date_of_death %}
+        {{ obj.date_of_death }}
+      {% endif %}
+      {% if obj.place_of_death %}
+        w
+        {% if obj.place_of_death.locative %}
+          {{ obj.place_of_death.locative }}
+        {% else %}
+          {{ obj.place_of_death.name }}
+        {% endif %}
+      {% endif %}
+    </dd>
+  {% endif %}
+
+  {% if obj.notablebook_set.exists %}
+    <dt>Najważniejsze dzieła:</dt>
+    <dd>
+      {% for nb in obj.notablebook_set.all %}
+        <i>{{ nb.book.title }}</i>{% if nb.book.original_year %}
+          ({{ nb.book.original_year }}){% endif %}{% if not forloop.last %}, {% endif %}
+      {% endfor %}
+    </dd>
+  {% endif %}
+
+</dl>
+
+{{ obj.description }}
index d4fd6b6..b762538 100644 (file)
@@ -20,4 +20,6 @@ urlpatterns = [
     path('terms/editor/', views.EditorTerms.as_view()),
 
     path('wikidata/<slug:model>/<qid>', views.WikidataView.as_view()),
     path('terms/editor/', views.EditorTerms.as_view()),
 
     path('wikidata/<slug:model>/<qid>', views.WikidataView.as_view()),
+
+    path('publish/author/<int:pk>/', views.publish_author, name='catalogue_publish_author'),
 ]
 ]
index 65b2980..c507aca 100644 (file)
@@ -4,9 +4,14 @@
 from django.apps import apps
 from django.db.models import Prefetch
 from django.http import Http404
 from django.apps import apps
 from django.db.models import Prefetch
 from django.http import Http404
+from django.urls import reverse
 from django.utils.formats import localize_input
 from django.utils.formats import localize_input
+from django.contrib.auth.decorators import login_required
 from django.contrib.auth.models import User
 from django.contrib.auth.models import User
+from django.shortcuts import get_object_or_404, redirect
+from django.views.decorators.http import require_POST
 from django.views.generic import DetailView, TemplateView
 from django.views.generic import DetailView, TemplateView
+import apiclient
 from . import models
 import documents.models
 from rest_framework.generics import ListAPIView
 from . import models
 import documents.models
 from rest_framework.generics import ListAPIView
@@ -126,6 +131,13 @@ class WikidataView(APIView):
                         "wd": d[fieldname].wikidata,
                         "label": str(d[fieldname]) or d[fieldname]._wikidata_label,
                     }
                         "wd": d[fieldname].wikidata,
                         "label": str(d[fieldname]) or d[fieldname]._wikidata_label,
                     }
+                elif hasattr(d[fieldname], 'all'):
+                    d[attname] = [
+                            {"model": type(item)._meta.model_name,
+                                "wd": item.wikidata,
+                                "label": str(item) or item._wikidata_label
+                                } for item in d[attname].all()
+                            ]
                 else:
                     d[fieldname] = localize_input(d[fieldname])
         return Response(d)
                 else:
                     d[fieldname] = localize_input(d[fieldname])
         return Response(d)
@@ -135,3 +147,16 @@ class WikidataView(APIView):
 
     def post(self, request, model, qid):
         return self.get_object(model, qid, save=True)
 
     def post(self, request, model, qid):
         return self.get_object(model, qid, save=True)
+
+
+@require_POST
+@login_required
+def publish_author(request, pk):
+    author = get_object_or_404(models.Author, pk=pk)
+    data = {
+        "description_pl": author.generate_description(),
+    }
+    apiclient.api_call(request.user, f"authors/{author.slug}/", data)
+    return redirect(reverse('admin:catalogue_author_change', args=[author.pk]))
+        
+    
index b5f3e94..3ec843a 100644 (file)
@@ -65,12 +65,16 @@ class WikidataModel(models.Model):
     def wikidata_fields_for_attribute(self, attname):
         field = getattr(type(self), attname)
         if type(self) in translator._registry:
     def wikidata_fields_for_attribute(self, attname):
         field = getattr(type(self), attname)
         if type(self) in translator._registry:
-            opts = translator.get_options_for_model(type(self))
-            if attname in opts.fields:
-                tfields = opts.fields[attname]
-                for tf in tfields:
-                    yield tf.name, tf.language
-                return
+            try:
+                opts = translator.get_options_for_model(type(self))
+            except:
+                pass
+            else:
+                if attname in opts.fields:
+                    tfields = opts.fields[attname]
+                    for tf in tfields:
+                        yield tf.name, tf.language
+                    return
 
         yield attname, settings.LANGUAGE_CODE
 
 
         yield attname, settings.LANGUAGE_CODE