Statistics
| Branch: | Tag: | Revision:

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

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