Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (24.8 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 8998f09a Sofia Papagiannaki
            RequestConfig(request, paginate={"per_page": settings.PAGINATE_BY}
362 70e11eaa Sofia Papagiannaki
                          ).configure(members_table)
363 70e11eaa Sofia Papagiannaki
364 70e11eaa Sofia Papagiannaki
        else:
365 70e11eaa Sofia Papagiannaki
            members_table = None
366 70e11eaa Sofia Papagiannaki
367 460b907d Kostas Papadimitriou
    else:
368 460b907d Kostas Papadimitriou
        # is application
369 70e11eaa Sofia Papagiannaki
        application_id = chain_or_app_id
370 70e11eaa Sofia Papagiannaki
        application = get_object_or_404(ProjectApplication, pk=application_id)
371 70e11eaa Sofia Papagiannaki
        members_table = None
372 70e11eaa Sofia Papagiannaki
        addmembers_form = None
373 70e11eaa Sofia Papagiannaki
374 70e11eaa Sofia Papagiannaki
    user = request.user
375 70e11eaa Sofia Papagiannaki
    is_project_admin = user.is_project_admin(application_id=application.id)
376 70e11eaa Sofia Papagiannaki
    is_owner = user.owns_application(application)
377 70e11eaa Sofia Papagiannaki
    if not (is_owner or is_project_admin) and not project_view:
378 70e11eaa Sofia Papagiannaki
        m = _(astakos_messages.NOT_ALLOWED)
379 70e11eaa Sofia Papagiannaki
        raise PermissionDenied(m)
380 70e11eaa Sofia Papagiannaki
381 8fb8d0cf Giorgos Korfiatis
    if (
382 8fb8d0cf Giorgos Korfiatis
        not (is_owner or is_project_admin) and project_view and
383 8fb8d0cf Giorgos Korfiatis
        not user.non_owner_can_view(project)
384 8fb8d0cf Giorgos Korfiatis
    ):
385 70e11eaa Sofia Papagiannaki
        m = _(astakos_messages.NOT_ALLOWED)
386 70e11eaa Sofia Papagiannaki
        raise PermissionDenied(m)
387 70e11eaa Sofia Papagiannaki
388 dc946891 Giorgos Korfiatis
    membership = user.get_membership(project) if project else None
389 dc946891 Giorgos Korfiatis
    membership_id = membership.id if membership else None
390 70e11eaa Sofia Papagiannaki
    mem_display = user.membership_display(project) if project else None
391 70e11eaa Sofia Papagiannaki
    can_join_req = can_join_request(project, user) if project else False
392 70e11eaa Sofia Papagiannaki
    can_leave_req = can_leave_request(project, user) if project else False
393 70e11eaa Sofia Papagiannaki
394 70e11eaa Sofia Papagiannaki
    return object_detail(
395 70e11eaa Sofia Papagiannaki
        request,
396 70e11eaa Sofia Papagiannaki
        queryset=ProjectApplication.objects.select_related(),
397 70e11eaa Sofia Papagiannaki
        object_id=application.id,
398 460b907d Kostas Papadimitriou
        template_name=template_name,
399 70e11eaa Sofia Papagiannaki
        extra_context={
400 70e11eaa Sofia Papagiannaki
            'project_view': project_view,
401 8eb176ab Kostas Papadimitriou
            'chain_id': chain_or_app_id,
402 8eb176ab Kostas Papadimitriou
            'application': application,
403 460b907d Kostas Papadimitriou
            'addmembers_form': addmembers_form,
404 460b907d Kostas Papadimitriou
            'approved_members_count': approved_members_count,
405 460b907d Kostas Papadimitriou
            'pending_members_count': pending_members_count,
406 70e11eaa Sofia Papagiannaki
            'members_table': members_table,
407 70e11eaa Sofia Papagiannaki
            'owner_mode': is_owner,
408 70e11eaa Sofia Papagiannaki
            'admin_mode': is_project_admin,
409 70e11eaa Sofia Papagiannaki
            'mem_display': mem_display,
410 dc946891 Giorgos Korfiatis
            'membership_id': membership_id,
411 70e11eaa Sofia Papagiannaki
            'can_join_request': can_join_req,
412 70e11eaa Sofia Papagiannaki
            'can_leave_request': can_leave_req,
413 8fb8d0cf Giorgos Korfiatis
            'members_status_filter': members_status_filter,
414 8c8f856b Olga Brani
            'remaining_memberships_count': remaining_memberships_count,
415 0f433ce2 Giorgos Korfiatis
        })
416 0f433ce2 Giorgos Korfiatis
417 70e11eaa Sofia Papagiannaki
418 70e11eaa Sofia Papagiannaki
@require_http_methods(["GET", "POST"])
419 70e11eaa Sofia Papagiannaki
@cookie_fix
420 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
421 70e11eaa Sofia Papagiannaki
def project_search(request):
422 70e11eaa Sofia Papagiannaki
    q = request.GET.get('q', '')
423 70e11eaa Sofia Papagiannaki
    form = ProjectSearchForm()
424 70e11eaa Sofia Papagiannaki
    q = q.strip()
425 70e11eaa Sofia Papagiannaki
426 70e11eaa Sofia Papagiannaki
    if request.method == "POST":
427 70e11eaa Sofia Papagiannaki
        form = ProjectSearchForm(request.POST)
428 70e11eaa Sofia Papagiannaki
        if form.is_valid():
429 70e11eaa Sofia Papagiannaki
            q = form.cleaned_data['q'].strip()
430 70e11eaa Sofia Papagiannaki
        else:
431 70e11eaa Sofia Papagiannaki
            q = None
432 70e11eaa Sofia Papagiannaki
433 70e11eaa Sofia Papagiannaki
    if q is None:
434 f243d667 Giorgos Korfiatis
        projects = Project.objects.none()
435 70e11eaa Sofia Papagiannaki
    else:
436 f243d667 Giorgos Korfiatis
        accepted = request.user.projectmembership_set.filter(
437 f243d667 Giorgos Korfiatis
            state__in=ProjectMembership.ACCEPTED_STATES).values_list(
438 72313b77 Giorgos Korfiatis
            'project', flat=True)
439 f243d667 Giorgos Korfiatis
440 f243d667 Giorgos Korfiatis
        projects = Project.objects.search_by_name(q)
441 f243d667 Giorgos Korfiatis
        projects = projects.filter(Project.o_state_q(Project.O_ACTIVE))
442 b10ceccd Giorgos Korfiatis
        projects = projects.exclude(id__in=accepted).select_related(
443 b10ceccd Giorgos Korfiatis
            'application', 'application__owner', 'application__applicant')
444 f243d667 Giorgos Korfiatis
445 b10ceccd Giorgos Korfiatis
    table = get_user_projects_table(projects, user=request.user,
446 b10ceccd Giorgos Korfiatis
                                    prefix="my_projects_")
447 70e11eaa Sofia Papagiannaki
    if request.method == "POST":
448 70e11eaa Sofia Papagiannaki
        table.caption = _('SEARCH RESULTS')
449 70e11eaa Sofia Papagiannaki
    else:
450 70e11eaa Sofia Papagiannaki
        table.caption = _('ALL PROJECTS')
451 70e11eaa Sofia Papagiannaki
452 70e11eaa Sofia Papagiannaki
    return object_list(
453 70e11eaa Sofia Papagiannaki
        request,
454 70e11eaa Sofia Papagiannaki
        projects,
455 70e11eaa Sofia Papagiannaki
        template_name='im/projects/project_list.html',
456 70e11eaa Sofia Papagiannaki
        extra_context={
457 8fb8d0cf Giorgos Korfiatis
            'form': form,
458 8fb8d0cf Giorgos Korfiatis
            'is_search': True,
459 8fb8d0cf Giorgos Korfiatis
            'q': q,
460 8fb8d0cf Giorgos Korfiatis
            'table': table
461 70e11eaa Sofia Papagiannaki
        })
462 70e11eaa Sofia Papagiannaki
463 8fb8d0cf Giorgos Korfiatis
464 70e11eaa Sofia Papagiannaki
@require_http_methods(["POST"])
465 70e11eaa Sofia Papagiannaki
@cookie_fix
466 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
467 70e11eaa Sofia Papagiannaki
def project_join(request, chain_id):
468 70e11eaa Sofia Papagiannaki
    next = request.GET.get('next')
469 70e11eaa Sofia Papagiannaki
    if not next:
470 70e11eaa Sofia Papagiannaki
        next = reverse('astakos.im.views.project_detail',
471 70e11eaa Sofia Papagiannaki
                       args=(chain_id,))
472 70e11eaa Sofia Papagiannaki
473 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
474 70e11eaa Sofia Papagiannaki
        _project_join(request, chain_id)
475 70e11eaa Sofia Papagiannaki
476 8998f09a Sofia Papagiannaki
    next = restrict_next(next, domain=settings.COOKIE_DOMAIN)
477 70e11eaa Sofia Papagiannaki
    return redirect(next)
478 70e11eaa Sofia Papagiannaki
479 70e11eaa Sofia Papagiannaki
480 a3e3917f Giorgos Korfiatis
@transaction.commit_on_success
481 70e11eaa Sofia Papagiannaki
def _project_join(request, chain_id):
482 70e11eaa Sofia Papagiannaki
    try:
483 70e11eaa Sofia Papagiannaki
        chain_id = int(chain_id)
484 e1723ca1 Giorgos Korfiatis
        membership = join_project(chain_id, request.user)
485 e1723ca1 Giorgos Korfiatis
        if membership.state != membership.REQUESTED:
486 70e11eaa Sofia Papagiannaki
            m = _(astakos_messages.USER_JOINED_PROJECT)
487 70e11eaa Sofia Papagiannaki
        else:
488 70e11eaa Sofia Papagiannaki
            m = _(astakos_messages.USER_JOIN_REQUEST_SUBMITTED)
489 70e11eaa Sofia Papagiannaki
        messages.success(request, m)
490 f12bcb3d Giorgos Korfiatis
    except ProjectError as e:
491 70e11eaa Sofia Papagiannaki
        messages.error(request, e)
492 70e11eaa Sofia Papagiannaki
493 70e11eaa Sofia Papagiannaki
494 70e11eaa Sofia Papagiannaki
@require_http_methods(["POST"])
495 70e11eaa Sofia Papagiannaki
@cookie_fix
496 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
497 dc946891 Giorgos Korfiatis
def project_leave(request, memb_id):
498 70e11eaa Sofia Papagiannaki
    next = request.GET.get('next')
499 70e11eaa Sofia Papagiannaki
    if not next:
500 70e11eaa Sofia Papagiannaki
        next = reverse('astakos.im.views.project_list')
501 70e11eaa Sofia Papagiannaki
502 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
503 dc946891 Giorgos Korfiatis
        _project_leave(request, memb_id)
504 70e11eaa Sofia Papagiannaki
505 8998f09a Sofia Papagiannaki
    next = restrict_next(next, domain=settings.COOKIE_DOMAIN)
506 70e11eaa Sofia Papagiannaki
    return redirect(next)
507 70e11eaa Sofia Papagiannaki
508 70e11eaa Sofia Papagiannaki
509 a3e3917f Giorgos Korfiatis
@transaction.commit_on_success
510 dc946891 Giorgos Korfiatis
def _project_leave(request, memb_id):
511 70e11eaa Sofia Papagiannaki
    try:
512 dc946891 Giorgos Korfiatis
        memb_id = int(memb_id)
513 dc946891 Giorgos Korfiatis
        auto_accepted = leave_project(memb_id, request.user)
514 70e11eaa Sofia Papagiannaki
        if auto_accepted:
515 70e11eaa Sofia Papagiannaki
            m = _(astakos_messages.USER_LEFT_PROJECT)
516 70e11eaa Sofia Papagiannaki
        else:
517 70e11eaa Sofia Papagiannaki
            m = _(astakos_messages.USER_LEAVE_REQUEST_SUBMITTED)
518 70e11eaa Sofia Papagiannaki
        messages.success(request, m)
519 f12bcb3d Giorgos Korfiatis
    except ProjectError as e:
520 70e11eaa Sofia Papagiannaki
        messages.error(request, e)
521 70e11eaa Sofia Papagiannaki
522 70e11eaa Sofia Papagiannaki
523 70e11eaa Sofia Papagiannaki
@require_http_methods(["POST"])
524 70e11eaa Sofia Papagiannaki
@cookie_fix
525 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
526 dc946891 Giorgos Korfiatis
def project_cancel_member(request, memb_id):
527 70e11eaa Sofia Papagiannaki
    next = request.GET.get('next')
528 70e11eaa Sofia Papagiannaki
    if not next:
529 70e11eaa Sofia Papagiannaki
        next = reverse('astakos.im.views.project_list')
530 70e11eaa Sofia Papagiannaki
531 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
532 dc946891 Giorgos Korfiatis
        _project_cancel_member(request, memb_id)
533 70e11eaa Sofia Papagiannaki
534 8998f09a Sofia Papagiannaki
    next = restrict_next(next, domain=settings.COOKIE_DOMAIN)
535 70e11eaa Sofia Papagiannaki
    return redirect(next)
536 70e11eaa Sofia Papagiannaki
537 70e11eaa Sofia Papagiannaki
538 a3e3917f Giorgos Korfiatis
@transaction.commit_on_success
539 dc946891 Giorgos Korfiatis
def _project_cancel_member(request, memb_id):
540 70e11eaa Sofia Papagiannaki
    try:
541 dc946891 Giorgos Korfiatis
        cancel_membership(memb_id, request.user)
542 70e11eaa Sofia Papagiannaki
        m = _(astakos_messages.USER_REQUEST_CANCELLED)
543 70e11eaa Sofia Papagiannaki
        messages.success(request, m)
544 f12bcb3d Giorgos Korfiatis
    except ProjectError as e:
545 70e11eaa Sofia Papagiannaki
        messages.error(request, e)
546 70e11eaa Sofia Papagiannaki
547 70e11eaa Sofia Papagiannaki
548 70e11eaa Sofia Papagiannaki
@require_http_methods(["POST"])
549 70e11eaa Sofia Papagiannaki
@cookie_fix
550 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
551 dc946891 Giorgos Korfiatis
def project_accept_member(request, memb_id):
552 70e11eaa Sofia Papagiannaki
553 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
554 dc946891 Giorgos Korfiatis
        _project_accept_member(request, memb_id)
555 70e11eaa Sofia Papagiannaki
556 59eb6ec5 Kostas Papadimitriou
    return redirect_back(request, 'project_list')
557 70e11eaa Sofia Papagiannaki
558 70e11eaa Sofia Papagiannaki
559 a3e3917f Giorgos Korfiatis
@transaction.commit_on_success
560 dc946891 Giorgos Korfiatis
def _project_accept_member(request, memb_id):
561 70e11eaa Sofia Papagiannaki
    try:
562 70e11eaa Sofia Papagiannaki
        memb_id = int(memb_id)
563 dc946891 Giorgos Korfiatis
        m = accept_membership(memb_id, request.user)
564 f12bcb3d Giorgos Korfiatis
    except ProjectError as e:
565 70e11eaa Sofia Papagiannaki
        messages.error(request, e)
566 70e11eaa Sofia Papagiannaki
567 70e11eaa Sofia Papagiannaki
    else:
568 70e11eaa Sofia Papagiannaki
        email = escape(m.person.email)
569 70e11eaa Sofia Papagiannaki
        msg = _(astakos_messages.USER_MEMBERSHIP_ACCEPTED) % email
570 70e11eaa Sofia Papagiannaki
        messages.success(request, msg)
571 70e11eaa Sofia Papagiannaki
572 70e11eaa Sofia Papagiannaki
573 70e11eaa Sofia Papagiannaki
@require_http_methods(["POST"])
574 70e11eaa Sofia Papagiannaki
@cookie_fix
575 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
576 dc946891 Giorgos Korfiatis
def project_remove_member(request, memb_id):
577 70e11eaa Sofia Papagiannaki
578 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
579 dc946891 Giorgos Korfiatis
        _project_remove_member(request, memb_id)
580 70e11eaa Sofia Papagiannaki
581 59eb6ec5 Kostas Papadimitriou
    return redirect_back(request, 'project_list')
582 70e11eaa Sofia Papagiannaki
583 70e11eaa Sofia Papagiannaki
584 a3e3917f Giorgos Korfiatis
@transaction.commit_on_success
585 dc946891 Giorgos Korfiatis
def _project_remove_member(request, memb_id):
586 70e11eaa Sofia Papagiannaki
    try:
587 70e11eaa Sofia Papagiannaki
        memb_id = int(memb_id)
588 dc946891 Giorgos Korfiatis
        m = remove_membership(memb_id, request.user)
589 f12bcb3d Giorgos Korfiatis
    except ProjectError as e:
590 70e11eaa Sofia Papagiannaki
        messages.error(request, e)
591 70e11eaa Sofia Papagiannaki
    else:
592 70e11eaa Sofia Papagiannaki
        email = escape(m.person.email)
593 70e11eaa Sofia Papagiannaki
        msg = _(astakos_messages.USER_MEMBERSHIP_REMOVED) % email
594 70e11eaa Sofia Papagiannaki
        messages.success(request, msg)
595 70e11eaa Sofia Papagiannaki
596 70e11eaa Sofia Papagiannaki
597 70e11eaa Sofia Papagiannaki
@require_http_methods(["POST"])
598 70e11eaa Sofia Papagiannaki
@cookie_fix
599 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
600 dc946891 Giorgos Korfiatis
def project_reject_member(request, memb_id):
601 70e11eaa Sofia Papagiannaki
602 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
603 dc946891 Giorgos Korfiatis
        _project_reject_member(request, memb_id)
604 70e11eaa Sofia Papagiannaki
605 59eb6ec5 Kostas Papadimitriou
    return redirect_back(request, 'project_list')
606 70e11eaa Sofia Papagiannaki
607 70e11eaa Sofia Papagiannaki
608 a3e3917f Giorgos Korfiatis
@transaction.commit_on_success
609 dc946891 Giorgos Korfiatis
def _project_reject_member(request, memb_id):
610 70e11eaa Sofia Papagiannaki
    try:
611 70e11eaa Sofia Papagiannaki
        memb_id = int(memb_id)
612 dc946891 Giorgos Korfiatis
        m = reject_membership(memb_id, request.user)
613 f12bcb3d Giorgos Korfiatis
    except ProjectError as e:
614 70e11eaa Sofia Papagiannaki
        messages.error(request, e)
615 70e11eaa Sofia Papagiannaki
    else:
616 70e11eaa Sofia Papagiannaki
        email = escape(m.person.email)
617 70e11eaa Sofia Papagiannaki
        msg = _(astakos_messages.USER_MEMBERSHIP_REJECTED) % email
618 70e11eaa Sofia Papagiannaki
        messages.success(request, msg)
619 70e11eaa Sofia Papagiannaki
620 70e11eaa Sofia Papagiannaki
621 70e11eaa Sofia Papagiannaki
@require_http_methods(["POST"])
622 70e11eaa Sofia Papagiannaki
@signed_terms_required
623 70e11eaa Sofia Papagiannaki
@login_required
624 70e11eaa Sofia Papagiannaki
@cookie_fix
625 70e11eaa Sofia Papagiannaki
def project_app_approve(request, application_id):
626 70e11eaa Sofia Papagiannaki
627 70e11eaa Sofia Papagiannaki
    if not request.user.is_project_admin():
628 70e11eaa Sofia Papagiannaki
        m = _(astakos_messages.NOT_ALLOWED)
629 70e11eaa Sofia Papagiannaki
        raise PermissionDenied(m)
630 70e11eaa Sofia Papagiannaki
631 70e11eaa Sofia Papagiannaki
    try:
632 51db2da2 Giorgos Korfiatis
        ProjectApplication.objects.get(id=application_id)
633 70e11eaa Sofia Papagiannaki
    except ProjectApplication.DoesNotExist:
634 70e11eaa Sofia Papagiannaki
        raise Http404
635 70e11eaa Sofia Papagiannaki
636 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
637 70e11eaa Sofia Papagiannaki
        _project_app_approve(request, application_id)
638 70e11eaa Sofia Papagiannaki
639 70e11eaa Sofia Papagiannaki
    chain_id = get_related_project_id(application_id)
640 f5389699 Kostas Papadimitriou
    if not chain_id:
641 f5389699 Kostas Papadimitriou
        return redirect_back(request, 'project_list')
642 70e11eaa Sofia Papagiannaki
    return redirect(reverse('project_detail', args=(chain_id,)))
643 70e11eaa Sofia Papagiannaki
644 70e11eaa Sofia Papagiannaki
645 a3e3917f Giorgos Korfiatis
@transaction.commit_on_success
646 70e11eaa Sofia Papagiannaki
def _project_app_approve(request, application_id):
647 70e11eaa Sofia Papagiannaki
    approve_application(application_id)
648 70e11eaa Sofia Papagiannaki
649 70e11eaa Sofia Papagiannaki
650 70e11eaa Sofia Papagiannaki
@require_http_methods(["POST"])
651 70e11eaa Sofia Papagiannaki
@signed_terms_required
652 70e11eaa Sofia Papagiannaki
@login_required
653 70e11eaa Sofia Papagiannaki
@cookie_fix
654 70e11eaa Sofia Papagiannaki
def project_app_deny(request, application_id):
655 70e11eaa Sofia Papagiannaki
656 70e11eaa Sofia Papagiannaki
    reason = request.POST.get('reason', None)
657 70e11eaa Sofia Papagiannaki
    if not reason:
658 70e11eaa Sofia Papagiannaki
        reason = None
659 70e11eaa Sofia Papagiannaki
660 70e11eaa Sofia Papagiannaki
    if not request.user.is_project_admin():
661 70e11eaa Sofia Papagiannaki
        m = _(astakos_messages.NOT_ALLOWED)
662 70e11eaa Sofia Papagiannaki
        raise PermissionDenied(m)
663 70e11eaa Sofia Papagiannaki
664 70e11eaa Sofia Papagiannaki
    try:
665 51db2da2 Giorgos Korfiatis
        ProjectApplication.objects.get(id=application_id)
666 70e11eaa Sofia Papagiannaki
    except ProjectApplication.DoesNotExist:
667 70e11eaa Sofia Papagiannaki
        raise Http404
668 70e11eaa Sofia Papagiannaki
669 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
670 70e11eaa Sofia Papagiannaki
        _project_app_deny(request, application_id, reason)
671 70e11eaa Sofia Papagiannaki
672 70e11eaa Sofia Papagiannaki
    return redirect(reverse('project_list'))
673 70e11eaa Sofia Papagiannaki
674 70e11eaa Sofia Papagiannaki
675 a3e3917f Giorgos Korfiatis
@transaction.commit_on_success
676 70e11eaa Sofia Papagiannaki
def _project_app_deny(request, application_id, reason):
677 70e11eaa Sofia Papagiannaki
    deny_application(application_id, reason=reason)
678 70e11eaa Sofia Papagiannaki
679 70e11eaa Sofia Papagiannaki
680 70e11eaa Sofia Papagiannaki
@require_http_methods(["POST"])
681 70e11eaa Sofia Papagiannaki
@signed_terms_required
682 70e11eaa Sofia Papagiannaki
@login_required
683 70e11eaa Sofia Papagiannaki
@cookie_fix
684 70e11eaa Sofia Papagiannaki
def project_app_dismiss(request, application_id):
685 70e11eaa Sofia Papagiannaki
    try:
686 70e11eaa Sofia Papagiannaki
        app = ProjectApplication.objects.get(id=application_id)
687 70e11eaa Sofia Papagiannaki
    except ProjectApplication.DoesNotExist:
688 70e11eaa Sofia Papagiannaki
        raise Http404
689 70e11eaa Sofia Papagiannaki
690 70e11eaa Sofia Papagiannaki
    if not request.user.owns_application(app):
691 70e11eaa Sofia Papagiannaki
        m = _(astakos_messages.NOT_ALLOWED)
692 70e11eaa Sofia Papagiannaki
        raise PermissionDenied(m)
693 70e11eaa Sofia Papagiannaki
694 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
695 70e11eaa Sofia Papagiannaki
        _project_app_dismiss(request, application_id)
696 70e11eaa Sofia Papagiannaki
697 70e11eaa Sofia Papagiannaki
    chain_id = None
698 70e11eaa Sofia Papagiannaki
    chain_id = get_related_project_id(application_id)
699 70e11eaa Sofia Papagiannaki
    if chain_id:
700 70e11eaa Sofia Papagiannaki
        next = reverse('project_detail', args=(chain_id,))
701 70e11eaa Sofia Papagiannaki
    else:
702 70e11eaa Sofia Papagiannaki
        next = reverse('project_list')
703 70e11eaa Sofia Papagiannaki
    return redirect(next)
704 70e11eaa Sofia Papagiannaki
705 70e11eaa Sofia Papagiannaki
706 70e11eaa Sofia Papagiannaki
def _project_app_dismiss(request, application_id):
707 70e11eaa Sofia Papagiannaki
    # XXX: dismiss application also does authorization
708 70e11eaa Sofia Papagiannaki
    dismiss_application(application_id, request_user=request.user)
709 460b907d Kostas Papadimitriou
710 460b907d Kostas Papadimitriou
711 460b907d Kostas Papadimitriou
@require_http_methods(["GET", "POST"])
712 460b907d Kostas Papadimitriou
@valid_astakos_user_required
713 460b907d Kostas Papadimitriou
def project_members(request, chain_id, members_status_filter=None,
714 460b907d Kostas Papadimitriou
                    template_name='im/projects/project_members.html'):
715 6d583e07 Giorgos Korfiatis
    project = get_object_or_404(Project, pk=chain_id)
716 7971e5da Kostas Papadimitriou
717 7971e5da Kostas Papadimitriou
    user = request.user
718 7971e5da Kostas Papadimitriou
    if not user.owns_project(project) and not user.is_project_admin():
719 7971e5da Kostas Papadimitriou
        return redirect(reverse('index'))
720 7971e5da Kostas Papadimitriou
721 460b907d Kostas Papadimitriou
    return common_detail(request, chain_id,
722 460b907d Kostas Papadimitriou
                         members_status_filter=members_status_filter,
723 460b907d Kostas Papadimitriou
                         template_name=template_name)
724 c363a678 Kostas Papadimitriou
725 c363a678 Kostas Papadimitriou
726 c363a678 Kostas Papadimitriou
@require_http_methods(["POST"])
727 c363a678 Kostas Papadimitriou
@valid_astakos_user_required
728 c363a678 Kostas Papadimitriou
def project_members_action(request, chain_id, action=None, redirect_to=''):
729 c363a678 Kostas Papadimitriou
730 c363a678 Kostas Papadimitriou
    actions_map = {
731 c363a678 Kostas Papadimitriou
        'remove': _project_remove_member,
732 c363a678 Kostas Papadimitriou
        'accept': _project_accept_member,
733 c363a678 Kostas Papadimitriou
        'reject': _project_reject_member
734 c363a678 Kostas Papadimitriou
    }
735 c363a678 Kostas Papadimitriou
736 c363a678 Kostas Papadimitriou
    if not action in actions_map.keys():
737 c363a678 Kostas Papadimitriou
        raise PermissionDenied
738 c363a678 Kostas Papadimitriou
739 c363a678 Kostas Papadimitriou
    member_ids = request.POST.getlist('members')
740 6d583e07 Giorgos Korfiatis
    project = get_object_or_404(Project, pk=chain_id)
741 c363a678 Kostas Papadimitriou
742 c363a678 Kostas Papadimitriou
    user = request.user
743 c363a678 Kostas Papadimitriou
    if not user.owns_project(project) and not user.is_project_admin():
744 c363a678 Kostas Papadimitriou
        return redirect(reverse('index'))
745 c363a678 Kostas Papadimitriou
746 06086f91 Kostas Papadimitriou
    logger.info("Batch members action from %s (chain: %r, action: %s, "
747 06086f91 Kostas Papadimitriou
                "members: %r)", user.log_display, chain_id, action, member_ids)
748 c363a678 Kostas Papadimitriou
749 c363a678 Kostas Papadimitriou
    action_func = actions_map.get(action)
750 c363a678 Kostas Papadimitriou
    for member_id in member_ids:
751 c363a678 Kostas Papadimitriou
        member_id = int(member_id)
752 c363a678 Kostas Papadimitriou
        with ExceptionHandler(request):
753 dc946891 Giorgos Korfiatis
            action_func(request, member_id)
754 c363a678 Kostas Papadimitriou
755 59eb6ec5 Kostas Papadimitriou
    return redirect_back(request, 'project_list')