Fixes and Clouds animations
[astakos] / snf-astakos-app / astakos / im / functions.py
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
43 from urllib import quote
44 from urlparse import urljoin
45 from smtplib import SMTPException
46
47 from astakos.im.settings import DEFAULT_CONTACT_EMAIL, DEFAULT_FROM_EMAIL, SITENAME, BASEURL, DEFAULT_ADMIN_EMAIL
48 from astakos.im.models import Invitation, AstakosUser
49
50 logger = logging.getLogger(__name__)
51
52 def send_verification(user, template_name='im/activation_email.txt'):
53     """
54     Send email to user to verify his/her email and activate his/her account.
55     
56     Raises SendVerificationError
57     """
58     url = '%s?auth=%s&next=%s' % (urljoin(BASEURL, reverse('astakos.im.views.activate')),
59                                     quote(user.auth_token),
60                                     quote(BASEURL))
61     message = render_to_string(template_name, {
62             'user': user,
63             'url': url,
64             'baseurl': BASEURL,
65             'site_name': SITENAME,
66             'support': DEFAULT_CONTACT_EMAIL})
67     sender = DEFAULT_FROM_EMAIL
68     try:
69         send_mail('%s alpha2 testing account activation is needed' % SITENAME, message, sender, [user.email])
70     except (SMTPException, socket.error) as e:
71         logger.exception(e)
72         raise SendVerificationError()
73     else:
74         logger.info('Sent activation %s', user)
75
76 def send_admin_notification(user, template_name='im/admin_notification.txt'):
77     """
78     Send email to DEFAULT_ADMIN_EMAIL to notify for a new user registration.
79     
80     Raises SendNotificationError
81     """
82     if not DEFAULT_ADMIN_EMAIL:
83         return
84     message = render_to_string(template_name, {
85             'user': user,
86             'baseurl': BASEURL,
87             'site_name': SITENAME,
88             'support': DEFAULT_CONTACT_EMAIL})
89     sender = DEFAULT_FROM_EMAIL
90     try:
91         send_mail('%s alpha2 testing account notification' % SITENAME, message, sender, [DEFAULT_ADMIN_EMAIL])
92     except (SMTPException, socket.error) as e:
93         logger.exception(e)
94         raise SendNotificationError()
95     else:
96         logger.info('Sent admin notification for user %s', user)
97
98 def send_invitation(invitation, template_name='im/invitation.txt'):
99     """
100     Send invitation email.
101     
102     Raises SendInvitationError
103     """
104     subject = _('Invitation to %s alpha2 testing' % SITENAME)
105     url = '%s?code=%d' % (urljoin(BASEURL, reverse('astakos.im.views.index')), invitation.code)
106     message = render_to_string('im/invitation.txt', {
107                 'invitation': invitation,
108                 'url': url,
109                 'baseurl': BASEURL,
110                 'site_name': SITENAME,
111                 'support': DEFAULT_CONTACT_EMAIL})
112     sender = DEFAULT_FROM_EMAIL
113     try:
114         send_mail(subject, message, sender, [invitation.username])
115     except (SMTPException, socket.error) as e:
116         logger.exception(e)
117         raise SendInvitationError()
118     else:
119         logger.info('Sent invitation %s', invitation)
120
121 def send_greeting(user, email_template_name='im/welcome_email.txt'):
122     """
123     Send welcome email.
124     
125     Raises SMTPException, socket.error
126     """
127     subject = _('Welcome to %s alpha2 testing' % SITENAME)
128     message = render_to_string(email_template_name, {
129                 'user': user,
130                 'url': urljoin(BASEURL, reverse('astakos.im.views.index')),
131                 'baseurl': BASEURL,
132                 'site_name': SITENAME,
133                 'support': DEFAULT_CONTACT_EMAIL})
134     sender = DEFAULT_FROM_EMAIL
135     try:
136         send_mail(subject, message, sender, [user.email])
137     except (SMTPException, socket.error) as e:
138         logger.exception(e)
139         raise SendGreetingError()
140     else:
141         logger.info('Sent greeting %s', user)
142
143 def send_feedback(msg, data, user, email_template_name='im/feedback_mail.txt'):
144     subject = _("Feedback from %s alpha2 testing" % SITENAME)
145     from_email = user.email
146     recipient_list = [DEFAULT_CONTACT_EMAIL]
147     content = render_to_string(email_template_name, {
148         'message': msg,
149         'data': data,
150         'user': user})
151     try:
152         send_mail(subject, content, from_email, recipient_list)
153     except (SMTPException, socket.error) as e:
154         logger.exception(e)
155         raise SendFeedbackError()
156     else:
157         logger.info('Sent feedback from %s', user.email)
158
159 def activate(user, email_template_name='im/welcome_email.txt'):
160     """
161     Activates the specific user and sends email.
162     
163     Raises SendGreetingError, ValidationError
164     """
165     user.is_active = True
166     user.save()
167     send_greeting(user, email_template_name)
168
169 def invite(invitation, inviter, email_template_name='im/welcome_email.txt'):
170     """
171     Send an invitation email and upon success reduces inviter's invitation by one.
172     
173     Raises SendInvitationError
174     """
175     invitation.inviter = inviter
176     invitation.save()
177     send_invitation(invitation, email_template_name)
178     inviter.invitations = max(0, inviter.invitations - 1)
179     inviter.save()
180
181 def set_user_credibility(email, has_credits):
182     try:
183         user = AstakosUser.objects.get(email=email, is_active=True)
184         user.has_credits = has_credits
185         user.save()
186     except AstakosUser.DoesNotExist, e:
187         logger.exception(e)
188     except ValidationError, e:
189         logger.exception(e)
190
191 class SendMailError(Exception):
192     pass
193
194 class SendAdminNotificationError(SendMailError):
195     def __init__(self):
196         self.message = _('Failed to send notification')
197         super(SendAdminNotificationError, self).__init__()
198
199 class SendVerificationError(SendMailError):
200     def __init__(self):
201         self.message = _('Failed to send verification')
202         super(SendVerificationError, self).__init__()
203
204 class SendInvitationError(SendMailError):
205     def __init__(self):
206         self.message = _('Failed to send invitation')
207         super(SendInvitationError, self).__init__()
208
209 class SendGreetingError(SendMailError):
210     def __init__(self):
211         self.message = _('Failed to send greeting')
212         super(SendGreetingError, self).__init__()
213
214 class SendFeedbackError(SendMailError):
215     def __init__(self):
216         self.message = _('Failed to send feedback')
217         super(SendFeedbackError, self).__init__()