Phone not required.
[wolnelektury.git] / src / annoy / models.py
index c8fdf2d..f6dd827 100644 (file)
@@ -1,44 +1,46 @@
+import hashlib
+import json
 from django.apps import apps
 from django.conf import settings
 from django.db import models
 from django.template import Context, Template
 from django.apps import apps
 from django.conf import settings
 from django.db import models
 from django.template import Context, Template
-from django.utils.translation import gettext_lazy as _
 from django.utils.timezone import now
 from .places import PLACES, PLACE_CHOICES, STYLES
 
 
 class Banner(models.Model):
 from django.utils.timezone import now
 from .places import PLACES, PLACE_CHOICES, STYLES
 
 
 class Banner(models.Model):
-    place = models.SlugField(_('place'), choices=PLACE_CHOICES)
+    place = models.SlugField('miejsce', choices=PLACE_CHOICES)
     style = models.CharField(
     style = models.CharField(
-        _('style'), max_length=255, blank=True,
+        'styl', max_length=255, blank=True,
         choices=STYLES,
         choices=STYLES,
-        help_text=_('Affects blackout.')
     )
     )
-    smallfont = models.BooleanField(_('small font'), default=False)
+    smallfont = models.BooleanField('mały font', default=False)
     text_color = models.CharField(max_length=10, blank=True)
     background_color = models.CharField(max_length=10, blank=True)
     action_label = models.CharField(
     text_color = models.CharField(max_length=10, blank=True)
     background_color = models.CharField(max_length=10, blank=True)
     action_label = models.CharField(
-        _('action label'),
+        'etykieta akcji',
         max_length=255, blank=True,
         max_length=255, blank=True,
-        help_text=_('If empty, whole banner will serve as a link')
+        help_text='Jeśli pusta, cały banner będzie służył jako link.'
     )
     )
-    open_label = models.CharField(_('open label'), max_length=255, blank=True)
-    close_label = models.CharField(_('close label'), max_length=255, blank=True)
-    text = models.TextField(_('text'))
-    image = models.FileField(_('image'), upload_to='annoy/banners/', blank=True)
-    url = models.CharField(_('url'), max_length=1024)
+    open_label = models.CharField('etykieta otwierania', max_length=255, blank=True)
+    close_label = models.CharField('etykieta zamykania', max_length=255, blank=True)
+    text = models.TextField('tekst')
+    image = models.FileField('obraz', upload_to='annoy/banners/', blank=True)
+    url = models.CharField('URL', max_length=1024)
     priority = models.PositiveSmallIntegerField(
     priority = models.PositiveSmallIntegerField(
-        _('priority'), default=0,
-        help_text=_('Banners with higher priority come first.'))
-    since = models.DateTimeField(_('since'), null=True, blank=True)
-    until = models.DateTimeField(_('until'), null=True, blank=True)
-    show_members = models.BooleanField(_('show members'), default=False)
-    staff_preview = models.BooleanField(_('staff preview'), default=False)
-    only_authenticated = models.BooleanField(_('only for authenticated users'), default=False)
+        'priorytet', default=0,
+        help_text='Bannery z wyższym priorytetem mają pierwszeństwo.')
+    since = models.DateTimeField('od', null=True, blank=True)
+    until = models.DateTimeField('do', null=True, blank=True)
+    target = models.IntegerField('cel', null=True, blank=True)
+    progress = models.IntegerField('postęp', null=True, blank=True)
+    show_members = models.BooleanField('widoczny dla członków klubu', default=False)
+    staff_preview = models.BooleanField('podgląd tylko dla zespołu', default=False)
+    only_authenticated = models.BooleanField('tylko dla zalogowanych', default=False)
 
     class Meta:
 
     class Meta:
-        verbose_name = _('banner')
-        verbose_name_plural = _('banners')
+        verbose_name = 'banner'
+        verbose_name_plural = 'bannery'
         ordering = ('place', '-priority',)
 
     def __str__(self):
         ordering = ('place', '-priority',)
 
     def __str__(self):
@@ -48,10 +50,10 @@ class Banner(models.Model):
         return Template(self.text).render(Context())
 
     @classmethod
         return Template(self.text).render(Context())
 
     @classmethod
-    def choice(cls, place, request):
+    def choice(cls, place, request, exemptions=True):
         Membership = apps.get_model('club', 'Membership')
 
         Membership = apps.get_model('club', 'Membership')
 
-        if hasattr(request, 'annoy_banner_exempt'):
+        if exemptions and hasattr(request, 'annoy_banner_exempt'):
             return cls.objects.none()
 
         if settings.DEBUG:
             return cls.objects.none()
 
         if settings.DEBUG:
@@ -77,14 +79,37 @@ class Banner(models.Model):
 
         return banners
 
 
         return banners
 
+    @property
+    def progress_percent(self):
+        if not self.target:
+            return 0
+        return (self.progress or 0) / self.target * 100
+
+    def update_progress(self):
+        # Total of new payments during the action.
+        # This definition will need to change for longer timespans.
+        if not self.since or not self.until or not self.target:
+            return
+        Schedule = apps.get_model('club', 'Schedule')
+        self.progress = Schedule.objects.filter(
+            payed_at__gte=self.since,
+            payed_at__lte=self.until,
+        ).aggregate(c=models.Sum('amount'))['c']
+        self.save(update_fields=['progress'])
+
+    @classmethod
+    def update_all_progress(cls):
+        for obj in cls.objects.exclude(target=None):
+            obj.update_progress()
+
 
 class DynamicTextInsert(models.Model):
 
 class DynamicTextInsert(models.Model):
-    paragraphs = models.IntegerField(_('pararaphs'))
+    paragraphs = models.IntegerField('akapity')
     url = models.CharField(max_length=1024)
 
     class Meta:
     url = models.CharField(max_length=1024)
 
     class Meta:
-        verbose_name = _('dynamic insert')
-        verbose_name_plural = _('dynamic inserts')
+        verbose_name = 'dynamiczna wstawka'
+        verbose_name_plural = 'dynamiczne wstawki'
         ordering = ('paragraphs', )
 
     def __str__(self):
         ordering = ('paragraphs', )
 
     def __str__(self):
@@ -107,5 +132,41 @@ class DynamicTextInsertText(models.Model):
     own_colors = models.BooleanField(default=False)
     background_color = models.CharField(max_length=10, blank=True)
     text_color = models.CharField(max_length=10, blank=True)
     own_colors = models.BooleanField(default=False)
     background_color = models.CharField(max_length=10, blank=True)
     text_color = models.CharField(max_length=10, blank=True)
-    text = models.TextField(_('text'))
+    text = models.TextField('tekst')
     image = models.FileField(blank=True, upload_to='annoy/inserts/')
     image = models.FileField(blank=True, upload_to='annoy/inserts/')
+
+
+class MediaInsertSet(models.Model):
+    file_format = models.CharField(max_length=8, choices=[
+        ('epub', 'epub'),
+        ('mobi', 'mobi'),
+        ('pdf', 'pdf'),
+        ])
+    etag = models.CharField(max_length=64, blank=True)
+
+    def update_etag(self):
+        self.etag = hashlib.sha1(json.dumps(self.get_texts()).encode('utf-8')).hexdigest()
+        self.save(update_fields=['etag'])
+
+    def get_texts(self):
+        return [t.text for t in self.mediainserttext_set.all()]
+
+    @classmethod
+    def get_for_format(cls, file_format):
+        return cls.objects.filter(file_format=file_format).first()
+
+    @classmethod
+    def get_texts_for(cls, file_format):
+        self = cls.get_for_format(file_format)
+        if self is None:
+            return []
+        return self.get_texts()
+
+
+class MediaInsertText(models.Model):
+    media_insert_set = models.ForeignKey(MediaInsertSet, models.CASCADE)
+    ordering = models.IntegerField()
+    text = models.TextField()
+
+    class Meta:
+        ordering = ('ordering',)