Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / functions.py @ 764d99c4

History | View | Annotate | Download (31.4 kB)

1 abd8467c Giorgos Korfiatis
# Copyright 2011, 2012, 2013 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 f9224cc0 Sofia Papagiannaki
from django.core.mail import send_mail, get_connection
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 9a06d96f Olga Brani
from django.contrib.auth.models import AnonymousUser
46 73fbaec4 Sofia Papagiannaki
from django.core.exceptions import PermissionDenied
47 974ee6a6 Sofia Papagiannaki
from django.db import IntegrityError
48 ff67242a Giorgos Korfiatis
from django.http import Http404
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 31bc3a62 Kostas Papadimitriou
    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 0a7a4104 Kostas Papadimitriou
    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 e30537f1 Sofia Papagiannaki
    AstakosUser, Invitation, ProjectMembership, ProjectApplication, Project,
69 c7c0ec58 Giorgos Korfiatis
    UserSetting,
70 aa27f246 Giorgos Korfiatis
    get_resource_names, new_chain)
71 9770ba6c Giorgos Korfiatis
from astakos.im.quotas import (qh_sync_user, qh_sync_users,
72 9e3af524 Giorgos Korfiatis
                               register_pending_apps)
73 a3eb3a95 Giorgos Korfiatis
from astakos.im.project_notif import (
74 466cc12c Giorgos Korfiatis
    membership_change_notify, membership_enroll_notify,
75 bb6a4465 Giorgos Korfiatis
    membership_request_notify, membership_leave_request_notify,
76 a3eb3a95 Giorgos Korfiatis
    application_submit_notify, application_approve_notify,
77 19eb3ee6 Giorgos Korfiatis
    application_deny_notify,
78 a3eb3a95 Giorgos Korfiatis
    project_termination_notify, project_suspension_notify)
79 0a7a4104 Kostas Papadimitriou
from astakos.im import settings
80 ae497612 Olga Brani
import astakos.im.messages as astakos_messages
81 f36af44a Antony Chazapis
82 f36af44a Antony Chazapis
logger = logging.getLogger(__name__)
83 f36af44a Antony Chazapis
84 5ce3ce4f Sofia Papagiannaki
85 bf0c6de5 Sofia Papagiannaki
def login(request, user):
86 bf0c6de5 Sofia Papagiannaki
    auth_login(request, user)
87 c3c2212a Sofia Papagiannaki
    from astakos.im.models import SessionCatalog
88 c3c2212a Sofia Papagiannaki
    SessionCatalog(
89 c0b26605 Sofia Papagiannaki
        session_key=request.session.session_key,
90 c3c2212a Sofia Papagiannaki
        user=user
91 c3c2212a Sofia Papagiannaki
    ).save()
92 5df4c364 Kostas Papadimitriou
    logger.info('%s logged in.', user.log_display)
93 5df4c364 Kostas Papadimitriou
94 bf0c6de5 Sofia Papagiannaki
95 5df4c364 Kostas Papadimitriou
def logout(request, *args, **kwargs):
96 5df4c364 Kostas Papadimitriou
    user = request.user
97 5df4c364 Kostas Papadimitriou
    auth_logout(request, *args, **kwargs)
98 5df4c364 Kostas Papadimitriou
    logger.info('%s logged out.', user.log_display)
99 111f3da6 Sofia Papagiannaki
100 5ce3ce4f Sofia Papagiannaki
101 683cf244 Sofia Papagiannaki
def send_verification(user, template_name='im/activation_email.txt'):
102 f36af44a Antony Chazapis
    """
103 683cf244 Sofia Papagiannaki
    Send email to user to verify his/her email and activate his/her account.
104 5ce3ce4f Sofia Papagiannaki

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

141 8f5a3a06 Sofia Papagiannaki
    Raises SendNotificationError
142 683cf244 Sofia Papagiannaki
    """
143 aab4d540 Sofia Papagiannaki
    dictionary = dictionary or {}
144 3abf6c78 Sofia Papagiannaki
    message = render_to_string(template_name, dictionary)
145 1cbce16f Sofia Papagiannaki
    sender = settings.SERVER_EMAIL
146 0a7a4104 Kostas Papadimitriou
    recipient_list = [e[1] for e in settings.HELPDESK + settings.MANAGERS]
147 8f5a3a06 Sofia Papagiannaki
    try:
148 31bc3a62 Kostas Papadimitriou
        send_mail(subject, message, sender, recipient_list,
149 f9224cc0 Sofia Papagiannaki
                  connection=get_connection())
150 8f5a3a06 Sofia Papagiannaki
    except (SMTPException, socket.error) as e:
151 8f5a3a06 Sofia Papagiannaki
        logger.exception(e)
152 8f5a3a06 Sofia Papagiannaki
        raise SendNotificationError()
153 8f5a3a06 Sofia Papagiannaki
    else:
154 5d5ce247 Kostas Papadimitriou
        user = dictionary.get('user')
155 5d5ce247 Kostas Papadimitriou
        msg = 'Sent admin notification for user %s' % user.log_display
156 aab4d540 Sofia Papagiannaki
        logger.log(LOGGING_LEVEL, msg)
157 683cf244 Sofia Papagiannaki
158 5ce3ce4f Sofia Papagiannaki
159 9a06d96f Olga Brani
def send_account_creation_notification(template_name, dictionary=None):
160 5d5ce247 Kostas Papadimitriou
    user = dictionary.get('user')
161 5d5ce247 Kostas Papadimitriou
    subject = _(ACCOUNT_CREATION_SUBJECT) % {'user': user.email}
162 9a06d96f Olga Brani
    return _send_admin_notification(template_name, dictionary, subject=subject)
163 9a06d96f Olga Brani
164 9a06d96f Olga Brani
165 f9aea9c8 Sofia Papagiannaki
def send_helpdesk_notification(user, template_name='im/helpdesk_notification.txt'):
166 a0be6a0c Sofia Papagiannaki
    """
167 31bc3a62 Kostas Papadimitriou
    Send email to settings.HELPDESK list to notify for a new user activation.
168 5ce3ce4f Sofia Papagiannaki

169 a0be6a0c Sofia Papagiannaki
    Raises SendNotificationError
170 a0be6a0c Sofia Papagiannaki
    """
171 3abf6c78 Sofia Papagiannaki
    message = render_to_string(
172 3abf6c78 Sofia Papagiannaki
        template_name,
173 3abf6c78 Sofia Papagiannaki
        {'user': user}
174 3abf6c78 Sofia Papagiannaki
    )
175 1cbce16f Sofia Papagiannaki
    sender = settings.SERVER_EMAIL
176 0a7a4104 Kostas Papadimitriou
    recipient_list = [e[1] for e in settings.HELPDESK + settings.MANAGERS]
177 a0be6a0c Sofia Papagiannaki
    try:
178 f9224cc0 Sofia Papagiannaki
        send_mail(_(HELPDESK_NOTIFICATION_EMAIL_SUBJECT) % {'user': user.email},
179 31bc3a62 Kostas Papadimitriou
                  message, sender, recipient_list, connection=get_connection())
180 a0be6a0c Sofia Papagiannaki
    except (SMTPException, socket.error) as e:
181 a0be6a0c Sofia Papagiannaki
        logger.exception(e)
182 a0be6a0c Sofia Papagiannaki
        raise SendNotificationError()
183 a0be6a0c Sofia Papagiannaki
    else:
184 3abf6c78 Sofia Papagiannaki
        msg = 'Sent helpdesk admin notification for %s' % user.email
185 aab4d540 Sofia Papagiannaki
        logger.log(LOGGING_LEVEL, msg)
186 a0be6a0c Sofia Papagiannaki
187 5ce3ce4f Sofia Papagiannaki
188 683cf244 Sofia Papagiannaki
def send_invitation(invitation, template_name='im/invitation.txt'):
189 683cf244 Sofia Papagiannaki
    """
190 683cf244 Sofia Papagiannaki
    Send invitation email.
191 5ce3ce4f Sofia Papagiannaki

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

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

289 27e26a41 Sofia Papagiannaki
    Raises SendGreetingError, ValidationError
290 683cf244 Sofia Papagiannaki
    """
291 683cf244 Sofia Papagiannaki
    user.is_active = True
292 4bdd7e3d Kostas Papadimitriou
    user.email_verified = True
293 f1ab6639 Kostas Papadimitriou
    if not user.activation_sent:
294 f1ab6639 Kostas Papadimitriou
        user.activation_sent = datetime.now()
295 683cf244 Sofia Papagiannaki
    user.save()
296 44104cd3 Giorgos Korfiatis
    qh_sync_user(user.id)
297 23b9b72f Sofia Papagiannaki
    send_helpdesk_notification(user, helpdesk_email_template_name)
298 683cf244 Sofia Papagiannaki
    send_greeting(user, email_template_name)
299 683cf244 Sofia Papagiannaki
300 21e0fdad Giorgos Korfiatis
def deactivate(user):
301 21e0fdad Giorgos Korfiatis
    user.is_active = False
302 21e0fdad Giorgos Korfiatis
    user.save()
303 21e0fdad Giorgos Korfiatis
304 73fbaec4 Sofia Papagiannaki
def invite(inviter, email, realname):
305 73fbaec4 Sofia Papagiannaki
    inv = Invitation(inviter=inviter, username=email, realname=realname)
306 73fbaec4 Sofia Papagiannaki
    inv.save()
307 73fbaec4 Sofia Papagiannaki
    send_invitation(inv)
308 e30537f1 Sofia Papagiannaki
    inviter.invitations = max(0, inviter.invitations - 1)
309 73fbaec4 Sofia Papagiannaki
    inviter.save()
310 5ce3ce4f Sofia Papagiannaki
311 9a06d96f Olga Brani
def switch_account_to_shibboleth(user, local_user,
312 9a06d96f Olga Brani
                                 greeting_template_name='im/welcome_email.txt'):
313 9a06d96f Olga Brani
    try:
314 9a06d96f Olga Brani
        provider = user.provider
315 9a06d96f Olga Brani
    except AttributeError:
316 23b9b72f Sofia Papagiannaki
        return
317 9a06d96f Olga Brani
    else:
318 9a06d96f Olga Brani
        if not provider == 'shibboleth':
319 9a06d96f Olga Brani
            return
320 9a06d96f Olga Brani
        user.delete()
321 9a06d96f Olga Brani
        local_user.provider = 'shibboleth'
322 9a06d96f Olga Brani
        local_user.third_party_identifier = user.third_party_identifier
323 9a06d96f Olga Brani
        local_user.save()
324 9a06d96f Olga Brani
        send_greeting(local_user, greeting_template_name)
325 9a06d96f Olga Brani
        return local_user
326 59f598f1 Sofia Papagiannaki
327 5ce3ce4f Sofia Papagiannaki
328 8f5a3a06 Sofia Papagiannaki
class SendMailError(Exception):
329 18ffbee1 Sofia Papagiannaki
    pass
330 8f5a3a06 Sofia Papagiannaki
331 5ce3ce4f Sofia Papagiannaki
332 8f5a3a06 Sofia Papagiannaki
class SendAdminNotificationError(SendMailError):
333 8f5a3a06 Sofia Papagiannaki
    def __init__(self):
334 ae497612 Olga Brani
        self.message = _(astakos_messages.ADMIN_NOTIFICATION_SEND_ERR)
335 18ffbee1 Sofia Papagiannaki
        super(SendAdminNotificationError, self).__init__()
336 8f5a3a06 Sofia Papagiannaki
337 5ce3ce4f Sofia Papagiannaki
338 18ffbee1 Sofia Papagiannaki
class SendVerificationError(SendMailError):
339 8f5a3a06 Sofia Papagiannaki
    def __init__(self):
340 ae497612 Olga Brani
        self.message = _(astakos_messages.VERIFICATION_SEND_ERR)
341 18ffbee1 Sofia Papagiannaki
        super(SendVerificationError, self).__init__()
342 8f5a3a06 Sofia Papagiannaki
343 5ce3ce4f Sofia Papagiannaki
344 18ffbee1 Sofia Papagiannaki
class SendInvitationError(SendMailError):
345 8f5a3a06 Sofia Papagiannaki
    def __init__(self):
346 ae497612 Olga Brani
        self.message = _(astakos_messages.INVITATION_SEND_ERR)
347 18ffbee1 Sofia Papagiannaki
        super(SendInvitationError, self).__init__()
348 8f5a3a06 Sofia Papagiannaki
349 5ce3ce4f Sofia Papagiannaki
350 18ffbee1 Sofia Papagiannaki
class SendGreetingError(SendMailError):
351 8f5a3a06 Sofia Papagiannaki
    def __init__(self):
352 ae497612 Olga Brani
        self.message = _(astakos_messages.GREETING_SEND_ERR)
353 18ffbee1 Sofia Papagiannaki
        super(SendGreetingError, self).__init__()
354 8f5a3a06 Sofia Papagiannaki
355 5ce3ce4f Sofia Papagiannaki
356 18ffbee1 Sofia Papagiannaki
class SendFeedbackError(SendMailError):
357 8f5a3a06 Sofia Papagiannaki
    def __init__(self):
358 ae497612 Olga Brani
        self.message = _(astakos_messages.FEEDBACK_SEND_ERR)
359 49790d9d Sofia Papagiannaki
        super(SendFeedbackError, self).__init__()
360 49790d9d Sofia Papagiannaki
361 5ce3ce4f Sofia Papagiannaki
362 49790d9d Sofia Papagiannaki
class ChangeEmailError(SendMailError):
363 49790d9d Sofia Papagiannaki
    def __init__(self):
364 ccab6eb5 Sofia Papagiannaki
        self.message = _(astakos_messages.CHANGE_EMAIL_SEND_ERR)
365 35f8ccf1 Sofia Papagiannaki
        super(ChangeEmailError, self).__init__()
366 a0be6a0c Sofia Papagiannaki
367 5ce3ce4f Sofia Papagiannaki
368 a0be6a0c Sofia Papagiannaki
class SendNotificationError(SendMailError):
369 a0be6a0c Sofia Papagiannaki
    def __init__(self):
370 ae497612 Olga Brani
        self.message = _(astakos_messages.NOTIFICATION_SEND_ERR)
371 a0be6a0c Sofia Papagiannaki
        super(SendNotificationError, self).__init__()
372 73fbaec4 Sofia Papagiannaki
373 73fbaec4 Sofia Papagiannaki
374 7a08e179 Giorgos Korfiatis
### PROJECT FUNCTIONS ###
375 fcc1e93f Sofia Papagiannaki
376 b0686c16 Giorgos Korfiatis
AUTO_ACCEPT_POLICY = 1
377 7a08e179 Giorgos Korfiatis
MODERATED_POLICY = 2
378 7a08e179 Giorgos Korfiatis
CLOSED_POLICY = 3
379 7a08e179 Giorgos Korfiatis
380 7a08e179 Giorgos Korfiatis
POLICIES = [AUTO_ACCEPT_POLICY, MODERATED_POLICY, CLOSED_POLICY]
381 b0686c16 Giorgos Korfiatis
382 73fbaec4 Sofia Papagiannaki
383 73fbaec4 Sofia Papagiannaki
def get_project_by_application_id(project_application_id):
384 73fbaec4 Sofia Papagiannaki
    try:
385 73fbaec4 Sofia Papagiannaki
        return Project.objects.get(application__id=project_application_id)
386 73fbaec4 Sofia Papagiannaki
    except Project.DoesNotExist:
387 7a08e179 Giorgos Korfiatis
        m = (_(astakos_messages.UNKNOWN_PROJECT_APPLICATION_ID) %
388 7a08e179 Giorgos Korfiatis
             project_application_id)
389 7a08e179 Giorgos Korfiatis
        raise IOError(m)
390 7a08e179 Giorgos Korfiatis
391 73fbaec4 Sofia Papagiannaki
392 a75dbd7b Giorgos Korfiatis
def get_related_project_id(application_id):
393 a75dbd7b Giorgos Korfiatis
    try:
394 a75dbd7b Giorgos Korfiatis
        app = ProjectApplication.objects.get(id=application_id)
395 a75dbd7b Giorgos Korfiatis
        chain = app.chain
396 7a08e179 Giorgos Korfiatis
        Project.objects.get(id=chain)
397 a75dbd7b Giorgos Korfiatis
        return chain
398 3966d268 Giorgos Korfiatis
    except (ProjectApplication.DoesNotExist, Project.DoesNotExist):
399 a75dbd7b Giorgos Korfiatis
        return None
400 a75dbd7b Giorgos Korfiatis
401 7a08e179 Giorgos Korfiatis
402 0932ac43 Giorgos Korfiatis
def get_chain_of_application_id(application_id):
403 0932ac43 Giorgos Korfiatis
    try:
404 0932ac43 Giorgos Korfiatis
        app = ProjectApplication.objects.get(id=application_id)
405 0932ac43 Giorgos Korfiatis
        chain = app.chain
406 0932ac43 Giorgos Korfiatis
        return chain.chain
407 7a08e179 Giorgos Korfiatis
    except ProjectApplication.DoesNotExist:
408 0932ac43 Giorgos Korfiatis
        return None
409 0932ac43 Giorgos Korfiatis
410 7a08e179 Giorgos Korfiatis
411 eb9ff37a Sofia Papagiannaki
def get_project_by_id(project_id):
412 eb9ff37a Sofia Papagiannaki
    try:
413 eb9ff37a Sofia Papagiannaki
        return Project.objects.get(id=project_id)
414 eb9ff37a Sofia Papagiannaki
    except Project.DoesNotExist:
415 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.UNKNOWN_PROJECT_ID) % project_id
416 7a08e179 Giorgos Korfiatis
        raise IOError(m)
417 7a08e179 Giorgos Korfiatis
418 eb9ff37a Sofia Papagiannaki
419 c10f1cf5 Giorgos Korfiatis
def get_project_by_name(name):
420 c10f1cf5 Giorgos Korfiatis
    try:
421 c10f1cf5 Giorgos Korfiatis
        return Project.objects.get(name=name)
422 c10f1cf5 Giorgos Korfiatis
    except Project.DoesNotExist:
423 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.UNKNOWN_PROJECT_ID) % name
424 7a08e179 Giorgos Korfiatis
        raise IOError(m)
425 c10f1cf5 Giorgos Korfiatis
426 c10f1cf5 Giorgos Korfiatis
427 8dcaa6ac Giorgos Korfiatis
def get_project_for_update(project_id):
428 8dcaa6ac Giorgos Korfiatis
    try:
429 ea1e5d9f Giorgos Korfiatis
        return Project.objects.get_for_update(id=project_id)
430 8dcaa6ac Giorgos Korfiatis
    except Project.DoesNotExist:
431 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.UNKNOWN_PROJECT_ID) % project_id
432 7a08e179 Giorgos Korfiatis
        raise IOError(m)
433 7a08e179 Giorgos Korfiatis
434 8dcaa6ac Giorgos Korfiatis
435 19eb3ee6 Giorgos Korfiatis
def get_application_for_update(application_id):
436 19eb3ee6 Giorgos Korfiatis
    try:
437 ea1e5d9f Giorgos Korfiatis
        return ProjectApplication.objects.get_for_update(id=application_id)
438 19eb3ee6 Giorgos Korfiatis
    except ProjectApplication.DoesNotExist:
439 19eb3ee6 Giorgos Korfiatis
        m = _(astakos_messages.UNKNOWN_PROJECT_APPLICATION_ID) % application_id
440 19eb3ee6 Giorgos Korfiatis
        raise IOError(m)
441 19eb3ee6 Giorgos Korfiatis
442 7a08e179 Giorgos Korfiatis
443 73fbaec4 Sofia Papagiannaki
def get_user_by_id(user_id):
444 73fbaec4 Sofia Papagiannaki
    try:
445 974ee6a6 Sofia Papagiannaki
        return AstakosUser.objects.get(id=user_id)
446 73fbaec4 Sofia Papagiannaki
    except AstakosUser.DoesNotExist:
447 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.UNKNOWN_USER_ID) % user_id
448 7a08e179 Giorgos Korfiatis
        raise IOError(m)
449 7a08e179 Giorgos Korfiatis
450 73fbaec4 Sofia Papagiannaki
451 3c049f6d Giorgos Korfiatis
def get_user_by_uuid(uuid):
452 3c049f6d Giorgos Korfiatis
    try:
453 3c049f6d Giorgos Korfiatis
        return AstakosUser.objects.get(uuid=uuid)
454 3c049f6d Giorgos Korfiatis
    except AstakosUser.DoesNotExist:
455 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.UNKNOWN_USER_ID) % uuid
456 7a08e179 Giorgos Korfiatis
        raise IOError(m)
457 3c049f6d Giorgos Korfiatis
458 97e93991 Kostas Papadimitriou
459 d07ce657 Giorgos Korfiatis
def get_membership_for_update(project_id, user_id):
460 73fbaec4 Sofia Papagiannaki
    try:
461 ea1e5d9f Giorgos Korfiatis
        objs = ProjectMembership.objects
462 d07ce657 Giorgos Korfiatis
        return objs.get_for_update(project__id=project_id,
463 d07ce657 Giorgos Korfiatis
                                   person__id=user_id)
464 73fbaec4 Sofia Papagiannaki
    except ProjectMembership.DoesNotExist:
465 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.NOT_MEMBERSHIP_REQUEST)
466 7a08e179 Giorgos Korfiatis
        raise IOError(m)
467 7a08e179 Giorgos Korfiatis
468 73fbaec4 Sofia Papagiannaki
469 7f3c4920 Giorgos Korfiatis
def get_membership_for_update_by_id(project_id, memb_id):
470 7f3c4920 Giorgos Korfiatis
    try:
471 7f3c4920 Giorgos Korfiatis
        objs = ProjectMembership.objects
472 7f3c4920 Giorgos Korfiatis
        return objs.get_for_update(project__id=project_id,
473 5dcf6618 Giorgos Korfiatis
                                   id=memb_id)
474 7f3c4920 Giorgos Korfiatis
    except ProjectMembership.DoesNotExist:
475 7f3c4920 Giorgos Korfiatis
        m = _(astakos_messages.NOT_MEMBERSHIP_REQUEST)
476 7f3c4920 Giorgos Korfiatis
        raise IOError(m)
477 7f3c4920 Giorgos Korfiatis
478 7f3c4920 Giorgos Korfiatis
479 d07ce657 Giorgos Korfiatis
def checkAllowed(entity, request_user, admin_only=False):
480 3c638f72 Giorgos Korfiatis
    if isinstance(entity, Project):
481 3c638f72 Giorgos Korfiatis
        application = entity.application
482 3c638f72 Giorgos Korfiatis
    elif isinstance(entity, ProjectApplication):
483 3c638f72 Giorgos Korfiatis
        application = entity
484 3c638f72 Giorgos Korfiatis
    else:
485 3c638f72 Giorgos Korfiatis
        m = "%s not a Project nor a ProjectApplication" % (entity,)
486 3c638f72 Giorgos Korfiatis
        raise ValueError(m)
487 3c638f72 Giorgos Korfiatis
488 d07ce657 Giorgos Korfiatis
    if not request_user or request_user.is_project_admin():
489 d07ce657 Giorgos Korfiatis
        return
490 d07ce657 Giorgos Korfiatis
491 d07ce657 Giorgos Korfiatis
    if not admin_only and application.owner == request_user:
492 d07ce657 Giorgos Korfiatis
        return
493 d07ce657 Giorgos Korfiatis
494 d07ce657 Giorgos Korfiatis
    m = _(astakos_messages.NOT_ALLOWED)
495 d07ce657 Giorgos Korfiatis
    raise PermissionDenied(m)
496 d07ce657 Giorgos Korfiatis
497 907f15db Giorgos Korfiatis
498 907f15db Giorgos Korfiatis
def checkAlive(project):
499 907f15db Giorgos Korfiatis
    if not project.is_alive:
500 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.NOT_ALIVE_PROJECT) % project.__dict__
501 7a08e179 Giorgos Korfiatis
        raise PermissionDenied(m)
502 7a08e179 Giorgos Korfiatis
503 907f15db Giorgos Korfiatis
504 ff67242a Giorgos Korfiatis
def accept_membership_checks(project, request_user):
505 907f15db Giorgos Korfiatis
    checkAllowed(project, request_user)
506 907f15db Giorgos Korfiatis
    checkAlive(project)
507 b0686c16 Giorgos Korfiatis
508 b0686c16 Giorgos Korfiatis
    join_policy = project.application.member_join_policy
509 b0686c16 Giorgos Korfiatis
    if join_policy == CLOSED_POLICY:
510 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.MEMBER_JOIN_POLICY_CLOSED)
511 7a08e179 Giorgos Korfiatis
        raise PermissionDenied(m)
512 b0686c16 Giorgos Korfiatis
513 8dcaa6ac Giorgos Korfiatis
    if project.violates_members_limit(adding=1):
514 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.MEMBER_NUMBER_LIMIT_REACHED)
515 7a08e179 Giorgos Korfiatis
        raise PermissionDenied(m)
516 73fbaec4 Sofia Papagiannaki
517 d07ce657 Giorgos Korfiatis
518 7f3c4920 Giorgos Korfiatis
def accept_membership(project_id, memb_id, request_user=None):
519 e47fb17a Sofia Papagiannaki
    project = get_project_for_update(project_id)
520 ff67242a Giorgos Korfiatis
    accept_membership_checks(project, request_user)
521 14f7f6a5 Giorgos Korfiatis
522 7f3c4920 Giorgos Korfiatis
    membership = get_membership_for_update_by_id(project_id, memb_id)
523 14f7f6a5 Giorgos Korfiatis
    if not membership.can_accept():
524 14f7f6a5 Giorgos Korfiatis
        m = _(astakos_messages.NOT_MEMBERSHIP_REQUEST)
525 14f7f6a5 Giorgos Korfiatis
        raise PermissionDenied(m)
526 d4fc6292 Giorgos Korfiatis
527 7f3c4920 Giorgos Korfiatis
    user = membership.person
528 73fbaec4 Sofia Papagiannaki
    membership.accept()
529 7f3c4920 Giorgos Korfiatis
    qh_sync_user(user.id)
530 f30f0170 Giorgos Korfiatis
    logger.info("User %s has been accepted in %s." %
531 7f3c4920 Giorgos Korfiatis
                (user.log_display, project))
532 73fbaec4 Sofia Papagiannaki
533 7f3c4920 Giorgos Korfiatis
    membership_change_notify(project, user, 'accepted')
534 73fbaec4 Sofia Papagiannaki
    return membership
535 73fbaec4 Sofia Papagiannaki
536 7a08e179 Giorgos Korfiatis
537 ff67242a Giorgos Korfiatis
def reject_membership_checks(project, request_user):
538 907f15db Giorgos Korfiatis
    checkAllowed(project, request_user)
539 907f15db Giorgos Korfiatis
    checkAlive(project)
540 e47fb17a Sofia Papagiannaki
541 d07ce657 Giorgos Korfiatis
542 7f3c4920 Giorgos Korfiatis
def reject_membership(project_id, memb_id, request_user=None):
543 e47fb17a Sofia Papagiannaki
    project = get_project_for_update(project_id)
544 ff67242a Giorgos Korfiatis
    reject_membership_checks(project, request_user)
545 7f3c4920 Giorgos Korfiatis
    membership = get_membership_for_update_by_id(project_id, memb_id)
546 14f7f6a5 Giorgos Korfiatis
    if not membership.can_reject():
547 14f7f6a5 Giorgos Korfiatis
        m = _(astakos_messages.NOT_MEMBERSHIP_REQUEST)
548 14f7f6a5 Giorgos Korfiatis
        raise PermissionDenied(m)
549 d4fc6292 Giorgos Korfiatis
550 7f3c4920 Giorgos Korfiatis
    user = membership.person
551 73fbaec4 Sofia Papagiannaki
    membership.reject()
552 f30f0170 Giorgos Korfiatis
    logger.info("Request of user %s for %s has been rejected." %
553 7f3c4920 Giorgos Korfiatis
                (user.log_display, project))
554 73fbaec4 Sofia Papagiannaki
555 7f3c4920 Giorgos Korfiatis
    membership_change_notify(project, user, 'rejected')
556 73fbaec4 Sofia Papagiannaki
    return membership
557 73fbaec4 Sofia Papagiannaki
558 7a08e179 Giorgos Korfiatis
559 aad0e329 Giorgos Korfiatis
def cancel_membership_checks(project):
560 aad0e329 Giorgos Korfiatis
    checkAlive(project)
561 aad0e329 Giorgos Korfiatis
562 d07ce657 Giorgos Korfiatis
563 d07ce657 Giorgos Korfiatis
def cancel_membership(project_id, request_user):
564 aad0e329 Giorgos Korfiatis
    project = get_project_for_update(project_id)
565 aad0e329 Giorgos Korfiatis
    cancel_membership_checks(project)
566 d07ce657 Giorgos Korfiatis
    membership = get_membership_for_update(project_id, request_user.id)
567 aad0e329 Giorgos Korfiatis
    if not membership.can_cancel():
568 aad0e329 Giorgos Korfiatis
        m = _(astakos_messages.NOT_MEMBERSHIP_REQUEST)
569 aad0e329 Giorgos Korfiatis
        raise PermissionDenied(m)
570 aad0e329 Giorgos Korfiatis
571 aad0e329 Giorgos Korfiatis
    membership.cancel()
572 f30f0170 Giorgos Korfiatis
    logger.info("Request of user %s for %s has been cancelled." %
573 f30f0170 Giorgos Korfiatis
                (membership.person.log_display, project))
574 aad0e329 Giorgos Korfiatis
575 7a08e179 Giorgos Korfiatis
576 ff67242a Giorgos Korfiatis
def remove_membership_checks(project, request_user=None):
577 907f15db Giorgos Korfiatis
    checkAllowed(project, request_user)
578 907f15db Giorgos Korfiatis
    checkAlive(project)
579 73fbaec4 Sofia Papagiannaki
580 b0686c16 Giorgos Korfiatis
    leave_policy = project.application.member_leave_policy
581 b0686c16 Giorgos Korfiatis
    if leave_policy == CLOSED_POLICY:
582 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.MEMBER_LEAVE_POLICY_CLOSED)
583 7a08e179 Giorgos Korfiatis
        raise PermissionDenied(m)
584 7a08e179 Giorgos Korfiatis
585 b0686c16 Giorgos Korfiatis
586 7f3c4920 Giorgos Korfiatis
def remove_membership(project_id, memb_id, request_user=None):
587 907f15db Giorgos Korfiatis
    project = get_project_for_update(project_id)
588 ff67242a Giorgos Korfiatis
    remove_membership_checks(project, request_user)
589 7f3c4920 Giorgos Korfiatis
    membership = get_membership_for_update_by_id(project_id, memb_id)
590 14f7f6a5 Giorgos Korfiatis
    if not membership.can_remove():
591 14f7f6a5 Giorgos Korfiatis
        m = _(astakos_messages.NOT_ACCEPTED_MEMBERSHIP)
592 14f7f6a5 Giorgos Korfiatis
        raise PermissionDenied(m)
593 d4fc6292 Giorgos Korfiatis
594 7f3c4920 Giorgos Korfiatis
    user = membership.person
595 73fbaec4 Sofia Papagiannaki
    membership.remove()
596 7f3c4920 Giorgos Korfiatis
    qh_sync_user(user.id)
597 f30f0170 Giorgos Korfiatis
    logger.info("User %s has been removed from %s." %
598 7f3c4920 Giorgos Korfiatis
                (user.log_display, project))
599 73fbaec4 Sofia Papagiannaki
600 7f3c4920 Giorgos Korfiatis
    membership_change_notify(project, user, 'removed')
601 73fbaec4 Sofia Papagiannaki
    return membership
602 73fbaec4 Sofia Papagiannaki
603 7a08e179 Giorgos Korfiatis
604 ff67242a Giorgos Korfiatis
def enroll_member(project_id, user, request_user=None):
605 907f15db Giorgos Korfiatis
    project = get_project_for_update(project_id)
606 ff67242a Giorgos Korfiatis
    accept_membership_checks(project, request_user)
607 e05c541e Giorgos Korfiatis
608 e05c541e Giorgos Korfiatis
    membership, created = ProjectMembership.objects.get_or_create(
609 e05c541e Giorgos Korfiatis
        project=project,
610 e05c541e Giorgos Korfiatis
        person=user)
611 14f7f6a5 Giorgos Korfiatis
612 14f7f6a5 Giorgos Korfiatis
    if not membership.can_accept():
613 14f7f6a5 Giorgos Korfiatis
        m = _(astakos_messages.NOT_MEMBERSHIP_REQUEST)
614 14f7f6a5 Giorgos Korfiatis
        raise PermissionDenied(m)
615 d4fc6292 Giorgos Korfiatis
616 907f15db Giorgos Korfiatis
    membership.accept()
617 e05c541e Giorgos Korfiatis
    qh_sync_user(user.id)
618 f30f0170 Giorgos Korfiatis
    logger.info("User %s has been enrolled in %s." %
619 f30f0170 Giorgos Korfiatis
                (membership.person.log_display, project))
620 570015d2 Giorgos Korfiatis
621 466cc12c Giorgos Korfiatis
    membership_enroll_notify(project, membership.person)
622 907f15db Giorgos Korfiatis
    return membership
623 8dcaa6ac Giorgos Korfiatis
624 7a08e179 Giorgos Korfiatis
625 ff67242a Giorgos Korfiatis
def leave_project_checks(project):
626 907f15db Giorgos Korfiatis
    checkAlive(project)
627 8dcaa6ac Giorgos Korfiatis
628 03869281 Sofia Papagiannaki
    leave_policy = project.application.member_leave_policy
629 b0686c16 Giorgos Korfiatis
    if leave_policy == CLOSED_POLICY:
630 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.MEMBER_LEAVE_POLICY_CLOSED)
631 7a08e179 Giorgos Korfiatis
        raise PermissionDenied(m)
632 7a08e179 Giorgos Korfiatis
633 73fbaec4 Sofia Papagiannaki
634 d4660e00 Giorgos Korfiatis
def can_leave_request(project, user):
635 d4660e00 Giorgos Korfiatis
    leave_policy = project.application.member_leave_policy
636 d4660e00 Giorgos Korfiatis
    if leave_policy == CLOSED_POLICY:
637 d4660e00 Giorgos Korfiatis
        return False
638 d4660e00 Giorgos Korfiatis
    m = user.get_membership(project)
639 d4660e00 Giorgos Korfiatis
    if m is None:
640 d4660e00 Giorgos Korfiatis
        return False
641 d4660e00 Giorgos Korfiatis
    if m.state != ProjectMembership.ACCEPTED:
642 d4660e00 Giorgos Korfiatis
        return False
643 d4660e00 Giorgos Korfiatis
    return True
644 d4660e00 Giorgos Korfiatis
645 d07ce657 Giorgos Korfiatis
646 d07ce657 Giorgos Korfiatis
def leave_project(project_id, request_user):
647 e47fb17a Sofia Papagiannaki
    project = get_project_for_update(project_id)
648 ff67242a Giorgos Korfiatis
    leave_project_checks(project)
649 d07ce657 Giorgos Korfiatis
    membership = get_membership_for_update(project_id, request_user.id)
650 14f7f6a5 Giorgos Korfiatis
    if not membership.can_leave():
651 14f7f6a5 Giorgos Korfiatis
        m = _(astakos_messages.NOT_ACCEPTED_MEMBERSHIP)
652 14f7f6a5 Giorgos Korfiatis
        raise PermissionDenied(m)
653 4e057833 Sofia Papagiannaki
654 bb6a4465 Giorgos Korfiatis
    auto_accepted = False
655 4e057833 Sofia Papagiannaki
    leave_policy = project.application.member_leave_policy
656 b0686c16 Giorgos Korfiatis
    if leave_policy == AUTO_ACCEPT_POLICY:
657 73fbaec4 Sofia Papagiannaki
        membership.remove()
658 d07ce657 Giorgos Korfiatis
        qh_sync_user(request_user.id)
659 f30f0170 Giorgos Korfiatis
        logger.info("User %s has left %s." %
660 f30f0170 Giorgos Korfiatis
                    (membership.person.log_display, project))
661 bb6a4465 Giorgos Korfiatis
        auto_accepted = True
662 73fbaec4 Sofia Papagiannaki
    else:
663 c1007621 Giorgos Korfiatis
        membership.leave_request()
664 f30f0170 Giorgos Korfiatis
        logger.info("User %s requested to leave %s." %
665 f30f0170 Giorgos Korfiatis
                    (membership.person.log_display, project))
666 bb6a4465 Giorgos Korfiatis
        membership_leave_request_notify(project, membership.person)
667 bb6a4465 Giorgos Korfiatis
    return auto_accepted
668 73fbaec4 Sofia Papagiannaki
669 7a08e179 Giorgos Korfiatis
670 ff67242a Giorgos Korfiatis
def join_project_checks(project):
671 907f15db Giorgos Korfiatis
    checkAlive(project)
672 8dcaa6ac Giorgos Korfiatis
673 974ee6a6 Sofia Papagiannaki
    join_policy = project.application.member_join_policy
674 b0686c16 Giorgos Korfiatis
    if join_policy == CLOSED_POLICY:
675 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.MEMBER_JOIN_POLICY_CLOSED)
676 7a08e179 Giorgos Korfiatis
        raise PermissionDenied(m)
677 7a08e179 Giorgos Korfiatis
678 73fbaec4 Sofia Papagiannaki
679 d4660e00 Giorgos Korfiatis
def can_join_request(project, user):
680 d4660e00 Giorgos Korfiatis
    join_policy = project.application.member_join_policy
681 d4660e00 Giorgos Korfiatis
    if join_policy == CLOSED_POLICY:
682 d4660e00 Giorgos Korfiatis
        return False
683 d4660e00 Giorgos Korfiatis
    m = user.get_membership(project)
684 d4660e00 Giorgos Korfiatis
    if m:
685 d4660e00 Giorgos Korfiatis
        return False
686 d4660e00 Giorgos Korfiatis
    return True
687 d4660e00 Giorgos Korfiatis
688 d07ce657 Giorgos Korfiatis
689 d07ce657 Giorgos Korfiatis
def join_project(project_id, request_user):
690 e47fb17a Sofia Papagiannaki
    project = get_project_for_update(project_id)
691 ff67242a Giorgos Korfiatis
    join_project_checks(project)
692 d07ce657 Giorgos Korfiatis
693 d07ce657 Giorgos Korfiatis
    membership, created = ProjectMembership.objects.get_or_create(
694 d07ce657 Giorgos Korfiatis
        project=project,
695 d07ce657 Giorgos Korfiatis
        person=request_user)
696 d07ce657 Giorgos Korfiatis
697 d07ce657 Giorgos Korfiatis
    if not created:
698 d07ce657 Giorgos Korfiatis
        msg = _(astakos_messages.MEMBERSHIP_REQUEST_EXISTS)
699 d07ce657 Giorgos Korfiatis
        raise PermissionDenied(msg)
700 73fbaec4 Sofia Papagiannaki
701 bb6a4465 Giorgos Korfiatis
    auto_accepted = False
702 4e057833 Sofia Papagiannaki
    join_policy = project.application.member_join_policy
703 7a08e179 Giorgos Korfiatis
    if (join_policy == AUTO_ACCEPT_POLICY and (
704 7a08e179 Giorgos Korfiatis
            not project.violates_members_limit(adding=1))):
705 73fbaec4 Sofia Papagiannaki
        membership.accept()
706 d07ce657 Giorgos Korfiatis
        qh_sync_user(request_user.id)
707 f30f0170 Giorgos Korfiatis
        logger.info("User %s joined %s." %
708 f30f0170 Giorgos Korfiatis
                    (membership.person.log_display, project))
709 bb6a4465 Giorgos Korfiatis
        auto_accepted = True
710 bb6a4465 Giorgos Korfiatis
    else:
711 bb6a4465 Giorgos Korfiatis
        membership_request_notify(project, membership.person)
712 f30f0170 Giorgos Korfiatis
        logger.info("User %s requested to join %s." %
713 f30f0170 Giorgos Korfiatis
                    (membership.person.log_display, project))
714 bb6a4465 Giorgos Korfiatis
    return auto_accepted
715 8dcaa6ac Giorgos Korfiatis
716 7a08e179 Giorgos Korfiatis
717 6da04174 Giorgos Korfiatis
def submit_application(owner=None,
718 6da04174 Giorgos Korfiatis
                       name=None,
719 6da04174 Giorgos Korfiatis
                       precursor_id=None,
720 6da04174 Giorgos Korfiatis
                       homepage=None,
721 6da04174 Giorgos Korfiatis
                       description=None,
722 6da04174 Giorgos Korfiatis
                       start_date=None,
723 6da04174 Giorgos Korfiatis
                       end_date=None,
724 6da04174 Giorgos Korfiatis
                       member_join_policy=None,
725 6da04174 Giorgos Korfiatis
                       member_leave_policy=None,
726 6da04174 Giorgos Korfiatis
                       limit_on_members_number=None,
727 6da04174 Giorgos Korfiatis
                       comments=None,
728 6da04174 Giorgos Korfiatis
                       resource_policies=None,
729 6da04174 Giorgos Korfiatis
                       request_user=None):
730 69c822cc Giorgos Korfiatis
731 3e3743f2 Giorgos Korfiatis
    precursor = None
732 15ca2bea Giorgos Korfiatis
    if precursor_id is not None:
733 ea1e5d9f Giorgos Korfiatis
        objs = ProjectApplication.objects
734 ea1e5d9f Giorgos Korfiatis
        precursor = objs.get_for_update(id=precursor_id)
735 73fbaec4 Sofia Papagiannaki
736 3e3743f2 Giorgos Korfiatis
        if (request_user and
737 3e3743f2 Giorgos Korfiatis
            (not precursor.owner == request_user and
738 beda5f0f Georgios D. Tsoukalas
             not request_user.is_superuser
739 beda5f0f Georgios D. Tsoukalas
             and not request_user.is_project_admin())):
740 3e3743f2 Giorgos Korfiatis
            m = _(astakos_messages.NOT_ALLOWED)
741 3e3743f2 Giorgos Korfiatis
            raise PermissionDenied(m)
742 ee4aa6eb Giorgos Korfiatis
743 9770ba6c Giorgos Korfiatis
    force = request_user.is_project_admin()
744 9770ba6c Giorgos Korfiatis
    ok, limit = qh_add_pending_app(owner, precursor, force)
745 9770ba6c Giorgos Korfiatis
    if not ok:
746 c7c0ec58 Giorgos Korfiatis
        m = _(astakos_messages.REACHED_PENDING_APPLICATION_LIMIT) % limit
747 c7c0ec58 Giorgos Korfiatis
        raise PermissionDenied(m)
748 c7c0ec58 Giorgos Korfiatis
749 6da04174 Giorgos Korfiatis
    application = ProjectApplication(
750 6da04174 Giorgos Korfiatis
        applicant=request_user,
751 6da04174 Giorgos Korfiatis
        owner=owner,
752 6da04174 Giorgos Korfiatis
        name=name,
753 6da04174 Giorgos Korfiatis
        precursor_application_id=precursor_id,
754 6da04174 Giorgos Korfiatis
        homepage=homepage,
755 6da04174 Giorgos Korfiatis
        description=description,
756 6da04174 Giorgos Korfiatis
        start_date=start_date,
757 6da04174 Giorgos Korfiatis
        end_date=end_date,
758 6da04174 Giorgos Korfiatis
        member_join_policy=member_join_policy,
759 6da04174 Giorgos Korfiatis
        member_leave_policy=member_leave_policy,
760 6da04174 Giorgos Korfiatis
        limit_on_members_number=limit_on_members_number,
761 6da04174 Giorgos Korfiatis
        comments=comments)
762 1352dabb Kostas Papadimitriou
763 3e3743f2 Giorgos Korfiatis
    if precursor is None:
764 3e3743f2 Giorgos Korfiatis
        application.chain = new_chain()
765 3e3743f2 Giorgos Korfiatis
    else:
766 3e3743f2 Giorgos Korfiatis
        chain = precursor.chain
767 3e3743f2 Giorgos Korfiatis
        application.chain = chain
768 ea1e5d9f Giorgos Korfiatis
        objs = ProjectApplication.objects
769 ea1e5d9f Giorgos Korfiatis
        q = objs.filter(chain=chain, state=ProjectApplication.PENDING)
770 ea1e5d9f Giorgos Korfiatis
        pending = q.select_for_update()
771 3e3743f2 Giorgos Korfiatis
        for app in pending:
772 3e3743f2 Giorgos Korfiatis
            app.state = ProjectApplication.REPLACED
773 3e3743f2 Giorgos Korfiatis
            app.save()
774 3e3743f2 Giorgos Korfiatis
775 3e3743f2 Giorgos Korfiatis
    application.save()
776 eee9ec4d Giorgos Korfiatis
    application.set_resource_policies(resource_policies)
777 f30f0170 Giorgos Korfiatis
    logger.info("User %s submitted %s." %
778 f30f0170 Giorgos Korfiatis
                (request_user.log_display, application.log_display))
779 a3eb3a95 Giorgos Korfiatis
    application_submit_notify(application)
780 a3eb3a95 Giorgos Korfiatis
    return application
781 73fbaec4 Sofia Papagiannaki
782 7a08e179 Giorgos Korfiatis
783 64d0c13e Giorgos Korfiatis
def cancel_application(application_id, request_user=None, reason=""):
784 3c638f72 Giorgos Korfiatis
    application = get_application_for_update(application_id)
785 3c638f72 Giorgos Korfiatis
    checkAllowed(application, request_user)
786 3c638f72 Giorgos Korfiatis
787 01bdbd17 Giorgos Korfiatis
    if not application.can_cancel():
788 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.APPLICATION_CANNOT_CANCEL %
789 7a08e179 Giorgos Korfiatis
              (application.id, application.state_display()))
790 01bdbd17 Giorgos Korfiatis
        raise PermissionDenied(m)
791 3c638f72 Giorgos Korfiatis
792 9770ba6c Giorgos Korfiatis
    qh_release_pending_app(application.owner)
793 9770ba6c Giorgos Korfiatis
794 3c638f72 Giorgos Korfiatis
    application.cancel()
795 f30f0170 Giorgos Korfiatis
    logger.info("%s has been cancelled." % (application.log_display))
796 3c638f72 Giorgos Korfiatis
797 7a08e179 Giorgos Korfiatis
798 64d0c13e Giorgos Korfiatis
def dismiss_application(application_id, request_user=None, reason=""):
799 3c638f72 Giorgos Korfiatis
    application = get_application_for_update(application_id)
800 3c638f72 Giorgos Korfiatis
    checkAllowed(application, request_user)
801 3c638f72 Giorgos Korfiatis
802 01bdbd17 Giorgos Korfiatis
    if not application.can_dismiss():
803 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.APPLICATION_CANNOT_DISMISS %
804 7a08e179 Giorgos Korfiatis
              (application.id, application.state_display()))
805 01bdbd17 Giorgos Korfiatis
        raise PermissionDenied(m)
806 3c638f72 Giorgos Korfiatis
807 3c638f72 Giorgos Korfiatis
    application.dismiss()
808 f30f0170 Giorgos Korfiatis
    logger.info("%s has been dismissed." % (application.log_display))
809 3c638f72 Giorgos Korfiatis
810 7a08e179 Giorgos Korfiatis
811 64d0c13e Giorgos Korfiatis
def deny_application(application_id, request_user=None, reason=""):
812 19eb3ee6 Giorgos Korfiatis
    application = get_application_for_update(application_id)
813 01bdbd17 Giorgos Korfiatis
814 d07ce657 Giorgos Korfiatis
    checkAllowed(application, request_user, admin_only=True)
815 d07ce657 Giorgos Korfiatis
816 01bdbd17 Giorgos Korfiatis
    if not application.can_deny():
817 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.APPLICATION_CANNOT_DENY %
818 7a08e179 Giorgos Korfiatis
              (application.id, application.state_display()))
819 01bdbd17 Giorgos Korfiatis
        raise PermissionDenied(m)
820 19eb3ee6 Giorgos Korfiatis
821 9770ba6c Giorgos Korfiatis
    qh_release_pending_app(application.owner)
822 9770ba6c Giorgos Korfiatis
823 2b745492 Giorgos Korfiatis
    application.deny(reason)
824 f30f0170 Giorgos Korfiatis
    logger.info("%s has been denied with reason \"%s\"." %
825 f30f0170 Giorgos Korfiatis
                (application.log_display, reason))
826 19eb3ee6 Giorgos Korfiatis
    application_deny_notify(application)
827 19eb3ee6 Giorgos Korfiatis
828 7a08e179 Giorgos Korfiatis
829 64d0c13e Giorgos Korfiatis
def approve_application(app_id, request_user=None, reason=""):
830 8dcaa6ac Giorgos Korfiatis
831 8dcaa6ac Giorgos Korfiatis
    try:
832 ea1e5d9f Giorgos Korfiatis
        objects = ProjectApplication.objects
833 ea1e5d9f Giorgos Korfiatis
        application = objects.get_for_update(id=app_id)
834 8dcaa6ac Giorgos Korfiatis
    except ProjectApplication.DoesNotExist:
835 6cee26a0 Giorgos Korfiatis
        m = _(astakos_messages.UNKNOWN_PROJECT_APPLICATION_ID % (app_id,))
836 6cee26a0 Giorgos Korfiatis
        raise PermissionDenied(m)
837 8dcaa6ac Giorgos Korfiatis
838 d07ce657 Giorgos Korfiatis
    checkAllowed(application, request_user, admin_only=True)
839 d07ce657 Giorgos Korfiatis
840 01bdbd17 Giorgos Korfiatis
    if not application.can_approve():
841 7a08e179 Giorgos Korfiatis
        m = _(astakos_messages.APPLICATION_CANNOT_APPROVE %
842 7a08e179 Giorgos Korfiatis
              (application.id, application.state_display()))
843 01bdbd17 Giorgos Korfiatis
        raise PermissionDenied(m)
844 01bdbd17 Giorgos Korfiatis
845 9770ba6c Giorgos Korfiatis
    qh_release_pending_app(application.owner)
846 64d0c13e Giorgos Korfiatis
    project = application.approve(reason)
847 570015d2 Giorgos Korfiatis
    qh_sync_projects([project])
848 f30f0170 Giorgos Korfiatis
    logger.info("%s has been approved." % (application.log_display))
849 a3eb3a95 Giorgos Korfiatis
    application_approve_notify(application)
850 eb9ff37a Sofia Papagiannaki
851 7a08e179 Giorgos Korfiatis
852 7eadc230 Giorgos Korfiatis
def check_expiration(execute=False):
853 7eadc230 Giorgos Korfiatis
    objects = Project.objects
854 7eadc230 Giorgos Korfiatis
    expired = objects.expired_projects()
855 7eadc230 Giorgos Korfiatis
    if execute:
856 7eadc230 Giorgos Korfiatis
        for project in expired:
857 7eadc230 Giorgos Korfiatis
            terminate(project.id)
858 7eadc230 Giorgos Korfiatis
859 7eadc230 Giorgos Korfiatis
    return [project.expiration_info() for project in expired]
860 7eadc230 Giorgos Korfiatis
861 7a08e179 Giorgos Korfiatis
862 d07ce657 Giorgos Korfiatis
def terminate(project_id, request_user=None):
863 5b9e9530 Giorgos Korfiatis
    project = get_project_for_update(project_id)
864 d07ce657 Giorgos Korfiatis
    checkAllowed(project, request_user, admin_only=True)
865 907f15db Giorgos Korfiatis
    checkAlive(project)
866 5b9e9530 Giorgos Korfiatis
867 5b9e9530 Giorgos Korfiatis
    project.terminate()
868 570015d2 Giorgos Korfiatis
    qh_sync_projects([project])
869 f30f0170 Giorgos Korfiatis
    logger.info("%s has been terminated." % (project))
870 570015d2 Giorgos Korfiatis
871 a3eb3a95 Giorgos Korfiatis
    project_termination_notify(project)
872 eb9ff37a Sofia Papagiannaki
873 7a08e179 Giorgos Korfiatis
874 d07ce657 Giorgos Korfiatis
def suspend(project_id, request_user=None):
875 eb9ff37a Sofia Papagiannaki
    project = get_project_by_id(project_id)
876 d07ce657 Giorgos Korfiatis
    checkAllowed(project, request_user, admin_only=True)
877 db99f198 Giorgos Korfiatis
    checkAlive(project)
878 db99f198 Giorgos Korfiatis
879 db99f198 Giorgos Korfiatis
    project.suspend()
880 570015d2 Giorgos Korfiatis
    qh_sync_projects([project])
881 f30f0170 Giorgos Korfiatis
    logger.info("%s has been suspended." % (project))
882 570015d2 Giorgos Korfiatis
883 a3eb3a95 Giorgos Korfiatis
    project_suspension_notify(project)
884 db99f198 Giorgos Korfiatis
885 7a08e179 Giorgos Korfiatis
886 d07ce657 Giorgos Korfiatis
def resume(project_id, request_user=None):
887 db99f198 Giorgos Korfiatis
    project = get_project_for_update(project_id)
888 d07ce657 Giorgos Korfiatis
    checkAllowed(project, request_user, admin_only=True)
889 db99f198 Giorgos Korfiatis
890 db99f198 Giorgos Korfiatis
    if not project.is_suspended:
891 db99f198 Giorgos Korfiatis
        m = _(astakos_messages.NOT_SUSPENDED_PROJECT) % project.__dict__
892 db99f198 Giorgos Korfiatis
        raise PermissionDenied(m)
893 db99f198 Giorgos Korfiatis
894 db99f198 Giorgos Korfiatis
    project.resume()
895 570015d2 Giorgos Korfiatis
    qh_sync_projects([project])
896 f30f0170 Giorgos Korfiatis
    logger.info("%s has been unsuspended." % (project))
897 ff67242a Giorgos Korfiatis
898 7a08e179 Giorgos Korfiatis
899 ff67242a Giorgos Korfiatis
def get_by_chain_or_404(chain_id):
900 ff67242a Giorgos Korfiatis
    try:
901 ff67242a Giorgos Korfiatis
        project = Project.objects.get(id=chain_id)
902 ff67242a Giorgos Korfiatis
        application = project.application
903 ff67242a Giorgos Korfiatis
        return project, application
904 ff67242a Giorgos Korfiatis
    except:
905 ff67242a Giorgos Korfiatis
        application = ProjectApplication.objects.latest_of_chain(chain_id)
906 ff67242a Giorgos Korfiatis
        if application is None:
907 ff67242a Giorgos Korfiatis
            raise Http404
908 ff67242a Giorgos Korfiatis
        else:
909 ff67242a Giorgos Korfiatis
            return None, application
910 c7c0ec58 Giorgos Korfiatis
911 c7c0ec58 Giorgos Korfiatis
912 c7c0ec58 Giorgos Korfiatis
def get_user_setting(user_id, key):
913 c7c0ec58 Giorgos Korfiatis
    try:
914 c7c0ec58 Giorgos Korfiatis
        setting = UserSetting.objects.get(
915 c7c0ec58 Giorgos Korfiatis
            user=user_id, setting=key)
916 c7c0ec58 Giorgos Korfiatis
        return setting.value
917 c7c0ec58 Giorgos Korfiatis
    except UserSetting.DoesNotExist:
918 0a7a4104 Kostas Papadimitriou
        return getattr(settings, key)
919 c7c0ec58 Giorgos Korfiatis
920 c7c0ec58 Giorgos Korfiatis
921 c7c0ec58 Giorgos Korfiatis
def set_user_setting(user_id, key, value):
922 c7c0ec58 Giorgos Korfiatis
    try:
923 c7c0ec58 Giorgos Korfiatis
        setting = UserSetting.objects.get_for_update(
924 c7c0ec58 Giorgos Korfiatis
            user=user_id, setting=key)
925 c7c0ec58 Giorgos Korfiatis
    except UserSetting.DoesNotExist:
926 c7c0ec58 Giorgos Korfiatis
        setting = UserSetting(user_id=user_id, setting=key)
927 c7c0ec58 Giorgos Korfiatis
    setting.value = value
928 c7c0ec58 Giorgos Korfiatis
    setting.save()
929 c7c0ec58 Giorgos Korfiatis
930 c7c0ec58 Giorgos Korfiatis
931 c7c0ec58 Giorgos Korfiatis
def unset_user_setting(user_id, key):
932 c7c0ec58 Giorgos Korfiatis
    UserSetting.objects.filter(user=user_id, setting=key).delete()
933 c7c0ec58 Giorgos Korfiatis
934 c7c0ec58 Giorgos Korfiatis
935 3f5851eb Giorgos Korfiatis
def _partition_by(f, l):
936 3f5851eb Giorgos Korfiatis
    d = {}
937 3f5851eb Giorgos Korfiatis
    for x in l:
938 3f5851eb Giorgos Korfiatis
        group = f(x)
939 3f5851eb Giorgos Korfiatis
        group_l = d.get(group, [])
940 3f5851eb Giorgos Korfiatis
        group_l.append(x)
941 3f5851eb Giorgos Korfiatis
        d[group] = group_l
942 3f5851eb Giorgos Korfiatis
    return d
943 3f5851eb Giorgos Korfiatis
944 3f5851eb Giorgos Korfiatis
945 3f5851eb Giorgos Korfiatis
def count_pending_app(users):
946 3f5851eb Giorgos Korfiatis
    apps = ProjectApplication.objects.filter(state=ProjectApplication.PENDING,
947 3f5851eb Giorgos Korfiatis
                                             owner__in=users)
948 3f5851eb Giorgos Korfiatis
    apps_d = _partition_by(lambda a: a.owner.uuid, apps)
949 3f5851eb Giorgos Korfiatis
950 3f5851eb Giorgos Korfiatis
    usage = {}
951 3f5851eb Giorgos Korfiatis
    for user in users:
952 3f5851eb Giorgos Korfiatis
        uuid = user.uuid
953 3f5851eb Giorgos Korfiatis
        usage[uuid] = len(apps_d.get(uuid, []))
954 3f5851eb Giorgos Korfiatis
    return usage
955 3f5851eb Giorgos Korfiatis
956 3f5851eb Giorgos Korfiatis
957 9770ba6c Giorgos Korfiatis
def qh_add_pending_app(user, precursor=None, force=False, dry_run=False):
958 c7c0ec58 Giorgos Korfiatis
    if precursor is None:
959 9770ba6c Giorgos Korfiatis
        diff = 1
960 9770ba6c Giorgos Korfiatis
    else:
961 9770ba6c Giorgos Korfiatis
        chain = precursor.chain
962 9770ba6c Giorgos Korfiatis
        objs = ProjectApplication.objects
963 9770ba6c Giorgos Korfiatis
        q = objs.filter(chain=chain, state=ProjectApplication.PENDING)
964 9770ba6c Giorgos Korfiatis
        count = q.count()
965 9770ba6c Giorgos Korfiatis
        diff = 1 - count
966 c7c0ec58 Giorgos Korfiatis
967 9e3af524 Giorgos Korfiatis
    return register_pending_apps(user, diff, force, dry_run)
968 c7c0ec58 Giorgos Korfiatis
969 c7c0ec58 Giorgos Korfiatis
970 9770ba6c Giorgos Korfiatis
def qh_release_pending_app(user):
971 9e3af524 Giorgos Korfiatis
    register_pending_apps(user, -1)
972 570015d2 Giorgos Korfiatis
973 570015d2 Giorgos Korfiatis
974 570015d2 Giorgos Korfiatis
def qh_sync_projects(projects):
975 8cbea11d Giorgos Korfiatis
976 8cbea11d Giorgos Korfiatis
    memberships = ProjectMembership.objects.filter(project__in=projects)
977 8cbea11d Giorgos Korfiatis
    user_ids = set(m.person_id for m in memberships)
978 8cbea11d Giorgos Korfiatis
979 44104cd3 Giorgos Korfiatis
    qh_sync_users(user_ids)