Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / functions.py @ 8c3e6cb5

History | View | Annotate | Download (25.1 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 974ee6a6 Sofia Papagiannaki
from django.db import IntegrityError
49 27e26a41 Sofia Papagiannaki
50 683cf244 Sofia Papagiannaki
from urllib import quote
51 f36af44a Antony Chazapis
from urlparse import urljoin
52 8f5a3a06 Sofia Papagiannaki
from smtplib import SMTPException
53 751d24cf Sofia Papagiannaki
from datetime import datetime
54 111f3da6 Sofia Papagiannaki
from functools import wraps
55 f36af44a Antony Chazapis
56 bf0c6de5 Sofia Papagiannaki
from astakos.im.settings import (
57 c0b26605 Sofia Papagiannaki
    DEFAULT_CONTACT_EMAIL, SITENAME, BASEURL, LOGGING_LEVEL,
58 c0b26605 Sofia Papagiannaki
    VERIFICATION_EMAIL_SUBJECT, ACCOUNT_CREATION_SUBJECT,
59 c0b26605 Sofia Papagiannaki
    GROUP_CREATION_SUBJECT, HELPDESK_NOTIFICATION_EMAIL_SUBJECT,
60 c0b26605 Sofia Papagiannaki
    INVITATION_EMAIL_SUBJECT, GREETING_EMAIL_SUBJECT, FEEDBACK_EMAIL_SUBJECT,
61 73fbaec4 Sofia Papagiannaki
    EMAIL_CHANGE_EMAIL_SUBJECT,
62 73fbaec4 Sofia Papagiannaki
    PROJECT_CREATION_SUBJECT, PROJECT_APPROVED_SUBJECT,
63 73fbaec4 Sofia Papagiannaki
    PROJECT_TERMINATION_SUBJECT, PROJECT_SUSPENSION_SUBJECT,
64 272cf735 Sofia Papagiannaki
    PROJECT_MEMBERSHIP_CHANGE_SUBJECT,
65 272cf735 Sofia Papagiannaki
    PROJECT_MEMBER_JOIN_POLICIES, PROJECT_MEMBER_LEAVE_POLICIES)
66 73fbaec4 Sofia Papagiannaki
from astakos.im.notifications import build_notification, NotificationError
67 73fbaec4 Sofia Papagiannaki
from astakos.im.models import (
68 974ee6a6 Sofia Papagiannaki
    AstakosUser, ProjectMembership, ProjectApplication, Project,
69 fcc1e93f Sofia Papagiannaki
    trigger_sync)
70 15ca2bea Giorgos Korfiatis
from astakos.im.models import submit_application as models_submit_application
71 73fbaec4 Sofia Papagiannaki
72 ae497612 Olga Brani
import astakos.im.messages as astakos_messages
73 f36af44a Antony Chazapis
74 f36af44a Antony Chazapis
logger = logging.getLogger(__name__)
75 f36af44a Antony Chazapis
76 5ce3ce4f Sofia Papagiannaki
77 111f3da6 Sofia Papagiannaki
def logged(func, msg):
78 111f3da6 Sofia Papagiannaki
    @wraps(func)
79 111f3da6 Sofia Papagiannaki
    def with_logging(*args, **kwargs):
80 111f3da6 Sofia Papagiannaki
        email = ''
81 111f3da6 Sofia Papagiannaki
        user = None
82 9a06d96f Olga Brani
        try:
83 111f3da6 Sofia Papagiannaki
            request = args[0]
84 9a06d96f Olga Brani
            email = request.user.email
85 9a06d96f Olga Brani
        except (KeyError, AttributeError), e:
86 9a06d96f Olga Brani
            email = ''
87 111f3da6 Sofia Papagiannaki
        r = func(*args, **kwargs)
88 c9e378c7 Sofia Papagiannaki
        if LOGGING_LEVEL:
89 aab4d540 Sofia Papagiannaki
            logger.log(LOGGING_LEVEL, msg % email)
90 111f3da6 Sofia Papagiannaki
        return r
91 111f3da6 Sofia Papagiannaki
    return with_logging
92 111f3da6 Sofia Papagiannaki
93 bf0c6de5 Sofia Papagiannaki
94 bf0c6de5 Sofia Papagiannaki
def login(request, user):
95 bf0c6de5 Sofia Papagiannaki
    auth_login(request, user)
96 c3c2212a Sofia Papagiannaki
    from astakos.im.models import SessionCatalog
97 c3c2212a Sofia Papagiannaki
    SessionCatalog(
98 c0b26605 Sofia Papagiannaki
        session_key=request.session.session_key,
99 c3c2212a Sofia Papagiannaki
        user=user
100 c3c2212a Sofia Papagiannaki
    ).save()
101 bf0c6de5 Sofia Papagiannaki
102 bf0c6de5 Sofia Papagiannaki
login = logged(login, '%s logged in.')
103 111f3da6 Sofia Papagiannaki
logout = logged(auth_logout, '%s logged out.')
104 111f3da6 Sofia Papagiannaki
105 5ce3ce4f Sofia Papagiannaki
106 683cf244 Sofia Papagiannaki
def send_verification(user, template_name='im/activation_email.txt'):
107 f36af44a Antony Chazapis
    """
108 683cf244 Sofia Papagiannaki
    Send email to user to verify his/her email and activate his/her account.
109 5ce3ce4f Sofia Papagiannaki

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

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

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

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

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

289 27e26a41 Sofia Papagiannaki
    Raises SendGreetingError, ValidationError
290 683cf244 Sofia Papagiannaki
    """
291 683cf244 Sofia Papagiannaki
    user.is_active = True
292 4bdd7e3d Kostas Papadimitriou
    user.email_verified = True
293 f1ab6639 Kostas Papadimitriou
    if not user.activation_sent:
294 f1ab6639 Kostas Papadimitriou
        user.activation_sent = datetime.now()
295 683cf244 Sofia Papagiannaki
    user.save()
296 23b9b72f Sofia Papagiannaki
    send_helpdesk_notification(user, helpdesk_email_template_name)
297 683cf244 Sofia Papagiannaki
    send_greeting(user, email_template_name)
298 683cf244 Sofia Papagiannaki
299 73fbaec4 Sofia Papagiannaki
def invite(inviter, email, realname):
300 73fbaec4 Sofia Papagiannaki
    inv = Invitation(inviter=inviter, username=email, realname=realname)
301 73fbaec4 Sofia Papagiannaki
    inv.save()
302 73fbaec4 Sofia Papagiannaki
    send_invitation(inv)
303 73fbaec4 Sofia Papagiannaki
    inviter.invitations = max(0, self.invitations - 1)
304 73fbaec4 Sofia Papagiannaki
    inviter.save()
305 5ce3ce4f Sofia Papagiannaki
306 9a06d96f Olga Brani
def switch_account_to_shibboleth(user, local_user,
307 9a06d96f Olga Brani
                                 greeting_template_name='im/welcome_email.txt'):
308 9a06d96f Olga Brani
    try:
309 9a06d96f Olga Brani
        provider = user.provider
310 9a06d96f Olga Brani
    except AttributeError:
311 23b9b72f Sofia Papagiannaki
        return
312 9a06d96f Olga Brani
    else:
313 9a06d96f Olga Brani
        if not provider == 'shibboleth':
314 9a06d96f Olga Brani
            return
315 9a06d96f Olga Brani
        user.delete()
316 9a06d96f Olga Brani
        local_user.provider = 'shibboleth'
317 9a06d96f Olga Brani
        local_user.third_party_identifier = user.third_party_identifier
318 9a06d96f Olga Brani
        local_user.save()
319 9a06d96f Olga Brani
        send_greeting(local_user, greeting_template_name)
320 9a06d96f Olga Brani
        return local_user
321 59f598f1 Sofia Papagiannaki
322 5ce3ce4f Sofia Papagiannaki
323 8f5a3a06 Sofia Papagiannaki
class SendMailError(Exception):
324 18ffbee1 Sofia Papagiannaki
    pass
325 8f5a3a06 Sofia Papagiannaki
326 5ce3ce4f Sofia Papagiannaki
327 8f5a3a06 Sofia Papagiannaki
class SendAdminNotificationError(SendMailError):
328 8f5a3a06 Sofia Papagiannaki
    def __init__(self):
329 ae497612 Olga Brani
        self.message = _(astakos_messages.ADMIN_NOTIFICATION_SEND_ERR)
330 18ffbee1 Sofia Papagiannaki
        super(SendAdminNotificationError, self).__init__()
331 8f5a3a06 Sofia Papagiannaki
332 5ce3ce4f Sofia Papagiannaki
333 18ffbee1 Sofia Papagiannaki
class SendVerificationError(SendMailError):
334 8f5a3a06 Sofia Papagiannaki
    def __init__(self):
335 ae497612 Olga Brani
        self.message = _(astakos_messages.VERIFICATION_SEND_ERR)
336 18ffbee1 Sofia Papagiannaki
        super(SendVerificationError, self).__init__()
337 8f5a3a06 Sofia Papagiannaki
338 5ce3ce4f Sofia Papagiannaki
339 18ffbee1 Sofia Papagiannaki
class SendInvitationError(SendMailError):
340 8f5a3a06 Sofia Papagiannaki
    def __init__(self):
341 ae497612 Olga Brani
        self.message = _(astakos_messages.INVITATION_SEND_ERR)
342 18ffbee1 Sofia Papagiannaki
        super(SendInvitationError, self).__init__()
343 8f5a3a06 Sofia Papagiannaki
344 5ce3ce4f Sofia Papagiannaki
345 18ffbee1 Sofia Papagiannaki
class SendGreetingError(SendMailError):
346 8f5a3a06 Sofia Papagiannaki
    def __init__(self):
347 ae497612 Olga Brani
        self.message = _(astakos_messages.GREETING_SEND_ERR)
348 18ffbee1 Sofia Papagiannaki
        super(SendGreetingError, self).__init__()
349 8f5a3a06 Sofia Papagiannaki
350 5ce3ce4f Sofia Papagiannaki
351 18ffbee1 Sofia Papagiannaki
class SendFeedbackError(SendMailError):
352 8f5a3a06 Sofia Papagiannaki
    def __init__(self):
353 ae497612 Olga Brani
        self.message = _(astakos_messages.FEEDBACK_SEND_ERR)
354 49790d9d Sofia Papagiannaki
        super(SendFeedbackError, self).__init__()
355 49790d9d Sofia Papagiannaki
356 5ce3ce4f Sofia Papagiannaki
357 49790d9d Sofia Papagiannaki
class ChangeEmailError(SendMailError):
358 49790d9d Sofia Papagiannaki
    def __init__(self):
359 ccab6eb5 Sofia Papagiannaki
        self.message = _(astakos_messages.CHANGE_EMAIL_SEND_ERR)
360 35f8ccf1 Sofia Papagiannaki
        super(ChangeEmailError, self).__init__()
361 a0be6a0c Sofia Papagiannaki
362 5ce3ce4f Sofia Papagiannaki
363 a0be6a0c Sofia Papagiannaki
class SendNotificationError(SendMailError):
364 a0be6a0c Sofia Papagiannaki
    def __init__(self):
365 ae497612 Olga Brani
        self.message = _(astakos_messages.NOTIFICATION_SEND_ERR)
366 a0be6a0c Sofia Papagiannaki
        super(SendNotificationError, self).__init__()
367 73fbaec4 Sofia Papagiannaki
368 73fbaec4 Sofia Papagiannaki
369 73fbaec4 Sofia Papagiannaki
### PROJECT VIEWS ###
370 fcc1e93f Sofia Papagiannaki
371 b0686c16 Giorgos Korfiatis
AUTO_ACCEPT_POLICY = 1
372 b0686c16 Giorgos Korfiatis
MODERATED_POLICY   = 2
373 b0686c16 Giorgos Korfiatis
CLOSED_POLICY      = 3
374 b0686c16 Giorgos Korfiatis
375 b0686c16 Giorgos Korfiatis
POLICIES = [ AUTO_ACCEPT_POLICY, MODERATED_POLICY, CLOSED_POLICY ]
376 73fbaec4 Sofia Papagiannaki
377 73fbaec4 Sofia Papagiannaki
def get_project_by_application_id(project_application_id):
378 73fbaec4 Sofia Papagiannaki
    try:
379 73fbaec4 Sofia Papagiannaki
        return Project.objects.get(application__id=project_application_id)
380 73fbaec4 Sofia Papagiannaki
    except Project.DoesNotExist:
381 73fbaec4 Sofia Papagiannaki
        raise IOError(
382 73fbaec4 Sofia Papagiannaki
            _(astakos_messages.UNKNOWN_PROJECT_APPLICATION_ID) % project_application_id)
383 73fbaec4 Sofia Papagiannaki
384 8dcaa6ac Giorgos Korfiatis
def get_project_id_of_application_id(project_application_id):
385 8dcaa6ac Giorgos Korfiatis
    try:
386 8dcaa6ac Giorgos Korfiatis
        return Project.objects.get(application__id=project_application_id).id
387 8dcaa6ac Giorgos Korfiatis
    except Project.DoesNotExist:
388 8dcaa6ac Giorgos Korfiatis
        raise IOError(
389 8dcaa6ac Giorgos Korfiatis
            _(astakos_messages.UNKNOWN_PROJECT_APPLICATION_ID) % project_application_id)
390 8dcaa6ac Giorgos Korfiatis
391 eb9ff37a Sofia Papagiannaki
def get_project_by_id(project_id):
392 eb9ff37a Sofia Papagiannaki
    try:
393 eb9ff37a Sofia Papagiannaki
        return Project.objects.get(id=project_id)
394 eb9ff37a Sofia Papagiannaki
    except Project.DoesNotExist:
395 eb9ff37a Sofia Papagiannaki
        raise IOError(
396 eb9ff37a Sofia Papagiannaki
            _(astakos_messages.UNKNOWN_PROJECT_ID) % project_id)
397 eb9ff37a Sofia Papagiannaki
398 8dcaa6ac Giorgos Korfiatis
def get_project_for_update(project_id):
399 8dcaa6ac Giorgos Korfiatis
    try:
400 8dcaa6ac Giorgos Korfiatis
        return Project.objects.select_for_update().get(id=project_id)
401 8dcaa6ac Giorgos Korfiatis
    except Project.DoesNotExist:
402 8dcaa6ac Giorgos Korfiatis
        raise IOError(
403 8dcaa6ac Giorgos Korfiatis
            _(astakos_messages.UNKNOWN_PROJECT_ID) % project_id)
404 8dcaa6ac Giorgos Korfiatis
405 73fbaec4 Sofia Papagiannaki
def get_user_by_id(user_id):
406 73fbaec4 Sofia Papagiannaki
    try:
407 974ee6a6 Sofia Papagiannaki
        return AstakosUser.objects.get(id=user_id)
408 73fbaec4 Sofia Papagiannaki
    except AstakosUser.DoesNotExist:
409 73fbaec4 Sofia Papagiannaki
        raise IOError(_(astakos_messages.UNKNOWN_USER_ID) % user_id)
410 73fbaec4 Sofia Papagiannaki
411 7dd3047d Sofia Papagiannaki
def create_membership(project, user):
412 7dd3047d Sofia Papagiannaki
    if isinstance(project, int):
413 8dcaa6ac Giorgos Korfiatis
        project = get_project_by_id(project)
414 7dd3047d Sofia Papagiannaki
    if isinstance(user, int):
415 7dd3047d Sofia Papagiannaki
        user = get_user_by_id(user)
416 7dd3047d Sofia Papagiannaki
    m = ProjectMembership(
417 7dd3047d Sofia Papagiannaki
        project=project,
418 7dd3047d Sofia Papagiannaki
        person=user,
419 7dd3047d Sofia Papagiannaki
        request_date=datetime.now())
420 73fbaec4 Sofia Papagiannaki
    try:
421 7dd3047d Sofia Papagiannaki
        m.save()
422 73fbaec4 Sofia Papagiannaki
    except IntegrityError, e:
423 73fbaec4 Sofia Papagiannaki
        raise IOError(_(astakos_messages.MEMBERSHIP_REQUEST_EXISTS))
424 73fbaec4 Sofia Papagiannaki
    else:
425 fc61dfb7 Sofia Papagiannaki
        return m
426 73fbaec4 Sofia Papagiannaki
427 8dcaa6ac Giorgos Korfiatis
def get_membership_for_update(project, user):
428 974ee6a6 Sofia Papagiannaki
    if isinstance(project, int):
429 8dcaa6ac Giorgos Korfiatis
        project = get_project_by_id(project)
430 974ee6a6 Sofia Papagiannaki
    if isinstance(user, int):
431 73fbaec4 Sofia Papagiannaki
        user = get_user_by_id(user)
432 73fbaec4 Sofia Papagiannaki
    try:
433 8dcaa6ac Giorgos Korfiatis
        return ProjectMembership.objects.select_for_update().get(
434 73fbaec4 Sofia Papagiannaki
            project=project,
435 73fbaec4 Sofia Papagiannaki
            person=user)
436 73fbaec4 Sofia Papagiannaki
    except ProjectMembership.DoesNotExist:
437 73fbaec4 Sofia Papagiannaki
        raise IOError(_(astakos_messages.NOT_MEMBERSHIP_REQUEST))
438 73fbaec4 Sofia Papagiannaki
439 8dcaa6ac Giorgos Korfiatis
def accept_membership(project_application_id, user, request_user=None):
440 73fbaec4 Sofia Papagiannaki
    """
441 73fbaec4 Sofia Papagiannaki
        Raises:
442 73fbaec4 Sofia Papagiannaki
            django.core.exceptions.PermissionDenied
443 73fbaec4 Sofia Papagiannaki
            IOError
444 73fbaec4 Sofia Papagiannaki
    """
445 8dcaa6ac Giorgos Korfiatis
    project_id = get_project_id_of_application_id(project_application_id)
446 8dcaa6ac Giorgos Korfiatis
    return do_accept_membership(project_id, user, request_user)
447 8dcaa6ac Giorgos Korfiatis
448 e47fb17a Sofia Papagiannaki
def do_accept_membership_checks(project, request_user):
449 73fbaec4 Sofia Papagiannaki
    if request_user and \
450 8dcaa6ac Giorgos Korfiatis
        (not project.application.owner == request_user and \
451 73fbaec4 Sofia Papagiannaki
            not request_user.is_superuser):
452 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(_(astakos_messages.NOT_ALLOWED))
453 8dcaa6ac Giorgos Korfiatis
    if not project.is_alive:
454 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(
455 8dcaa6ac Giorgos Korfiatis
            _(astakos_messages.NOT_ALIVE_PROJECT) % project.__dict__)
456 b0686c16 Giorgos Korfiatis
457 b0686c16 Giorgos Korfiatis
    join_policy = project.application.member_join_policy
458 b0686c16 Giorgos Korfiatis
    if join_policy == CLOSED_POLICY:
459 b0686c16 Giorgos Korfiatis
        raise PermissionDenied(_(astakos_messages.MEMBER_JOIN_POLICY_CLOSED))
460 b0686c16 Giorgos Korfiatis
461 8dcaa6ac Giorgos Korfiatis
    if project.violates_members_limit(adding=1):
462 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(_(astakos_messages.MEMBER_NUMBER_LIMIT_REACHED))
463 73fbaec4 Sofia Papagiannaki
464 e47fb17a Sofia Papagiannaki
def do_accept_membership(
465 e47fb17a Sofia Papagiannaki
        project_id, user, request_user=None, bypass_checks=False):
466 e47fb17a Sofia Papagiannaki
    project = get_project_for_update(project_id)
467 e47fb17a Sofia Papagiannaki
468 e47fb17a Sofia Papagiannaki
    if not bypass_checks:
469 e47fb17a Sofia Papagiannaki
        do_accept_membership_checks(project, request_user)
470 e47fb17a Sofia Papagiannaki
471 8dcaa6ac Giorgos Korfiatis
    membership = get_membership_for_update(project, user)
472 73fbaec4 Sofia Papagiannaki
    membership.accept()
473 3e47bb0b Sofia Papagiannaki
    trigger_sync()
474 73fbaec4 Sofia Papagiannaki
475 73fbaec4 Sofia Papagiannaki
    try:
476 73fbaec4 Sofia Papagiannaki
        notification = build_notification(
477 73fbaec4 Sofia Papagiannaki
            settings.SERVER_EMAIL,
478 974ee6a6 Sofia Papagiannaki
            [membership.person.email],
479 8dcaa6ac Giorgos Korfiatis
            _(PROJECT_MEMBERSHIP_CHANGE_SUBJECT) % project.__dict__,
480 73fbaec4 Sofia Papagiannaki
            template='im/projects/project_membership_change_notification.txt',
481 8dcaa6ac Giorgos Korfiatis
            dictionary={'object':project.application, 'action':'accepted'})
482 73fbaec4 Sofia Papagiannaki
        notification.send()
483 73fbaec4 Sofia Papagiannaki
    except NotificationError, e:
484 f7fc5a34 Giorgos Korfiatis
        logger.error(e.message)
485 73fbaec4 Sofia Papagiannaki
    return membership
486 73fbaec4 Sofia Papagiannaki
487 8dcaa6ac Giorgos Korfiatis
def reject_membership(project_application_id, 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 8dcaa6ac Giorgos Korfiatis
    project_id = get_project_id_of_application_id(project_application_id)
494 8dcaa6ac Giorgos Korfiatis
    return do_reject_membership(project_id, user, request_user)
495 8dcaa6ac Giorgos Korfiatis
496 e47fb17a Sofia Papagiannaki
def do_reject_membership_checks(project, request_user):
497 73fbaec4 Sofia Papagiannaki
    if request_user and \
498 8dcaa6ac Giorgos Korfiatis
        (not project.application.owner == request_user and \
499 73fbaec4 Sofia Papagiannaki
            not request_user.is_superuser):
500 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(_(astakos_messages.NOT_ALLOWED))
501 8dcaa6ac Giorgos Korfiatis
    if not project.is_alive:
502 e47fb17a Sofia Papagiannaki
        raise PermissionDenied(
503 e47fb17a Sofia Papagiannaki
            _(astakos_messages.NOT_ALIVE_PROJECT) % project.__dict__)
504 e47fb17a Sofia Papagiannaki
505 e47fb17a Sofia Papagiannaki
def do_reject_membership(
506 e47fb17a Sofia Papagiannaki
        project_id, user, request_user=None, bypass_checks=False):
507 e47fb17a Sofia Papagiannaki
    project = get_project_for_update(project_id)
508 73fbaec4 Sofia Papagiannaki
509 e47fb17a Sofia Papagiannaki
    if not bypass_checks:
510 e47fb17a Sofia Papagiannaki
        do_reject_membership_checks(project, request_user)
511 1352dabb Kostas Papadimitriou
512 8dcaa6ac Giorgos Korfiatis
    membership = get_membership_for_update(project, user)
513 73fbaec4 Sofia Papagiannaki
    membership.reject()
514 73fbaec4 Sofia Papagiannaki
515 73fbaec4 Sofia Papagiannaki
    try:
516 73fbaec4 Sofia Papagiannaki
        notification = build_notification(
517 73fbaec4 Sofia Papagiannaki
            settings.SERVER_EMAIL,
518 974ee6a6 Sofia Papagiannaki
            [membership.person.email],
519 8dcaa6ac Giorgos Korfiatis
            _(PROJECT_MEMBERSHIP_CHANGE_SUBJECT) % project.__dict__,
520 73fbaec4 Sofia Papagiannaki
            template='im/projects/project_membership_change_notification.txt',
521 8dcaa6ac Giorgos Korfiatis
            dictionary={'object':project.application, 'action':'rejected'})
522 73fbaec4 Sofia Papagiannaki
        notification.send()
523 73fbaec4 Sofia Papagiannaki
    except NotificationError, e:
524 f7fc5a34 Giorgos Korfiatis
        logger.error(e.message)
525 73fbaec4 Sofia Papagiannaki
    return membership
526 73fbaec4 Sofia Papagiannaki
527 8dcaa6ac Giorgos Korfiatis
def remove_membership(project_application_id, user, request_user=None):
528 73fbaec4 Sofia Papagiannaki
    """
529 73fbaec4 Sofia Papagiannaki
        Raises:
530 73fbaec4 Sofia Papagiannaki
            django.core.exceptions.PermissionDenied
531 73fbaec4 Sofia Papagiannaki
            IOError
532 73fbaec4 Sofia Papagiannaki
    """
533 8dcaa6ac Giorgos Korfiatis
    project_id = get_project_id_of_application_id(project_application_id)
534 8dcaa6ac Giorgos Korfiatis
    return do_remove_membership(project_id, user, request_user)
535 8dcaa6ac Giorgos Korfiatis
536 8c3e6cb5 Kostas Papadimitriou
def do_remove_membership_checks(project, membership, request_user=None):
537 73fbaec4 Sofia Papagiannaki
    if request_user and \
538 8dcaa6ac Giorgos Korfiatis
        (not project.application.owner == request_user and \
539 73fbaec4 Sofia Papagiannaki
            not request_user.is_superuser):
540 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(_(astakos_messages.NOT_ALLOWED))
541 8dcaa6ac Giorgos Korfiatis
    if not project.is_alive:
542 e47fb17a Sofia Papagiannaki
        raise PermissionDenied(
543 e47fb17a Sofia Papagiannaki
            _(astakos_messages.NOT_ALIVE_PROJECT) % project.__dict__)
544 e47fb17a Sofia Papagiannaki
545 e47fb17a Sofia Papagiannaki
def do_remove_membership(
546 e47fb17a Sofia Papagiannaki
        project_id, user, request_user=None, bypass_checks=False):
547 e47fb17a Sofia Papagiannaki
    project = get_project_for_update(project_id)
548 e47fb17a Sofia Papagiannaki
549 e47fb17a Sofia Papagiannaki
    if not bypass_checks:
550 e47fb17a Sofia Papagiannaki
        do_remove_membership_checks(project, request_user)
551 73fbaec4 Sofia Papagiannaki
552 b0686c16 Giorgos Korfiatis
    leave_policy = project.application.member_leave_policy
553 b0686c16 Giorgos Korfiatis
    if leave_policy == CLOSED_POLICY:
554 b0686c16 Giorgos Korfiatis
        raise PermissionDenied(_(astakos_messages.MEMBER_LEAVE_POLICY_CLOSED))
555 b0686c16 Giorgos Korfiatis
556 8dcaa6ac Giorgos Korfiatis
    membership = get_membership_for_update(project, user)
557 73fbaec4 Sofia Papagiannaki
    membership.remove()
558 3e47bb0b Sofia Papagiannaki
    trigger_sync()
559 73fbaec4 Sofia Papagiannaki
560 73fbaec4 Sofia Papagiannaki
    try:
561 73fbaec4 Sofia Papagiannaki
        notification = build_notification(
562 73fbaec4 Sofia Papagiannaki
            settings.SERVER_EMAIL,
563 974ee6a6 Sofia Papagiannaki
            [membership.person.email],
564 8dcaa6ac Giorgos Korfiatis
            _(PROJECT_MEMBERSHIP_CHANGE_SUBJECT) % project.__dict__,
565 73fbaec4 Sofia Papagiannaki
            template='im/projects/project_membership_change_notification.txt',
566 8dcaa6ac Giorgos Korfiatis
            dictionary={'object':project.application, 'action':'removed'})
567 73fbaec4 Sofia Papagiannaki
        notification.send()
568 73fbaec4 Sofia Papagiannaki
    except NotificationError, e:
569 f7fc5a34 Giorgos Korfiatis
        logger.error(e.message)
570 73fbaec4 Sofia Papagiannaki
    return membership
571 73fbaec4 Sofia Papagiannaki
572 8dcaa6ac Giorgos Korfiatis
def enroll_member(project_application_id, user, request_user=None):
573 8dcaa6ac Giorgos Korfiatis
    project_id = get_project_id_of_application_id(project_application_id)
574 8dcaa6ac Giorgos Korfiatis
    return do_enroll_member(project_id, user, request_user)
575 8dcaa6ac Giorgos Korfiatis
576 8dcaa6ac Giorgos Korfiatis
def do_enroll_member(project_id, user, request_user=None):
577 8dcaa6ac Giorgos Korfiatis
    membership = create_membership(project_id, user)
578 e47fb17a Sofia Papagiannaki
    return do_accept_membership(
579 e47fb17a Sofia Papagiannaki
        project_id, user, request_user, bypass_checks=True)
580 8dcaa6ac Giorgos Korfiatis
581 73fbaec4 Sofia Papagiannaki
def leave_project(project_application_id, user_id):
582 73fbaec4 Sofia Papagiannaki
    """
583 73fbaec4 Sofia Papagiannaki
        Raises:
584 73fbaec4 Sofia Papagiannaki
            django.core.exceptions.PermissionDenied
585 73fbaec4 Sofia Papagiannaki
            IOError
586 73fbaec4 Sofia Papagiannaki
    """
587 8dcaa6ac Giorgos Korfiatis
    project_id = get_project_id_of_application_id(project_application_id)
588 8dcaa6ac Giorgos Korfiatis
    return do_leave_project(project_id, user_id)
589 8dcaa6ac Giorgos Korfiatis
590 e47fb17a Sofia Papagiannaki
def do_leave_project_checks(project):
591 8dcaa6ac Giorgos Korfiatis
    if not project.is_alive:
592 8dcaa6ac Giorgos Korfiatis
        m = _(astakos_messages.NOT_ALIVE_PROJECT) % project.__dict__
593 8dcaa6ac Giorgos Korfiatis
        raise PermissionDenied(m)
594 8dcaa6ac Giorgos Korfiatis
595 03869281 Sofia Papagiannaki
    leave_policy = project.application.member_leave_policy
596 b0686c16 Giorgos Korfiatis
    if leave_policy == CLOSED_POLICY:
597 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(_(astakos_messages.MEMBER_LEAVE_POLICY_CLOSED))
598 73fbaec4 Sofia Papagiannaki
599 e47fb17a Sofia Papagiannaki
def do_leave_project(project_id, user_id, bypass_checks=False):
600 e47fb17a Sofia Papagiannaki
    project = get_project_for_update(project_id)
601 e47fb17a Sofia Papagiannaki
602 e47fb17a Sofia Papagiannaki
    if not bypass_checks:
603 1352dabb Kostas Papadimitriou
        do_leave_project_checks(project)
604 e47fb17a Sofia Papagiannaki
605 8dcaa6ac Giorgos Korfiatis
    membership = get_membership_for_update(project, user_id)
606 4e057833 Sofia Papagiannaki
607 4e057833 Sofia Papagiannaki
    leave_policy = project.application.member_leave_policy
608 b0686c16 Giorgos Korfiatis
    if leave_policy == AUTO_ACCEPT_POLICY:
609 73fbaec4 Sofia Papagiannaki
        membership.remove()
610 3e47bb0b Sofia Papagiannaki
        trigger_sync()
611 73fbaec4 Sofia Papagiannaki
    else:
612 73fbaec4 Sofia Papagiannaki
        membership.leave_request_date = datetime.now()
613 73fbaec4 Sofia Papagiannaki
        membership.save()
614 73fbaec4 Sofia Papagiannaki
    return membership
615 73fbaec4 Sofia Papagiannaki
616 73fbaec4 Sofia Papagiannaki
def join_project(project_application_id, user_id):
617 73fbaec4 Sofia Papagiannaki
    """
618 73fbaec4 Sofia Papagiannaki
        Raises:
619 73fbaec4 Sofia Papagiannaki
            django.core.exceptions.PermissionDenied
620 73fbaec4 Sofia Papagiannaki
            IOError
621 73fbaec4 Sofia Papagiannaki
    """
622 8dcaa6ac Giorgos Korfiatis
    project_id = get_project_id_of_application_id(project_application_id)
623 8dcaa6ac Giorgos Korfiatis
    return do_join_project(project_id, user_id)
624 8dcaa6ac Giorgos Korfiatis
625 e47fb17a Sofia Papagiannaki
def do_join_project_checks(project):
626 8dcaa6ac Giorgos Korfiatis
    if not project.is_alive:
627 8dcaa6ac Giorgos Korfiatis
        m = _(astakos_messages.NOT_ALIVE_PROJECT) % project.__dict__
628 8dcaa6ac Giorgos Korfiatis
        raise PermissionDenied(m)
629 8dcaa6ac Giorgos Korfiatis
630 974ee6a6 Sofia Papagiannaki
    join_policy = project.application.member_join_policy
631 b0686c16 Giorgos Korfiatis
    if join_policy == CLOSED_POLICY:
632 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(_(astakos_messages.MEMBER_JOIN_POLICY_CLOSED))
633 73fbaec4 Sofia Papagiannaki
634 e47fb17a Sofia Papagiannaki
def do_join_project(project_id, user_id, bypass_checks=False):
635 e47fb17a Sofia Papagiannaki
    project = get_project_for_update(project_id)
636 e47fb17a Sofia Papagiannaki
637 e47fb17a Sofia Papagiannaki
    if not bypass_checks:
638 e47fb17a Sofia Papagiannaki
        do_join_project_checks(project)
639 e47fb17a Sofia Papagiannaki
640 8dcaa6ac Giorgos Korfiatis
    membership = create_membership(project, user_id)
641 73fbaec4 Sofia Papagiannaki
642 4e057833 Sofia Papagiannaki
    join_policy = project.application.member_join_policy
643 b0686c16 Giorgos Korfiatis
    if (join_policy == AUTO_ACCEPT_POLICY and
644 a073c3b2 Giorgos Korfiatis
        not project.violates_members_limit(adding=1)):
645 73fbaec4 Sofia Papagiannaki
        membership.accept()
646 3e47bb0b Sofia Papagiannaki
        trigger_sync()
647 73fbaec4 Sofia Papagiannaki
    return membership
648 8dcaa6ac Giorgos Korfiatis
649 69c822cc Giorgos Korfiatis
def submit_application(**kw):
650 69c822cc Giorgos Korfiatis
651 15ca2bea Giorgos Korfiatis
    precursor_id = kw.get('precursor_application', None)
652 15ca2bea Giorgos Korfiatis
    if precursor_id is not None:
653 15ca2bea Giorgos Korfiatis
        sfu = ProjectApplication.objects.select_for_update()
654 15ca2bea Giorgos Korfiatis
        precursor = sfu.get(id=precursor_id)
655 15ca2bea Giorgos Korfiatis
        kw['precursor_application'] = precursor
656 73fbaec4 Sofia Papagiannaki
657 15ca2bea Giorgos Korfiatis
    application = models_submit_application(**kw)
658 1352dabb Kostas Papadimitriou
659 73fbaec4 Sofia Papagiannaki
    try:
660 73fbaec4 Sofia Papagiannaki
        notification = build_notification(
661 73fbaec4 Sofia Papagiannaki
            settings.SERVER_EMAIL,
662 73fbaec4 Sofia Papagiannaki
            [i[1] for i in settings.ADMINS],
663 73fbaec4 Sofia Papagiannaki
            _(PROJECT_CREATION_SUBJECT) % application.__dict__,
664 73fbaec4 Sofia Papagiannaki
            template='im/projects/project_creation_notification.txt',
665 73fbaec4 Sofia Papagiannaki
            dictionary={'object':application})
666 73fbaec4 Sofia Papagiannaki
        notification.send()
667 73fbaec4 Sofia Papagiannaki
    except NotificationError, e:
668 3d4a0a9b Sofia Papagiannaki
        logger.error(e)
669 15ca2bea Giorgos Korfiatis
    return application.id
670 73fbaec4 Sofia Papagiannaki
671 8dcaa6ac Giorgos Korfiatis
def update_application(app_id, **kw):
672 8dcaa6ac Giorgos Korfiatis
    app = ProjectApplication.objects.get(id=app_id)
673 8dcaa6ac Giorgos Korfiatis
    app.id = None
674 8dcaa6ac Giorgos Korfiatis
    app.state = app.PENDING
675 8dcaa6ac Giorgos Korfiatis
    app.precursor_application_id = app_id
676 8dcaa6ac Giorgos Korfiatis
    app.issue_date = datetime.now()
677 8dcaa6ac Giorgos Korfiatis
678 8dcaa6ac Giorgos Korfiatis
    resource_policies = kw.pop('resource_policies', None)
679 be4811c0 Giorgos Korfiatis
    for k, v in kw.iteritems():
680 8dcaa6ac Giorgos Korfiatis
        setattr(app, k, v)
681 8dcaa6ac Giorgos Korfiatis
    app.save()
682 8dcaa6ac Giorgos Korfiatis
    app.resource_policies = resource_policies
683 8dcaa6ac Giorgos Korfiatis
    return app.id
684 8dcaa6ac Giorgos Korfiatis
685 8dcaa6ac Giorgos Korfiatis
def approve_application(app):
686 8dcaa6ac Giorgos Korfiatis
687 8dcaa6ac Giorgos Korfiatis
    app_id = app if isinstance(app, int) else app.id
688 8dcaa6ac Giorgos Korfiatis
689 8dcaa6ac Giorgos Korfiatis
    try:
690 8dcaa6ac Giorgos Korfiatis
        objects = ProjectApplication.objects.select_for_update()
691 8dcaa6ac Giorgos Korfiatis
        application = objects.get(id=app_id)
692 8dcaa6ac Giorgos Korfiatis
    except ProjectApplication.DoesNotExist:
693 8dcaa6ac Giorgos Korfiatis
        raise PermissionDenied()
694 8dcaa6ac Giorgos Korfiatis
695 73fbaec4 Sofia Papagiannaki
    application.approve()
696 3e47bb0b Sofia Papagiannaki
    trigger_sync()
697 8dcaa6ac Giorgos Korfiatis
698 73fbaec4 Sofia Papagiannaki
    try:
699 73fbaec4 Sofia Papagiannaki
        notification = build_notification(
700 73fbaec4 Sofia Papagiannaki
            settings.SERVER_EMAIL,
701 974ee6a6 Sofia Papagiannaki
            [application.owner.email],
702 974ee6a6 Sofia Papagiannaki
            _(PROJECT_APPROVED_SUBJECT) % application.__dict__,
703 73fbaec4 Sofia Papagiannaki
            template='im/projects/project_approval_notification.txt',
704 73fbaec4 Sofia Papagiannaki
            dictionary={'object':application})
705 73fbaec4 Sofia Papagiannaki
        notification.send()
706 73fbaec4 Sofia Papagiannaki
    except NotificationError, e:
707 f7fc5a34 Giorgos Korfiatis
        logger.error(e.message)
708 eb9ff37a Sofia Papagiannaki
709 eb9ff37a Sofia Papagiannaki
def terminate(project_id):
710 5b9e9530 Giorgos Korfiatis
    project = get_project_for_update(project_id)
711 5b9e9530 Giorgos Korfiatis
712 5b9e9530 Giorgos Korfiatis
    if not project.is_alive:
713 5b9e9530 Giorgos Korfiatis
        m = _(astakos_messages.NOT_ALIVE_PROJECT) % project.__dict__
714 5b9e9530 Giorgos Korfiatis
        raise PermissionDenied(m)
715 5b9e9530 Giorgos Korfiatis
716 5b9e9530 Giorgos Korfiatis
    project.terminate()
717 eb9ff37a Sofia Papagiannaki
    trigger_sync()
718 eb9ff37a Sofia Papagiannaki
719 eb9ff37a Sofia Papagiannaki
    try:
720 eb9ff37a Sofia Papagiannaki
        notification = build_notification(
721 eb9ff37a Sofia Papagiannaki
            settings.SERVER_EMAIL,
722 eb9ff37a Sofia Papagiannaki
            [project.application.owner.email],
723 eb9ff37a Sofia Papagiannaki
            _(PROJECT_TERMINATION_SUBJECT) % project.__dict__,
724 eb9ff37a Sofia Papagiannaki
            template='im/projects/project_termination_notification.txt',
725 eb9ff37a Sofia Papagiannaki
            dictionary={'object':project.application}
726 eb9ff37a Sofia Papagiannaki
        ).send()
727 eb9ff37a Sofia Papagiannaki
    except NotificationError, e:
728 eb9ff37a Sofia Papagiannaki
        logger.error(e.message)
729 eb9ff37a Sofia Papagiannaki
730 eb9ff37a Sofia Papagiannaki
def suspend(project_id):
731 eb9ff37a Sofia Papagiannaki
    project = get_project_by_id(project_id)
732 eb9ff37a Sofia Papagiannaki
    project.last_approval_date = None
733 eb9ff37a Sofia Papagiannaki
    project.save()
734 eb9ff37a Sofia Papagiannaki
    trigger_sync()
735 1352dabb Kostas Papadimitriou
736 eb9ff37a Sofia Papagiannaki
    try:
737 eb9ff37a Sofia Papagiannaki
        notification = build_notification(
738 eb9ff37a Sofia Papagiannaki
            settings.SERVER_EMAIL,
739 eb9ff37a Sofia Papagiannaki
            [project.application.owner.email],
740 eb9ff37a Sofia Papagiannaki
            _(PROJECT_SUSPENSION_SUBJECT) % project.__dict__,
741 eb9ff37a Sofia Papagiannaki
            template='im/projects/project_suspension_notification.txt',
742 eb9ff37a Sofia Papagiannaki
            dictionary={'object':project.application}
743 eb9ff37a Sofia Papagiannaki
        ).send()
744 eb9ff37a Sofia Papagiannaki
    except NotificationError, e:
745 eb9ff37a Sofia Papagiannaki
        logger.error(e.message)