e510391c42e41c9c706caf16fe8d540bc19295b3
[wolnelektury.git] / src / pdcounter / models.py
1 # This file is part of Wolnelektury, licensed under GNU Affero GPLv3 or later.
2 # Copyright © Fundacja Nowoczesna Polska. See NOTICE for more information.
3 #
4 from django.apps import apps
5 from django.conf import settings
6 from django.db import models
7 from django.urls import reverse
8 from datetime import datetime
9 from django.db.models.signals import post_save, post_delete
10 from search.utils import UnaccentSearchVector
11
12
13 class Author(models.Model):
14     name = models.CharField('imię i nazwisko', max_length=50, db_index=True)
15     slug = models.SlugField('slug', max_length=120, db_index=True, unique=True)
16     sort_key = models.CharField('klucz sortowania', max_length=120, db_index=True)
17     description = models.TextField('opis', blank=True)
18     death = models.IntegerField('rok śmierci', blank=True, null=True)
19     gazeta_link = models.CharField(blank=True, max_length=240)
20     wiki_link = models.CharField(blank=True, max_length=240)
21
22     class Meta:
23         ordering = ('sort_key',)
24         verbose_name = 'autor'
25         verbose_name_plural = 'autorzy'
26
27     @property
28     def category(self):
29         return "author"
30
31     def __str__(self):
32         return self.name
33
34     def __repr__(self):
35         return "Author(slug=%r)" % self.slug
36
37     def get_absolute_url(self):
38         return reverse('tagged_object_list', args=[self.url_chunk])
39
40     def has_description(self):
41         return len(self.description) > 0
42     has_description.short_description = 'opis'
43     has_description.boolean = True
44
45     @classmethod
46     def search(cls, query, qs=None):
47         Tag = apps.get_model('catalogue', 'Tag')
48         if qs is None:
49             qs = cls.objects.all()
50         pd_authors = qs.annotate(search_vector=UnaccentSearchVector('name')).filter(search_vector=query)
51         existing_slugs = Tag.objects.filter(
52             category='author', slug__in=list(pd_authors.values_list('slug', flat=True))) \
53             .values_list('slug', flat=True)
54         pd_authors = pd_authors.exclude(slug__in=existing_slugs)
55         return pd_authors
56
57     def alive(self):
58         return self.death is None
59
60     def in_pd(self):
61         """ tests whether an author is in public domain """
62         return self.death is not None and self.goes_to_pd() <= datetime.now().year
63
64     def goes_to_pd(self):
65         """ calculates the year of public domain entry for an author """
66         return self.death + 71 if self.death is not None else None
67
68     @property
69     def url_chunk(self):
70         return '/'.join(('autor', self.slug))
71
72
73 class BookStub(models.Model):
74     title = models.CharField('tytuł', max_length=120)
75     author = models.CharField('autor', max_length=120)
76     pd = models.IntegerField('trafia do domeny publicznej', null=True, blank=True)
77     slug = models.SlugField('slug', max_length=120, unique=True, db_index=True)
78     translator = models.TextField('tłumacz', blank=True)
79
80     class Meta:
81         ordering = ('title',)
82         verbose_name = 'zapowiedź książki'
83         verbose_name_plural = 'zapowiedzi książek'
84
85     def __str__(self):
86         return self.title
87
88     @classmethod
89     def search(cls, query, qs=None):
90         Book = apps.get_model('catalogue', 'Book')
91         if qs is None:
92             qs = cls.objects.all()
93         pd_books = qs.annotate(search_vector=UnaccentSearchVector('title')).filter(search_vector=query)
94         existing_slugs = Book.objects.filter(
95             slug__in=list(pd_books.values_list('slug', flat=True))) \
96             .values_list('slug', flat=True)
97         pd_books = pd_books.exclude(slug__in=existing_slugs)
98         return pd_books
99
100     def get_absolute_url(self):
101         return reverse('book_detail', args=[self.slug])
102
103     def in_pd(self):
104         return self.pd is not None and self.pd <= datetime.now().year
105
106     @property
107     def name(self):
108         return self.title
109
110     def pretty_title(self, html_links=False):
111         return ', '.join((self.author, self.title))