Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / functions.py @ be62cfa8

History | View | Annotate | Download (20.7 kB)

1 f36af44a Antony Chazapis
# Copyright 2011 GRNET S.A. All rights reserved.
2 5ce3ce4f Sofia Papagiannaki
#
3 f36af44a Antony Chazapis
# Redistribution and use in source and binary forms, with or
4 f36af44a Antony Chazapis
# without modification, are permitted provided that the following
5 f36af44a Antony Chazapis
# conditions are met:
6 5ce3ce4f Sofia Papagiannaki
#
7 f36af44a Antony Chazapis
#   1. Redistributions of source code must retain the above
8 f36af44a Antony Chazapis
#      copyright notice, this list of conditions and the following
9 f36af44a Antony Chazapis
#      disclaimer.
10 5ce3ce4f Sofia Papagiannaki
#
11 f36af44a Antony Chazapis
#   2. Redistributions in binary form must reproduce the above
12 f36af44a Antony Chazapis
#      copyright notice, this list of conditions and the following
13 f36af44a Antony Chazapis
#      disclaimer in the documentation and/or other materials
14 f36af44a Antony Chazapis
#      provided with the distribution.
15 5ce3ce4f Sofia Papagiannaki
#
16 f36af44a Antony Chazapis
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 f36af44a Antony Chazapis
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 f36af44a Antony Chazapis
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 f36af44a Antony Chazapis
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 f36af44a Antony Chazapis
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 f36af44a Antony Chazapis
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 f36af44a Antony Chazapis
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 f36af44a Antony Chazapis
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 f36af44a Antony Chazapis
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 f36af44a Antony Chazapis
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 f36af44a Antony Chazapis
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 f36af44a Antony Chazapis
# POSSIBILITY OF SUCH DAMAGE.
28 5ce3ce4f Sofia Papagiannaki
#
29 f36af44a Antony Chazapis
# The views and conclusions contained in the software and
30 f36af44a Antony Chazapis
# documentation are those of the authors and should not be
31 f36af44a Antony Chazapis
# interpreted as representing official policies, either expressed
32 f36af44a Antony Chazapis
# or implied, of GRNET S.A.
33 f36af44a Antony Chazapis
34 f36af44a Antony Chazapis
import logging
35 8f5a3a06 Sofia Papagiannaki
import socket
36 f36af44a Antony Chazapis
37 f36af44a Antony Chazapis
from django.utils.translation import ugettext as _
38 f36af44a Antony Chazapis
from django.template.loader import render_to_string
39 f36af44a Antony Chazapis
from django.core.mail import send_mail
40 f36af44a Antony Chazapis
from django.core.urlresolvers import reverse
41 49790d9d Sofia Papagiannaki
from django.template import Context, loader
42 bf0c6de5 Sofia Papagiannaki
from django.contrib.auth import (
43 bf0c6de5 Sofia Papagiannaki
    login as auth_login,
44 73fbaec4 Sofia Papagiannaki
    logout as auth_logout)
45 1cbce16f Sofia Papagiannaki
from django.conf import settings
46 9a06d96f Olga Brani
from django.contrib.auth.models import AnonymousUser
47 73fbaec4 Sofia Papagiannaki
from django.core.exceptions import PermissionDenied
48 27e26a41 Sofia Papagiannaki
49 683cf244 Sofia Papagiannaki
from urllib import quote
50 f36af44a Antony Chazapis
from urlparse import urljoin
51 8f5a3a06 Sofia Papagiannaki
from smtplib import SMTPException
52 751d24cf Sofia Papagiannaki
from datetime import datetime
53 111f3da6 Sofia Papagiannaki
from functools import wraps
54 f36af44a Antony Chazapis
55 bf0c6de5 Sofia Papagiannaki
from astakos.im.settings import (
56 c0b26605 Sofia Papagiannaki
    DEFAULT_CONTACT_EMAIL, SITENAME, BASEURL, LOGGING_LEVEL,
57 c0b26605 Sofia Papagiannaki
    VERIFICATION_EMAIL_SUBJECT, ACCOUNT_CREATION_SUBJECT,
58 c0b26605 Sofia Papagiannaki
    GROUP_CREATION_SUBJECT, HELPDESK_NOTIFICATION_EMAIL_SUBJECT,
59 c0b26605 Sofia Papagiannaki
    INVITATION_EMAIL_SUBJECT, GREETING_EMAIL_SUBJECT, FEEDBACK_EMAIL_SUBJECT,
60 73fbaec4 Sofia Papagiannaki
    EMAIL_CHANGE_EMAIL_SUBJECT,
61 73fbaec4 Sofia Papagiannaki
    PROJECT_CREATION_SUBJECT, PROJECT_APPROVED_SUBJECT,
62 73fbaec4 Sofia Papagiannaki
    PROJECT_TERMINATION_SUBJECT, PROJECT_SUSPENSION_SUBJECT,
63 73fbaec4 Sofia Papagiannaki
    PROJECT_MEMBERSHIP_CHANGE_SUBJECT)
64 73fbaec4 Sofia Papagiannaki
from astakos.im.notifications import build_notification, NotificationError
65 73fbaec4 Sofia Papagiannaki
from astakos.im.models import (
66 73fbaec4 Sofia Papagiannaki
    ProjectMembership, ProjectApplication)
67 73fbaec4 Sofia Papagiannaki
68 ae497612 Olga Brani
import astakos.im.messages as astakos_messages
69 f36af44a Antony Chazapis
70 f36af44a Antony Chazapis
logger = logging.getLogger(__name__)
71 f36af44a Antony Chazapis
72 5ce3ce4f Sofia Papagiannaki
73 111f3da6 Sofia Papagiannaki
def logged(func, msg):
74 111f3da6 Sofia Papagiannaki
    @wraps(func)
75 111f3da6 Sofia Papagiannaki
    def with_logging(*args, **kwargs):
76 111f3da6 Sofia Papagiannaki
        email = ''
77 111f3da6 Sofia Papagiannaki
        user = None
78 9a06d96f Olga Brani
        try:
79 111f3da6 Sofia Papagiannaki
            request = args[0]
80 9a06d96f Olga Brani
            email = request.user.email
81 9a06d96f Olga Brani
        except (KeyError, AttributeError), e:
82 9a06d96f Olga Brani
            email = ''
83 111f3da6 Sofia Papagiannaki
        r = func(*args, **kwargs)
84 c9e378c7 Sofia Papagiannaki
        if LOGGING_LEVEL:
85 aab4d540 Sofia Papagiannaki
            logger.log(LOGGING_LEVEL, msg % email)
86 111f3da6 Sofia Papagiannaki
        return r
87 111f3da6 Sofia Papagiannaki
    return with_logging
88 111f3da6 Sofia Papagiannaki
89 bf0c6de5 Sofia Papagiannaki
90 bf0c6de5 Sofia Papagiannaki
def login(request, user):
91 bf0c6de5 Sofia Papagiannaki
    auth_login(request, user)
92 c3c2212a Sofia Papagiannaki
    from astakos.im.models import SessionCatalog
93 c3c2212a Sofia Papagiannaki
    SessionCatalog(
94 c0b26605 Sofia Papagiannaki
        session_key=request.session.session_key,
95 c3c2212a Sofia Papagiannaki
        user=user
96 c3c2212a Sofia Papagiannaki
    ).save()
97 bf0c6de5 Sofia Papagiannaki
98 bf0c6de5 Sofia Papagiannaki
login = logged(login, '%s logged in.')
99 111f3da6 Sofia Papagiannaki
logout = logged(auth_logout, '%s logged out.')
100 111f3da6 Sofia Papagiannaki
101 5ce3ce4f Sofia Papagiannaki
102 683cf244 Sofia Papagiannaki
def send_verification(user, template_name='im/activation_email.txt'):
103 f36af44a Antony Chazapis
    """
104 683cf244 Sofia Papagiannaki
    Send email to user to verify his/her email and activate his/her account.
105 5ce3ce4f Sofia Papagiannaki

106 8f5a3a06 Sofia Papagiannaki
    Raises SendVerificationError
107 f36af44a Antony Chazapis
    """
108 6ff7a7ca Sofia Papagiannaki
    url = '%s?auth=%s&next=%s' % (urljoin(BASEURL, reverse('activate')),
109 5ce3ce4f Sofia Papagiannaki
                                  quote(user.auth_token),
110 5ce3ce4f Sofia Papagiannaki
                                  quote(urljoin(BASEURL, reverse('index'))))
111 683cf244 Sofia Papagiannaki
    message = render_to_string(template_name, {
112 5ce3ce4f Sofia Papagiannaki
                               'user': user,
113 5ce3ce4f Sofia Papagiannaki
                               'url': url,
114 5ce3ce4f Sofia Papagiannaki
                               'baseurl': BASEURL,
115 5ce3ce4f Sofia Papagiannaki
                               'site_name': SITENAME,
116 5ce3ce4f Sofia Papagiannaki
                               'support': DEFAULT_CONTACT_EMAIL})
117 1cbce16f Sofia Papagiannaki
    sender = settings.SERVER_EMAIL
118 8f5a3a06 Sofia Papagiannaki
    try:
119 1fcf4a99 Kostas Papadimitriou
        send_mail(_(VERIFICATION_EMAIL_SUBJECT), message, sender, [user.email])
120 8f5a3a06 Sofia Papagiannaki
    except (SMTPException, socket.error) as e:
121 8f5a3a06 Sofia Papagiannaki
        logger.exception(e)
122 8f5a3a06 Sofia Papagiannaki
        raise SendVerificationError()
123 8f5a3a06 Sofia Papagiannaki
    else:
124 111f3da6 Sofia Papagiannaki
        msg = 'Sent activation %s' % user.email
125 aab4d540 Sofia Papagiannaki
        logger.log(LOGGING_LEVEL, msg)
126 683cf244 Sofia Papagiannaki
127 5ce3ce4f Sofia Papagiannaki
128 751d24cf Sofia Papagiannaki
def send_activation(user, template_name='im/activation_email.txt'):
129 751d24cf Sofia Papagiannaki
    send_verification(user, template_name)
130 751d24cf Sofia Papagiannaki
    user.activation_sent = datetime.now()
131 751d24cf Sofia Papagiannaki
    user.save()
132 683cf244 Sofia Papagiannaki
133 5ce3ce4f Sofia Papagiannaki
134 9a06d96f Olga Brani
def _send_admin_notification(template_name,
135 9a06d96f Olga Brani
                             dictionary=None,
136 9a06d96f Olga Brani
                             subject='alpha2 testing notification',):
137 683cf244 Sofia Papagiannaki
    """
138 1cbce16f Sofia Papagiannaki
    Send notification email to settings.ADMINS.
139 5ce3ce4f Sofia Papagiannaki

140 8f5a3a06 Sofia Papagiannaki
    Raises SendNotificationError
141 683cf244 Sofia Papagiannaki
    """
142 1cbce16f Sofia Papagiannaki
    if not settings.ADMINS:
143 683cf244 Sofia Papagiannaki
        return
144 aab4d540 Sofia Papagiannaki
    dictionary = dictionary or {}
145 3abf6c78 Sofia Papagiannaki
    message = render_to_string(template_name, dictionary)
146 1cbce16f Sofia Papagiannaki
    sender = settings.SERVER_EMAIL
147 8f5a3a06 Sofia Papagiannaki
    try:
148 9a06d96f Olga Brani
        send_mail(subject,
149 8cc49f4d Sofia Papagiannaki
                  message, sender, [i[1] for i in settings.ADMINS])
150 8f5a3a06 Sofia Papagiannaki
    except (SMTPException, socket.error) as e:
151 8f5a3a06 Sofia Papagiannaki
        logger.exception(e)
152 8f5a3a06 Sofia Papagiannaki
        raise SendNotificationError()
153 8f5a3a06 Sofia Papagiannaki
    else:
154 4327c8fc Kostas Papadimitriou
        msg = 'Sent admin notification for user %s' % dictionary.get('email',
155 4327c8fc Kostas Papadimitriou
                                                                     None)
156 aab4d540 Sofia Papagiannaki
        logger.log(LOGGING_LEVEL, msg)
157 683cf244 Sofia Papagiannaki
158 5ce3ce4f Sofia Papagiannaki
159 9a06d96f Olga Brani
def send_account_creation_notification(template_name, dictionary=None):
160 9a06d96f Olga Brani
    user = dictionary.get('user', AnonymousUser())
161 29b87e7c Sofia Papagiannaki
    subject = _(ACCOUNT_CREATION_SUBJECT) % {'user':user.get('email', '')}
162 9a06d96f Olga Brani
    return _send_admin_notification(template_name, dictionary, subject=subject)
163 9a06d96f Olga Brani
164 9a06d96f Olga Brani
165 9a06d96f Olga Brani
def send_group_creation_notification(template_name, dictionary=None):
166 c3c2212a Sofia Papagiannaki
    group = dictionary.get('group')
167 c3c2212a Sofia Papagiannaki
    if not group:
168 c3c2212a Sofia Papagiannaki
        return
169 29b87e7c Sofia Papagiannaki
    subject = _(GROUP_CREATION_SUBJECT) % {'group':group.get('name', '')}
170 9a06d96f Olga Brani
    return _send_admin_notification(template_name, dictionary, subject=subject)
171 9a06d96f Olga Brani
172 9a06d96f Olga Brani
173 f9aea9c8 Sofia Papagiannaki
def send_helpdesk_notification(user, template_name='im/helpdesk_notification.txt'):
174 a0be6a0c Sofia Papagiannaki
    """
175 a0be6a0c Sofia Papagiannaki
    Send email to DEFAULT_CONTACT_EMAIL to notify for a new user activation.
176 5ce3ce4f Sofia Papagiannaki

177 a0be6a0c Sofia Papagiannaki
    Raises SendNotificationError
178 a0be6a0c Sofia Papagiannaki
    """
179 a0be6a0c Sofia Papagiannaki
    if not DEFAULT_CONTACT_EMAIL:
180 a0be6a0c Sofia Papagiannaki
        return
181 3abf6c78 Sofia Papagiannaki
    message = render_to_string(
182 3abf6c78 Sofia Papagiannaki
        template_name,
183 3abf6c78 Sofia Papagiannaki
        {'user': user}
184 3abf6c78 Sofia Papagiannaki
    )
185 1cbce16f Sofia Papagiannaki
    sender = settings.SERVER_EMAIL
186 a0be6a0c Sofia Papagiannaki
    try:
187 9a06d96f Olga Brani
        send_mail(
188 9a06d96f Olga Brani
            _(HELPDESK_NOTIFICATION_EMAIL_SUBJECT) % {'user': user.email},
189 9a06d96f Olga Brani
            message, sender, [DEFAULT_CONTACT_EMAIL])
190 a0be6a0c Sofia Papagiannaki
    except (SMTPException, socket.error) as e:
191 a0be6a0c Sofia Papagiannaki
        logger.exception(e)
192 a0be6a0c Sofia Papagiannaki
        raise SendNotificationError()
193 a0be6a0c Sofia Papagiannaki
    else:
194 3abf6c78 Sofia Papagiannaki
        msg = 'Sent helpdesk admin notification for %s' % user.email
195 aab4d540 Sofia Papagiannaki
        logger.log(LOGGING_LEVEL, msg)
196 a0be6a0c Sofia Papagiannaki
197 5ce3ce4f Sofia Papagiannaki
198 683cf244 Sofia Papagiannaki
def send_invitation(invitation, template_name='im/invitation.txt'):
199 683cf244 Sofia Papagiannaki
    """
200 683cf244 Sofia Papagiannaki
    Send invitation email.
201 5ce3ce4f Sofia Papagiannaki

202 8f5a3a06 Sofia Papagiannaki
    Raises SendInvitationError
203 683cf244 Sofia Papagiannaki
    """
204 1fcf4a99 Kostas Papadimitriou
    subject = _(INVITATION_EMAIL_SUBJECT)
205 6ff7a7ca Sofia Papagiannaki
    url = '%s?code=%d' % (urljoin(BASEURL, reverse('index')), invitation.code)
206 aab4d540 Sofia Papagiannaki
    message = render_to_string(template_name, {
207 5ce3ce4f Sofia Papagiannaki
                               'invitation': invitation,
208 5ce3ce4f Sofia Papagiannaki
                               'url': url,
209 5ce3ce4f Sofia Papagiannaki
                               'baseurl': BASEURL,
210 5ce3ce4f Sofia Papagiannaki
                               'site_name': SITENAME,
211 5ce3ce4f Sofia Papagiannaki
                               'support': DEFAULT_CONTACT_EMAIL})
212 1cbce16f Sofia Papagiannaki
    sender = settings.SERVER_EMAIL
213 8f5a3a06 Sofia Papagiannaki
    try:
214 8f5a3a06 Sofia Papagiannaki
        send_mail(subject, message, sender, [invitation.username])
215 8f5a3a06 Sofia Papagiannaki
    except (SMTPException, socket.error) as e:
216 8f5a3a06 Sofia Papagiannaki
        logger.exception(e)
217 8f5a3a06 Sofia Papagiannaki
        raise SendInvitationError()
218 8f5a3a06 Sofia Papagiannaki
    else:
219 111f3da6 Sofia Papagiannaki
        msg = 'Sent invitation %s' % invitation
220 aab4d540 Sofia Papagiannaki
        logger.log(LOGGING_LEVEL, msg)
221 c0b26605 Sofia Papagiannaki
        invitation.inviter.invitations = max(0, invitation.inviter.invitations - 1)
222 9a06d96f Olga Brani
        invitation.inviter.save()
223 683cf244 Sofia Papagiannaki
224 5ce3ce4f Sofia Papagiannaki
225 683cf244 Sofia Papagiannaki
def send_greeting(user, email_template_name='im/welcome_email.txt'):
226 683cf244 Sofia Papagiannaki
    """
227 683cf244 Sofia Papagiannaki
    Send welcome email.
228 5ce3ce4f Sofia Papagiannaki

229 f36af44a Antony Chazapis
    Raises SMTPException, socket.error
230 f36af44a Antony Chazapis
    """
231 4f78c22c Sofia Papagiannaki
    subject = _(GREETING_EMAIL_SUBJECT)
232 f36af44a Antony Chazapis
    message = render_to_string(email_template_name, {
233 5ce3ce4f Sofia Papagiannaki
                               'user': user,
234 5ce3ce4f Sofia Papagiannaki
                               'url': urljoin(BASEURL, reverse('index')),
235 5ce3ce4f Sofia Papagiannaki
                               'baseurl': BASEURL,
236 5ce3ce4f Sofia Papagiannaki
                               'site_name': SITENAME,
237 5ce3ce4f Sofia Papagiannaki
                               'support': DEFAULT_CONTACT_EMAIL})
238 1cbce16f Sofia Papagiannaki
    sender = settings.SERVER_EMAIL
239 8f5a3a06 Sofia Papagiannaki
    try:
240 8f5a3a06 Sofia Papagiannaki
        send_mail(subject, message, sender, [user.email])
241 8f5a3a06 Sofia Papagiannaki
    except (SMTPException, socket.error) as e:
242 8f5a3a06 Sofia Papagiannaki
        logger.exception(e)
243 8f5a3a06 Sofia Papagiannaki
        raise SendGreetingError()
244 8f5a3a06 Sofia Papagiannaki
    else:
245 111f3da6 Sofia Papagiannaki
        msg = 'Sent greeting %s' % user.email
246 aab4d540 Sofia Papagiannaki
        logger.log(LOGGING_LEVEL, msg)
247 8f5a3a06 Sofia Papagiannaki
248 5ce3ce4f Sofia Papagiannaki
249 8f5a3a06 Sofia Papagiannaki
def send_feedback(msg, data, user, email_template_name='im/feedback_mail.txt'):
250 4f78c22c Sofia Papagiannaki
    subject = _(FEEDBACK_EMAIL_SUBJECT)
251 8f5a3a06 Sofia Papagiannaki
    from_email = user.email
252 8f5a3a06 Sofia Papagiannaki
    recipient_list = [DEFAULT_CONTACT_EMAIL]
253 8f5a3a06 Sofia Papagiannaki
    content = render_to_string(email_template_name, {
254 8f5a3a06 Sofia Papagiannaki
        'message': msg,
255 8f5a3a06 Sofia Papagiannaki
        'data': data,
256 8f5a3a06 Sofia Papagiannaki
        'user': user})
257 8f5a3a06 Sofia Papagiannaki
    try:
258 8f5a3a06 Sofia Papagiannaki
        send_mail(subject, content, from_email, recipient_list)
259 8f5a3a06 Sofia Papagiannaki
    except (SMTPException, socket.error) as e:
260 8f5a3a06 Sofia Papagiannaki
        logger.exception(e)
261 8f5a3a06 Sofia Papagiannaki
        raise SendFeedbackError()
262 8f5a3a06 Sofia Papagiannaki
    else:
263 111f3da6 Sofia Papagiannaki
        msg = 'Sent feedback from %s' % user.email
264 aab4d540 Sofia Papagiannaki
        logger.log(LOGGING_LEVEL, msg)
265 f36af44a Antony Chazapis
266 5ce3ce4f Sofia Papagiannaki
267 73fbaec4 Sofia Papagiannaki
def send_change_email(
268 73fbaec4 Sofia Papagiannaki
    ec, request, email_template_name='registration/email_change_email.txt'):
269 49790d9d Sofia Papagiannaki
    try:
270 34a76cdb Kostas Papadimitriou
        url = ec.get_url()
271 49790d9d Sofia Papagiannaki
        url = request.build_absolute_uri(url)
272 49790d9d Sofia Papagiannaki
        t = loader.get_template(email_template_name)
273 49790d9d Sofia Papagiannaki
        c = {'url': url, 'site_name': SITENAME}
274 1cbce16f Sofia Papagiannaki
        from_email = settings.SERVER_EMAIL
275 1fcf4a99 Kostas Papadimitriou
        send_mail(_(EMAIL_CHANGE_EMAIL_SUBJECT),
276 9a06d96f Olga Brani
                  t.render(Context(c)), from_email, [ec.new_email_address])
277 49790d9d Sofia Papagiannaki
    except (SMTPException, socket.error) as e:
278 49790d9d Sofia Papagiannaki
        logger.exception(e)
279 49790d9d Sofia Papagiannaki
        raise ChangeEmailError()
280 49790d9d Sofia Papagiannaki
    else:
281 111f3da6 Sofia Papagiannaki
        msg = 'Sent change email for %s' % ec.user.email
282 aab4d540 Sofia Papagiannaki
        logger.log(LOGGING_LEVEL, msg)
283 f36af44a Antony Chazapis
284 5ce3ce4f Sofia Papagiannaki
285 f9aea9c8 Sofia Papagiannaki
def activate(
286 f9aea9c8 Sofia Papagiannaki
    user,
287 f9aea9c8 Sofia Papagiannaki
    email_template_name='im/welcome_email.txt',
288 f9aea9c8 Sofia Papagiannaki
    helpdesk_email_template_name='im/helpdesk_notification.txt',
289 73fbaec4 Sofia Papagiannaki
    verify_email=False):
290 683cf244 Sofia Papagiannaki
    """
291 683cf244 Sofia Papagiannaki
    Activates the specific user and sends email.
292 5ce3ce4f Sofia Papagiannaki

293 27e26a41 Sofia Papagiannaki
    Raises SendGreetingError, ValidationError
294 683cf244 Sofia Papagiannaki
    """
295 683cf244 Sofia Papagiannaki
    user.is_active = True
296 4bdd7e3d Kostas Papadimitriou
    user.email_verified = True
297 f1ab6639 Kostas Papadimitriou
    if not user.activation_sent:
298 f1ab6639 Kostas Papadimitriou
        user.activation_sent = datetime.now()
299 683cf244 Sofia Papagiannaki
    user.save()
300 23b9b72f Sofia Papagiannaki
    send_helpdesk_notification(user, helpdesk_email_template_name)
301 683cf244 Sofia Papagiannaki
    send_greeting(user, email_template_name)
302 683cf244 Sofia Papagiannaki
303 73fbaec4 Sofia Papagiannaki
def invite(inviter, email, realname):
304 73fbaec4 Sofia Papagiannaki
    inv = Invitation(inviter=inviter, username=email, realname=realname)
305 73fbaec4 Sofia Papagiannaki
    inv.save()
306 73fbaec4 Sofia Papagiannaki
    send_invitation(inv)
307 73fbaec4 Sofia Papagiannaki
    inviter.invitations = max(0, self.invitations - 1)
308 73fbaec4 Sofia Papagiannaki
    inviter.save()
309 5ce3ce4f Sofia Papagiannaki
310 9a06d96f Olga Brani
def switch_account_to_shibboleth(user, local_user,
311 9a06d96f Olga Brani
                                 greeting_template_name='im/welcome_email.txt'):
312 9a06d96f Olga Brani
    try:
313 9a06d96f Olga Brani
        provider = user.provider
314 9a06d96f Olga Brani
    except AttributeError:
315 23b9b72f Sofia Papagiannaki
        return
316 9a06d96f Olga Brani
    else:
317 9a06d96f Olga Brani
        if not provider == 'shibboleth':
318 9a06d96f Olga Brani
            return
319 9a06d96f Olga Brani
        user.delete()
320 9a06d96f Olga Brani
        local_user.provider = 'shibboleth'
321 9a06d96f Olga Brani
        local_user.third_party_identifier = user.third_party_identifier
322 9a06d96f Olga Brani
        local_user.save()
323 9a06d96f Olga Brani
        send_greeting(local_user, greeting_template_name)
324 9a06d96f Olga Brani
        return local_user
325 59f598f1 Sofia Papagiannaki
326 5ce3ce4f Sofia Papagiannaki
327 8f5a3a06 Sofia Papagiannaki
class SendMailError(Exception):
328 18ffbee1 Sofia Papagiannaki
    pass
329 8f5a3a06 Sofia Papagiannaki
330 5ce3ce4f Sofia Papagiannaki
331 8f5a3a06 Sofia Papagiannaki
class SendAdminNotificationError(SendMailError):
332 8f5a3a06 Sofia Papagiannaki
    def __init__(self):
333 ae497612 Olga Brani
        self.message = _(astakos_messages.ADMIN_NOTIFICATION_SEND_ERR)
334 18ffbee1 Sofia Papagiannaki
        super(SendAdminNotificationError, self).__init__()
335 8f5a3a06 Sofia Papagiannaki
336 5ce3ce4f Sofia Papagiannaki
337 18ffbee1 Sofia Papagiannaki
class SendVerificationError(SendMailError):
338 8f5a3a06 Sofia Papagiannaki
    def __init__(self):
339 ae497612 Olga Brani
        self.message = _(astakos_messages.VERIFICATION_SEND_ERR)
340 18ffbee1 Sofia Papagiannaki
        super(SendVerificationError, self).__init__()
341 8f5a3a06 Sofia Papagiannaki
342 5ce3ce4f Sofia Papagiannaki
343 18ffbee1 Sofia Papagiannaki
class SendInvitationError(SendMailError):
344 8f5a3a06 Sofia Papagiannaki
    def __init__(self):
345 ae497612 Olga Brani
        self.message = _(astakos_messages.INVITATION_SEND_ERR)
346 18ffbee1 Sofia Papagiannaki
        super(SendInvitationError, self).__init__()
347 8f5a3a06 Sofia Papagiannaki
348 5ce3ce4f Sofia Papagiannaki
349 18ffbee1 Sofia Papagiannaki
class SendGreetingError(SendMailError):
350 8f5a3a06 Sofia Papagiannaki
    def __init__(self):
351 ae497612 Olga Brani
        self.message = _(astakos_messages.GREETING_SEND_ERR)
352 18ffbee1 Sofia Papagiannaki
        super(SendGreetingError, self).__init__()
353 8f5a3a06 Sofia Papagiannaki
354 5ce3ce4f Sofia Papagiannaki
355 18ffbee1 Sofia Papagiannaki
class SendFeedbackError(SendMailError):
356 8f5a3a06 Sofia Papagiannaki
    def __init__(self):
357 ae497612 Olga Brani
        self.message = _(astakos_messages.FEEDBACK_SEND_ERR)
358 49790d9d Sofia Papagiannaki
        super(SendFeedbackError, self).__init__()
359 49790d9d Sofia Papagiannaki
360 5ce3ce4f Sofia Papagiannaki
361 49790d9d Sofia Papagiannaki
class ChangeEmailError(SendMailError):
362 49790d9d Sofia Papagiannaki
    def __init__(self):
363 ccab6eb5 Sofia Papagiannaki
        self.message = _(astakos_messages.CHANGE_EMAIL_SEND_ERR)
364 35f8ccf1 Sofia Papagiannaki
        super(ChangeEmailError, self).__init__()
365 a0be6a0c Sofia Papagiannaki
366 5ce3ce4f Sofia Papagiannaki
367 a0be6a0c Sofia Papagiannaki
class SendNotificationError(SendMailError):
368 a0be6a0c Sofia Papagiannaki
    def __init__(self):
369 ae497612 Olga Brani
        self.message = _(astakos_messages.NOTIFICATION_SEND_ERR)
370 a0be6a0c Sofia Papagiannaki
        super(SendNotificationError, self).__init__()
371 73fbaec4 Sofia Papagiannaki
372 73fbaec4 Sofia Papagiannaki
373 73fbaec4 Sofia Papagiannaki
### PROJECT VIEWS ###
374 73fbaec4 Sofia Papagiannaki
def get_join_policy(str_policy):
375 73fbaec4 Sofia Papagiannaki
    try:
376 73fbaec4 Sofia Papagiannaki
        return MemberJoinPolicy.objects.get(policy=str_policy)
377 73fbaec4 Sofia Papagiannaki
    except:
378 73fbaec4 Sofia Papagiannaki
        return None
379 73fbaec4 Sofia Papagiannaki
380 73fbaec4 Sofia Papagiannaki
def get_leave_policy(str_policy):
381 73fbaec4 Sofia Papagiannaki
    try:
382 73fbaec4 Sofia Papagiannaki
        return MemberLeavePolicy.objects.get(policy=str_policy)
383 73fbaec4 Sofia Papagiannaki
    except:
384 73fbaec4 Sofia Papagiannaki
        return None
385 73fbaec4 Sofia Papagiannaki
    
386 73fbaec4 Sofia Papagiannaki
_auto_accept_join = False
387 73fbaec4 Sofia Papagiannaki
def get_auto_accept_join_policy():
388 73fbaec4 Sofia Papagiannaki
    global _auto_accept_join
389 73fbaec4 Sofia Papagiannaki
    if _auto_accept_join is not False:
390 73fbaec4 Sofia Papagiannaki
        return _auto_accept_join
391 73fbaec4 Sofia Papagiannaki
    _auto_accept = get_join_policy('auto_accept')
392 73fbaec4 Sofia Papagiannaki
    return _auto_accept
393 73fbaec4 Sofia Papagiannaki
394 73fbaec4 Sofia Papagiannaki
_closed_join = False
395 73fbaec4 Sofia Papagiannaki
def get_closed_join_policy():
396 73fbaec4 Sofia Papagiannaki
    global _closed_join
397 73fbaec4 Sofia Papagiannaki
    if _closed_join is not False:
398 73fbaec4 Sofia Papagiannaki
        return _closed_join
399 73fbaec4 Sofia Papagiannaki
    _closed_join = get_join_policy('closed')
400 73fbaec4 Sofia Papagiannaki
    return _closed_join
401 73fbaec4 Sofia Papagiannaki
402 73fbaec4 Sofia Papagiannaki
_auto_accept_leave = False
403 73fbaec4 Sofia Papagiannaki
def get_auto_accept_leave_policy():
404 73fbaec4 Sofia Papagiannaki
    global _auto_accept_leave
405 73fbaec4 Sofia Papagiannaki
    if _auto_accept_leave is not False:
406 73fbaec4 Sofia Papagiannaki
        return _auto_accept_leave
407 73fbaec4 Sofia Papagiannaki
    _auto_accept_leave = get_leave_policy('auto_accept')
408 73fbaec4 Sofia Papagiannaki
    return _auto_accept_leave
409 73fbaec4 Sofia Papagiannaki
410 73fbaec4 Sofia Papagiannaki
_closed_leave = False
411 73fbaec4 Sofia Papagiannaki
def get_closed_leave_policy():
412 73fbaec4 Sofia Papagiannaki
    global _closed_leave
413 73fbaec4 Sofia Papagiannaki
    if _closed_leave is not False:
414 73fbaec4 Sofia Papagiannaki
        return _closed_leave
415 73fbaec4 Sofia Papagiannaki
    _closed_leave = get_leave_policy('closed')
416 73fbaec4 Sofia Papagiannaki
    return _closed_leave
417 73fbaec4 Sofia Papagiannaki
418 73fbaec4 Sofia Papagiannaki
def get_project_by_application_id(project_application_id):
419 73fbaec4 Sofia Papagiannaki
    try:
420 73fbaec4 Sofia Papagiannaki
        return Project.objects.get(application__id=project_application_id)
421 73fbaec4 Sofia Papagiannaki
    except Project.DoesNotExist:
422 73fbaec4 Sofia Papagiannaki
        raise IOError(
423 73fbaec4 Sofia Papagiannaki
            _(astakos_messages.UNKNOWN_PROJECT_APPLICATION_ID) % project_application_id)
424 73fbaec4 Sofia Papagiannaki
425 73fbaec4 Sofia Papagiannaki
def get_user_by_id(user_id):
426 73fbaec4 Sofia Papagiannaki
    try:
427 73fbaec4 Sofia Papagiannaki
        return AstakosUser.objects.get(user__id=user_id)
428 73fbaec4 Sofia Papagiannaki
    except AstakosUser.DoesNotExist:
429 73fbaec4 Sofia Papagiannaki
        raise IOError(_(astakos_messages.UNKNOWN_USER_ID) % user_id)
430 73fbaec4 Sofia Papagiannaki
431 73fbaec4 Sofia Papagiannaki
def create_membership(project_application_id, user_id):
432 73fbaec4 Sofia Papagiannaki
    try:
433 73fbaec4 Sofia Papagiannaki
        project = get_project_by_application_id(project_application_id)
434 73fbaec4 Sofia Papagiannaki
        m = ProjectMembership(
435 73fbaec4 Sofia Papagiannaki
            project=project,
436 73fbaec4 Sofia Papagiannaki
            person__id=user_id,
437 73fbaec4 Sofia Papagiannaki
            request_date=datetime.now())
438 73fbaec4 Sofia Papagiannaki
    except IntegrityError, e:
439 73fbaec4 Sofia Papagiannaki
        raise IOError(_(astakos_messages.MEMBERSHIP_REQUEST_EXISTS))
440 73fbaec4 Sofia Papagiannaki
    else:
441 73fbaec4 Sofia Papagiannaki
        m.save()
442 73fbaec4 Sofia Papagiannaki
443 73fbaec4 Sofia Papagiannaki
def get_membership(project, user):
444 73fbaec4 Sofia Papagiannaki
    if isinstace(project, int):
445 73fbaec4 Sofia Papagiannaki
        project = get_project_by_application_id(project)
446 73fbaec4 Sofia Papagiannaki
    if isinstace(user, int):
447 73fbaec4 Sofia Papagiannaki
        user = get_user_by_id(user)
448 73fbaec4 Sofia Papagiannaki
    try:
449 73fbaec4 Sofia Papagiannaki
        return ProjectMembership.objects.select_related().get(
450 73fbaec4 Sofia Papagiannaki
            project=project,
451 73fbaec4 Sofia Papagiannaki
            person=user)
452 73fbaec4 Sofia Papagiannaki
    except ProjectMembership.DoesNotExist:
453 73fbaec4 Sofia Papagiannaki
        raise IOError(_(astakos_messages.NOT_MEMBERSHIP_REQUEST))
454 73fbaec4 Sofia Papagiannaki
455 73fbaec4 Sofia Papagiannaki
def accept_membership(request, project, user, request_user=None):
456 73fbaec4 Sofia Papagiannaki
    """
457 73fbaec4 Sofia Papagiannaki
        Raises:
458 73fbaec4 Sofia Papagiannaki
            django.core.exceptions.PermissionDenied
459 73fbaec4 Sofia Papagiannaki
            IOError
460 73fbaec4 Sofia Papagiannaki
    """
461 73fbaec4 Sofia Papagiannaki
    membership = get_membership(project, user)
462 73fbaec4 Sofia Papagiannaki
    if request_user and \
463 73fbaec4 Sofia Papagiannaki
        (not membership.project.current_application.owner == request_user and \
464 73fbaec4 Sofia Papagiannaki
            not request_user.is_superuser):
465 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(_(astakos_messages.NOT_ALLOWED))
466 73fbaec4 Sofia Papagiannaki
    if not self.project.is_alive:
467 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(
468 73fbaec4 Sofia Papagiannaki
            _(astakos_messages.NOT_ALIVE_PROJECT) % membership.project.__dict__)
469 73fbaec4 Sofia Papagiannaki
    if len(self.project.approved_members) + 1 > \
470 73fbaec4 Sofia Papagiannaki
        self.project.definition.limit_on_members_number:
471 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(_(astakos_messages.MEMBER_NUMBER_LIMIT_REACHED))
472 73fbaec4 Sofia Papagiannaki
473 73fbaec4 Sofia Papagiannaki
    membership.accept()
474 73fbaec4 Sofia Papagiannaki
475 73fbaec4 Sofia Papagiannaki
    try:
476 73fbaec4 Sofia Papagiannaki
        notification = build_notification(
477 73fbaec4 Sofia Papagiannaki
            settings.SERVER_EMAIL,
478 73fbaec4 Sofia Papagiannaki
            [self.person.email],
479 73fbaec4 Sofia Papagiannaki
            _(PROJECT_MEMBERSHIP_CHANGE_SUBJECT) % membership.project.definition.__dict__,
480 73fbaec4 Sofia Papagiannaki
            template='im/projects/project_membership_change_notification.txt',
481 73fbaec4 Sofia Papagiannaki
            dictionary={'object':membership.project.current_application, 'action':'accepted'})
482 73fbaec4 Sofia Papagiannaki
        notification.send()
483 73fbaec4 Sofia Papagiannaki
    except NotificationError, e:
484 73fbaec4 Sofia Papagiannaki
        logger.error(e.messages)
485 73fbaec4 Sofia Papagiannaki
    return membership
486 73fbaec4 Sofia Papagiannaki
487 73fbaec4 Sofia Papagiannaki
def reject_membership(project, user, request_user=None):
488 73fbaec4 Sofia Papagiannaki
    """
489 73fbaec4 Sofia Papagiannaki
        Raises:
490 73fbaec4 Sofia Papagiannaki
            django.core.exceptions.PermissionDenied
491 73fbaec4 Sofia Papagiannaki
            IOError
492 73fbaec4 Sofia Papagiannaki
    """
493 73fbaec4 Sofia Papagiannaki
    membership = get_membership(project, user)
494 73fbaec4 Sofia Papagiannaki
    if request_user and \
495 73fbaec4 Sofia Papagiannaki
        (not membership.project.current_application.owner == request_user and \
496 73fbaec4 Sofia Papagiannaki
            not request_user.is_superuser):
497 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(_(astakos_messages.NOT_ALLOWED))
498 73fbaec4 Sofia Papagiannaki
    if not membership.project.is_alive:
499 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(_(astakos_messages.NOT_ALIVE_PROJECT) % project.__dict__)
500 73fbaec4 Sofia Papagiannaki
501 73fbaec4 Sofia Papagiannaki
    membership.reject()
502 73fbaec4 Sofia Papagiannaki
503 73fbaec4 Sofia Papagiannaki
    try:
504 73fbaec4 Sofia Papagiannaki
        notification = build_notification(
505 73fbaec4 Sofia Papagiannaki
            settings.SERVER_EMAIL,
506 73fbaec4 Sofia Papagiannaki
            [self.person.email],
507 73fbaec4 Sofia Papagiannaki
            _(PROJECT_MEMBERSHIP_CHANGE_SUBJECT) % self.project.definition.__dict__,
508 73fbaec4 Sofia Papagiannaki
            template='im/projects/project_membership_change_notification.txt',
509 73fbaec4 Sofia Papagiannaki
            dictionary={'object':self.project.current_application, 'action':'rejected'})
510 73fbaec4 Sofia Papagiannaki
        notification.send()
511 73fbaec4 Sofia Papagiannaki
    except NotificationError, e:
512 73fbaec4 Sofia Papagiannaki
        logger.error(e.messages)
513 73fbaec4 Sofia Papagiannaki
    return membership
514 73fbaec4 Sofia Papagiannaki
515 73fbaec4 Sofia Papagiannaki
def remove_membership(project, user, request_user=None):
516 73fbaec4 Sofia Papagiannaki
    """
517 73fbaec4 Sofia Papagiannaki
        Raises:
518 73fbaec4 Sofia Papagiannaki
            django.core.exceptions.PermissionDenied
519 73fbaec4 Sofia Papagiannaki
            IOError
520 73fbaec4 Sofia Papagiannaki
    """
521 73fbaec4 Sofia Papagiannaki
    membership = get_membership(project, user)
522 73fbaec4 Sofia Papagiannaki
    if request_user and \
523 73fbaec4 Sofia Papagiannaki
        (not membership.project.current_application.owner == request_user and \
524 73fbaec4 Sofia Papagiannaki
            not request_user.is_superuser):
525 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(_(astakos_messages.NOT_ALLOWED))
526 73fbaec4 Sofia Papagiannaki
    if not self.project.is_alive:
527 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(_(astakos_messages.NOT_ALIVE_PROJECT) % membership.project.__dict__)
528 73fbaec4 Sofia Papagiannaki
529 73fbaec4 Sofia Papagiannaki
    membership.remove()
530 73fbaec4 Sofia Papagiannaki
531 73fbaec4 Sofia Papagiannaki
    try:
532 73fbaec4 Sofia Papagiannaki
        notification = build_notification(
533 73fbaec4 Sofia Papagiannaki
            settings.SERVER_EMAIL,
534 73fbaec4 Sofia Papagiannaki
            [self.person.email],
535 73fbaec4 Sofia Papagiannaki
            _(PROJECT_MEMBERSHIP_CHANGE_SUBJECT) % membership.project.definition.__dict__,
536 73fbaec4 Sofia Papagiannaki
            template='im/projects/project_membership_change_notification.txt',
537 73fbaec4 Sofia Papagiannaki
            dictionary={'object':membership.project.current_application, 'action':'removed'})
538 73fbaec4 Sofia Papagiannaki
        notification.send()
539 73fbaec4 Sofia Papagiannaki
    except NotificationError, e:
540 73fbaec4 Sofia Papagiannaki
        logger.error(e.messages)
541 73fbaec4 Sofia Papagiannaki
    return membership
542 73fbaec4 Sofia Papagiannaki
543 73fbaec4 Sofia Papagiannaki
def leave_project(project_application_id, user_id):
544 73fbaec4 Sofia Papagiannaki
    """
545 73fbaec4 Sofia Papagiannaki
        Raises:
546 73fbaec4 Sofia Papagiannaki
            django.core.exceptions.PermissionDenied
547 73fbaec4 Sofia Papagiannaki
            IOError
548 73fbaec4 Sofia Papagiannaki
    """
549 73fbaec4 Sofia Papagiannaki
    project = get_project_by_application_id(project_application_id)
550 73fbaec4 Sofia Papagiannaki
    leave_policy = project.current_application.definition.member_join_policy
551 73fbaec4 Sofia Papagiannaki
    if leave_policy == get_closed_leave():
552 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(_(astakos_messages.MEMBER_LEAVE_POLICY_CLOSED))
553 73fbaec4 Sofia Papagiannaki
554 73fbaec4 Sofia Papagiannaki
    membership = get_membership(project_application_id, user_id)
555 73fbaec4 Sofia Papagiannaki
    if leave_policy == get_auto_accept_leave():
556 73fbaec4 Sofia Papagiannaki
        membership.remove()
557 73fbaec4 Sofia Papagiannaki
    else:
558 73fbaec4 Sofia Papagiannaki
        membership.leave_request_date = datetime.now()
559 73fbaec4 Sofia Papagiannaki
        membership.save()
560 73fbaec4 Sofia Papagiannaki
    return membership
561 73fbaec4 Sofia Papagiannaki
562 73fbaec4 Sofia Papagiannaki
def join_project(project_application_id, user_id):
563 73fbaec4 Sofia Papagiannaki
    """
564 73fbaec4 Sofia Papagiannaki
        Raises:
565 73fbaec4 Sofia Papagiannaki
            django.core.exceptions.PermissionDenied
566 73fbaec4 Sofia Papagiannaki
            IOError
567 73fbaec4 Sofia Papagiannaki
    """
568 73fbaec4 Sofia Papagiannaki
    project = get_project_by_application_id(project_application_id)
569 73fbaec4 Sofia Papagiannaki
    join_policy = project.current_application.definition.member_join_policy
570 73fbaec4 Sofia Papagiannaki
    if join_policy == get_closed_join():
571 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(_(astakos_messages.MEMBER_JOIN_POLICY_CLOSED))
572 73fbaec4 Sofia Papagiannaki
573 73fbaec4 Sofia Papagiannaki
    membership = create_membership(project_application_id, user_id)
574 73fbaec4 Sofia Papagiannaki
575 73fbaec4 Sofia Papagiannaki
    if join_policy == get_auto_accept_join():
576 73fbaec4 Sofia Papagiannaki
        membership.accept()
577 73fbaec4 Sofia Papagiannaki
    return membership
578 73fbaec4 Sofia Papagiannaki
    
579 73fbaec4 Sofia Papagiannaki
def submit_application(
580 73fbaec4 Sofia Papagiannaki
    application, resource_policies, applicant, comments, precursor_application=None):
581 73fbaec4 Sofia Papagiannaki
582 73fbaec4 Sofia Papagiannaki
    application.submit(
583 73fbaec4 Sofia Papagiannaki
        resource_policies, applicant, comments, precursor_application)
584 73fbaec4 Sofia Papagiannaki
    
585 73fbaec4 Sofia Papagiannaki
    try:
586 73fbaec4 Sofia Papagiannaki
        notification = build_notification(
587 73fbaec4 Sofia Papagiannaki
            settings.SERVER_EMAIL,
588 73fbaec4 Sofia Papagiannaki
            [i[1] for i in settings.ADMINS],
589 73fbaec4 Sofia Papagiannaki
            _(PROJECT_CREATION_SUBJECT) % application.__dict__,
590 73fbaec4 Sofia Papagiannaki
            template='im/projects/project_creation_notification.txt',
591 73fbaec4 Sofia Papagiannaki
            dictionary={'object':application})
592 73fbaec4 Sofia Papagiannaki
        notification.send()
593 73fbaec4 Sofia Papagiannaki
    except NotificationError, e:
594 3d4a0a9b Sofia Papagiannaki
        logger.error(e)
595 73fbaec4 Sofia Papagiannaki
    return application
596 73fbaec4 Sofia Papagiannaki
597 73fbaec4 Sofia Papagiannaki
def approve_application(application):
598 73fbaec4 Sofia Papagiannaki
    application.approve()
599 73fbaec4 Sofia Papagiannaki
#     rejected = application.project.sync()
600 73fbaec4 Sofia Papagiannaki
601 73fbaec4 Sofia Papagiannaki
    try:
602 73fbaec4 Sofia Papagiannaki
        notification = build_notification(
603 73fbaec4 Sofia Papagiannaki
            settings.SERVER_EMAIL,
604 73fbaec4 Sofia Papagiannaki
            [self.owner.email],
605 73fbaec4 Sofia Papagiannaki
            _(PROJECT_APPROVED_SUBJECT) % application.definition.__dict__,
606 73fbaec4 Sofia Papagiannaki
            template='im/projects/project_approval_notification.txt',
607 73fbaec4 Sofia Papagiannaki
            dictionary={'object':application})
608 73fbaec4 Sofia Papagiannaki
        notification.send()
609 73fbaec4 Sofia Papagiannaki
    except NotificationError, e:
610 73fbaec4 Sofia Papagiannaki
        logger.error(e.messages)