X-Git-Url: https://git.mdrn.pl/redakcja.git/blobdiff_plain/e23ceedf469dc115c335f497c6c3e0834cda0ebc..refs/heads/master:/src/catalogue/models.py diff --git a/src/catalogue/models.py b/src/catalogue/models.py index 8db23ab3..d4111cb2 100644 --- a/src/catalogue/models.py +++ b/src/catalogue/models.py @@ -1,6 +1,7 @@ from collections import Counter from datetime import date, timedelta import decimal +import io import re from urllib.request import urlopen from django.apps import apps @@ -11,6 +12,9 @@ from django.urls import reverse from django.utils.translation import gettext_lazy as _ from admin_ordering.models import OrderableModel from wikidata.client import Client +from librarian import DCNS +from librarian.cover import make_cover +from librarian.dcparser import BookInfo, Person from .constants import WIKIDATA from .wikidata import WikidataModel from .wikimedia import WikiMedia @@ -198,6 +202,9 @@ class NotableBook(OrderableModel): author = models.ForeignKey(Author, models.CASCADE) book = models.ForeignKey('Book', models.CASCADE) + def __str__(self): + return self.book.title + class Category(WikidataModel): name = models.CharField(_("name"), max_length=255) @@ -227,6 +234,10 @@ class Epoch(Category): class Genre(Category): + thema = models.CharField( + max_length=32, blank=True, + help_text='Odpowiadający kwalifikator Thema.' + ) plural = models.CharField( 'liczba mnoga', max_length=255, blank=True, ) @@ -253,6 +264,8 @@ class Kind(Category): class Book(WikidataModel): slug = models.SlugField(max_length=255, blank=True, null=True, unique=True) + parent = models.ForeignKey('self', models.SET_NULL, null=True, blank=True) + parent_number = models.IntegerField(null=True, blank=True) authors = models.ManyToManyField(Author, blank=True, verbose_name=_("authors")) translators = models.ManyToManyField( Author, @@ -290,6 +303,8 @@ class Book(WikidataModel): free_license = models.BooleanField(_('free license'), default=False) polona_missing = models.BooleanField(_('missing on Polona'), default=False) + cover = models.FileField(blank=True, upload_to='catalogue/cover') + monthly_views_reader = models.IntegerField(default=0) monthly_views_page = models.IntegerField(default=0) @@ -320,6 +335,25 @@ class Book(WikidataModel): txt = f"{txt}, tłum. {tstr}" return txt + def build_cover(self): + width, height = 212, 300 + # TODO: BookInfo shouldn't be required to build a cover. + info = BookInfo(rdf_attrs={}, dc_fields={ + DCNS('creator'): [Person('Mickiewicz', 'Adam')], + DCNS('title'): ['Ziutek'], + DCNS('date'): ['1900-01-01'], + DCNS('publisher'): ['F'], + DCNS('language'): ['pol'], + DCNS('identifier.url'): ['test'], + DCNS('rights'): ['-'], + }) + cover = make_cover(info, width=width, height=height) + out = io.BytesIO() + ext = cover.ext() + cover.save(out) + self.cover.save(f'{self.slug}.{ext}', out, save=False) + type(self).objects.filter(pk=self.pk).update(cover=self.cover) + def get_absolute_url(self): return reverse("catalogue_book", args=[self.slug]) @@ -377,11 +411,8 @@ class Book(WikidataModel): for work_type in WorkType.objects.all() } - def scans_gallery(self): - bs = self.booksource_set.first() - if bs is None: - return '' - return bs.pk + def scans_galleries(self): + return [bs.pk for bs in self.booksource_set.all()] def is_published(self): return any(b.is_published() for b in self.document_books.all()) @@ -422,6 +453,15 @@ class Book(WikidataModel): self._content_stats = stats return stats + @property + def are_sources_ready(self): + if not self.booksource_set.exists(): + return False + for bs in self.booksource_set.all(): + if not bs.source.has_view_files() or not bs.source.has_ocr_files() or bs.source.modified_at > bs.source.processed_at: + return False + return True + chars = lambda self: self.content_stats.get('chars', '') chars_with_fn = lambda self: self.content_stats.get('chars_with_fn', '') words = lambda self: self.content_stats.get('words', '') @@ -431,6 +471,18 @@ class Book(WikidataModel): chars_out_verse = lambda self: self.content_stats.get('chars_out_verse', '') chars_out_verse_with_fn = lambda self: self.content_stats.get('chars_out_verse_with_fn', '') + +class EditorNote(models.Model): + book = models.ForeignKey(Book, models.CASCADE) + user = models.ForeignKey(settings.AUTH_USER_MODEL, models.CASCADE) + created_at = models.DateTimeField(auto_now_add=True) + changed_at = models.DateTimeField(auto_now=True) + note = models.TextField(blank=True) + rate = models.IntegerField(default=3, choices=[ + (n, n) for n in range(1, 6) + ]) + + class CollectionCategory(models.Model): name = models.CharField(_("name"), max_length=255) parent = models.ForeignKey('self', models.SET_NULL, related_name='children', null=True, blank=True, verbose_name=_("parent")) @@ -590,7 +642,12 @@ class BookMonthlyStats(models.Model): class Thema(models.Model): - code = models.CharField(max_length=128, unique=True) + code = models.CharField( + max_length=128, unique=True, + help_text='Używamy rozszerzenia .WL- do oznaczania własnych kodów.
' + 'Przykładowo, w przypadku potrzeby stworzenia nowej kategorii „insurekcja kościuszkowska”, ' + 'można by ją utworzyć jako 3MLQ‑PL‑A.WL-A, czyli w ramach już istniejącej wyższej kategorii 3MLQ‑PL‑A „rozbiory Polski”.', + ) name = models.CharField(max_length=1024) slug = models.SlugField( max_length=255, null=True, blank=True, unique=True,