Fixes #4076: Recommendations from collections.
[wolnelektury.git] / src / annoy / models.py
1 from django.apps import apps
2 from django.conf import settings
3 from django.db import models
4 from django.template import Context, Template
5 from django.utils.translation import ugettext_lazy as _
6 from django.utils.timezone import now
7 from .places import PLACES, PLACE_CHOICES
8
9
10 class Banner(models.Model):
11     place = models.SlugField(_('place'), choices=PLACE_CHOICES)
12     action_label = models.CharField(
13         _('action label'),
14         max_length=255, blank=True,
15         help_text=_('If empty, whole banner will serve as a link')
16     )
17     open_label = models.CharField(_('open label'), max_length=255, blank=True)
18     close_label = models.CharField(_('close label'), max_length=255, blank=True)
19     text = models.TextField(_('text'))
20     image = models.FileField(_('image'), upload_to='annoy/banners/', blank=True)
21     url = models.CharField(_('url'), max_length=1024)
22     priority = models.PositiveSmallIntegerField(
23         _('priority'), default=0,
24         help_text=_('Banners with higher priority come first.'))
25     since = models.DateTimeField(_('since'), null=True, blank=True)
26     until = models.DateTimeField(_('until'), null=True, blank=True)
27     show_members = models.BooleanField(_('show members'), default=False)
28     staff_preview = models.BooleanField(_('staff preview'), default=False)
29
30     class Meta:
31         verbose_name = _('banner')
32         verbose_name_plural = _('banners')
33         ordering = ('place', '-priority',)
34
35     def __str__(self):
36         return self.text
37
38     def get_text(self):
39         return Template(self.text).render(Context())
40
41     @classmethod
42     def choice(cls, place, request):
43         Membership = apps.get_model('club', 'Membership')
44
45         if hasattr(request, 'annoy_banner_exempt'):
46             return cls.objects.none()
47
48         if settings.DEBUG:
49             assert place in PLACES, f"Banner place `{place}` must be defined in annoy.places."
50
51         n = now()
52         banners = cls.objects.filter(
53             place=place
54         ).exclude(
55             since__gt=n
56         ).exclude(
57             until__lt=n
58         ).order_by('-priority', '?')
59
60         if not request.user.is_staff:
61             banners = banners.filter(staff_preview=False)
62
63         if request:
64             if Membership.is_active_for(request.user):
65                 banners = banners.filter(show_members=True)
66         return banners
67
68
69 class DynamicTextInsert(models.Model):
70     paragraphs = models.IntegerField(_('pararaphs'))
71     url = models.CharField(max_length=1024)
72
73     class Meta:
74         verbose_name = _('dynamic insert')
75         verbose_name_plural = _('dynamic inserts')
76         ordering = ('paragraphs', )
77
78     def __str__(self):
79         return str(self.paragraphs)
80
81     @classmethod
82     def get_all(cls, request):
83         Membership = apps.get_model('club', 'Membership')
84         if Membership.is_active_for(request.user) and not request.user.is_staff:
85             return cls.objects.none()
86         return cls.objects.all()
87
88
89     def choose(self):
90         return self.dynamictextinserttext_set.order_by('?').first()
91
92
93 class DynamicTextInsertText(models.Model):
94     insert = models.ForeignKey(DynamicTextInsert, models.CASCADE)
95     own_colors = models.BooleanField(default=False)
96     background_color = models.CharField(max_length=10, blank=True)
97     text_color = models.CharField(max_length=10, blank=True)
98     text = models.TextField(_('text'))
99     image = models.FileField(blank=True, upload_to='annoy/inserts/')