682e97bc39fa20075690d210fb80f8fc7c9784f8
[redakcja.git] / src / catalogue / models.py
1 from django.apps import apps
2 from django.db import models
3 from django.urls import reverse
4 from django.utils.translation import gettext_lazy as _
5 from wikidata.client import Client
6 from .constants import WIKIDATA
7 from .utils import UnrelatedManager
8 from .wikidata import WikidataMixin
9
10
11 class Author(WikidataMixin, models.Model):
12     slug = models.SlugField(max_length=255, null=True, blank=True, unique=True)
13     first_name = models.CharField(max_length=255, blank=True)
14     last_name = models.CharField(max_length=255, blank=True)
15
16     name_de = models.CharField(max_length=255, blank=True)
17     name_lt = models.CharField(max_length=255, blank=True)
18
19     gender = models.CharField(max_length=255, blank=True)
20     nationality = models.CharField(max_length=255, blank=True)
21     year_of_death = models.SmallIntegerField(null=True, blank=True)
22     status = models.PositiveSmallIntegerField(
23         null=True,
24         blank=True,
25         choices=[
26             (1, _("Alive")),
27             (2, _("Dead")),
28             (3, _("Long dead")),
29             (4, _("Unknown")),
30         ],
31     )
32     notes = models.TextField(blank=True)
33     gazeta_link = models.CharField(max_length=255, blank=True)
34     culturepl_link = models.CharField(max_length=255, blank=True)
35
36     description = models.TextField(blank=True)
37     description_de = models.TextField(blank=True)
38     description_lt = models.TextField(blank=True)
39
40     priority = models.PositiveSmallIntegerField(
41         default=0, choices=[(0, _("Low")), (1, _("Medium")), (2, _("High"))]
42     )
43     collections = models.ManyToManyField("Collection", blank=True)
44
45     class Meta:
46         verbose_name = _('author')
47         verbose_name_plural = _('authors')
48         ordering = ("last_name", "first_name", "year_of_death")
49
50     class Wikidata:
51         first_name = WIKIDATA.GIVEN_NAME
52         last_name = WIKIDATA.LAST_NAME
53         year_of_death = WIKIDATA.DATE_OF_DEATH
54         gender = WIKIDATA.GENDER
55         notes = "description"
56
57     def __str__(self):
58         return f"{self.first_name} {self.last_name}"
59
60     def get_absolute_url(self):
61         return reverse("catalogue_author", args=[self.slug])
62
63     @property
64     def pd_year(self):
65         if self.year_of_death:
66             return self.year_of_death + 71
67         elif self.year_of_death == 0:
68             return 0
69         else:
70             return None
71
72
73 class Category(WikidataMixin, models.Model):
74     name = models.CharField(max_length=255)
75     slug = models.SlugField(max_length=255, unique=True)
76
77     class Meta:
78         abstract = True
79
80
81 class Epoch(Category):
82     class Meta:
83         verbose_name = _('epoch')
84         verbose_name_plural = _('epochs')
85
86
87 class Genre(Category):
88     class Meta:
89         verbose_name = _('genre')
90         verbose_name_plural = _('genres')
91
92
93 class Kind(Category):
94     class Meta:
95         verbose_name = _('kind')
96         verbose_name_plural = _('kinds')
97
98
99 class Book(WikidataMixin, models.Model):
100     slug = models.SlugField(max_length=255, blank=True, null=True, unique=True)
101     authors = models.ManyToManyField(Author, blank=True)
102     translators = models.ManyToManyField(
103         Author,
104         related_name="translated_book_set",
105         related_query_name="translated_book",
106         blank=True,
107     )
108     epochs = models.ManyToManyField(Epoch, blank=True)
109     kinds = models.ManyToManyField(Kind, blank=True)
110     genres = models.ManyToManyField(Genre, blank=True)
111     title = models.CharField(max_length=255, blank=True)
112     language = models.CharField(max_length=255, blank=True)
113     based_on = models.ForeignKey(
114         "self", models.PROTECT, related_name="translation", null=True, blank=True
115     )
116     scans_source = models.CharField(max_length=255, blank=True)
117     text_source = models.CharField(max_length=255, blank=True)
118     notes = models.TextField(blank=True)
119     priority = models.PositiveSmallIntegerField(
120         default=0, choices=[(0, _("Low")), (1, _("Medium")), (2, _("High"))]
121     )
122     pd_year = models.IntegerField(null=True, blank=True)
123     gazeta_link = models.CharField(max_length=255, blank=True)
124     collections = models.ManyToManyField("Collection", blank=True)
125
126     objects = UnrelatedManager()
127
128     class Meta:
129         ordering = ("title",)
130         verbose_name = _('book')
131         verbose_name_plural = _('books')
132
133     class Wikidata:
134         authors = WIKIDATA.AUTHOR
135         translators = WIKIDATA.TRANSLATOR
136         title = WIKIDATA.TITLE
137         language = WIKIDATA.LANGUAGE
138         based_on = WIKIDATA.BASED_ON
139         notes = "description"
140
141     def __str__(self):
142         txt = self.title
143         astr = self.authors_str()
144         if astr:
145             txt = f"{astr} – {txt}"
146         tstr = self.translators_str()
147         if tstr:
148             txt = f"{txt} (tłum. {tstr})"
149         return txt
150
151     def get_absolute_url(self):
152         return reverse("catalogue_book", args=[self.slug])
153     
154     def authors_str(self):
155         return ", ".join(str(author) for author in self.authors.all())
156
157     def translators_str(self):
158         return ", ".join(str(author) for author in self.translators.all())
159
160     def get_document_books(self):
161         DBook = apps.get_model("documents", "Book")
162         return DBook.objects.filter(dc_slug=self.slug)
163
164
165 class Collection(models.Model):
166     name = models.CharField(max_length=255)
167     slug = models.SlugField(max_length=255, unique=True)
168
169     class Meta:
170         verbose_name = _('collection')
171         verbose_name_plural = _('collections')
172
173     def __str__(self):
174         return self.name
175