Statistics
| Branch: | Tag: | Revision:

root / snf-astakos-app / astakos / im / views / projects.py @ b1cb2583

History | View | Annotate | Download (24.7 kB)

1 9fb7a900 Giorgos Korfiatis
# Copyright 2011, 2012, 2013 GRNET S.A. All rights reserved.
2 70e11eaa Sofia Papagiannaki
#
3 70e11eaa Sofia Papagiannaki
# Redistribution and use in source and binary forms, with or
4 70e11eaa Sofia Papagiannaki
# without modification, are permitted provided that the following
5 70e11eaa Sofia Papagiannaki
# conditions are met:
6 70e11eaa Sofia Papagiannaki
#
7 70e11eaa Sofia Papagiannaki
#   1. Redistributions of source code must retain the above
8 70e11eaa Sofia Papagiannaki
#      copyright notice, this list of conditions and the following
9 70e11eaa Sofia Papagiannaki
#      disclaimer.
10 70e11eaa Sofia Papagiannaki
#
11 70e11eaa Sofia Papagiannaki
#   2. Redistributions in binary form must reproduce the above
12 70e11eaa Sofia Papagiannaki
#      copyright notice, this list of conditions and the following
13 70e11eaa Sofia Papagiannaki
#      disclaimer in the documentation and/or other materials
14 70e11eaa Sofia Papagiannaki
#      provided with the distribution.
15 70e11eaa Sofia Papagiannaki
#
16 70e11eaa Sofia Papagiannaki
# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
17 70e11eaa Sofia Papagiannaki
# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 70e11eaa Sofia Papagiannaki
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 70e11eaa Sofia Papagiannaki
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
20 70e11eaa Sofia Papagiannaki
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21 70e11eaa Sofia Papagiannaki
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22 70e11eaa Sofia Papagiannaki
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 70e11eaa Sofia Papagiannaki
# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
24 70e11eaa Sofia Papagiannaki
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 70e11eaa Sofia Papagiannaki
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
26 70e11eaa Sofia Papagiannaki
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 70e11eaa Sofia Papagiannaki
# POSSIBILITY OF SUCH DAMAGE.
28 70e11eaa Sofia Papagiannaki
#
29 70e11eaa Sofia Papagiannaki
# The views and conclusions contained in the software and
30 70e11eaa Sofia Papagiannaki
# documentation are those of the authors and should not be
31 70e11eaa Sofia Papagiannaki
# interpreted as representing official policies, either expressed
32 70e11eaa Sofia Papagiannaki
# or implied, of GRNET S.A.
33 70e11eaa Sofia Papagiannaki
34 70e11eaa Sofia Papagiannaki
import logging
35 70e11eaa Sofia Papagiannaki
import inflect
36 70e11eaa Sofia Papagiannaki
37 70e11eaa Sofia Papagiannaki
engine = inflect.engine()
38 70e11eaa Sofia Papagiannaki
39 70e11eaa Sofia Papagiannaki
from django_tables2 import RequestConfig
40 70e11eaa Sofia Papagiannaki
41 70e11eaa Sofia Papagiannaki
from django.shortcuts import get_object_or_404
42 70e11eaa Sofia Papagiannaki
from django.contrib import messages
43 70e11eaa Sofia Papagiannaki
from django.core.urlresolvers import reverse
44 3e0a032d Sofia Papagiannaki
from django.http import Http404
45 70e11eaa Sofia Papagiannaki
from django.shortcuts import redirect
46 70e11eaa Sofia Papagiannaki
from django.utils.html import escape
47 70e11eaa Sofia Papagiannaki
from django.utils.translation import ugettext as _
48 70e11eaa Sofia Papagiannaki
from django.views.generic.list_detail import object_list, object_detail
49 3e0a032d Sofia Papagiannaki
from django.core.exceptions import PermissionDenied
50 70e11eaa Sofia Papagiannaki
from django.views.decorators.http import require_http_methods
51 a3e3917f Giorgos Korfiatis
from django.db import transaction
52 70e11eaa Sofia Papagiannaki
53 70e11eaa Sofia Papagiannaki
import astakos.im.messages as astakos_messages
54 70e11eaa Sofia Papagiannaki
55 70e11eaa Sofia Papagiannaki
from astakos.im import tables
56 6d583e07 Giorgos Korfiatis
from astakos.im.models import ProjectApplication, ProjectMembership, Project
57 3e0a032d Sofia Papagiannaki
from astakos.im.util import get_context, restrict_next
58 3e0a032d Sofia Papagiannaki
from astakos.im.forms import ProjectApplicationForm, AddProjectMembersForm, \
59 3e0a032d Sofia Papagiannaki
    ProjectSearchForm
60 3e0a032d Sofia Papagiannaki
from astakos.im.functions import check_pending_app_quota, accept_membership, \
61 3e0a032d Sofia Papagiannaki
    reject_membership, remove_membership, cancel_membership, leave_project, \
62 3e0a032d Sofia Papagiannaki
    join_project, enroll_member, can_join_request, can_leave_request, \
63 6d583e07 Giorgos Korfiatis
    get_related_project_id, approve_application, \
64 f12bcb3d Giorgos Korfiatis
    deny_application, cancel_application, dismiss_application, ProjectError
65 8998f09a Sofia Papagiannaki
from astakos.im import settings
66 59eb6ec5 Kostas Papadimitriou
from astakos.im.util import redirect_back
67 70e11eaa Sofia Papagiannaki
from astakos.im.views.util import render_response, _create_object, \
68 9fb7a900 Giorgos Korfiatis
    _update_object, _resources_catalog, ExceptionHandler
69 70e11eaa Sofia Papagiannaki
from astakos.im.views.decorators import cookie_fix, signed_terms_required,\
70 b6496f0c Kostas Papadimitriou
    valid_astakos_user_required, login_required
71 70e11eaa Sofia Papagiannaki
72 70e11eaa Sofia Papagiannaki
logger = logging.getLogger(__name__)
73 70e11eaa Sofia Papagiannaki
74 70e11eaa Sofia Papagiannaki
75 70e11eaa Sofia Papagiannaki
@cookie_fix
76 70e11eaa Sofia Papagiannaki
def how_it_works(request):
77 70e11eaa Sofia Papagiannaki
    return render_response(
78 70e11eaa Sofia Papagiannaki
        'im/how_it_works.html',
79 70e11eaa Sofia Papagiannaki
        context_instance=get_context(request))
80 70e11eaa Sofia Papagiannaki
81 70e11eaa Sofia Papagiannaki
82 70e11eaa Sofia Papagiannaki
@require_http_methods(["GET", "POST"])
83 70e11eaa Sofia Papagiannaki
@cookie_fix
84 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
85 70e11eaa Sofia Papagiannaki
def project_add(request):
86 70e11eaa Sofia Papagiannaki
    user = request.user
87 70e11eaa Sofia Papagiannaki
    if not user.is_project_admin():
88 70e11eaa Sofia Papagiannaki
        ok, limit = check_pending_app_quota(user)
89 70e11eaa Sofia Papagiannaki
        if not ok:
90 70e11eaa Sofia Papagiannaki
            m = _(astakos_messages.PENDING_APPLICATION_LIMIT_ADD) % limit
91 70e11eaa Sofia Papagiannaki
            messages.error(request, m)
92 70e11eaa Sofia Papagiannaki
            next = reverse('astakos.im.views.project_list')
93 8998f09a Sofia Papagiannaki
            next = restrict_next(next, domain=settings.COOKIE_DOMAIN)
94 70e11eaa Sofia Papagiannaki
            return redirect(next)
95 70e11eaa Sofia Papagiannaki
96 70e11eaa Sofia Papagiannaki
    details_fields = ["name", "homepage", "description", "start_date",
97 70e11eaa Sofia Papagiannaki
                      "end_date", "comments"]
98 70e11eaa Sofia Papagiannaki
    membership_fields = ["member_join_policy", "member_leave_policy",
99 70e11eaa Sofia Papagiannaki
                         "limit_on_members_number"]
100 2dc27ac1 Giorgos Korfiatis
    resource_catalog, resource_groups = _resources_catalog()
101 70e11eaa Sofia Papagiannaki
    if resource_catalog is False:
102 70e11eaa Sofia Papagiannaki
        # on fail resource_groups contains the result object
103 70e11eaa Sofia Papagiannaki
        result = resource_groups
104 70e11eaa Sofia Papagiannaki
        messages.error(request, 'Unable to retrieve system resources: %s' %
105 70e11eaa Sofia Papagiannaki
                       result.reason)
106 70e11eaa Sofia Papagiannaki
    extra_context = {
107 70e11eaa Sofia Papagiannaki
        'resource_catalog': resource_catalog,
108 70e11eaa Sofia Papagiannaki
        'resource_groups': resource_groups,
109 70e11eaa Sofia Papagiannaki
        'show_form': True,
110 70e11eaa Sofia Papagiannaki
        'details_fields': details_fields,
111 70e11eaa Sofia Papagiannaki
        'membership_fields': membership_fields}
112 70e11eaa Sofia Papagiannaki
113 70e11eaa Sofia Papagiannaki
    response = None
114 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
115 9024ed2e Giorgos Korfiatis
        response = create_app_object(request, extra_context=extra_context)
116 70e11eaa Sofia Papagiannaki
117 70e11eaa Sofia Papagiannaki
    if response is not None:
118 70e11eaa Sofia Papagiannaki
        return response
119 70e11eaa Sofia Papagiannaki
120 70e11eaa Sofia Papagiannaki
    next = reverse('astakos.im.views.project_list')
121 8998f09a Sofia Papagiannaki
    next = restrict_next(next, domain=settings.COOKIE_DOMAIN)
122 70e11eaa Sofia Papagiannaki
    return redirect(next)
123 70e11eaa Sofia Papagiannaki
124 70e11eaa Sofia Papagiannaki
125 a3e3917f Giorgos Korfiatis
@transaction.commit_on_success
126 9024ed2e Giorgos Korfiatis
def create_app_object(request, extra_context=None):
127 9024ed2e Giorgos Korfiatis
    try:
128 bb528b2e Giorgos Korfiatis
        summary = 'im/projects/projectapplication_form_summary.html'
129 9024ed2e Giorgos Korfiatis
        return _create_object(
130 9024ed2e Giorgos Korfiatis
            request,
131 9024ed2e Giorgos Korfiatis
            template_name='im/projects/projectapplication_form.html',
132 bb528b2e Giorgos Korfiatis
            summary_template_name=summary,
133 9024ed2e Giorgos Korfiatis
            extra_context=extra_context,
134 9024ed2e Giorgos Korfiatis
            post_save_redirect=reverse('project_list'),
135 9024ed2e Giorgos Korfiatis
            form_class=ProjectApplicationForm,
136 9024ed2e Giorgos Korfiatis
            msg=_("The %(verbose_name)s has been received and "
137 9024ed2e Giorgos Korfiatis
                  "is under consideration."))
138 f12bcb3d Giorgos Korfiatis
    except ProjectError as e:
139 9024ed2e Giorgos Korfiatis
        messages.error(request, e)
140 9024ed2e Giorgos Korfiatis
141 9024ed2e Giorgos Korfiatis
142 b10ceccd Giorgos Korfiatis
def get_user_projects_table(projects, user, prefix):
143 b10ceccd Giorgos Korfiatis
    apps = ProjectApplication.objects.pending_per_project(projects)
144 b10ceccd Giorgos Korfiatis
    memberships = user.projectmembership_set.one_per_project()
145 b10ceccd Giorgos Korfiatis
    objs = ProjectMembership.objects
146 b10ceccd Giorgos Korfiatis
    accepted_ms = objs.any_accepted_per_project(projects)
147 b10ceccd Giorgos Korfiatis
    requested_ms = objs.requested_per_project(projects)
148 b10ceccd Giorgos Korfiatis
    return tables.UserProjectsTable(projects, user=user,
149 b10ceccd Giorgos Korfiatis
                                    prefix=prefix,
150 b10ceccd Giorgos Korfiatis
                                    pending_apps=apps,
151 b10ceccd Giorgos Korfiatis
                                    memberships=memberships,
152 b10ceccd Giorgos Korfiatis
                                    accepted=accepted_ms,
153 b10ceccd Giorgos Korfiatis
                                    requested=requested_ms)
154 b10ceccd Giorgos Korfiatis
155 b10ceccd Giorgos Korfiatis
156 70e11eaa Sofia Papagiannaki
@require_http_methods(["GET"])
157 70e11eaa Sofia Papagiannaki
@cookie_fix
158 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
159 70e11eaa Sofia Papagiannaki
def project_list(request):
160 b10ceccd Giorgos Korfiatis
    projects = Project.objects.user_accessible_projects(request.user)
161 91a9dbe4 Giorgos Korfiatis
    table = (get_user_projects_table(projects, user=request.user,
162 91a9dbe4 Giorgos Korfiatis
                                     prefix="my_projects_")
163 91a9dbe4 Giorgos Korfiatis
             if list(projects) else None)
164 91a9dbe4 Giorgos Korfiatis
165 70e11eaa Sofia Papagiannaki
    return object_list(
166 70e11eaa Sofia Papagiannaki
        request,
167 70e11eaa Sofia Papagiannaki
        projects,
168 70e11eaa Sofia Papagiannaki
        template_name='im/projects/project_list.html',
169 70e11eaa Sofia Papagiannaki
        extra_context={
170 8fb8d0cf Giorgos Korfiatis
            'is_search': False,
171 70e11eaa Sofia Papagiannaki
            'table': table,
172 70e11eaa Sofia Papagiannaki
        })
173 70e11eaa Sofia Papagiannaki
174 70e11eaa Sofia Papagiannaki
175 70e11eaa Sofia Papagiannaki
@require_http_methods(["POST"])
176 70e11eaa Sofia Papagiannaki
@cookie_fix
177 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
178 70e11eaa Sofia Papagiannaki
def project_app_cancel(request, application_id):
179 70e11eaa Sofia Papagiannaki
    next = request.GET.get('next')
180 70e11eaa Sofia Papagiannaki
    chain_id = None
181 70e11eaa Sofia Papagiannaki
182 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
183 70e11eaa Sofia Papagiannaki
        chain_id = _project_app_cancel(request, application_id)
184 70e11eaa Sofia Papagiannaki
185 70e11eaa Sofia Papagiannaki
    if not next:
186 70e11eaa Sofia Papagiannaki
        if chain_id:
187 70e11eaa Sofia Papagiannaki
            next = reverse('astakos.im.views.project_detail', args=(chain_id,))
188 70e11eaa Sofia Papagiannaki
        else:
189 70e11eaa Sofia Papagiannaki
            next = reverse('astakos.im.views.project_list')
190 70e11eaa Sofia Papagiannaki
191 8998f09a Sofia Papagiannaki
    next = restrict_next(next, domain=settings.COOKIE_DOMAIN)
192 70e11eaa Sofia Papagiannaki
    return redirect(next)
193 70e11eaa Sofia Papagiannaki
194 8fb8d0cf Giorgos Korfiatis
195 a3e3917f Giorgos Korfiatis
@transaction.commit_on_success
196 70e11eaa Sofia Papagiannaki
def _project_app_cancel(request, application_id):
197 70e11eaa Sofia Papagiannaki
    chain_id = None
198 70e11eaa Sofia Papagiannaki
    try:
199 70e11eaa Sofia Papagiannaki
        application_id = int(application_id)
200 70e11eaa Sofia Papagiannaki
        chain_id = get_related_project_id(application_id)
201 70e11eaa Sofia Papagiannaki
        cancel_application(application_id, request.user)
202 f12bcb3d Giorgos Korfiatis
    except ProjectError as e:
203 70e11eaa Sofia Papagiannaki
        messages.error(request, e)
204 70e11eaa Sofia Papagiannaki
205 70e11eaa Sofia Papagiannaki
    else:
206 70e11eaa Sofia Papagiannaki
        msg = _(astakos_messages.APPLICATION_CANCELLED)
207 70e11eaa Sofia Papagiannaki
        messages.success(request, msg)
208 70e11eaa Sofia Papagiannaki
        return chain_id
209 70e11eaa Sofia Papagiannaki
210 70e11eaa Sofia Papagiannaki
211 70e11eaa Sofia Papagiannaki
@require_http_methods(["GET", "POST"])
212 70e11eaa Sofia Papagiannaki
@cookie_fix
213 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
214 70e11eaa Sofia Papagiannaki
def project_modify(request, application_id):
215 70e11eaa Sofia Papagiannaki
216 70e11eaa Sofia Papagiannaki
    try:
217 70e11eaa Sofia Papagiannaki
        app = ProjectApplication.objects.get(id=application_id)
218 70e11eaa Sofia Papagiannaki
    except ProjectApplication.DoesNotExist:
219 70e11eaa Sofia Papagiannaki
        raise Http404
220 70e11eaa Sofia Papagiannaki
221 70e11eaa Sofia Papagiannaki
    user = request.user
222 70e11eaa Sofia Papagiannaki
    if not (user.owns_application(app) or user.is_project_admin(app.id)):
223 70e11eaa Sofia Papagiannaki
        m = _(astakos_messages.NOT_ALLOWED)
224 70e11eaa Sofia Papagiannaki
        raise PermissionDenied(m)
225 70e11eaa Sofia Papagiannaki
226 70e11eaa Sofia Papagiannaki
    if not user.is_project_admin():
227 70e11eaa Sofia Papagiannaki
        owner = app.owner
228 c4028837 Giorgos Korfiatis
        ok, limit = check_pending_app_quota(owner, project=app.chain)
229 70e11eaa Sofia Papagiannaki
        if not ok:
230 70e11eaa Sofia Papagiannaki
            m = _(astakos_messages.PENDING_APPLICATION_LIMIT_MODIFY) % limit
231 70e11eaa Sofia Papagiannaki
            messages.error(request, m)
232 70e11eaa Sofia Papagiannaki
            next = reverse('astakos.im.views.project_list')
233 8998f09a Sofia Papagiannaki
            next = restrict_next(next, domain=settings.COOKIE_DOMAIN)
234 70e11eaa Sofia Papagiannaki
            return redirect(next)
235 70e11eaa Sofia Papagiannaki
236 70e11eaa Sofia Papagiannaki
    details_fields = ["name", "homepage", "description", "start_date",
237 70e11eaa Sofia Papagiannaki
                      "end_date", "comments"]
238 70e11eaa Sofia Papagiannaki
    membership_fields = ["member_join_policy", "member_leave_policy",
239 70e11eaa Sofia Papagiannaki
                         "limit_on_members_number"]
240 2dc27ac1 Giorgos Korfiatis
    resource_catalog, resource_groups = _resources_catalog()
241 70e11eaa Sofia Papagiannaki
    if resource_catalog is False:
242 70e11eaa Sofia Papagiannaki
        # on fail resource_groups contains the result object
243 70e11eaa Sofia Papagiannaki
        result = resource_groups
244 70e11eaa Sofia Papagiannaki
        messages.error(request, 'Unable to retrieve system resources: %s' %
245 70e11eaa Sofia Papagiannaki
                       result.reason)
246 70e11eaa Sofia Papagiannaki
    extra_context = {
247 70e11eaa Sofia Papagiannaki
        'resource_catalog': resource_catalog,
248 70e11eaa Sofia Papagiannaki
        'resource_groups': resource_groups,
249 70e11eaa Sofia Papagiannaki
        'show_form': True,
250 70e11eaa Sofia Papagiannaki
        'details_fields': details_fields,
251 70e11eaa Sofia Papagiannaki
        'update_form': True,
252 70e11eaa Sofia Papagiannaki
        'membership_fields': membership_fields
253 70e11eaa Sofia Papagiannaki
    }
254 70e11eaa Sofia Papagiannaki
255 70e11eaa Sofia Papagiannaki
    response = None
256 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
257 9024ed2e Giorgos Korfiatis
        response = update_app_object(request, application_id,
258 9024ed2e Giorgos Korfiatis
                                     extra_context=extra_context)
259 70e11eaa Sofia Papagiannaki
260 70e11eaa Sofia Papagiannaki
    if response is not None:
261 70e11eaa Sofia Papagiannaki
        return response
262 70e11eaa Sofia Papagiannaki
263 70e11eaa Sofia Papagiannaki
    next = reverse('astakos.im.views.project_list')
264 8998f09a Sofia Papagiannaki
    next = restrict_next(next, domain=settings.COOKIE_DOMAIN)
265 70e11eaa Sofia Papagiannaki
    return redirect(next)
266 70e11eaa Sofia Papagiannaki
267 8fb8d0cf Giorgos Korfiatis
268 a3e3917f Giorgos Korfiatis
@transaction.commit_on_success
269 9024ed2e Giorgos Korfiatis
def update_app_object(request, object_id, extra_context=None):
270 9024ed2e Giorgos Korfiatis
    try:
271 bb528b2e Giorgos Korfiatis
        summary = 'im/projects/projectapplication_form_summary.html'
272 9024ed2e Giorgos Korfiatis
        return _update_object(
273 9024ed2e Giorgos Korfiatis
            request,
274 9024ed2e Giorgos Korfiatis
            object_id=object_id,
275 9024ed2e Giorgos Korfiatis
            template_name='im/projects/projectapplication_form.html',
276 bb528b2e Giorgos Korfiatis
            summary_template_name=summary,
277 9024ed2e Giorgos Korfiatis
            extra_context=extra_context,
278 9024ed2e Giorgos Korfiatis
            post_save_redirect=reverse('project_list'),
279 9024ed2e Giorgos Korfiatis
            form_class=ProjectApplicationForm,
280 9024ed2e Giorgos Korfiatis
            msg=_("The %(verbose_name)s has been received and is under "
281 9024ed2e Giorgos Korfiatis
                  "consideration."))
282 f12bcb3d Giorgos Korfiatis
    except ProjectError as e:
283 9024ed2e Giorgos Korfiatis
        messages.error(request, e)
284 9024ed2e Giorgos Korfiatis
285 9024ed2e Giorgos Korfiatis
286 70e11eaa Sofia Papagiannaki
@require_http_methods(["GET", "POST"])
287 70e11eaa Sofia Papagiannaki
@cookie_fix
288 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
289 70e11eaa Sofia Papagiannaki
def project_app(request, application_id):
290 70e11eaa Sofia Papagiannaki
    return common_detail(request, application_id, project_view=False)
291 70e11eaa Sofia Papagiannaki
292 8fb8d0cf Giorgos Korfiatis
293 70e11eaa Sofia Papagiannaki
@require_http_methods(["GET", "POST"])
294 70e11eaa Sofia Papagiannaki
@cookie_fix
295 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
296 70e11eaa Sofia Papagiannaki
def project_detail(request, chain_id):
297 70e11eaa Sofia Papagiannaki
    return common_detail(request, chain_id)
298 70e11eaa Sofia Papagiannaki
299 8fb8d0cf Giorgos Korfiatis
300 a3e3917f Giorgos Korfiatis
@transaction.commit_on_success
301 70e11eaa Sofia Papagiannaki
def addmembers(request, chain_id, addmembers_form):
302 70e11eaa Sofia Papagiannaki
    if addmembers_form.is_valid():
303 70e11eaa Sofia Papagiannaki
        try:
304 70e11eaa Sofia Papagiannaki
            chain_id = int(chain_id)
305 8fb8d0cf Giorgos Korfiatis
            map(lambda u: enroll_member(chain_id,
306 8fb8d0cf Giorgos Korfiatis
                                        u,
307 8fb8d0cf Giorgos Korfiatis
                                        request_user=request.user),
308 70e11eaa Sofia Papagiannaki
                addmembers_form.valid_users)
309 f12bcb3d Giorgos Korfiatis
        except ProjectError as e:
310 70e11eaa Sofia Papagiannaki
            messages.error(request, e)
311 70e11eaa Sofia Papagiannaki
312 460b907d Kostas Papadimitriou
313 d895de37 Giorgos Korfiatis
MEMBERSHIP_STATUS_FILTER = {
314 d895de37 Giorgos Korfiatis
    0: lambda x: x.requested(),
315 d895de37 Giorgos Korfiatis
    1: lambda x: x.any_accepted(),
316 d895de37 Giorgos Korfiatis
}
317 d895de37 Giorgos Korfiatis
318 d895de37 Giorgos Korfiatis
319 460b907d Kostas Papadimitriou
def common_detail(request, chain_or_app_id, project_view=True,
320 460b907d Kostas Papadimitriou
                  template_name='im/projects/project_detail.html',
321 460b907d Kostas Papadimitriou
                  members_status_filter=None):
322 70e11eaa Sofia Papagiannaki
    project = None
323 9df6f541 Kostas Papadimitriou
    approved_members_count = 0
324 9df6f541 Kostas Papadimitriou
    pending_members_count = 0
325 8c8f856b Olga Brani
    remaining_memberships_count = None
326 70e11eaa Sofia Papagiannaki
    if project_view:
327 70e11eaa Sofia Papagiannaki
        chain_id = chain_or_app_id
328 70e11eaa Sofia Papagiannaki
        if request.method == 'POST':
329 70e11eaa Sofia Papagiannaki
            addmembers_form = AddProjectMembersForm(
330 70e11eaa Sofia Papagiannaki
                request.POST,
331 70e11eaa Sofia Papagiannaki
                chain_id=int(chain_id),
332 70e11eaa Sofia Papagiannaki
                request_user=request.user)
333 70e11eaa Sofia Papagiannaki
            with ExceptionHandler(request):
334 70e11eaa Sofia Papagiannaki
                addmembers(request, chain_id, addmembers_form)
335 70e11eaa Sofia Papagiannaki
336 70e11eaa Sofia Papagiannaki
            if addmembers_form.is_valid():
337 70e11eaa Sofia Papagiannaki
                addmembers_form = AddProjectMembersForm()  # clear form data
338 70e11eaa Sofia Papagiannaki
        else:
339 70e11eaa Sofia Papagiannaki
            addmembers_form = AddProjectMembersForm()  # initialize form
340 70e11eaa Sofia Papagiannaki
341 6d583e07 Giorgos Korfiatis
        project = get_object_or_404(Project, pk=chain_id)
342 6d583e07 Giorgos Korfiatis
        application = project.application
343 70e11eaa Sofia Papagiannaki
        if project:
344 d895de37 Giorgos Korfiatis
            members = project.projectmembership_set
345 d895de37 Giorgos Korfiatis
            approved_members_count = project.members_count()
346 460b907d Kostas Papadimitriou
            pending_members_count = project.count_pending_memberships()
347 8c8f856b Olga Brani
            _limit = application.limit_on_members_number
348 8c8f856b Olga Brani
            if _limit is not None:
349 8c8f856b Olga Brani
                remaining_memberships_count = \
350 8c8f856b Olga Brani
                    max(0, _limit - approved_members_count)
351 d895de37 Giorgos Korfiatis
            flt = MEMBERSHIP_STATUS_FILTER.get(members_status_filter)
352 d895de37 Giorgos Korfiatis
            if flt is not None:
353 d895de37 Giorgos Korfiatis
                members = flt(members)
354 f243d667 Giorgos Korfiatis
            else:
355 f243d667 Giorgos Korfiatis
                members = members.associated()
356 d895de37 Giorgos Korfiatis
            members = members.select_related()
357 70e11eaa Sofia Papagiannaki
            members_table = tables.ProjectMembersTable(project,
358 70e11eaa Sofia Papagiannaki
                                                       members,
359 70e11eaa Sofia Papagiannaki
                                                       user=request.user,
360 70e11eaa Sofia Papagiannaki
                                                       prefix="members_")
361 70e11eaa Sofia Papagiannaki
        else:
362 70e11eaa Sofia Papagiannaki
            members_table = None
363 70e11eaa Sofia Papagiannaki
364 460b907d Kostas Papadimitriou
    else:
365 460b907d Kostas Papadimitriou
        # is application
366 70e11eaa Sofia Papagiannaki
        application_id = chain_or_app_id
367 70e11eaa Sofia Papagiannaki
        application = get_object_or_404(ProjectApplication, pk=application_id)
368 70e11eaa Sofia Papagiannaki
        members_table = None
369 70e11eaa Sofia Papagiannaki
        addmembers_form = None
370 70e11eaa Sofia Papagiannaki
371 70e11eaa Sofia Papagiannaki
    user = request.user
372 70e11eaa Sofia Papagiannaki
    is_project_admin = user.is_project_admin(application_id=application.id)
373 70e11eaa Sofia Papagiannaki
    is_owner = user.owns_application(application)
374 70e11eaa Sofia Papagiannaki
    if not (is_owner or is_project_admin) and not project_view:
375 70e11eaa Sofia Papagiannaki
        m = _(astakos_messages.NOT_ALLOWED)
376 70e11eaa Sofia Papagiannaki
        raise PermissionDenied(m)
377 70e11eaa Sofia Papagiannaki
378 8fb8d0cf Giorgos Korfiatis
    if (
379 8fb8d0cf Giorgos Korfiatis
        not (is_owner or is_project_admin) and project_view and
380 8fb8d0cf Giorgos Korfiatis
        not user.non_owner_can_view(project)
381 8fb8d0cf Giorgos Korfiatis
    ):
382 70e11eaa Sofia Papagiannaki
        m = _(astakos_messages.NOT_ALLOWED)
383 70e11eaa Sofia Papagiannaki
        raise PermissionDenied(m)
384 70e11eaa Sofia Papagiannaki
385 dc946891 Giorgos Korfiatis
    membership = user.get_membership(project) if project else None
386 dc946891 Giorgos Korfiatis
    membership_id = membership.id if membership else None
387 70e11eaa Sofia Papagiannaki
    mem_display = user.membership_display(project) if project else None
388 70e11eaa Sofia Papagiannaki
    can_join_req = can_join_request(project, user) if project else False
389 70e11eaa Sofia Papagiannaki
    can_leave_req = can_leave_request(project, user) if project else False
390 70e11eaa Sofia Papagiannaki
391 70e11eaa Sofia Papagiannaki
    return object_detail(
392 70e11eaa Sofia Papagiannaki
        request,
393 70e11eaa Sofia Papagiannaki
        queryset=ProjectApplication.objects.select_related(),
394 70e11eaa Sofia Papagiannaki
        object_id=application.id,
395 460b907d Kostas Papadimitriou
        template_name=template_name,
396 70e11eaa Sofia Papagiannaki
        extra_context={
397 70e11eaa Sofia Papagiannaki
            'project_view': project_view,
398 8eb176ab Kostas Papadimitriou
            'chain_id': chain_or_app_id,
399 8eb176ab Kostas Papadimitriou
            'application': application,
400 460b907d Kostas Papadimitriou
            'addmembers_form': addmembers_form,
401 460b907d Kostas Papadimitriou
            'approved_members_count': approved_members_count,
402 460b907d Kostas Papadimitriou
            'pending_members_count': pending_members_count,
403 70e11eaa Sofia Papagiannaki
            'members_table': members_table,
404 70e11eaa Sofia Papagiannaki
            'owner_mode': is_owner,
405 70e11eaa Sofia Papagiannaki
            'admin_mode': is_project_admin,
406 70e11eaa Sofia Papagiannaki
            'mem_display': mem_display,
407 dc946891 Giorgos Korfiatis
            'membership_id': membership_id,
408 70e11eaa Sofia Papagiannaki
            'can_join_request': can_join_req,
409 70e11eaa Sofia Papagiannaki
            'can_leave_request': can_leave_req,
410 8fb8d0cf Giorgos Korfiatis
            'members_status_filter': members_status_filter,
411 8c8f856b Olga Brani
            'remaining_memberships_count': remaining_memberships_count,
412 0f433ce2 Giorgos Korfiatis
        })
413 0f433ce2 Giorgos Korfiatis
414 70e11eaa Sofia Papagiannaki
415 70e11eaa Sofia Papagiannaki
@require_http_methods(["GET", "POST"])
416 70e11eaa Sofia Papagiannaki
@cookie_fix
417 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
418 70e11eaa Sofia Papagiannaki
def project_search(request):
419 70e11eaa Sofia Papagiannaki
    q = request.GET.get('q', '')
420 70e11eaa Sofia Papagiannaki
    form = ProjectSearchForm()
421 70e11eaa Sofia Papagiannaki
    q = q.strip()
422 70e11eaa Sofia Papagiannaki
423 70e11eaa Sofia Papagiannaki
    if request.method == "POST":
424 70e11eaa Sofia Papagiannaki
        form = ProjectSearchForm(request.POST)
425 70e11eaa Sofia Papagiannaki
        if form.is_valid():
426 70e11eaa Sofia Papagiannaki
            q = form.cleaned_data['q'].strip()
427 70e11eaa Sofia Papagiannaki
        else:
428 70e11eaa Sofia Papagiannaki
            q = None
429 70e11eaa Sofia Papagiannaki
430 70e11eaa Sofia Papagiannaki
    if q is None:
431 f243d667 Giorgos Korfiatis
        projects = Project.objects.none()
432 70e11eaa Sofia Papagiannaki
    else:
433 f243d667 Giorgos Korfiatis
        accepted = request.user.projectmembership_set.filter(
434 f243d667 Giorgos Korfiatis
            state__in=ProjectMembership.ACCEPTED_STATES).values_list(
435 72313b77 Giorgos Korfiatis
            'project', flat=True)
436 f243d667 Giorgos Korfiatis
437 f243d667 Giorgos Korfiatis
        projects = Project.objects.search_by_name(q)
438 f243d667 Giorgos Korfiatis
        projects = projects.filter(Project.o_state_q(Project.O_ACTIVE))
439 b10ceccd Giorgos Korfiatis
        projects = projects.exclude(id__in=accepted).select_related(
440 b10ceccd Giorgos Korfiatis
            'application', 'application__owner', 'application__applicant')
441 f243d667 Giorgos Korfiatis
442 b10ceccd Giorgos Korfiatis
    table = get_user_projects_table(projects, user=request.user,
443 b10ceccd Giorgos Korfiatis
                                    prefix="my_projects_")
444 70e11eaa Sofia Papagiannaki
    if request.method == "POST":
445 70e11eaa Sofia Papagiannaki
        table.caption = _('SEARCH RESULTS')
446 70e11eaa Sofia Papagiannaki
    else:
447 70e11eaa Sofia Papagiannaki
        table.caption = _('ALL PROJECTS')
448 70e11eaa Sofia Papagiannaki
449 70e11eaa Sofia Papagiannaki
    return object_list(
450 70e11eaa Sofia Papagiannaki
        request,
451 70e11eaa Sofia Papagiannaki
        projects,
452 70e11eaa Sofia Papagiannaki
        template_name='im/projects/project_list.html',
453 70e11eaa Sofia Papagiannaki
        extra_context={
454 8fb8d0cf Giorgos Korfiatis
            'form': form,
455 8fb8d0cf Giorgos Korfiatis
            'is_search': True,
456 8fb8d0cf Giorgos Korfiatis
            'q': q,
457 8fb8d0cf Giorgos Korfiatis
            'table': table
458 70e11eaa Sofia Papagiannaki
        })
459 70e11eaa Sofia Papagiannaki
460 8fb8d0cf Giorgos Korfiatis
461 70e11eaa Sofia Papagiannaki
@require_http_methods(["POST"])
462 70e11eaa Sofia Papagiannaki
@cookie_fix
463 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
464 70e11eaa Sofia Papagiannaki
def project_join(request, chain_id):
465 70e11eaa Sofia Papagiannaki
    next = request.GET.get('next')
466 70e11eaa Sofia Papagiannaki
    if not next:
467 70e11eaa Sofia Papagiannaki
        next = reverse('astakos.im.views.project_detail',
468 70e11eaa Sofia Papagiannaki
                       args=(chain_id,))
469 70e11eaa Sofia Papagiannaki
470 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
471 70e11eaa Sofia Papagiannaki
        _project_join(request, chain_id)
472 70e11eaa Sofia Papagiannaki
473 8998f09a Sofia Papagiannaki
    next = restrict_next(next, domain=settings.COOKIE_DOMAIN)
474 70e11eaa Sofia Papagiannaki
    return redirect(next)
475 70e11eaa Sofia Papagiannaki
476 70e11eaa Sofia Papagiannaki
477 a3e3917f Giorgos Korfiatis
@transaction.commit_on_success
478 70e11eaa Sofia Papagiannaki
def _project_join(request, chain_id):
479 70e11eaa Sofia Papagiannaki
    try:
480 70e11eaa Sofia Papagiannaki
        chain_id = int(chain_id)
481 e1723ca1 Giorgos Korfiatis
        membership = join_project(chain_id, request.user)
482 e1723ca1 Giorgos Korfiatis
        if membership.state != membership.REQUESTED:
483 70e11eaa Sofia Papagiannaki
            m = _(astakos_messages.USER_JOINED_PROJECT)
484 70e11eaa Sofia Papagiannaki
        else:
485 70e11eaa Sofia Papagiannaki
            m = _(astakos_messages.USER_JOIN_REQUEST_SUBMITTED)
486 70e11eaa Sofia Papagiannaki
        messages.success(request, m)
487 f12bcb3d Giorgos Korfiatis
    except ProjectError as e:
488 70e11eaa Sofia Papagiannaki
        messages.error(request, e)
489 70e11eaa Sofia Papagiannaki
490 70e11eaa Sofia Papagiannaki
491 70e11eaa Sofia Papagiannaki
@require_http_methods(["POST"])
492 70e11eaa Sofia Papagiannaki
@cookie_fix
493 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
494 dc946891 Giorgos Korfiatis
def project_leave(request, memb_id):
495 70e11eaa Sofia Papagiannaki
    next = request.GET.get('next')
496 70e11eaa Sofia Papagiannaki
    if not next:
497 70e11eaa Sofia Papagiannaki
        next = reverse('astakos.im.views.project_list')
498 70e11eaa Sofia Papagiannaki
499 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
500 dc946891 Giorgos Korfiatis
        _project_leave(request, memb_id)
501 70e11eaa Sofia Papagiannaki
502 8998f09a Sofia Papagiannaki
    next = restrict_next(next, domain=settings.COOKIE_DOMAIN)
503 70e11eaa Sofia Papagiannaki
    return redirect(next)
504 70e11eaa Sofia Papagiannaki
505 70e11eaa Sofia Papagiannaki
506 a3e3917f Giorgos Korfiatis
@transaction.commit_on_success
507 dc946891 Giorgos Korfiatis
def _project_leave(request, memb_id):
508 70e11eaa Sofia Papagiannaki
    try:
509 dc946891 Giorgos Korfiatis
        memb_id = int(memb_id)
510 dc946891 Giorgos Korfiatis
        auto_accepted = leave_project(memb_id, request.user)
511 70e11eaa Sofia Papagiannaki
        if auto_accepted:
512 70e11eaa Sofia Papagiannaki
            m = _(astakos_messages.USER_LEFT_PROJECT)
513 70e11eaa Sofia Papagiannaki
        else:
514 70e11eaa Sofia Papagiannaki
            m = _(astakos_messages.USER_LEAVE_REQUEST_SUBMITTED)
515 70e11eaa Sofia Papagiannaki
        messages.success(request, m)
516 f12bcb3d Giorgos Korfiatis
    except ProjectError as e:
517 70e11eaa Sofia Papagiannaki
        messages.error(request, e)
518 70e11eaa Sofia Papagiannaki
519 70e11eaa Sofia Papagiannaki
520 70e11eaa Sofia Papagiannaki
@require_http_methods(["POST"])
521 70e11eaa Sofia Papagiannaki
@cookie_fix
522 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
523 dc946891 Giorgos Korfiatis
def project_cancel_member(request, memb_id):
524 70e11eaa Sofia Papagiannaki
    next = request.GET.get('next')
525 70e11eaa Sofia Papagiannaki
    if not next:
526 70e11eaa Sofia Papagiannaki
        next = reverse('astakos.im.views.project_list')
527 70e11eaa Sofia Papagiannaki
528 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
529 dc946891 Giorgos Korfiatis
        _project_cancel_member(request, memb_id)
530 70e11eaa Sofia Papagiannaki
531 8998f09a Sofia Papagiannaki
    next = restrict_next(next, domain=settings.COOKIE_DOMAIN)
532 70e11eaa Sofia Papagiannaki
    return redirect(next)
533 70e11eaa Sofia Papagiannaki
534 70e11eaa Sofia Papagiannaki
535 a3e3917f Giorgos Korfiatis
@transaction.commit_on_success
536 dc946891 Giorgos Korfiatis
def _project_cancel_member(request, memb_id):
537 70e11eaa Sofia Papagiannaki
    try:
538 dc946891 Giorgos Korfiatis
        cancel_membership(memb_id, request.user)
539 70e11eaa Sofia Papagiannaki
        m = _(astakos_messages.USER_REQUEST_CANCELLED)
540 70e11eaa Sofia Papagiannaki
        messages.success(request, m)
541 f12bcb3d Giorgos Korfiatis
    except ProjectError as e:
542 70e11eaa Sofia Papagiannaki
        messages.error(request, e)
543 70e11eaa Sofia Papagiannaki
544 70e11eaa Sofia Papagiannaki
545 70e11eaa Sofia Papagiannaki
@require_http_methods(["POST"])
546 70e11eaa Sofia Papagiannaki
@cookie_fix
547 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
548 dc946891 Giorgos Korfiatis
def project_accept_member(request, memb_id):
549 70e11eaa Sofia Papagiannaki
550 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
551 dc946891 Giorgos Korfiatis
        _project_accept_member(request, memb_id)
552 70e11eaa Sofia Papagiannaki
553 59eb6ec5 Kostas Papadimitriou
    return redirect_back(request, 'project_list')
554 70e11eaa Sofia Papagiannaki
555 70e11eaa Sofia Papagiannaki
556 a3e3917f Giorgos Korfiatis
@transaction.commit_on_success
557 dc946891 Giorgos Korfiatis
def _project_accept_member(request, memb_id):
558 70e11eaa Sofia Papagiannaki
    try:
559 70e11eaa Sofia Papagiannaki
        memb_id = int(memb_id)
560 dc946891 Giorgos Korfiatis
        m = accept_membership(memb_id, request.user)
561 f12bcb3d Giorgos Korfiatis
    except ProjectError as e:
562 70e11eaa Sofia Papagiannaki
        messages.error(request, e)
563 70e11eaa Sofia Papagiannaki
564 70e11eaa Sofia Papagiannaki
    else:
565 70e11eaa Sofia Papagiannaki
        email = escape(m.person.email)
566 70e11eaa Sofia Papagiannaki
        msg = _(astakos_messages.USER_MEMBERSHIP_ACCEPTED) % email
567 70e11eaa Sofia Papagiannaki
        messages.success(request, msg)
568 70e11eaa Sofia Papagiannaki
569 70e11eaa Sofia Papagiannaki
570 70e11eaa Sofia Papagiannaki
@require_http_methods(["POST"])
571 70e11eaa Sofia Papagiannaki
@cookie_fix
572 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
573 dc946891 Giorgos Korfiatis
def project_remove_member(request, memb_id):
574 70e11eaa Sofia Papagiannaki
575 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
576 dc946891 Giorgos Korfiatis
        _project_remove_member(request, memb_id)
577 70e11eaa Sofia Papagiannaki
578 59eb6ec5 Kostas Papadimitriou
    return redirect_back(request, 'project_list')
579 70e11eaa Sofia Papagiannaki
580 70e11eaa Sofia Papagiannaki
581 a3e3917f Giorgos Korfiatis
@transaction.commit_on_success
582 dc946891 Giorgos Korfiatis
def _project_remove_member(request, memb_id):
583 70e11eaa Sofia Papagiannaki
    try:
584 70e11eaa Sofia Papagiannaki
        memb_id = int(memb_id)
585 dc946891 Giorgos Korfiatis
        m = remove_membership(memb_id, request.user)
586 f12bcb3d Giorgos Korfiatis
    except ProjectError as e:
587 70e11eaa Sofia Papagiannaki
        messages.error(request, e)
588 70e11eaa Sofia Papagiannaki
    else:
589 70e11eaa Sofia Papagiannaki
        email = escape(m.person.email)
590 70e11eaa Sofia Papagiannaki
        msg = _(astakos_messages.USER_MEMBERSHIP_REMOVED) % email
591 70e11eaa Sofia Papagiannaki
        messages.success(request, msg)
592 70e11eaa Sofia Papagiannaki
593 70e11eaa Sofia Papagiannaki
594 70e11eaa Sofia Papagiannaki
@require_http_methods(["POST"])
595 70e11eaa Sofia Papagiannaki
@cookie_fix
596 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
597 dc946891 Giorgos Korfiatis
def project_reject_member(request, memb_id):
598 70e11eaa Sofia Papagiannaki
599 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
600 dc946891 Giorgos Korfiatis
        _project_reject_member(request, memb_id)
601 70e11eaa Sofia Papagiannaki
602 59eb6ec5 Kostas Papadimitriou
    return redirect_back(request, 'project_list')
603 70e11eaa Sofia Papagiannaki
604 70e11eaa Sofia Papagiannaki
605 a3e3917f Giorgos Korfiatis
@transaction.commit_on_success
606 dc946891 Giorgos Korfiatis
def _project_reject_member(request, memb_id):
607 70e11eaa Sofia Papagiannaki
    try:
608 70e11eaa Sofia Papagiannaki
        memb_id = int(memb_id)
609 dc946891 Giorgos Korfiatis
        m = reject_membership(memb_id, request.user)
610 f12bcb3d Giorgos Korfiatis
    except ProjectError as e:
611 70e11eaa Sofia Papagiannaki
        messages.error(request, e)
612 70e11eaa Sofia Papagiannaki
    else:
613 70e11eaa Sofia Papagiannaki
        email = escape(m.person.email)
614 70e11eaa Sofia Papagiannaki
        msg = _(astakos_messages.USER_MEMBERSHIP_REJECTED) % email
615 70e11eaa Sofia Papagiannaki
        messages.success(request, msg)
616 70e11eaa Sofia Papagiannaki
617 70e11eaa Sofia Papagiannaki
618 70e11eaa Sofia Papagiannaki
@require_http_methods(["POST"])
619 70e11eaa Sofia Papagiannaki
@signed_terms_required
620 70e11eaa Sofia Papagiannaki
@login_required
621 70e11eaa Sofia Papagiannaki
@cookie_fix
622 70e11eaa Sofia Papagiannaki
def project_app_approve(request, application_id):
623 70e11eaa Sofia Papagiannaki
624 70e11eaa Sofia Papagiannaki
    if not request.user.is_project_admin():
625 70e11eaa Sofia Papagiannaki
        m = _(astakos_messages.NOT_ALLOWED)
626 70e11eaa Sofia Papagiannaki
        raise PermissionDenied(m)
627 70e11eaa Sofia Papagiannaki
628 70e11eaa Sofia Papagiannaki
    try:
629 51db2da2 Giorgos Korfiatis
        ProjectApplication.objects.get(id=application_id)
630 70e11eaa Sofia Papagiannaki
    except ProjectApplication.DoesNotExist:
631 70e11eaa Sofia Papagiannaki
        raise Http404
632 70e11eaa Sofia Papagiannaki
633 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
634 70e11eaa Sofia Papagiannaki
        _project_app_approve(request, application_id)
635 70e11eaa Sofia Papagiannaki
636 70e11eaa Sofia Papagiannaki
    chain_id = get_related_project_id(application_id)
637 f5389699 Kostas Papadimitriou
    if not chain_id:
638 f5389699 Kostas Papadimitriou
        return redirect_back(request, 'project_list')
639 70e11eaa Sofia Papagiannaki
    return redirect(reverse('project_detail', args=(chain_id,)))
640 70e11eaa Sofia Papagiannaki
641 70e11eaa Sofia Papagiannaki
642 a3e3917f Giorgos Korfiatis
@transaction.commit_on_success
643 70e11eaa Sofia Papagiannaki
def _project_app_approve(request, application_id):
644 70e11eaa Sofia Papagiannaki
    approve_application(application_id)
645 70e11eaa Sofia Papagiannaki
646 70e11eaa Sofia Papagiannaki
647 70e11eaa Sofia Papagiannaki
@require_http_methods(["POST"])
648 70e11eaa Sofia Papagiannaki
@signed_terms_required
649 70e11eaa Sofia Papagiannaki
@login_required
650 70e11eaa Sofia Papagiannaki
@cookie_fix
651 70e11eaa Sofia Papagiannaki
def project_app_deny(request, application_id):
652 70e11eaa Sofia Papagiannaki
653 70e11eaa Sofia Papagiannaki
    reason = request.POST.get('reason', None)
654 70e11eaa Sofia Papagiannaki
    if not reason:
655 70e11eaa Sofia Papagiannaki
        reason = None
656 70e11eaa Sofia Papagiannaki
657 70e11eaa Sofia Papagiannaki
    if not request.user.is_project_admin():
658 70e11eaa Sofia Papagiannaki
        m = _(astakos_messages.NOT_ALLOWED)
659 70e11eaa Sofia Papagiannaki
        raise PermissionDenied(m)
660 70e11eaa Sofia Papagiannaki
661 70e11eaa Sofia Papagiannaki
    try:
662 51db2da2 Giorgos Korfiatis
        ProjectApplication.objects.get(id=application_id)
663 70e11eaa Sofia Papagiannaki
    except ProjectApplication.DoesNotExist:
664 70e11eaa Sofia Papagiannaki
        raise Http404
665 70e11eaa Sofia Papagiannaki
666 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
667 70e11eaa Sofia Papagiannaki
        _project_app_deny(request, application_id, reason)
668 70e11eaa Sofia Papagiannaki
669 70e11eaa Sofia Papagiannaki
    return redirect(reverse('project_list'))
670 70e11eaa Sofia Papagiannaki
671 70e11eaa Sofia Papagiannaki
672 a3e3917f Giorgos Korfiatis
@transaction.commit_on_success
673 70e11eaa Sofia Papagiannaki
def _project_app_deny(request, application_id, reason):
674 70e11eaa Sofia Papagiannaki
    deny_application(application_id, reason=reason)
675 70e11eaa Sofia Papagiannaki
676 70e11eaa Sofia Papagiannaki
677 70e11eaa Sofia Papagiannaki
@require_http_methods(["POST"])
678 70e11eaa Sofia Papagiannaki
@signed_terms_required
679 70e11eaa Sofia Papagiannaki
@login_required
680 70e11eaa Sofia Papagiannaki
@cookie_fix
681 70e11eaa Sofia Papagiannaki
def project_app_dismiss(request, application_id):
682 70e11eaa Sofia Papagiannaki
    try:
683 70e11eaa Sofia Papagiannaki
        app = ProjectApplication.objects.get(id=application_id)
684 70e11eaa Sofia Papagiannaki
    except ProjectApplication.DoesNotExist:
685 70e11eaa Sofia Papagiannaki
        raise Http404
686 70e11eaa Sofia Papagiannaki
687 70e11eaa Sofia Papagiannaki
    if not request.user.owns_application(app):
688 70e11eaa Sofia Papagiannaki
        m = _(astakos_messages.NOT_ALLOWED)
689 70e11eaa Sofia Papagiannaki
        raise PermissionDenied(m)
690 70e11eaa Sofia Papagiannaki
691 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
692 70e11eaa Sofia Papagiannaki
        _project_app_dismiss(request, application_id)
693 70e11eaa Sofia Papagiannaki
694 70e11eaa Sofia Papagiannaki
    chain_id = None
695 70e11eaa Sofia Papagiannaki
    chain_id = get_related_project_id(application_id)
696 70e11eaa Sofia Papagiannaki
    if chain_id:
697 70e11eaa Sofia Papagiannaki
        next = reverse('project_detail', args=(chain_id,))
698 70e11eaa Sofia Papagiannaki
    else:
699 70e11eaa Sofia Papagiannaki
        next = reverse('project_list')
700 70e11eaa Sofia Papagiannaki
    return redirect(next)
701 70e11eaa Sofia Papagiannaki
702 70e11eaa Sofia Papagiannaki
703 70e11eaa Sofia Papagiannaki
def _project_app_dismiss(request, application_id):
704 70e11eaa Sofia Papagiannaki
    # XXX: dismiss application also does authorization
705 70e11eaa Sofia Papagiannaki
    dismiss_application(application_id, request_user=request.user)
706 460b907d Kostas Papadimitriou
707 460b907d Kostas Papadimitriou
708 460b907d Kostas Papadimitriou
@require_http_methods(["GET", "POST"])
709 460b907d Kostas Papadimitriou
@valid_astakos_user_required
710 460b907d Kostas Papadimitriou
def project_members(request, chain_id, members_status_filter=None,
711 460b907d Kostas Papadimitriou
                    template_name='im/projects/project_members.html'):
712 6d583e07 Giorgos Korfiatis
    project = get_object_or_404(Project, pk=chain_id)
713 7971e5da Kostas Papadimitriou
714 7971e5da Kostas Papadimitriou
    user = request.user
715 7971e5da Kostas Papadimitriou
    if not user.owns_project(project) and not user.is_project_admin():
716 7971e5da Kostas Papadimitriou
        return redirect(reverse('index'))
717 7971e5da Kostas Papadimitriou
718 460b907d Kostas Papadimitriou
    return common_detail(request, chain_id,
719 460b907d Kostas Papadimitriou
                         members_status_filter=members_status_filter,
720 460b907d Kostas Papadimitriou
                         template_name=template_name)
721 c363a678 Kostas Papadimitriou
722 c363a678 Kostas Papadimitriou
723 c363a678 Kostas Papadimitriou
@require_http_methods(["POST"])
724 c363a678 Kostas Papadimitriou
@valid_astakos_user_required
725 c363a678 Kostas Papadimitriou
def project_members_action(request, chain_id, action=None, redirect_to=''):
726 c363a678 Kostas Papadimitriou
727 c363a678 Kostas Papadimitriou
    actions_map = {
728 c363a678 Kostas Papadimitriou
        'remove': _project_remove_member,
729 c363a678 Kostas Papadimitriou
        'accept': _project_accept_member,
730 c363a678 Kostas Papadimitriou
        'reject': _project_reject_member
731 c363a678 Kostas Papadimitriou
    }
732 c363a678 Kostas Papadimitriou
733 c363a678 Kostas Papadimitriou
    if not action in actions_map.keys():
734 c363a678 Kostas Papadimitriou
        raise PermissionDenied
735 c363a678 Kostas Papadimitriou
736 c363a678 Kostas Papadimitriou
    member_ids = request.POST.getlist('members')
737 6d583e07 Giorgos Korfiatis
    project = get_object_or_404(Project, pk=chain_id)
738 c363a678 Kostas Papadimitriou
739 c363a678 Kostas Papadimitriou
    user = request.user
740 c363a678 Kostas Papadimitriou
    if not user.owns_project(project) and not user.is_project_admin():
741 c363a678 Kostas Papadimitriou
        return redirect(reverse('index'))
742 c363a678 Kostas Papadimitriou
743 06086f91 Kostas Papadimitriou
    logger.info("Batch members action from %s (chain: %r, action: %s, "
744 06086f91 Kostas Papadimitriou
                "members: %r)", user.log_display, chain_id, action, member_ids)
745 c363a678 Kostas Papadimitriou
746 c363a678 Kostas Papadimitriou
    action_func = actions_map.get(action)
747 c363a678 Kostas Papadimitriou
    for member_id in member_ids:
748 c363a678 Kostas Papadimitriou
        member_id = int(member_id)
749 c363a678 Kostas Papadimitriou
        with ExceptionHandler(request):
750 dc946891 Giorgos Korfiatis
            action_func(request, member_id)
751 c363a678 Kostas Papadimitriou
752 59eb6ec5 Kostas Papadimitriou
    return redirect_back(request, 'project_list')