3 from django.apps import apps
4 from django.conf import settings
5 from django.db import models
6 from django.template import Context, Template
7 from django.utils.timezone import now
8 from .places import PLACES, PLACE_CHOICES, STYLES
11 class Banner(models.Model):
12 place = models.SlugField('miejsce', choices=PLACE_CHOICES)
13 style = models.CharField(
14 'styl', max_length=255, blank=True,
16 help_text='Dotyczy blackoutu.'
18 smallfont = models.BooleanField('mały font', default=False)
19 text_color = models.CharField(max_length=10, blank=True)
20 background_color = models.CharField(max_length=10, blank=True)
21 action_label = models.CharField(
23 max_length=255, blank=True,
24 help_text='Jeśli pusta, cały banner będzie służył jako link.'
26 open_label = models.CharField('etykieta otwierania', max_length=255, blank=True)
27 close_label = models.CharField('etykieta zamykania', max_length=255, blank=True)
28 text = models.TextField('tekst')
29 image = models.FileField('obraz', upload_to='annoy/banners/', blank=True)
30 url = models.CharField('URL', max_length=1024)
31 priority = models.PositiveSmallIntegerField(
32 'priorytet', default=0,
33 help_text='Bannery z wyższym priorytetem mają pierwszeństwo.')
34 since = models.DateTimeField('od', null=True, blank=True)
35 until = models.DateTimeField('do', null=True, blank=True)
36 show_members = models.BooleanField('widoczny dla członków klubu', default=False)
37 staff_preview = models.BooleanField('podgląd tylko dla zespołu', default=False)
38 only_authenticated = models.BooleanField('tylko dla zalogowanych', default=False)
41 verbose_name = 'banner'
42 verbose_name_plural = 'bannery'
43 ordering = ('place', '-priority',)
49 return Template(self.text).render(Context())
52 def choice(cls, place, request):
53 Membership = apps.get_model('club', 'Membership')
55 if hasattr(request, 'annoy_banner_exempt'):
56 return cls.objects.none()
59 assert place in PLACES, f"Banner place `{place}` must be defined in annoy.places."
62 banners = cls.objects.filter(
68 ).order_by('-priority', '?')
70 if not request.user.is_authenticated:
71 banners = banners.filter(only_authenticated=False)
73 if not request.user.is_staff:
74 banners = banners.filter(staff_preview=False)
76 if Membership.is_active_for(request.user):
77 banners = banners.filter(show_members=True)
82 class DynamicTextInsert(models.Model):
83 paragraphs = models.IntegerField('akapity')
84 url = models.CharField(max_length=1024)
87 verbose_name = 'dynamiczna wstawka'
88 verbose_name_plural = 'dynamiczne wstawki'
89 ordering = ('paragraphs', )
92 return str(self.paragraphs)
95 def get_all(cls, request):
96 Membership = apps.get_model('club', 'Membership')
97 if Membership.is_active_for(request.user) and not request.user.is_staff:
98 return cls.objects.none()
99 return cls.objects.all()
103 return self.dynamictextinserttext_set.order_by('?').first()
106 class DynamicTextInsertText(models.Model):
107 insert = models.ForeignKey(DynamicTextInsert, models.CASCADE)
108 own_colors = models.BooleanField(default=False)
109 background_color = models.CharField(max_length=10, blank=True)
110 text_color = models.CharField(max_length=10, blank=True)
111 text = models.TextField('tekst')
112 image = models.FileField(blank=True, upload_to='annoy/inserts/')
115 class MediaInsertSet(models.Model):
116 file_format = models.CharField(max_length=8, choices=[
120 etag = models.CharField(max_length=64, blank=True)
122 def update_etag(self):
123 self.etag = hashlib.sha1(json.dumps(self.get_texts()).encode('utf-8')).hexdigest()
124 self.save(update_fields=['etag'])
127 return [t.text for t in self.mediainserttext_set.all()]
130 def get_for_format(cls, file_format):
131 return cls.objects.filter(file_format=file_format).first()
134 def get_texts_for(cls, file_format):
135 self = cls.get_for_format(file_format)
138 return self.get_texts()
141 class MediaInsertText(models.Model):
142 media_insert_set = models.ForeignKey(MediaInsertSet, models.CASCADE)
143 ordering = models.IntegerField()
144 text = models.TextField()
147 ordering = ('ordering',)
150 from django.db.models.signals import post_save, post_delete
151 from django.dispatch import receiver
153 @receiver(post_delete, sender=MediaInsertText)
154 @receiver(post_save, sender=MediaInsertText)
155 def update_etag(sender, instance, **kwargs):
156 instance.media_insert_set.update_etag()