Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / functions.py @ 69b26576

History | View | Annotate | Download (24.9 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 b0686c16 Giorgos Korfiatis
AUTO_ACCEPT_POLICY = 1
371 b0686c16 Giorgos Korfiatis
MODERATED_POLICY   = 2
372 b0686c16 Giorgos Korfiatis
CLOSED_POLICY      = 3
373 b0686c16 Giorgos Korfiatis
374 b0686c16 Giorgos Korfiatis
POLICIES = [ AUTO_ACCEPT_POLICY, MODERATED_POLICY, CLOSED_POLICY ]
375 73fbaec4 Sofia Papagiannaki
376 73fbaec4 Sofia Papagiannaki
def get_project_by_application_id(project_application_id):
377 73fbaec4 Sofia Papagiannaki
    try:
378 73fbaec4 Sofia Papagiannaki
        return Project.objects.get(application__id=project_application_id)
379 73fbaec4 Sofia Papagiannaki
    except Project.DoesNotExist:
380 73fbaec4 Sofia Papagiannaki
        raise IOError(
381 73fbaec4 Sofia Papagiannaki
            _(astakos_messages.UNKNOWN_PROJECT_APPLICATION_ID) % project_application_id)
382 73fbaec4 Sofia Papagiannaki
383 8dcaa6ac Giorgos Korfiatis
def get_project_id_of_application_id(project_application_id):
384 8dcaa6ac Giorgos Korfiatis
    try:
385 8dcaa6ac Giorgos Korfiatis
        return Project.objects.get(application__id=project_application_id).id
386 8dcaa6ac Giorgos Korfiatis
    except Project.DoesNotExist:
387 8dcaa6ac Giorgos Korfiatis
        raise IOError(
388 8dcaa6ac Giorgos Korfiatis
            _(astakos_messages.UNKNOWN_PROJECT_APPLICATION_ID) % project_application_id)
389 8dcaa6ac Giorgos Korfiatis
390 eb9ff37a Sofia Papagiannaki
def get_project_by_id(project_id):
391 eb9ff37a Sofia Papagiannaki
    try:
392 eb9ff37a Sofia Papagiannaki
        return Project.objects.get(id=project_id)
393 eb9ff37a Sofia Papagiannaki
    except Project.DoesNotExist:
394 eb9ff37a Sofia Papagiannaki
        raise IOError(
395 eb9ff37a Sofia Papagiannaki
            _(astakos_messages.UNKNOWN_PROJECT_ID) % project_id)
396 eb9ff37a Sofia Papagiannaki
397 8dcaa6ac Giorgos Korfiatis
def get_project_for_update(project_id):
398 8dcaa6ac Giorgos Korfiatis
    try:
399 8dcaa6ac Giorgos Korfiatis
        return Project.objects.select_for_update().get(id=project_id)
400 8dcaa6ac Giorgos Korfiatis
    except Project.DoesNotExist:
401 8dcaa6ac Giorgos Korfiatis
        raise IOError(
402 8dcaa6ac Giorgos Korfiatis
            _(astakos_messages.UNKNOWN_PROJECT_ID) % project_id)
403 8dcaa6ac Giorgos Korfiatis
404 73fbaec4 Sofia Papagiannaki
def get_user_by_id(user_id):
405 73fbaec4 Sofia Papagiannaki
    try:
406 974ee6a6 Sofia Papagiannaki
        return AstakosUser.objects.get(id=user_id)
407 73fbaec4 Sofia Papagiannaki
    except AstakosUser.DoesNotExist:
408 73fbaec4 Sofia Papagiannaki
        raise IOError(_(astakos_messages.UNKNOWN_USER_ID) % user_id)
409 73fbaec4 Sofia Papagiannaki
410 7dd3047d Sofia Papagiannaki
def create_membership(project, user):
411 7dd3047d Sofia Papagiannaki
    if isinstance(project, int):
412 8dcaa6ac Giorgos Korfiatis
        project = get_project_by_id(project)
413 7dd3047d Sofia Papagiannaki
    if isinstance(user, int):
414 7dd3047d Sofia Papagiannaki
        user = get_user_by_id(user)
415 7dd3047d Sofia Papagiannaki
    m = ProjectMembership(
416 7dd3047d Sofia Papagiannaki
        project=project,
417 7dd3047d Sofia Papagiannaki
        person=user,
418 7dd3047d Sofia Papagiannaki
        request_date=datetime.now())
419 73fbaec4 Sofia Papagiannaki
    try:
420 7dd3047d Sofia Papagiannaki
        m.save()
421 73fbaec4 Sofia Papagiannaki
    except IntegrityError, e:
422 73fbaec4 Sofia Papagiannaki
        raise IOError(_(astakos_messages.MEMBERSHIP_REQUEST_EXISTS))
423 73fbaec4 Sofia Papagiannaki
    else:
424 fc61dfb7 Sofia Papagiannaki
        return m
425 73fbaec4 Sofia Papagiannaki
426 8dcaa6ac Giorgos Korfiatis
def get_membership_for_update(project, user):
427 974ee6a6 Sofia Papagiannaki
    if isinstance(project, int):
428 8dcaa6ac Giorgos Korfiatis
        project = get_project_by_id(project)
429 974ee6a6 Sofia Papagiannaki
    if isinstance(user, int):
430 73fbaec4 Sofia Papagiannaki
        user = get_user_by_id(user)
431 73fbaec4 Sofia Papagiannaki
    try:
432 8dcaa6ac Giorgos Korfiatis
        return ProjectMembership.objects.select_for_update().get(
433 73fbaec4 Sofia Papagiannaki
            project=project,
434 73fbaec4 Sofia Papagiannaki
            person=user)
435 73fbaec4 Sofia Papagiannaki
    except ProjectMembership.DoesNotExist:
436 73fbaec4 Sofia Papagiannaki
        raise IOError(_(astakos_messages.NOT_MEMBERSHIP_REQUEST))
437 73fbaec4 Sofia Papagiannaki
438 8dcaa6ac Giorgos Korfiatis
def accept_membership(project_application_id, user, request_user=None):
439 73fbaec4 Sofia Papagiannaki
    """
440 73fbaec4 Sofia Papagiannaki
        Raises:
441 73fbaec4 Sofia Papagiannaki
            django.core.exceptions.PermissionDenied
442 73fbaec4 Sofia Papagiannaki
            IOError
443 73fbaec4 Sofia Papagiannaki
    """
444 8dcaa6ac Giorgos Korfiatis
    project_id = get_project_id_of_application_id(project_application_id)
445 8dcaa6ac Giorgos Korfiatis
    return do_accept_membership(project_id, user, request_user)
446 8dcaa6ac Giorgos Korfiatis
447 e47fb17a Sofia Papagiannaki
def do_accept_membership_checks(project, request_user):
448 73fbaec4 Sofia Papagiannaki
    if request_user and \
449 8dcaa6ac Giorgos Korfiatis
        (not project.application.owner == request_user and \
450 73fbaec4 Sofia Papagiannaki
            not request_user.is_superuser):
451 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(_(astakos_messages.NOT_ALLOWED))
452 8dcaa6ac Giorgos Korfiatis
    if not project.is_alive:
453 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(
454 8dcaa6ac Giorgos Korfiatis
            _(astakos_messages.NOT_ALIVE_PROJECT) % project.__dict__)
455 b0686c16 Giorgos Korfiatis
456 b0686c16 Giorgos Korfiatis
    join_policy = project.application.member_join_policy
457 b0686c16 Giorgos Korfiatis
    if join_policy == CLOSED_POLICY:
458 b0686c16 Giorgos Korfiatis
        raise PermissionDenied(_(astakos_messages.MEMBER_JOIN_POLICY_CLOSED))
459 b0686c16 Giorgos Korfiatis
460 8dcaa6ac Giorgos Korfiatis
    if project.violates_members_limit(adding=1):
461 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(_(astakos_messages.MEMBER_NUMBER_LIMIT_REACHED))
462 73fbaec4 Sofia Papagiannaki
463 e47fb17a Sofia Papagiannaki
def do_accept_membership(
464 e47fb17a Sofia Papagiannaki
        project_id, user, request_user=None, bypass_checks=False):
465 e47fb17a Sofia Papagiannaki
    project = get_project_for_update(project_id)
466 e47fb17a Sofia Papagiannaki
467 e47fb17a Sofia Papagiannaki
    if not bypass_checks:
468 e47fb17a Sofia Papagiannaki
        do_accept_membership_checks(project, request_user)
469 e47fb17a Sofia Papagiannaki
470 8dcaa6ac Giorgos Korfiatis
    membership = get_membership_for_update(project, user)
471 73fbaec4 Sofia Papagiannaki
    membership.accept()
472 3e47bb0b Sofia Papagiannaki
    trigger_sync()
473 73fbaec4 Sofia Papagiannaki
474 73fbaec4 Sofia Papagiannaki
    try:
475 73fbaec4 Sofia Papagiannaki
        notification = build_notification(
476 73fbaec4 Sofia Papagiannaki
            settings.SERVER_EMAIL,
477 974ee6a6 Sofia Papagiannaki
            [membership.person.email],
478 8dcaa6ac Giorgos Korfiatis
            _(PROJECT_MEMBERSHIP_CHANGE_SUBJECT) % project.__dict__,
479 73fbaec4 Sofia Papagiannaki
            template='im/projects/project_membership_change_notification.txt',
480 8dcaa6ac Giorgos Korfiatis
            dictionary={'object':project.application, 'action':'accepted'})
481 73fbaec4 Sofia Papagiannaki
        notification.send()
482 73fbaec4 Sofia Papagiannaki
    except NotificationError, e:
483 f7fc5a34 Giorgos Korfiatis
        logger.error(e.message)
484 73fbaec4 Sofia Papagiannaki
    return membership
485 73fbaec4 Sofia Papagiannaki
486 8dcaa6ac Giorgos Korfiatis
def reject_membership(project_application_id, user, request_user=None):
487 73fbaec4 Sofia Papagiannaki
    """
488 73fbaec4 Sofia Papagiannaki
        Raises:
489 73fbaec4 Sofia Papagiannaki
            django.core.exceptions.PermissionDenied
490 73fbaec4 Sofia Papagiannaki
            IOError
491 73fbaec4 Sofia Papagiannaki
    """
492 8dcaa6ac Giorgos Korfiatis
    project_id = get_project_id_of_application_id(project_application_id)
493 8dcaa6ac Giorgos Korfiatis
    return do_reject_membership(project_id, user, request_user)
494 8dcaa6ac Giorgos Korfiatis
495 e47fb17a Sofia Papagiannaki
def do_reject_membership_checks(project, request_user):
496 73fbaec4 Sofia Papagiannaki
    if request_user and \
497 8dcaa6ac Giorgos Korfiatis
        (not project.application.owner == request_user and \
498 73fbaec4 Sofia Papagiannaki
            not request_user.is_superuser):
499 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(_(astakos_messages.NOT_ALLOWED))
500 8dcaa6ac Giorgos Korfiatis
    if not project.is_alive:
501 e47fb17a Sofia Papagiannaki
        raise PermissionDenied(
502 e47fb17a Sofia Papagiannaki
            _(astakos_messages.NOT_ALIVE_PROJECT) % project.__dict__)
503 e47fb17a Sofia Papagiannaki
504 e47fb17a Sofia Papagiannaki
def do_reject_membership(
505 e47fb17a Sofia Papagiannaki
        project_id, user, request_user=None, bypass_checks=False):
506 e47fb17a Sofia Papagiannaki
    project = get_project_for_update(project_id)
507 73fbaec4 Sofia Papagiannaki
508 e47fb17a Sofia Papagiannaki
    if not bypass_checks:
509 e47fb17a Sofia Papagiannaki
        do_reject_membership_checks(project, request_user)
510 e47fb17a Sofia Papagiannaki
    
511 8dcaa6ac Giorgos Korfiatis
    membership = get_membership_for_update(project, user)
512 73fbaec4 Sofia Papagiannaki
    membership.reject()
513 73fbaec4 Sofia Papagiannaki
514 73fbaec4 Sofia Papagiannaki
    try:
515 73fbaec4 Sofia Papagiannaki
        notification = build_notification(
516 73fbaec4 Sofia Papagiannaki
            settings.SERVER_EMAIL,
517 974ee6a6 Sofia Papagiannaki
            [membership.person.email],
518 8dcaa6ac Giorgos Korfiatis
            _(PROJECT_MEMBERSHIP_CHANGE_SUBJECT) % project.__dict__,
519 73fbaec4 Sofia Papagiannaki
            template='im/projects/project_membership_change_notification.txt',
520 8dcaa6ac Giorgos Korfiatis
            dictionary={'object':project.application, 'action':'rejected'})
521 73fbaec4 Sofia Papagiannaki
        notification.send()
522 73fbaec4 Sofia Papagiannaki
    except NotificationError, e:
523 f7fc5a34 Giorgos Korfiatis
        logger.error(e.message)
524 73fbaec4 Sofia Papagiannaki
    return membership
525 73fbaec4 Sofia Papagiannaki
526 8dcaa6ac Giorgos Korfiatis
def remove_membership(project_application_id, user, request_user=None):
527 73fbaec4 Sofia Papagiannaki
    """
528 73fbaec4 Sofia Papagiannaki
        Raises:
529 73fbaec4 Sofia Papagiannaki
            django.core.exceptions.PermissionDenied
530 73fbaec4 Sofia Papagiannaki
            IOError
531 73fbaec4 Sofia Papagiannaki
    """
532 8dcaa6ac Giorgos Korfiatis
    project_id = get_project_id_of_application_id(project_application_id)
533 8dcaa6ac Giorgos Korfiatis
    return do_remove_membership(project_id, user, request_user)
534 8dcaa6ac Giorgos Korfiatis
535 d38522fe Sofia Papagiannaki
def do_remove_membership_checks(project, membership, request_user):
536 73fbaec4 Sofia Papagiannaki
    if request_user and \
537 8dcaa6ac Giorgos Korfiatis
        (not project.application.owner == request_user and \
538 73fbaec4 Sofia Papagiannaki
            not request_user.is_superuser):
539 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(_(astakos_messages.NOT_ALLOWED))
540 8dcaa6ac Giorgos Korfiatis
    if not project.is_alive:
541 e47fb17a Sofia Papagiannaki
        raise PermissionDenied(
542 e47fb17a Sofia Papagiannaki
            _(astakos_messages.NOT_ALIVE_PROJECT) % project.__dict__)
543 e47fb17a Sofia Papagiannaki
544 e47fb17a Sofia Papagiannaki
def do_remove_membership(
545 e47fb17a Sofia Papagiannaki
        project_id, user, request_user=None, bypass_checks=False):
546 e47fb17a Sofia Papagiannaki
    project = get_project_for_update(project_id)
547 e47fb17a Sofia Papagiannaki
548 e47fb17a Sofia Papagiannaki
    if not bypass_checks:
549 e47fb17a Sofia Papagiannaki
        do_remove_membership_checks(project, request_user)
550 73fbaec4 Sofia Papagiannaki
551 b0686c16 Giorgos Korfiatis
    leave_policy = project.application.member_leave_policy
552 b0686c16 Giorgos Korfiatis
    if leave_policy == CLOSED_POLICY:
553 b0686c16 Giorgos Korfiatis
        raise PermissionDenied(_(astakos_messages.MEMBER_LEAVE_POLICY_CLOSED))
554 b0686c16 Giorgos Korfiatis
555 8dcaa6ac Giorgos Korfiatis
    membership = get_membership_for_update(project, user)
556 73fbaec4 Sofia Papagiannaki
    membership.remove()
557 3e47bb0b Sofia Papagiannaki
    trigger_sync()
558 73fbaec4 Sofia Papagiannaki
559 73fbaec4 Sofia Papagiannaki
    try:
560 73fbaec4 Sofia Papagiannaki
        notification = build_notification(
561 73fbaec4 Sofia Papagiannaki
            settings.SERVER_EMAIL,
562 974ee6a6 Sofia Papagiannaki
            [membership.person.email],
563 8dcaa6ac Giorgos Korfiatis
            _(PROJECT_MEMBERSHIP_CHANGE_SUBJECT) % project.__dict__,
564 73fbaec4 Sofia Papagiannaki
            template='im/projects/project_membership_change_notification.txt',
565 8dcaa6ac Giorgos Korfiatis
            dictionary={'object':project.application, 'action':'removed'})
566 73fbaec4 Sofia Papagiannaki
        notification.send()
567 73fbaec4 Sofia Papagiannaki
    except NotificationError, e:
568 f7fc5a34 Giorgos Korfiatis
        logger.error(e.message)
569 73fbaec4 Sofia Papagiannaki
    return membership
570 73fbaec4 Sofia Papagiannaki
571 8dcaa6ac Giorgos Korfiatis
def enroll_member(project_application_id, user, request_user=None):
572 8dcaa6ac Giorgos Korfiatis
    project_id = get_project_id_of_application_id(project_application_id)
573 8dcaa6ac Giorgos Korfiatis
    return do_enroll_member(project_id, user, request_user)
574 8dcaa6ac Giorgos Korfiatis
575 8dcaa6ac Giorgos Korfiatis
def do_enroll_member(project_id, user, request_user=None):
576 8dcaa6ac Giorgos Korfiatis
    membership = create_membership(project_id, user)
577 e47fb17a Sofia Papagiannaki
    return do_accept_membership(
578 e47fb17a Sofia Papagiannaki
        project_id, user, request_user, bypass_checks=True)
579 8dcaa6ac Giorgos Korfiatis
580 73fbaec4 Sofia Papagiannaki
def leave_project(project_application_id, user_id):
581 73fbaec4 Sofia Papagiannaki
    """
582 73fbaec4 Sofia Papagiannaki
        Raises:
583 73fbaec4 Sofia Papagiannaki
            django.core.exceptions.PermissionDenied
584 73fbaec4 Sofia Papagiannaki
            IOError
585 73fbaec4 Sofia Papagiannaki
    """
586 8dcaa6ac Giorgos Korfiatis
    project_id = get_project_id_of_application_id(project_application_id)
587 8dcaa6ac Giorgos Korfiatis
    return do_leave_project(project_id, user_id)
588 8dcaa6ac Giorgos Korfiatis
589 e47fb17a Sofia Papagiannaki
def do_leave_project_checks(project):
590 8dcaa6ac Giorgos Korfiatis
    if not project.is_alive:
591 8dcaa6ac Giorgos Korfiatis
        m = _(astakos_messages.NOT_ALIVE_PROJECT) % project.__dict__
592 8dcaa6ac Giorgos Korfiatis
        raise PermissionDenied(m)
593 8dcaa6ac Giorgos Korfiatis
594 03869281 Sofia Papagiannaki
    leave_policy = project.application.member_leave_policy
595 b0686c16 Giorgos Korfiatis
    if leave_policy == CLOSED_POLICY:
596 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(_(astakos_messages.MEMBER_LEAVE_POLICY_CLOSED))
597 73fbaec4 Sofia Papagiannaki
598 e47fb17a Sofia Papagiannaki
def do_leave_project(project_id, user_id, bypass_checks=False):
599 e47fb17a Sofia Papagiannaki
    project = get_project_for_update(project_id)
600 e47fb17a Sofia Papagiannaki
601 e47fb17a Sofia Papagiannaki
    if not bypass_checks:
602 e47fb17a Sofia Papagiannaki
        do_leave_project_checks(projetc)
603 e47fb17a Sofia Papagiannaki
604 8dcaa6ac Giorgos Korfiatis
    membership = get_membership_for_update(project, user_id)
605 4e057833 Sofia Papagiannaki
606 4e057833 Sofia Papagiannaki
    leave_policy = project.application.member_leave_policy
607 b0686c16 Giorgos Korfiatis
    if leave_policy == AUTO_ACCEPT_POLICY:
608 73fbaec4 Sofia Papagiannaki
        membership.remove()
609 3e47bb0b Sofia Papagiannaki
        trigger_sync()
610 73fbaec4 Sofia Papagiannaki
    else:
611 73fbaec4 Sofia Papagiannaki
        membership.leave_request_date = datetime.now()
612 73fbaec4 Sofia Papagiannaki
        membership.save()
613 73fbaec4 Sofia Papagiannaki
    return membership
614 73fbaec4 Sofia Papagiannaki
615 73fbaec4 Sofia Papagiannaki
def join_project(project_application_id, user_id):
616 73fbaec4 Sofia Papagiannaki
    """
617 73fbaec4 Sofia Papagiannaki
        Raises:
618 73fbaec4 Sofia Papagiannaki
            django.core.exceptions.PermissionDenied
619 73fbaec4 Sofia Papagiannaki
            IOError
620 73fbaec4 Sofia Papagiannaki
    """
621 8dcaa6ac Giorgos Korfiatis
    project_id = get_project_id_of_application_id(project_application_id)
622 8dcaa6ac Giorgos Korfiatis
    return do_join_project(project_id, user_id)
623 8dcaa6ac Giorgos Korfiatis
624 e47fb17a Sofia Papagiannaki
def do_join_project_checks(project):
625 8dcaa6ac Giorgos Korfiatis
    if not project.is_alive:
626 8dcaa6ac Giorgos Korfiatis
        m = _(astakos_messages.NOT_ALIVE_PROJECT) % project.__dict__
627 8dcaa6ac Giorgos Korfiatis
        raise PermissionDenied(m)
628 8dcaa6ac Giorgos Korfiatis
629 974ee6a6 Sofia Papagiannaki
    join_policy = project.application.member_join_policy
630 b0686c16 Giorgos Korfiatis
    if join_policy == CLOSED_POLICY:
631 73fbaec4 Sofia Papagiannaki
        raise PermissionDenied(_(astakos_messages.MEMBER_JOIN_POLICY_CLOSED))
632 73fbaec4 Sofia Papagiannaki
633 e47fb17a Sofia Papagiannaki
def do_join_project(project_id, user_id, bypass_checks=False):
634 e47fb17a Sofia Papagiannaki
    project = get_project_for_update(project_id)
635 e47fb17a Sofia Papagiannaki
636 e47fb17a Sofia Papagiannaki
    if not bypass_checks:
637 e47fb17a Sofia Papagiannaki
        do_join_project_checks(project)
638 e47fb17a Sofia Papagiannaki
639 8dcaa6ac Giorgos Korfiatis
    membership = create_membership(project, user_id)
640 73fbaec4 Sofia Papagiannaki
641 4e057833 Sofia Papagiannaki
    join_policy = project.application.member_join_policy
642 b0686c16 Giorgos Korfiatis
    if (join_policy == AUTO_ACCEPT_POLICY and
643 a073c3b2 Giorgos Korfiatis
        not project.violates_members_limit(adding=1)):
644 73fbaec4 Sofia Papagiannaki
        membership.accept()
645 3e47bb0b Sofia Papagiannaki
        trigger_sync()
646 73fbaec4 Sofia Papagiannaki
    return membership
647 8dcaa6ac Giorgos Korfiatis
648 73fbaec4 Sofia Papagiannaki
def submit_application(
649 e47fb17a Sofia Papagiannaki
        application, resource_policies, applicant, comments,
650 e47fb17a Sofia Papagiannaki
        precursor_application=None):
651 73fbaec4 Sofia Papagiannaki
652 73fbaec4 Sofia Papagiannaki
    application.submit(
653 73fbaec4 Sofia Papagiannaki
        resource_policies, applicant, comments, precursor_application)
654 73fbaec4 Sofia Papagiannaki
    
655 73fbaec4 Sofia Papagiannaki
    try:
656 73fbaec4 Sofia Papagiannaki
        notification = build_notification(
657 73fbaec4 Sofia Papagiannaki
            settings.SERVER_EMAIL,
658 73fbaec4 Sofia Papagiannaki
            [i[1] for i in settings.ADMINS],
659 73fbaec4 Sofia Papagiannaki
            _(PROJECT_CREATION_SUBJECT) % application.__dict__,
660 73fbaec4 Sofia Papagiannaki
            template='im/projects/project_creation_notification.txt',
661 73fbaec4 Sofia Papagiannaki
            dictionary={'object':application})
662 73fbaec4 Sofia Papagiannaki
        notification.send()
663 73fbaec4 Sofia Papagiannaki
    except NotificationError, e:
664 3d4a0a9b Sofia Papagiannaki
        logger.error(e)
665 73fbaec4 Sofia Papagiannaki
    return application
666 73fbaec4 Sofia Papagiannaki
667 8dcaa6ac Giorgos Korfiatis
def update_application(app_id, **kw):
668 8dcaa6ac Giorgos Korfiatis
    app = ProjectApplication.objects.get(id=app_id)
669 8dcaa6ac Giorgos Korfiatis
    app.id = None
670 8dcaa6ac Giorgos Korfiatis
    app.state = app.PENDING
671 8dcaa6ac Giorgos Korfiatis
    app.precursor_application_id = app_id
672 8dcaa6ac Giorgos Korfiatis
    app.issue_date = datetime.now()
673 8dcaa6ac Giorgos Korfiatis
674 8dcaa6ac Giorgos Korfiatis
    resource_policies = kw.pop('resource_policies', None)
675 be4811c0 Giorgos Korfiatis
    for k, v in kw.iteritems():
676 8dcaa6ac Giorgos Korfiatis
        setattr(app, k, v)
677 8dcaa6ac Giorgos Korfiatis
    app.save()
678 8dcaa6ac Giorgos Korfiatis
    app.resource_policies = resource_policies
679 8dcaa6ac Giorgos Korfiatis
    return app.id
680 8dcaa6ac Giorgos Korfiatis
681 8dcaa6ac Giorgos Korfiatis
def approve_application(app):
682 8dcaa6ac Giorgos Korfiatis
683 8dcaa6ac Giorgos Korfiatis
    app_id = app if isinstance(app, int) else app.id
684 8dcaa6ac Giorgos Korfiatis
685 8dcaa6ac Giorgos Korfiatis
    try:
686 8dcaa6ac Giorgos Korfiatis
        objects = ProjectApplication.objects.select_for_update()
687 8dcaa6ac Giorgos Korfiatis
        application = objects.get(id=app_id)
688 8dcaa6ac Giorgos Korfiatis
    except ProjectApplication.DoesNotExist:
689 8dcaa6ac Giorgos Korfiatis
        raise PermissionDenied()
690 8dcaa6ac Giorgos Korfiatis
691 73fbaec4 Sofia Papagiannaki
    application.approve()
692 3e47bb0b Sofia Papagiannaki
    trigger_sync()
693 8dcaa6ac Giorgos Korfiatis
694 73fbaec4 Sofia Papagiannaki
    try:
695 73fbaec4 Sofia Papagiannaki
        notification = build_notification(
696 73fbaec4 Sofia Papagiannaki
            settings.SERVER_EMAIL,
697 974ee6a6 Sofia Papagiannaki
            [application.owner.email],
698 974ee6a6 Sofia Papagiannaki
            _(PROJECT_APPROVED_SUBJECT) % application.__dict__,
699 73fbaec4 Sofia Papagiannaki
            template='im/projects/project_approval_notification.txt',
700 73fbaec4 Sofia Papagiannaki
            dictionary={'object':application})
701 73fbaec4 Sofia Papagiannaki
        notification.send()
702 73fbaec4 Sofia Papagiannaki
    except NotificationError, e:
703 f7fc5a34 Giorgos Korfiatis
        logger.error(e.message)
704 eb9ff37a Sofia Papagiannaki
705 eb9ff37a Sofia Papagiannaki
def terminate(project_id):
706 5b9e9530 Giorgos Korfiatis
    project = get_project_for_update(project_id)
707 5b9e9530 Giorgos Korfiatis
708 5b9e9530 Giorgos Korfiatis
    if not project.is_alive:
709 5b9e9530 Giorgos Korfiatis
        m = _(astakos_messages.NOT_ALIVE_PROJECT) % project.__dict__
710 5b9e9530 Giorgos Korfiatis
        raise PermissionDenied(m)
711 5b9e9530 Giorgos Korfiatis
712 5b9e9530 Giorgos Korfiatis
    project.terminate()
713 eb9ff37a Sofia Papagiannaki
    trigger_sync()
714 eb9ff37a Sofia Papagiannaki
715 eb9ff37a Sofia Papagiannaki
    try:
716 eb9ff37a Sofia Papagiannaki
        notification = build_notification(
717 eb9ff37a Sofia Papagiannaki
            settings.SERVER_EMAIL,
718 eb9ff37a Sofia Papagiannaki
            [project.application.owner.email],
719 eb9ff37a Sofia Papagiannaki
            _(PROJECT_TERMINATION_SUBJECT) % project.__dict__,
720 eb9ff37a Sofia Papagiannaki
            template='im/projects/project_termination_notification.txt',
721 eb9ff37a Sofia Papagiannaki
            dictionary={'object':project.application}
722 eb9ff37a Sofia Papagiannaki
        ).send()
723 eb9ff37a Sofia Papagiannaki
    except NotificationError, e:
724 eb9ff37a Sofia Papagiannaki
        logger.error(e.message)
725 eb9ff37a Sofia Papagiannaki
726 eb9ff37a Sofia Papagiannaki
def suspend(project_id):
727 eb9ff37a Sofia Papagiannaki
    project = get_project_by_id(project_id)
728 eb9ff37a Sofia Papagiannaki
    project.last_approval_date = None
729 eb9ff37a Sofia Papagiannaki
    project.save()
730 eb9ff37a Sofia Papagiannaki
    trigger_sync()
731 eb9ff37a Sofia Papagiannaki
    
732 eb9ff37a Sofia Papagiannaki
    try:
733 eb9ff37a Sofia Papagiannaki
        notification = build_notification(
734 eb9ff37a Sofia Papagiannaki
            settings.SERVER_EMAIL,
735 eb9ff37a Sofia Papagiannaki
            [project.application.owner.email],
736 eb9ff37a Sofia Papagiannaki
            _(PROJECT_SUSPENSION_SUBJECT) % project.__dict__,
737 eb9ff37a Sofia Papagiannaki
            template='im/projects/project_suspension_notification.txt',
738 eb9ff37a Sofia Papagiannaki
            dictionary={'object':project.application}
739 eb9ff37a Sofia Papagiannaki
        ).send()
740 eb9ff37a Sofia Papagiannaki
    except NotificationError, e:
741 eb9ff37a Sofia Papagiannaki
        logger.error(e.message)