Statistics
| Branch: | Tag: | Revision:

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

History | View | Annotate | Download (21.4 kB)

1 70e11eaa Sofia Papagiannaki
# Copyright 2011-2012 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.contrib.auth.decorators import login_required
44 70e11eaa Sofia Papagiannaki
from django.core.urlresolvers import reverse
45 3e0a032d Sofia Papagiannaki
from django.http import Http404
46 70e11eaa Sofia Papagiannaki
from django.shortcuts import redirect
47 70e11eaa Sofia Papagiannaki
from django.utils.html import escape
48 70e11eaa Sofia Papagiannaki
from django.utils.translation import ugettext as _
49 70e11eaa Sofia Papagiannaki
from django.views.generic.list_detail import object_list, object_detail
50 3e0a032d Sofia Papagiannaki
from django.core.exceptions import PermissionDenied
51 70e11eaa Sofia Papagiannaki
from django.views.decorators.http import require_http_methods
52 70e11eaa Sofia Papagiannaki
from django.db.models import Q
53 70e11eaa Sofia Papagiannaki
54 70e11eaa Sofia Papagiannaki
from snf_django.lib.db.transaction import commit_on_success_strict
55 70e11eaa Sofia Papagiannaki
56 70e11eaa Sofia Papagiannaki
import astakos.im.messages as astakos_messages
57 70e11eaa Sofia Papagiannaki
58 70e11eaa Sofia Papagiannaki
from astakos.im import tables
59 3e0a032d Sofia Papagiannaki
from astakos.im.models import ProjectApplication
60 3e0a032d Sofia Papagiannaki
from astakos.im.util import get_context, restrict_next
61 3e0a032d Sofia Papagiannaki
from astakos.im.forms import ProjectApplicationForm, AddProjectMembersForm, \
62 3e0a032d Sofia Papagiannaki
    ProjectSearchForm
63 3e0a032d Sofia Papagiannaki
from astakos.im.functions import check_pending_app_quota, accept_membership, \
64 3e0a032d Sofia Papagiannaki
    reject_membership, remove_membership, cancel_membership, leave_project, \
65 3e0a032d Sofia Papagiannaki
    join_project, enroll_member, can_join_request, can_leave_request, \
66 3e0a032d Sofia Papagiannaki
    get_related_project_id, get_by_chain_or_404, approve_application, \
67 3e0a032d Sofia Papagiannaki
    deny_application, cancel_application, dismiss_application
68 8998f09a Sofia Papagiannaki
from astakos.im import settings
69 70e11eaa Sofia Papagiannaki
from astakos.im.ctx import ExceptionHandler
70 70e11eaa Sofia Papagiannaki
from astakos.im.views.util import render_response, _create_object, \
71 70e11eaa Sofia Papagiannaki
    _update_object, _resources_catalog
72 70e11eaa Sofia Papagiannaki
from astakos.im.views.decorators import cookie_fix, signed_terms_required,\
73 3e0a032d Sofia Papagiannaki
    valid_astakos_user_required
74 70e11eaa Sofia Papagiannaki
75 70e11eaa Sofia Papagiannaki
logger = logging.getLogger(__name__)
76 70e11eaa Sofia Papagiannaki
77 70e11eaa Sofia Papagiannaki
78 70e11eaa Sofia Papagiannaki
@cookie_fix
79 70e11eaa Sofia Papagiannaki
def how_it_works(request):
80 70e11eaa Sofia Papagiannaki
    return render_response(
81 70e11eaa Sofia Papagiannaki
        'im/how_it_works.html',
82 70e11eaa Sofia Papagiannaki
        context_instance=get_context(request))
83 70e11eaa Sofia Papagiannaki
84 70e11eaa Sofia Papagiannaki
85 70e11eaa Sofia Papagiannaki
@require_http_methods(["GET", "POST"])
86 70e11eaa Sofia Papagiannaki
@cookie_fix
87 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
88 70e11eaa Sofia Papagiannaki
def project_add(request):
89 70e11eaa Sofia Papagiannaki
    user = request.user
90 70e11eaa Sofia Papagiannaki
    if not user.is_project_admin():
91 70e11eaa Sofia Papagiannaki
        ok, limit = check_pending_app_quota(user)
92 70e11eaa Sofia Papagiannaki
        if not ok:
93 70e11eaa Sofia Papagiannaki
            m = _(astakos_messages.PENDING_APPLICATION_LIMIT_ADD) % limit
94 70e11eaa Sofia Papagiannaki
            messages.error(request, m)
95 70e11eaa Sofia Papagiannaki
            next = reverse('astakos.im.views.project_list')
96 8998f09a Sofia Papagiannaki
            next = restrict_next(next, domain=settings.COOKIE_DOMAIN)
97 70e11eaa Sofia Papagiannaki
            return redirect(next)
98 70e11eaa Sofia Papagiannaki
99 70e11eaa Sofia Papagiannaki
    details_fields = ["name", "homepage", "description", "start_date",
100 70e11eaa Sofia Papagiannaki
                      "end_date", "comments"]
101 70e11eaa Sofia Papagiannaki
    membership_fields = ["member_join_policy", "member_leave_policy",
102 70e11eaa Sofia Papagiannaki
                         "limit_on_members_number"]
103 70e11eaa Sofia Papagiannaki
    resource_catalog, resource_groups = _resources_catalog(for_project=True)
104 70e11eaa Sofia Papagiannaki
    if resource_catalog is False:
105 70e11eaa Sofia Papagiannaki
        # on fail resource_groups contains the result object
106 70e11eaa Sofia Papagiannaki
        result = resource_groups
107 70e11eaa Sofia Papagiannaki
        messages.error(request, 'Unable to retrieve system resources: %s' %
108 70e11eaa Sofia Papagiannaki
                       result.reason)
109 70e11eaa Sofia Papagiannaki
    extra_context = {
110 70e11eaa Sofia Papagiannaki
        'resource_catalog': resource_catalog,
111 70e11eaa Sofia Papagiannaki
        'resource_groups': resource_groups,
112 70e11eaa Sofia Papagiannaki
        'show_form': True,
113 70e11eaa Sofia Papagiannaki
        'details_fields': details_fields,
114 70e11eaa Sofia Papagiannaki
        'membership_fields': membership_fields}
115 70e11eaa Sofia Papagiannaki
116 70e11eaa Sofia Papagiannaki
    response = None
117 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
118 70e11eaa Sofia Papagiannaki
        response = _create_object(
119 70e11eaa Sofia Papagiannaki
            request,
120 70e11eaa Sofia Papagiannaki
            template_name='im/projects/projectapplication_form.html',
121 70e11eaa Sofia Papagiannaki
            extra_context=extra_context,
122 70e11eaa Sofia Papagiannaki
            post_save_redirect=reverse('project_list'),
123 70e11eaa Sofia Papagiannaki
            form_class=ProjectApplicationForm,
124 70e11eaa Sofia Papagiannaki
            msg=_("The %(verbose_name)s has been received and "
125 70e11eaa Sofia Papagiannaki
                  "is under consideration."),
126 70e11eaa Sofia Papagiannaki
            )
127 70e11eaa Sofia Papagiannaki
128 70e11eaa Sofia Papagiannaki
    if response is not None:
129 70e11eaa Sofia Papagiannaki
        return response
130 70e11eaa Sofia Papagiannaki
131 70e11eaa Sofia Papagiannaki
    next = reverse('astakos.im.views.project_list')
132 8998f09a Sofia Papagiannaki
    next = restrict_next(next, domain=settings.COOKIE_DOMAIN)
133 70e11eaa Sofia Papagiannaki
    return redirect(next)
134 70e11eaa Sofia Papagiannaki
135 70e11eaa Sofia Papagiannaki
136 70e11eaa Sofia Papagiannaki
@require_http_methods(["GET"])
137 70e11eaa Sofia Papagiannaki
@cookie_fix
138 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
139 70e11eaa Sofia Papagiannaki
def project_list(request):
140 70e11eaa Sofia Papagiannaki
    projects = ProjectApplication.objects.user_accessible_projects(request.user).select_related()
141 70e11eaa Sofia Papagiannaki
    table = tables.UserProjectApplicationsTable(projects, user=request.user,
142 70e11eaa Sofia Papagiannaki
                                                prefix="my_projects_")
143 8998f09a Sofia Papagiannaki
    RequestConfig(request, 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 70e11eaa Sofia Papagiannaki
            '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 70e11eaa Sofia Papagiannaki
@commit_on_success_strict()
175 70e11eaa Sofia Papagiannaki
def _project_app_cancel(request, application_id):
176 70e11eaa Sofia Papagiannaki
    chain_id = None
177 70e11eaa Sofia Papagiannaki
    try:
178 70e11eaa Sofia Papagiannaki
        application_id = int(application_id)
179 70e11eaa Sofia Papagiannaki
        chain_id = get_related_project_id(application_id)
180 70e11eaa Sofia Papagiannaki
        cancel_application(application_id, request.user)
181 70e11eaa Sofia Papagiannaki
    except (IOError, PermissionDenied), e:
182 70e11eaa Sofia Papagiannaki
        messages.error(request, e)
183 70e11eaa Sofia Papagiannaki
184 70e11eaa Sofia Papagiannaki
    else:
185 70e11eaa Sofia Papagiannaki
        msg = _(astakos_messages.APPLICATION_CANCELLED)
186 70e11eaa Sofia Papagiannaki
        messages.success(request, msg)
187 70e11eaa Sofia Papagiannaki
        return chain_id
188 70e11eaa Sofia Papagiannaki
189 70e11eaa Sofia Papagiannaki
190 70e11eaa Sofia Papagiannaki
@require_http_methods(["GET", "POST"])
191 70e11eaa Sofia Papagiannaki
@cookie_fix
192 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
193 70e11eaa Sofia Papagiannaki
def project_modify(request, application_id):
194 70e11eaa Sofia Papagiannaki
195 70e11eaa Sofia Papagiannaki
    try:
196 70e11eaa Sofia Papagiannaki
        app = ProjectApplication.objects.get(id=application_id)
197 70e11eaa Sofia Papagiannaki
    except ProjectApplication.DoesNotExist:
198 70e11eaa Sofia Papagiannaki
        raise Http404
199 70e11eaa Sofia Papagiannaki
200 70e11eaa Sofia Papagiannaki
    user = request.user
201 70e11eaa Sofia Papagiannaki
    if not (user.owns_application(app) or user.is_project_admin(app.id)):
202 70e11eaa Sofia Papagiannaki
        m = _(astakos_messages.NOT_ALLOWED)
203 70e11eaa Sofia Papagiannaki
        raise PermissionDenied(m)
204 70e11eaa Sofia Papagiannaki
205 70e11eaa Sofia Papagiannaki
    if not user.is_project_admin():
206 70e11eaa Sofia Papagiannaki
        owner = app.owner
207 70e11eaa Sofia Papagiannaki
        ok, limit = check_pending_app_quota(owner, precursor=app)
208 70e11eaa Sofia Papagiannaki
        if not ok:
209 70e11eaa Sofia Papagiannaki
            m = _(astakos_messages.PENDING_APPLICATION_LIMIT_MODIFY) % limit
210 70e11eaa Sofia Papagiannaki
            messages.error(request, m)
211 70e11eaa Sofia Papagiannaki
            next = reverse('astakos.im.views.project_list')
212 8998f09a Sofia Papagiannaki
            next = restrict_next(next, domain=settings.COOKIE_DOMAIN)
213 70e11eaa Sofia Papagiannaki
            return redirect(next)
214 70e11eaa Sofia Papagiannaki
215 70e11eaa Sofia Papagiannaki
    details_fields = ["name", "homepage", "description", "start_date",
216 70e11eaa Sofia Papagiannaki
                      "end_date", "comments"]
217 70e11eaa Sofia Papagiannaki
    membership_fields = ["member_join_policy", "member_leave_policy",
218 70e11eaa Sofia Papagiannaki
                         "limit_on_members_number"]
219 70e11eaa Sofia Papagiannaki
    resource_catalog, resource_groups = _resources_catalog(for_project=True)
220 70e11eaa Sofia Papagiannaki
    if resource_catalog is False:
221 70e11eaa Sofia Papagiannaki
        # on fail resource_groups contains the result object
222 70e11eaa Sofia Papagiannaki
        result = resource_groups
223 70e11eaa Sofia Papagiannaki
        messages.error(request, 'Unable to retrieve system resources: %s' %
224 70e11eaa Sofia Papagiannaki
                       result.reason)
225 70e11eaa Sofia Papagiannaki
    extra_context = {
226 70e11eaa Sofia Papagiannaki
        'resource_catalog': resource_catalog,
227 70e11eaa Sofia Papagiannaki
        'resource_groups': resource_groups,
228 70e11eaa Sofia Papagiannaki
        'show_form': True,
229 70e11eaa Sofia Papagiannaki
        'details_fields': details_fields,
230 70e11eaa Sofia Papagiannaki
        'update_form': True,
231 70e11eaa Sofia Papagiannaki
        'membership_fields': membership_fields
232 70e11eaa Sofia Papagiannaki
    }
233 70e11eaa Sofia Papagiannaki
234 70e11eaa Sofia Papagiannaki
    response = None
235 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
236 70e11eaa Sofia Papagiannaki
        response = _update_object(
237 70e11eaa Sofia Papagiannaki
            request,
238 70e11eaa Sofia Papagiannaki
            object_id=application_id,
239 70e11eaa Sofia Papagiannaki
            template_name='im/projects/projectapplication_form.html',
240 70e11eaa Sofia Papagiannaki
            extra_context=extra_context,
241 70e11eaa Sofia Papagiannaki
            post_save_redirect=reverse('project_list'),
242 70e11eaa Sofia Papagiannaki
            form_class=ProjectApplicationForm,
243 70e11eaa Sofia Papagiannaki
            msg=_("The %(verbose_name)s has been received and is under "
244 70e11eaa Sofia Papagiannaki
                  "consideration."))
245 70e11eaa Sofia Papagiannaki
246 70e11eaa Sofia Papagiannaki
    if response is not None:
247 70e11eaa Sofia Papagiannaki
        return response
248 70e11eaa Sofia Papagiannaki
249 70e11eaa Sofia Papagiannaki
    next = reverse('astakos.im.views.project_list')
250 8998f09a Sofia Papagiannaki
    next = restrict_next(next, domain=settings.COOKIE_DOMAIN)
251 70e11eaa Sofia Papagiannaki
    return redirect(next)
252 70e11eaa Sofia Papagiannaki
253 70e11eaa Sofia Papagiannaki
@require_http_methods(["GET", "POST"])
254 70e11eaa Sofia Papagiannaki
@cookie_fix
255 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
256 70e11eaa Sofia Papagiannaki
def project_app(request, application_id):
257 70e11eaa Sofia Papagiannaki
    return common_detail(request, application_id, project_view=False)
258 70e11eaa Sofia Papagiannaki
259 70e11eaa Sofia Papagiannaki
@require_http_methods(["GET", "POST"])
260 70e11eaa Sofia Papagiannaki
@cookie_fix
261 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
262 70e11eaa Sofia Papagiannaki
def project_detail(request, chain_id):
263 70e11eaa Sofia Papagiannaki
    return common_detail(request, chain_id)
264 70e11eaa Sofia Papagiannaki
265 70e11eaa Sofia Papagiannaki
@commit_on_success_strict()
266 70e11eaa Sofia Papagiannaki
def addmembers(request, chain_id, addmembers_form):
267 70e11eaa Sofia Papagiannaki
    if addmembers_form.is_valid():
268 70e11eaa Sofia Papagiannaki
        try:
269 70e11eaa Sofia Papagiannaki
            chain_id = int(chain_id)
270 70e11eaa Sofia Papagiannaki
            map(lambda u: enroll_member(
271 70e11eaa Sofia Papagiannaki
                    chain_id,
272 70e11eaa Sofia Papagiannaki
                    u,
273 70e11eaa Sofia Papagiannaki
                    request_user=request.user),
274 70e11eaa Sofia Papagiannaki
                addmembers_form.valid_users)
275 70e11eaa Sofia Papagiannaki
        except (IOError, PermissionDenied), e:
276 70e11eaa Sofia Papagiannaki
            messages.error(request, e)
277 70e11eaa Sofia Papagiannaki
278 70e11eaa Sofia Papagiannaki
def common_detail(request, chain_or_app_id, project_view=True):
279 70e11eaa Sofia Papagiannaki
    project = None
280 70e11eaa Sofia Papagiannaki
    if project_view:
281 70e11eaa Sofia Papagiannaki
        chain_id = chain_or_app_id
282 70e11eaa Sofia Papagiannaki
        if request.method == 'POST':
283 70e11eaa Sofia Papagiannaki
            addmembers_form = AddProjectMembersForm(
284 70e11eaa Sofia Papagiannaki
                request.POST,
285 70e11eaa Sofia Papagiannaki
                chain_id=int(chain_id),
286 70e11eaa Sofia Papagiannaki
                request_user=request.user)
287 70e11eaa Sofia Papagiannaki
            with ExceptionHandler(request):
288 70e11eaa Sofia Papagiannaki
                addmembers(request, chain_id, addmembers_form)
289 70e11eaa Sofia Papagiannaki
290 70e11eaa Sofia Papagiannaki
            if addmembers_form.is_valid():
291 70e11eaa Sofia Papagiannaki
                addmembers_form = AddProjectMembersForm()  # clear form data
292 70e11eaa Sofia Papagiannaki
        else:
293 70e11eaa Sofia Papagiannaki
            addmembers_form = AddProjectMembersForm()  # initialize form
294 70e11eaa Sofia Papagiannaki
295 70e11eaa Sofia Papagiannaki
        project, application = get_by_chain_or_404(chain_id)
296 70e11eaa Sofia Papagiannaki
        if project:
297 70e11eaa Sofia Papagiannaki
            members = project.projectmembership_set.select_related()
298 70e11eaa Sofia Papagiannaki
            members_table = tables.ProjectMembersTable(project,
299 70e11eaa Sofia Papagiannaki
                                                       members,
300 70e11eaa Sofia Papagiannaki
                                                       user=request.user,
301 70e11eaa Sofia Papagiannaki
                                                       prefix="members_")
302 8998f09a Sofia Papagiannaki
            RequestConfig(request, paginate={"per_page": settings.PAGINATE_BY}
303 70e11eaa Sofia Papagiannaki
                          ).configure(members_table)
304 70e11eaa Sofia Papagiannaki
305 70e11eaa Sofia Papagiannaki
        else:
306 70e11eaa Sofia Papagiannaki
            members_table = None
307 70e11eaa Sofia Papagiannaki
308 70e11eaa Sofia Papagiannaki
    else: # is application
309 70e11eaa Sofia Papagiannaki
        application_id = chain_or_app_id
310 70e11eaa Sofia Papagiannaki
        application = get_object_or_404(ProjectApplication, pk=application_id)
311 70e11eaa Sofia Papagiannaki
        members_table = None
312 70e11eaa Sofia Papagiannaki
        addmembers_form = None
313 70e11eaa Sofia Papagiannaki
314 70e11eaa Sofia Papagiannaki
    modifications_table = None
315 70e11eaa Sofia Papagiannaki
316 70e11eaa Sofia Papagiannaki
    user = request.user
317 70e11eaa Sofia Papagiannaki
    is_project_admin = user.is_project_admin(application_id=application.id)
318 70e11eaa Sofia Papagiannaki
    is_owner = user.owns_application(application)
319 70e11eaa Sofia Papagiannaki
    if not (is_owner or is_project_admin) and not project_view:
320 70e11eaa Sofia Papagiannaki
        m = _(astakos_messages.NOT_ALLOWED)
321 70e11eaa Sofia Papagiannaki
        raise PermissionDenied(m)
322 70e11eaa Sofia Papagiannaki
323 70e11eaa Sofia Papagiannaki
    if (not (is_owner or is_project_admin) and project_view and
324 70e11eaa Sofia Papagiannaki
        not user.non_owner_can_view(project)):
325 70e11eaa Sofia Papagiannaki
        m = _(astakos_messages.NOT_ALLOWED)
326 70e11eaa Sofia Papagiannaki
        raise PermissionDenied(m)
327 70e11eaa Sofia Papagiannaki
328 70e11eaa Sofia Papagiannaki
    following_applications = list(application.pending_modifications())
329 70e11eaa Sofia Papagiannaki
    following_applications.reverse()
330 70e11eaa Sofia Papagiannaki
    modifications_table = (
331 70e11eaa Sofia Papagiannaki
        tables.ProjectModificationApplicationsTable(following_applications,
332 70e11eaa Sofia Papagiannaki
                                                    user=request.user,
333 70e11eaa Sofia Papagiannaki
                                                    prefix="modifications_"))
334 70e11eaa Sofia Papagiannaki
335 70e11eaa Sofia Papagiannaki
    mem_display = user.membership_display(project) if project else None
336 70e11eaa Sofia Papagiannaki
    can_join_req = can_join_request(project, user) if project else False
337 70e11eaa Sofia Papagiannaki
    can_leave_req = can_leave_request(project, user) if project else False
338 70e11eaa Sofia Papagiannaki
339 70e11eaa Sofia Papagiannaki
    return object_detail(
340 70e11eaa Sofia Papagiannaki
        request,
341 70e11eaa Sofia Papagiannaki
        queryset=ProjectApplication.objects.select_related(),
342 70e11eaa Sofia Papagiannaki
        object_id=application.id,
343 70e11eaa Sofia Papagiannaki
        template_name='im/projects/project_detail.html',
344 70e11eaa Sofia Papagiannaki
        extra_context={
345 70e11eaa Sofia Papagiannaki
            'project_view': project_view,
346 70e11eaa Sofia Papagiannaki
            'addmembers_form':addmembers_form,
347 70e11eaa Sofia Papagiannaki
            'members_table': members_table,
348 70e11eaa Sofia Papagiannaki
            'owner_mode': is_owner,
349 70e11eaa Sofia Papagiannaki
            'admin_mode': is_project_admin,
350 70e11eaa Sofia Papagiannaki
            'modifications_table': modifications_table,
351 70e11eaa Sofia Papagiannaki
            'mem_display': mem_display,
352 70e11eaa Sofia Papagiannaki
            'can_join_request': can_join_req,
353 70e11eaa Sofia Papagiannaki
            'can_leave_request': can_leave_req,
354 70e11eaa Sofia Papagiannaki
            })
355 70e11eaa Sofia Papagiannaki
356 70e11eaa Sofia Papagiannaki
@require_http_methods(["GET", "POST"])
357 70e11eaa Sofia Papagiannaki
@cookie_fix
358 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
359 70e11eaa Sofia Papagiannaki
def project_search(request):
360 70e11eaa Sofia Papagiannaki
    q = request.GET.get('q', '')
361 70e11eaa Sofia Papagiannaki
    form = ProjectSearchForm()
362 70e11eaa Sofia Papagiannaki
    q = q.strip()
363 70e11eaa Sofia Papagiannaki
364 70e11eaa Sofia Papagiannaki
    if request.method == "POST":
365 70e11eaa Sofia Papagiannaki
        form = ProjectSearchForm(request.POST)
366 70e11eaa Sofia Papagiannaki
        if form.is_valid():
367 70e11eaa Sofia Papagiannaki
            q = form.cleaned_data['q'].strip()
368 70e11eaa Sofia Papagiannaki
        else:
369 70e11eaa Sofia Papagiannaki
            q = None
370 70e11eaa Sofia Papagiannaki
371 70e11eaa Sofia Papagiannaki
    if q is None:
372 70e11eaa Sofia Papagiannaki
        projects = ProjectApplication.objects.none()
373 70e11eaa Sofia Papagiannaki
    else:
374 70e11eaa Sofia Papagiannaki
        accepted_projects = request.user.projectmembership_set.filter(
375 70e11eaa Sofia Papagiannaki
            ~Q(acceptance_date__isnull=True)).values_list('project', flat=True)
376 70e11eaa Sofia Papagiannaki
        projects = ProjectApplication.objects.search_by_name(q)
377 70e11eaa Sofia Papagiannaki
        projects = projects.filter(~Q(project__last_approval_date__isnull=True))
378 70e11eaa Sofia Papagiannaki
        projects = projects.exclude(project__in=accepted_projects)
379 70e11eaa Sofia Papagiannaki
380 70e11eaa Sofia Papagiannaki
    table = tables.UserProjectApplicationsTable(projects, user=request.user,
381 70e11eaa Sofia Papagiannaki
                                                prefix="my_projects_")
382 70e11eaa Sofia Papagiannaki
    if request.method == "POST":
383 70e11eaa Sofia Papagiannaki
        table.caption = _('SEARCH RESULTS')
384 70e11eaa Sofia Papagiannaki
    else:
385 70e11eaa Sofia Papagiannaki
        table.caption = _('ALL PROJECTS')
386 70e11eaa Sofia Papagiannaki
387 8998f09a Sofia Papagiannaki
    RequestConfig(request, paginate={"per_page": settings.PAGINATE_BY}).configure(table)
388 70e11eaa Sofia Papagiannaki
389 70e11eaa Sofia Papagiannaki
    return object_list(
390 70e11eaa Sofia Papagiannaki
        request,
391 70e11eaa Sofia Papagiannaki
        projects,
392 70e11eaa Sofia Papagiannaki
        template_name='im/projects/project_list.html',
393 70e11eaa Sofia Papagiannaki
        extra_context={
394 70e11eaa Sofia Papagiannaki
          'form': form,
395 70e11eaa Sofia Papagiannaki
          'is_search': True,
396 70e11eaa Sofia Papagiannaki
          'q': q,
397 70e11eaa Sofia Papagiannaki
          'table': table
398 70e11eaa Sofia Papagiannaki
        })
399 70e11eaa Sofia Papagiannaki
400 70e11eaa Sofia Papagiannaki
@require_http_methods(["POST"])
401 70e11eaa Sofia Papagiannaki
@cookie_fix
402 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
403 70e11eaa Sofia Papagiannaki
def project_join(request, chain_id):
404 70e11eaa Sofia Papagiannaki
    next = request.GET.get('next')
405 70e11eaa Sofia Papagiannaki
    if not next:
406 70e11eaa Sofia Papagiannaki
        next = reverse('astakos.im.views.project_detail',
407 70e11eaa Sofia Papagiannaki
                       args=(chain_id,))
408 70e11eaa Sofia Papagiannaki
409 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
410 70e11eaa Sofia Papagiannaki
        _project_join(request, chain_id)
411 70e11eaa Sofia Papagiannaki
412 70e11eaa Sofia Papagiannaki
413 8998f09a Sofia Papagiannaki
    next = restrict_next(next, domain=settings.COOKIE_DOMAIN)
414 70e11eaa Sofia Papagiannaki
    return redirect(next)
415 70e11eaa Sofia Papagiannaki
416 70e11eaa Sofia Papagiannaki
417 70e11eaa Sofia Papagiannaki
@commit_on_success_strict()
418 70e11eaa Sofia Papagiannaki
def _project_join(request, chain_id):
419 70e11eaa Sofia Papagiannaki
    try:
420 70e11eaa Sofia Papagiannaki
        chain_id = int(chain_id)
421 70e11eaa Sofia Papagiannaki
        auto_accepted = join_project(chain_id, request.user)
422 70e11eaa Sofia Papagiannaki
        if auto_accepted:
423 70e11eaa Sofia Papagiannaki
            m = _(astakos_messages.USER_JOINED_PROJECT)
424 70e11eaa Sofia Papagiannaki
        else:
425 70e11eaa Sofia Papagiannaki
            m = _(astakos_messages.USER_JOIN_REQUEST_SUBMITTED)
426 70e11eaa Sofia Papagiannaki
        messages.success(request, m)
427 70e11eaa Sofia Papagiannaki
    except (IOError, PermissionDenied), e:
428 70e11eaa Sofia Papagiannaki
        messages.error(request, e)
429 70e11eaa Sofia Papagiannaki
430 70e11eaa Sofia Papagiannaki
431 70e11eaa Sofia Papagiannaki
@require_http_methods(["POST"])
432 70e11eaa Sofia Papagiannaki
@cookie_fix
433 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
434 70e11eaa Sofia Papagiannaki
def project_leave(request, chain_id):
435 70e11eaa Sofia Papagiannaki
    next = request.GET.get('next')
436 70e11eaa Sofia Papagiannaki
    if not next:
437 70e11eaa Sofia Papagiannaki
        next = reverse('astakos.im.views.project_list')
438 70e11eaa Sofia Papagiannaki
439 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
440 70e11eaa Sofia Papagiannaki
        _project_leave(request, chain_id)
441 70e11eaa Sofia Papagiannaki
442 8998f09a Sofia Papagiannaki
    next = restrict_next(next, domain=settings.COOKIE_DOMAIN)
443 70e11eaa Sofia Papagiannaki
    return redirect(next)
444 70e11eaa Sofia Papagiannaki
445 70e11eaa Sofia Papagiannaki
446 70e11eaa Sofia Papagiannaki
@commit_on_success_strict()
447 70e11eaa Sofia Papagiannaki
def _project_leave(request, chain_id):
448 70e11eaa Sofia Papagiannaki
    try:
449 70e11eaa Sofia Papagiannaki
        chain_id = int(chain_id)
450 70e11eaa Sofia Papagiannaki
        auto_accepted = leave_project(chain_id, request.user)
451 70e11eaa Sofia Papagiannaki
        if auto_accepted:
452 70e11eaa Sofia Papagiannaki
            m = _(astakos_messages.USER_LEFT_PROJECT)
453 70e11eaa Sofia Papagiannaki
        else:
454 70e11eaa Sofia Papagiannaki
            m = _(astakos_messages.USER_LEAVE_REQUEST_SUBMITTED)
455 70e11eaa Sofia Papagiannaki
        messages.success(request, m)
456 70e11eaa Sofia Papagiannaki
    except (IOError, PermissionDenied), e:
457 70e11eaa Sofia Papagiannaki
        messages.error(request, e)
458 70e11eaa Sofia Papagiannaki
459 70e11eaa Sofia Papagiannaki
460 70e11eaa Sofia Papagiannaki
@require_http_methods(["POST"])
461 70e11eaa Sofia Papagiannaki
@cookie_fix
462 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
463 70e11eaa Sofia Papagiannaki
def project_cancel(request, chain_id):
464 70e11eaa Sofia Papagiannaki
    next = request.GET.get('next')
465 70e11eaa Sofia Papagiannaki
    if not next:
466 70e11eaa Sofia Papagiannaki
        next = reverse('astakos.im.views.project_list')
467 70e11eaa Sofia Papagiannaki
468 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
469 70e11eaa Sofia Papagiannaki
        _project_cancel(request, chain_id)
470 70e11eaa Sofia Papagiannaki
471 8998f09a Sofia Papagiannaki
    next = restrict_next(next, domain=settings.COOKIE_DOMAIN)
472 70e11eaa Sofia Papagiannaki
    return redirect(next)
473 70e11eaa Sofia Papagiannaki
474 70e11eaa Sofia Papagiannaki
475 70e11eaa Sofia Papagiannaki
@commit_on_success_strict()
476 70e11eaa Sofia Papagiannaki
def _project_cancel(request, chain_id):
477 70e11eaa Sofia Papagiannaki
    try:
478 70e11eaa Sofia Papagiannaki
        chain_id = int(chain_id)
479 70e11eaa Sofia Papagiannaki
        cancel_membership(chain_id, request.user)
480 70e11eaa Sofia Papagiannaki
        m = _(astakos_messages.USER_REQUEST_CANCELLED)
481 70e11eaa Sofia Papagiannaki
        messages.success(request, m)
482 70e11eaa Sofia Papagiannaki
    except (IOError, PermissionDenied), e:
483 70e11eaa Sofia Papagiannaki
        messages.error(request, e)
484 70e11eaa Sofia Papagiannaki
485 70e11eaa Sofia Papagiannaki
486 70e11eaa Sofia Papagiannaki
487 70e11eaa Sofia Papagiannaki
@require_http_methods(["POST"])
488 70e11eaa Sofia Papagiannaki
@cookie_fix
489 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
490 70e11eaa Sofia Papagiannaki
def project_accept_member(request, chain_id, memb_id):
491 70e11eaa Sofia Papagiannaki
492 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
493 70e11eaa Sofia Papagiannaki
        _project_accept_member(request, chain_id, memb_id)
494 70e11eaa Sofia Papagiannaki
495 70e11eaa Sofia Papagiannaki
    return redirect(reverse('project_detail', args=(chain_id,)))
496 70e11eaa Sofia Papagiannaki
497 70e11eaa Sofia Papagiannaki
498 70e11eaa Sofia Papagiannaki
@commit_on_success_strict()
499 70e11eaa Sofia Papagiannaki
def _project_accept_member(request, chain_id, memb_id):
500 70e11eaa Sofia Papagiannaki
    try:
501 70e11eaa Sofia Papagiannaki
        chain_id = int(chain_id)
502 70e11eaa Sofia Papagiannaki
        memb_id = int(memb_id)
503 70e11eaa Sofia Papagiannaki
        m = accept_membership(chain_id, memb_id, request.user)
504 70e11eaa Sofia Papagiannaki
    except (IOError, PermissionDenied), e:
505 70e11eaa Sofia Papagiannaki
        messages.error(request, e)
506 70e11eaa Sofia Papagiannaki
507 70e11eaa Sofia Papagiannaki
    else:
508 70e11eaa Sofia Papagiannaki
        email = escape(m.person.email)
509 70e11eaa Sofia Papagiannaki
        msg = _(astakos_messages.USER_MEMBERSHIP_ACCEPTED) % email
510 70e11eaa Sofia Papagiannaki
        messages.success(request, msg)
511 70e11eaa Sofia Papagiannaki
512 70e11eaa Sofia Papagiannaki
513 70e11eaa Sofia Papagiannaki
@require_http_methods(["POST"])
514 70e11eaa Sofia Papagiannaki
@cookie_fix
515 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
516 70e11eaa Sofia Papagiannaki
def project_remove_member(request, chain_id, memb_id):
517 70e11eaa Sofia Papagiannaki
518 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
519 70e11eaa Sofia Papagiannaki
        _project_remove_member(request, chain_id, memb_id)
520 70e11eaa Sofia Papagiannaki
521 70e11eaa Sofia Papagiannaki
    return redirect(reverse('project_detail', args=(chain_id,)))
522 70e11eaa Sofia Papagiannaki
523 70e11eaa Sofia Papagiannaki
524 70e11eaa Sofia Papagiannaki
@commit_on_success_strict()
525 70e11eaa Sofia Papagiannaki
def _project_remove_member(request, chain_id, memb_id):
526 70e11eaa Sofia Papagiannaki
    try:
527 70e11eaa Sofia Papagiannaki
        chain_id = int(chain_id)
528 70e11eaa Sofia Papagiannaki
        memb_id = int(memb_id)
529 70e11eaa Sofia Papagiannaki
        m = remove_membership(chain_id, memb_id, request.user)
530 70e11eaa Sofia Papagiannaki
    except (IOError, PermissionDenied), e:
531 70e11eaa Sofia Papagiannaki
        messages.error(request, e)
532 70e11eaa Sofia Papagiannaki
    else:
533 70e11eaa Sofia Papagiannaki
        email = escape(m.person.email)
534 70e11eaa Sofia Papagiannaki
        msg = _(astakos_messages.USER_MEMBERSHIP_REMOVED) % email
535 70e11eaa Sofia Papagiannaki
        messages.success(request, msg)
536 70e11eaa Sofia Papagiannaki
537 70e11eaa Sofia Papagiannaki
538 70e11eaa Sofia Papagiannaki
@require_http_methods(["POST"])
539 70e11eaa Sofia Papagiannaki
@cookie_fix
540 70e11eaa Sofia Papagiannaki
@valid_astakos_user_required
541 70e11eaa Sofia Papagiannaki
def project_reject_member(request, chain_id, memb_id):
542 70e11eaa Sofia Papagiannaki
543 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
544 70e11eaa Sofia Papagiannaki
        _project_reject_member(request, chain_id, memb_id)
545 70e11eaa Sofia Papagiannaki
546 70e11eaa Sofia Papagiannaki
    return redirect(reverse('project_detail', args=(chain_id,)))
547 70e11eaa Sofia Papagiannaki
548 70e11eaa Sofia Papagiannaki
549 70e11eaa Sofia Papagiannaki
@commit_on_success_strict()
550 70e11eaa Sofia Papagiannaki
def _project_reject_member(request, chain_id, memb_id):
551 70e11eaa Sofia Papagiannaki
    try:
552 70e11eaa Sofia Papagiannaki
        chain_id = int(chain_id)
553 70e11eaa Sofia Papagiannaki
        memb_id = int(memb_id)
554 70e11eaa Sofia Papagiannaki
        m = reject_membership(chain_id, memb_id, request.user)
555 70e11eaa Sofia Papagiannaki
    except (IOError, PermissionDenied), e:
556 70e11eaa Sofia Papagiannaki
        messages.error(request, e)
557 70e11eaa Sofia Papagiannaki
    else:
558 70e11eaa Sofia Papagiannaki
        email = escape(m.person.email)
559 70e11eaa Sofia Papagiannaki
        msg = _(astakos_messages.USER_MEMBERSHIP_REJECTED) % email
560 70e11eaa Sofia Papagiannaki
        messages.success(request, msg)
561 70e11eaa Sofia Papagiannaki
562 70e11eaa Sofia Papagiannaki
563 70e11eaa Sofia Papagiannaki
@require_http_methods(["POST"])
564 70e11eaa Sofia Papagiannaki
@signed_terms_required
565 70e11eaa Sofia Papagiannaki
@login_required
566 70e11eaa Sofia Papagiannaki
@cookie_fix
567 70e11eaa Sofia Papagiannaki
def project_app_approve(request, application_id):
568 70e11eaa Sofia Papagiannaki
569 70e11eaa Sofia Papagiannaki
    if not request.user.is_project_admin():
570 70e11eaa Sofia Papagiannaki
        m = _(astakos_messages.NOT_ALLOWED)
571 70e11eaa Sofia Papagiannaki
        raise PermissionDenied(m)
572 70e11eaa Sofia Papagiannaki
573 70e11eaa Sofia Papagiannaki
    try:
574 70e11eaa Sofia Papagiannaki
        app = ProjectApplication.objects.get(id=application_id)
575 70e11eaa Sofia Papagiannaki
    except ProjectApplication.DoesNotExist:
576 70e11eaa Sofia Papagiannaki
        raise Http404
577 70e11eaa Sofia Papagiannaki
578 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
579 70e11eaa Sofia Papagiannaki
        _project_app_approve(request, application_id)
580 70e11eaa Sofia Papagiannaki
581 70e11eaa Sofia Papagiannaki
    chain_id = get_related_project_id(application_id)
582 70e11eaa Sofia Papagiannaki
    return redirect(reverse('project_detail', args=(chain_id,)))
583 70e11eaa Sofia Papagiannaki
584 70e11eaa Sofia Papagiannaki
585 70e11eaa Sofia Papagiannaki
@commit_on_success_strict()
586 70e11eaa Sofia Papagiannaki
def _project_app_approve(request, application_id):
587 70e11eaa Sofia Papagiannaki
    approve_application(application_id)
588 70e11eaa Sofia Papagiannaki
589 70e11eaa Sofia Papagiannaki
590 70e11eaa Sofia Papagiannaki
@require_http_methods(["POST"])
591 70e11eaa Sofia Papagiannaki
@signed_terms_required
592 70e11eaa Sofia Papagiannaki
@login_required
593 70e11eaa Sofia Papagiannaki
@cookie_fix
594 70e11eaa Sofia Papagiannaki
def project_app_deny(request, application_id):
595 70e11eaa Sofia Papagiannaki
596 70e11eaa Sofia Papagiannaki
    reason = request.POST.get('reason', None)
597 70e11eaa Sofia Papagiannaki
    if not reason:
598 70e11eaa Sofia Papagiannaki
        reason = None
599 70e11eaa Sofia Papagiannaki
600 70e11eaa Sofia Papagiannaki
    if not request.user.is_project_admin():
601 70e11eaa Sofia Papagiannaki
        m = _(astakos_messages.NOT_ALLOWED)
602 70e11eaa Sofia Papagiannaki
        raise PermissionDenied(m)
603 70e11eaa Sofia Papagiannaki
604 70e11eaa Sofia Papagiannaki
    try:
605 70e11eaa Sofia Papagiannaki
        app = ProjectApplication.objects.get(id=application_id)
606 70e11eaa Sofia Papagiannaki
    except ProjectApplication.DoesNotExist:
607 70e11eaa Sofia Papagiannaki
        raise Http404
608 70e11eaa Sofia Papagiannaki
609 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
610 70e11eaa Sofia Papagiannaki
        _project_app_deny(request, application_id, reason)
611 70e11eaa Sofia Papagiannaki
612 70e11eaa Sofia Papagiannaki
    return redirect(reverse('project_list'))
613 70e11eaa Sofia Papagiannaki
614 70e11eaa Sofia Papagiannaki
615 70e11eaa Sofia Papagiannaki
@commit_on_success_strict()
616 70e11eaa Sofia Papagiannaki
def _project_app_deny(request, application_id, reason):
617 70e11eaa Sofia Papagiannaki
    deny_application(application_id, reason=reason)
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_dismiss(request, application_id):
625 70e11eaa Sofia Papagiannaki
    try:
626 70e11eaa Sofia Papagiannaki
        app = ProjectApplication.objects.get(id=application_id)
627 70e11eaa Sofia Papagiannaki
    except ProjectApplication.DoesNotExist:
628 70e11eaa Sofia Papagiannaki
        raise Http404
629 70e11eaa Sofia Papagiannaki
630 70e11eaa Sofia Papagiannaki
    if not request.user.owns_application(app):
631 70e11eaa Sofia Papagiannaki
        m = _(astakos_messages.NOT_ALLOWED)
632 70e11eaa Sofia Papagiannaki
        raise PermissionDenied(m)
633 70e11eaa Sofia Papagiannaki
634 70e11eaa Sofia Papagiannaki
    with ExceptionHandler(request):
635 70e11eaa Sofia Papagiannaki
        _project_app_dismiss(request, application_id)
636 70e11eaa Sofia Papagiannaki
637 70e11eaa Sofia Papagiannaki
    chain_id = None
638 70e11eaa Sofia Papagiannaki
    chain_id = get_related_project_id(application_id)
639 70e11eaa Sofia Papagiannaki
    if chain_id:
640 70e11eaa Sofia Papagiannaki
        next = reverse('project_detail', args=(chain_id,))
641 70e11eaa Sofia Papagiannaki
    else:
642 70e11eaa Sofia Papagiannaki
        next = reverse('project_list')
643 70e11eaa Sofia Papagiannaki
    return redirect(next)
644 70e11eaa Sofia Papagiannaki
645 70e11eaa Sofia Papagiannaki
646 70e11eaa Sofia Papagiannaki
def _project_app_dismiss(request, application_id):
647 70e11eaa Sofia Papagiannaki
    # XXX: dismiss application also does authorization
648 70e11eaa Sofia Papagiannaki
    dismiss_application(application_id, request_user=request.user)