Changed label and help_text for public review button on studentproposal review page.
[Melange.git] / app / soc / views / models / organization.py
blobd9564f5a9e95dc4c60fc6bb12e3a73f688993906
1 #!/usr/bin/python2.5
3 # Copyright 2008 the Melange authors.
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
9 # http://www.apache.org/licenses/LICENSE-2.0
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
17 """Views for Organizations.
18 """
20 __authors__ = [
21 '"Augie Fackler" <durin42@gmail.com>',
22 '"Sverre Rabbelier" <sverre@rabbelier.nl>',
23 '"Lennard de Rijk" <ljvderijk@gmail.com>',
27 import itertools
29 from django import forms
30 from django.utils.translation import ugettext
32 from soc.logic import cleaning
33 from soc.logic import dicts
34 from soc.logic import accounts
35 from soc.logic.models import mentor as mentor_logic
36 from soc.logic.models import organization as org_logic
37 from soc.logic.models import org_admin as org_admin_logic
38 from soc.logic.models import org_app as org_app_logic
39 from soc.logic.models import user as user_logic
40 from soc.views import helper
41 from soc.views import out_of_band
42 from soc.views.helper import access
43 from soc.views.helper import decorators
44 from soc.views.helper import dynaform
45 from soc.views.helper import lists
46 from soc.views.helper import redirects
47 from soc.views.helper import widgets
48 from soc.views.models import group
50 import soc.models.organization
51 import soc.logic.models.organization
53 class View(group.View):
54 """View methods for the Organization model.
55 """
57 def __init__(self, params=None):
58 """Defines the fields and methods required for the base View class
59 to provide the user with list, public, create, edit and delete views.
61 Params:
62 original_params: a dict with params for this View
63 """
65 from soc.views.models import program as program_view
67 rights = access.Checker(params)
68 rights['any_access'] = ['allow']
69 rights['show'] = ['allow']
70 rights['create'] = ['checkIsDeveloper']
71 rights['edit'] = [('checkHasActiveRoleForKeyFieldsAsScope',
72 org_admin_logic.logic,),
73 ('checkGroupIsActiveForLinkId', org_logic.logic)]
74 rights['delete'] = ['checkIsDeveloper']
75 rights['home'] = ['allow']
76 rights['public_list'] = ['allow']
77 rights['apply_mentor'] = ['checkIsUser']
78 rights['list_requests'] = [('checkHasActiveRoleForKeyFieldsAsScope',
79 org_admin_logic.logic)]
80 rights['list_roles'] = [('checkHasActiveRoleForKeyFieldsAsScope',
81 org_admin_logic.logic)]
82 rights['applicant'] = [('checkIsApplicationAccepted',
83 org_app_logic.logic)]
84 rights['list_proposals'] = [('checkHasAny', [
85 [('checkHasActiveRoleForKeyFieldsAsScope', [org_admin_logic.logic]),
86 ('checkHasActiveRoleForKeyFieldsAsScope', [mentor_logic.logic])]
87 ])]
89 new_params = {}
90 new_params['logic'] = soc.logic.models.organization.logic
91 new_params['rights'] = rights
93 new_params['scope_view'] = program_view
94 new_params['scope_redirect'] = redirects.getCreateRedirect
96 new_params['name'] = "Organization"
97 new_params['url_name'] = "org"
98 new_params['document_prefix'] = "org"
99 new_params['sidebar_grouping'] = 'Organizations'
101 new_params['public_template'] = 'soc/organization/public.html'
102 new_params['list_row'] = 'soc/organization/list/row.html'
103 new_params['list_heading'] = 'soc/organization/list/heading.html'
105 new_params['application_logic'] = org_app_logic
106 new_params['group_applicant_url'] = True
107 new_params['sans_link_id_public_list'] = True
109 new_params['extra_dynaexclude'] = ['slots', 'nr_applications', 'nr_mentors']
111 patterns = []
113 patterns += [
114 (r'^%(url_name)s/(?P<access_type>apply_mentor)/%(scope)s$',
115 'soc.views.models.%(module_name)s.apply_mentor',
116 "List of all %(name_plural)s you can apply to"),
117 (r'^%(url_name)s/(?P<access_type>list_proposals)/%(key_fields)s$',
118 'soc.views.models.%(module_name)s.list_proposals',
119 "List of all Student Proposals for this %(name)s"),
122 new_params['extra_django_patterns'] = patterns
124 new_params['create_dynafields'] = [
125 {'name': 'link_id',
126 'base': forms.fields.CharField,
127 'label': 'Organization Link ID',
131 new_params['create_extra_dynaproperties'] = {
132 'scope_path': forms.CharField(widget=forms.HiddenInput,
133 required=True),
134 'description': forms.fields.CharField(
135 widget=helper.widgets.FullTinyMCE(
136 attrs={'rows': 25, 'cols': 100})),
137 'contrib_template': forms.fields.CharField(
138 widget=helper.widgets.FullTinyMCE(
139 attrs={'rows': 25, 'cols': 100})),
140 'clean_description': cleaning.clean_html_content('description'),
141 'clean_contrib_template': cleaning.clean_html_content(
142 'contrib_template'),
143 'clean_ideas': cleaning.clean_url('ideas'),
144 'clean': cleaning.validate_new_group('link_id', 'scope_path',
145 soc.logic.models.organization, org_app_logic)
148 new_params['edit_extra_dynaproperties'] = {
149 'clean': cleaning.clean_refs(new_params, ['home_link_id'])
152 params = dicts.merge(params, new_params)
154 super(View, self).__init__(params=params)
156 # create and store the special form for applicants
157 updated_fields = {
158 'link_id': forms.CharField(widget=widgets.ReadOnlyInput(),
159 required=False),
160 'clean_link_id': cleaning.clean_link_id('link_id')
163 applicant_create_form = dynaform.extendDynaForm(
164 dynaform = self._params['create_form'],
165 dynaproperties = updated_fields)
167 params['applicant_create_form'] = applicant_create_form
169 @decorators.merge_params
170 @decorators.check_access
171 def applyMentor(self, request, access_type,
172 page_name=None, params=None, **kwargs):
173 """Shows a list of all organizations and you can choose one to
174 apply to become a mentor.
176 Args:
177 request: the standard Django HTTP request object
178 access_type : the name of the access type which should be checked
179 page_name: the page name displayed in templates as page and header title
180 params: a dict with params for this View
181 kwargs: the Key Fields for the specified entity
184 list_params = params.copy()
185 list_params['list_action'] = (redirects.getRequestRedirectForRole, 'mentor')
186 list_params['list_description'] = ugettext('Choose an Organization which '
187 'you want to become a Mentor for.')
189 filter = {'scope_path': kwargs['scope_path'],
190 'status' : 'active'}
192 return self.list(request, access_type,
193 page_name, params=list_params, filter=filter)
195 @decorators.merge_params
196 @decorators.check_access
197 def listProposals(self, request, access_type,
198 page_name=None, params=None, **kwargs):
199 """Lists all proposals for the organization given in kwargs.
201 For params see base.View.public().
204 from soc.logic.models.ranker_root import logic as ranker_root_logic
205 from soc.models import student_proposal
206 from soc.views.helper import list_info as list_info_helper
207 from soc.views.models import student_proposal as student_proposal_view
209 try:
210 org_entity = self._logic.getFromKeyFieldsOr404(kwargs)
211 except out_of_band.Error, error:
212 return helper.responses.errorResponse(
213 error, request, template=params['error_public'])
215 context = {}
216 context['entity'] = org_entity
218 list_params = student_proposal_view.view.getParams().copy()
219 list_params['list_template'] = 'soc/student_proposal/list_for_org.html'
221 ranked_params = list_params.copy()# ranked proposals
222 ranked_params['list_row'] = ('soc/%(module_name)s/list/'
223 'detailed_row.html' % list_params)
224 ranked_params['list_heading'] = ('soc/%(module_name)s/list/'
225 'detailed_heading.html' % list_params)
226 ranked_params['list_description'] = '%s already under review sent to %s' % (
227 ranked_params['name_plural'], org_entity.name)
228 ranked_params['list_action'] = (redirects.getReviewRedirect, ranked_params)
230 # TODO(ljvderijk) once sorting with IN operator is fixed,
231 # make this list show more
232 filter = {'org': org_entity,
233 'status': 'pending'}
235 # order by descending score
236 order = ['-score']
238 prop_list = lists.getListContent(
239 request, ranked_params, filter, order=order, idx=0)
241 proposals = prop_list['data']
243 # get a list of scores
244 scores = [[proposal.score] for proposal in proposals]
246 # retrieve the ranker
247 fields = {'link_id': student_proposal.DEF_RANKER_NAME,
248 'scope': org_entity}
250 ranker_root = ranker_root_logic.getForFields(fields, unique=True)
251 ranker = ranker_root_logic.getRootFromEntity(ranker_root)
253 # retrieve the ranks for these scores
254 ranks = [rank+1 for rank in ranker.FindRanks(scores)]
256 # link the proposals to the rank
257 ranking = dict([i for i in itertools.izip(proposals, ranks)])
259 assigned_proposals = []
261 # only when the program allows allocations
262 # to be seen we should color the list
263 if org_entity.scope.allocations_visible:
264 # get the limit and offset for the list
265 _, offset = lists.getLimitAndOffset(request, 'offset_0', 'limit_0')
267 # determine the amount of proposals to color
268 to_color = max(0, org_entity.slots - offset)
269 assigned_proposals = proposals[0:to_color]
271 # show the amount of slots assigned on the webpage
272 context['slots_visible'] = True
274 # update the prop_list with the ranking and coloring information
275 prop_list['info'] = (list_info_helper.getStudentProposalInfo(ranking,
276 assigned_proposals), None)
278 new_params = list_params.copy() # new proposals
279 new_params['list_description'] = 'List of new %s sent to %s ' % (
280 new_params['name_plural'], org_entity.name)
281 new_params['list_action'] = (redirects.getReviewRedirect, new_params)
283 filter = {'org': org_entity,
284 'status': 'new'}
286 contents = []
287 new_list = lists.getListContent(
288 request, new_params, filter, idx=1, need_content=True)
290 ip_params = list_params.copy() # ineligible proposals
292 description = ugettext('List of ineligible %s sent to %s ') % (
293 ip_params['name_plural'], org_entity.name)
295 ip_params['list_description'] = description
296 ip_params['list_action'] = (redirects.getReviewRedirect, ip_params)
298 filter = {'org': org_entity,
299 'status': 'invalid'}
301 ip_list = lists.getListContent(
302 request, ip_params, filter, idx=1, need_content=True)
304 # fill contents with all the needed lists
305 if new_list != None:
306 contents.append(new_list)
308 contents.append(prop_list)
310 if ip_list != None:
311 contents.append(ip_list)
313 # call the _list method from base to display the list
314 return self._list(request, list_params, contents, page_name, context)
316 @decorators.merge_params
317 @decorators.check_access
318 def listPublic(self, request, access_type, page_name=None,
319 params=None, filter=None, **kwargs):
320 """See base.View.list.
323 account = accounts.getCurrentAccount()
324 user = user_logic.logic.getForAccount(account) if account else None
326 try:
327 rights = self._params['rights']
328 rights.setCurrentUser(account, user)
329 rights.checkIsHost()
330 is_host = True
331 except out_of_band.Error:
332 is_host = False
334 new_params = {}
336 if is_host:
337 new_params['list_action'] = (redirects.getAdminRedirect, params)
338 else:
339 new_params['list_action'] = (redirects.getPublicRedirect, params)
340 # safe to merge them the wrong way around because of @merge_params
341 params = dicts.merge(new_params, params)
343 new_filter = {}
345 new_filter['scope_path'] = kwargs['scope_path']
346 new_filter['status'] = 'active'
347 filter = dicts.merge(filter, new_filter)
349 content = lists.getListContent(request, params, filter)
350 contents = [content]
352 return self._list(request, params, contents, page_name)
354 def _getExtraMenuItems(self, role_description, params=None):
355 """Used to create the specific Organization menu entries.
357 For args see group.View._getExtraMenuItems().
359 submenus = []
361 group_entity = role_description['group']
362 roles = role_description['roles']
364 if roles.get('org_admin') or roles.get('mentor'):
365 # add a link to view all the student proposals
366 submenu = (redirects.getListProposalsRedirect(group_entity, params),
367 "View all Student Proposals", 'any_access')
368 submenus.append(submenu)
371 if roles.get('org_admin'):
372 # add a link to the management page
373 submenu = (redirects.getListRolesRedirect(group_entity, params),
374 "Manage Admins and Mentors", 'any_access')
375 submenus.append(submenu)
377 # add a link to invite an org admin
378 submenu = (redirects.getInviteRedirectForRole(group_entity, 'org_admin'),
379 "Invite an Admin", 'any_access')
380 submenus.append(submenu)
382 # add a link to invite a member
383 submenu = (redirects.getInviteRedirectForRole(group_entity, 'mentor'),
384 "Invite a Mentor", 'any_access')
385 submenus.append(submenu)
387 # add a link to the request page
388 submenu = (redirects.getListRequestsRedirect(group_entity, params),
389 "List Requests and Invites", 'any_access')
390 submenus.append(submenu)
392 # add a link to the edit page
393 submenu = (redirects.getEditRedirect(group_entity, params),
394 "Edit Organization Profile", 'any_access')
395 submenus.append(submenu)
397 if roles.get('org_admin') or roles.get('mentor'):
398 submenu = (redirects.getCreateDocumentRedirect(group_entity, 'org'),
399 "Create a New Document", 'any_access')
400 submenus.append(submenu)
402 submenu = (redirects.getListDocumentsRedirect(group_entity, 'org'),
403 "List Documents", 'any_access')
404 submenus.append(submenu)
407 if roles.get('org_admin'):
408 # add a link to the resign page
409 submenu = (redirects.getManageRedirect(roles['org_admin'],
410 {'url_name': 'org_admin'}),
411 "Resign as Admin", 'any_access')
412 submenus.append(submenu)
414 # add a link to the edit page
415 submenu = (redirects.getEditRedirect(roles['org_admin'],
416 {'url_name': 'org_admin'}),
417 "Edit My Admin Profile", 'any_access')
418 submenus.append(submenu)
421 if roles.get('mentor'):
422 # add a link to the resign page
423 submenu = (redirects.getManageRedirect(roles['mentor'],
424 {'url_name' : 'mentor'}),
425 "Resign as Mentor", 'any_access')
426 submenus.append(submenu)
428 # add a link to the edit page
429 submenu = (redirects.getEditRedirect(roles['mentor'],
430 {'url_name': 'mentor'}),
431 "Edit My Mentor Profile", 'any_access')
432 submenus.append(submenu)
434 return submenus
437 view = View()
439 admin = decorators.view(view.admin)
440 applicant = decorators.view(view.applicant)
441 apply_mentor = decorators.view(view.applyMentor)
442 create = decorators.view(view.create)
443 delete = decorators.view(view.delete)
444 edit = decorators.view(view.edit)
445 home = decorators.view(view.home)
446 list = decorators.view(view.list)
447 list_proposals = decorators.view(view.listProposals)
448 list_public = decorators.view(view.listPublic)
449 list_requests = decorators.view(view.listRequests)
450 list_roles = decorators.view(view.listRoles)
451 public = decorators.view(view.public)
452 export = decorators.view(view.export)
453 pick = decorators.view(view.pick)