Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / functions.py @ 4b852017

History | View | Annotate | Download (24.6 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 73fbaec4 Sofia Papagiannaki
71 ae497612 Olga Brani
import astakos.im.messages as astakos_messages
72 f36af44a Antony Chazapis
73 f36af44a Antony Chazapis
logger = logging.getLogger(__name__)
74 f36af44a Antony Chazapis
75 5ce3ce4f Sofia Papagiannaki
76 111f3da6 Sofia Papagiannaki
def logged(func, msg):
77 111f3da6 Sofia Papagiannaki
    @wraps(func)
78 111f3da6 Sofia Papagiannaki
    def with_logging(*args, **kwargs):
79 111f3da6 Sofia Papagiannaki
        email = ''
80 111f3da6 Sofia Papagiannaki
        user = None
81 9a06d96f Olga Brani
        try:
82 111f3da6 Sofia Papagiannaki
            request = args[0]
83 9a06d96f Olga Brani
            email = request.user.email
84 9a06d96f Olga Brani
        except (KeyError, AttributeError), e:
85 9a06d96f Olga Brani
            email = ''
86 111f3da6 Sofia Papagiannaki
        r = func(*args, **kwargs)
87 c9e378c7 Sofia Papagiannaki
        if LOGGING_LEVEL:
88 aab4d540 Sofia Papagiannaki
            logger.log(LOGGING_LEVEL, msg % email)
89 111f3da6 Sofia Papagiannaki
        return r
90 111f3da6 Sofia Papagiannaki
    return with_logging
91 111f3da6 Sofia Papagiannaki
92 bf0c6de5 Sofia Papagiannaki
93 bf0c6de5 Sofia Papagiannaki
def login(request, user):
94 bf0c6de5 Sofia Papagiannaki
    auth_login(request, user)
95 c3c2212a Sofia Papagiannaki
    from astakos.im.models import SessionCatalog
96 c3c2212a Sofia Papagiannaki
    SessionCatalog(
97 c0b26605 Sofia Papagiannaki
        session_key=request.session.session_key,
98 c3c2212a Sofia Papagiannaki
        user=user
99 c3c2212a Sofia Papagiannaki
    ).save()
100 bf0c6de5 Sofia Papagiannaki
101 bf0c6de5 Sofia Papagiannaki
login = logged(login, '%s logged in.')
102 111f3da6 Sofia Papagiannaki
logout = logged(auth_logout, '%s logged out.')
103 111f3da6 Sofia Papagiannaki
104 5ce3ce4f Sofia Papagiannaki
105 683cf244 Sofia Papagiannaki
def send_verification(user, template_name='im/activation_email.txt'):
106 f36af44a Antony Chazapis
    """
107 683cf244 Sofia Papagiannaki
    Send email to user to verify his/her email and activate his/her account.
108 5ce3ce4f Sofia Papagiannaki

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

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

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

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

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

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