Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / functions.py @ 751d24cf

History | View | Annotate | Download (8.8 kB)

1
# Copyright 2011 GRNET S.A. All rights reserved.
2
# 
3
# Redistribution and use in source and binary forms, with or
4
# without modification, are permitted provided that the following
5
# conditions are met:
6
# 
7
#   1. Redistributions of source code must retain the above
8
#      copyright notice, this list of conditions and the following
9
#      disclaimer.
10
# 
11
#   2. Redistributions in binary form must reproduce the above
12
#      copyright notice, this list of conditions and the following
13
#      disclaimer in the documentation and/or other materials
14
#      provided with the distribution.
15
# 
16
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27
# POSSIBILITY OF SUCH DAMAGE.
28
# 
29
# The views and conclusions contained in the software and
30
# documentation are those of the authors and should not be
31
# interpreted as representing official policies, either expressed
32
# or implied, of GRNET S.A.
33

    
34
import logging
35
import socket
36

    
37
from django.utils.translation import ugettext as _
38
from django.template.loader import render_to_string
39
from django.core.mail import send_mail
40
from django.core.urlresolvers import reverse
41
from django.core.exceptions import ValidationError
42
from django.template import Context, loader
43

    
44
from urllib import quote
45
from urlparse import urljoin
46
from smtplib import SMTPException
47
from datetime import datetime
48

    
49
from astakos.im.settings import DEFAULT_CONTACT_EMAIL, DEFAULT_FROM_EMAIL, SITENAME, BASEURL, DEFAULT_ADMIN_EMAIL
50
from astakos.im.models import Invitation, AstakosUser
51

    
52
logger = logging.getLogger(__name__)
53

    
54
def send_verification(user, template_name='im/activation_email.txt'):
55
    """
56
    Send email to user to verify his/her email and activate his/her account.
57
    
58
    Raises SendVerificationError
59
    """
60
    url = '%s?auth=%s&next=%s' % (urljoin(BASEURL, reverse('astakos.im.views.activate')),
61
                                    quote(user.auth_token),
62
                                    quote(BASEURL))
63
    message = render_to_string(template_name, {
64
            'user': user,
65
            'url': url,
66
            'baseurl': BASEURL,
67
            'site_name': SITENAME,
68
            'support': DEFAULT_CONTACT_EMAIL})
69
    sender = DEFAULT_FROM_EMAIL
70
    try:
71
        send_mail('%s alpha2 testing account activation is needed' % SITENAME, message, sender, [user.email])
72
    except (SMTPException, socket.error) as e:
73
        logger.exception(e)
74
        raise SendVerificationError()
75
    else:
76
        logger.info('Sent activation %s', user)
77

    
78
def send_activation(user, template_name='im/activation_email.txt'):
79
    send_verification(user, template_name)
80
    user.activation_sent = datetime.now()
81
    user.save()
82

    
83
def send_admin_notification(user, template_name='im/admin_notification.txt'):
84
    """
85
    Send email to DEFAULT_ADMIN_EMAIL to notify for a new user registration.
86
    
87
    Raises SendNotificationError
88
    """
89
    if not DEFAULT_ADMIN_EMAIL:
90
        return
91
    message = render_to_string(template_name, {
92
            'user': user,
93
            'baseurl': BASEURL,
94
            'site_name': SITENAME,
95
            'support': DEFAULT_CONTACT_EMAIL})
96
    sender = DEFAULT_FROM_EMAIL
97
    try:
98
        send_mail('%s alpha2 testing account notification' % SITENAME, message, sender, [DEFAULT_ADMIN_EMAIL])
99
    except (SMTPException, socket.error) as e:
100
        logger.exception(e)
101
        raise SendNotificationError()
102
    else:
103
        logger.info('Sent admin notification for user %s', user)
104

    
105
def send_invitation(invitation, template_name='im/invitation.txt'):
106
    """
107
    Send invitation email.
108
    
109
    Raises SendInvitationError
110
    """
111
    subject = _('Invitation to %s alpha2 testing' % SITENAME)
112
    url = '%s?code=%d' % (urljoin(BASEURL, reverse('astakos.im.views.index')), invitation.code)
113
    message = render_to_string('im/invitation.txt', {
114
                'invitation': invitation,
115
                'url': url,
116
                'baseurl': BASEURL,
117
                'site_name': SITENAME,
118
                'support': DEFAULT_CONTACT_EMAIL})
119
    sender = DEFAULT_FROM_EMAIL
120
    try:
121
        send_mail(subject, message, sender, [invitation.username])
122
    except (SMTPException, socket.error) as e:
123
        logger.exception(e)
124
        raise SendInvitationError()
125
    else:
126
        logger.info('Sent invitation %s', invitation)
127

    
128
def send_greeting(user, email_template_name='im/welcome_email.txt'):
129
    """
130
    Send welcome email.
131
    
132
    Raises SMTPException, socket.error
133
    """
134
    subject = _('Welcome to %s alpha2 testing' % SITENAME)
135
    message = render_to_string(email_template_name, {
136
                'user': user,
137
                'url': urljoin(BASEURL, reverse('astakos.im.views.index')),
138
                'baseurl': BASEURL,
139
                'site_name': SITENAME,
140
                'support': DEFAULT_CONTACT_EMAIL})
141
    sender = DEFAULT_FROM_EMAIL
142
    try:
143
        send_mail(subject, message, sender, [user.email])
144
    except (SMTPException, socket.error) as e:
145
        logger.exception(e)
146
        raise SendGreetingError()
147
    else:
148
        logger.info('Sent greeting %s', user)
149

    
150
def send_feedback(msg, data, user, email_template_name='im/feedback_mail.txt'):
151
    subject = _("Feedback from %s alpha2 testing" % SITENAME)
152
    from_email = user.email
153
    recipient_list = [DEFAULT_CONTACT_EMAIL]
154
    content = render_to_string(email_template_name, {
155
        'message': msg,
156
        'data': data,
157
        'user': user})
158
    try:
159
        send_mail(subject, content, from_email, recipient_list)
160
    except (SMTPException, socket.error) as e:
161
        logger.exception(e)
162
        raise SendFeedbackError()
163
    else:
164
        logger.info('Sent feedback from %s', user.email)
165

    
166
def send_change_email(ec, request, email_template_name='registration/email_change_email.txt'):
167
    try:
168
        url = reverse('email_change_confirm',
169
                      kwargs={'activation_key':ec.activation_key})
170
        url = request.build_absolute_uri(url)
171
        t = loader.get_template(email_template_name)
172
        c = {'url': url, 'site_name': SITENAME}
173
        from_email = DEFAULT_FROM_EMAIL
174
        send_mail(_("Email change on %s alpha2 testing") % SITENAME,
175
            t.render(Context(c)), from_email, [ec.new_email_address])
176
    except (SMTPException, socket.error) as e:
177
        logger.exception(e)
178
        raise ChangeEmailError()
179
    else:
180
        logger.info('Sent change email for %s', ec.user.email)
181

    
182
def activate(user, email_template_name='im/welcome_email.txt'):
183
    """
184
    Activates the specific user and sends email.
185
    
186
    Raises SendGreetingError, ValidationError
187
    """
188
    user.is_active = True
189
    user.save()
190
    send_greeting(user, email_template_name)
191

    
192
def invite(invitation, inviter, email_template_name='im/welcome_email.txt'):
193
    """
194
    Send an invitation email and upon success reduces inviter's invitation by one.
195
    
196
    Raises SendInvitationError
197
    """
198
    invitation.inviter = inviter
199
    invitation.save()
200
    send_invitation(invitation, email_template_name)
201
    inviter.invitations = max(0, inviter.invitations - 1)
202
    inviter.save()
203

    
204
def set_user_credibility(email, has_credits):
205
    try:
206
        user = AstakosUser.objects.get(email=email, is_active=True)
207
        user.has_credits = has_credits
208
        user.save()
209
    except AstakosUser.DoesNotExist, e:
210
        logger.exception(e)
211
    except ValidationError, e:
212
        logger.exception(e)
213

    
214
class SendMailError(Exception):
215
    pass
216

    
217
class SendAdminNotificationError(SendMailError):
218
    def __init__(self):
219
        self.message = _('Failed to send notification')
220
        super(SendAdminNotificationError, self).__init__()
221

    
222
class SendVerificationError(SendMailError):
223
    def __init__(self):
224
        self.message = _('Failed to send verification')
225
        super(SendVerificationError, self).__init__()
226

    
227
class SendInvitationError(SendMailError):
228
    def __init__(self):
229
        self.message = _('Failed to send invitation')
230
        super(SendInvitationError, self).__init__()
231

    
232
class SendGreetingError(SendMailError):
233
    def __init__(self):
234
        self.message = _('Failed to send greeting')
235
        super(SendGreetingError, self).__init__()
236

    
237
class SendFeedbackError(SendMailError):
238
    def __init__(self):
239
        self.message = _('Failed to send feedback')
240
        super(SendFeedbackError, self).__init__()
241

    
242
class ChangeEmailError(SendMailError):
243
    def __init__(self):
244
        self.message = _('Failed to send change email')
245
        super(ChangeEmailError, self).__init__()