Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (23.7 kB)

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