Projet

Général

Profil

Télécharger (4,98 ko) Statistiques
| Branche: | Tag: | Révision:

root / corbo / models.py @ d17392b7

1
from datetime import datetime
2
import logging
3
from html2text import HTML2Text
4
from emails.django import Message
5
from lxml.etree import HTML as HTMLTree
6

    
7
from django.utils import timezone
8
from django.conf import settings
9
from django.db import models
10
from django.core.files.storage import DefaultStorage
11
from django.utils.translation import ugettext_lazy as _
12
from django.core import signing
13
from django.template import loader, Context
14
from django.core.urlresolvers import reverse
15

    
16
from ckeditor.fields import RichTextField
17

    
18
channel_choices = (
19
    ('mailto', _('Email')),
20
    ('homepage', _('Homepage'))
21
)
22

    
23
logger = logging.getLogger(__name__)
24

    
25
class Category(models.Model):
26
    name = models.CharField(max_length=64, blank=False, null=False)
27
    ctime = models.DateTimeField(auto_now_add=True)
28

    
29
    def __unicode__(self):
30
        return self.name
31

    
32

    
33
class Announce(models.Model):
34
    category  = models.ForeignKey('Category', verbose_name=_('category'))
35
    title = models.CharField(_('title'), max_length=256,
36
                             help_text=_('maximum 256 characters'))
37
    text = RichTextField(_('Content'))
38
    publication_time = models.DateTimeField(_('publication time'), blank=True,
39
                                            null=True)
40
    expiration_time = models.DateTimeField(_('Expires on'), blank=True,
41
                                           null=True)
42
    ctime = models.DateTimeField(_('creation time'), auto_now_add=True)
43
    mtime = models.DateTimeField(_('modification time'), auto_now=True)
44

    
45
    def __unicode__(self):
46
        return u'{title} ({id}) at {mtime}'.format(title=self.title,
47
                                    id=self.id, mtime=self.mtime)
48

    
49
    def is_expired(self):
50
        if self.expiration_time:
51
            return self.expiration_time < timezone.now()
52
        return False
53

    
54
    def is_published(self):
55
        if self.is_expired():
56
            return False
57
        if self.publication_time:
58
            return self.publication_time <= timezone.now()
59
        return False
60

    
61
    class Meta:
62
        verbose_name = _('announce')
63
        ordering = ('-mtime',)
64

    
65

    
66
class Broadcast(models.Model):
67
    announce = models.ForeignKey(Announce, verbose_name=_('announce'))
68
    deliver_time = models.DateTimeField(_('Deliver time'), null=True)
69
    result = models.TextField(_('result'), blank=True)
70

    
71
    def __unicode__(self):
72
        if self.deliver_time:
73
            return u'announce {id} delivered via at {time}'.format(
74
                id=self.announce.id, time=self.deliver_time)
75
        return u'announce {id} to deliver'.format(id=self.announce.id)
76

    
77
    def send(self):
78
        subscriptions = self.announce.category.subscription_set.all()
79
        total_sent = 0
80
        handler = HTML2Text()
81
        template = loader.get_template('corbo/announce.html')
82
        m = Message(subject=self.announce.title, mail_from=settings.CORBO_DEFAULT_FROM_EMAIL)
83
        html_tree = HTMLTree(self.announce.text)
84
        storage = DefaultStorage()
85
        for img in html_tree.xpath('//img/@src'):
86
            img_path = img.lstrip(storage.base_url)
87
            m.attach(filename=img, data=storage.open(img_path))
88
            m.attachments[img].is_inline = True
89
        for s in subscriptions:
90
            if not s.identifier:
91
                continue
92
            unsubscribe_token = signing.dumps({'category': self.announce.category.pk,
93
                                               'identifier': s.identifier})
94
            unsubscribe_link = reverse('unsubscribe', kwargs={'unsubscription_token': unsubscribe_token})
95
            message = template.render(Context({'unsubscribe_link': unsubscribe_link,
96
                                               'content': self.announce.text}))
97
            m.html = message
98
            m.transformer.load_and_transform()
99
            m.transformer.synchronize_inline_images()
100
            m.transformer.save()
101
            handler.body_width = 0
102
            m.text = handler.handle(message)
103
            sent = m.send(to=s.identifier)
104
            if sent:
105
                total_sent += 1
106
                logger.info('Announce "%s" sent to %s', self.announce.title, s.identifier)
107
            else:
108
                logger.warning('Error occured while sending announce "%s" to %s.',
109
                               self.announce.title, s.identifier)
110
        self.result = total_sent
111
        self.deliver_time = timezone.now()
112
        self.save()
113

    
114
    class Meta:
115
        verbose_name = _('sent')
116
        ordering = ('-deliver_time',)
117

    
118

    
119
class Subscription(models.Model):
120
    category = models.ForeignKey('Category', verbose_name=_('Category'))
121
    uuid = models.CharField(_('User identifier'), max_length=128, blank=True)
122
    identifier = models.CharField(_('identifier'), max_length=128, blank=True,
123
            help_text=_('ex.: mailto, homepage, ...'))
124

    
125
    def get_identifier_display(self):
126
        try:
127
            scheme, identifier = self.identifier.split(':')
128
            return identifier
129
        except ValueError:
130
            return self.identifier
131

    
132
    class Meta:
133
        unique_together = ('category', 'identifier', 'uuid')
(6-6/11)