Changed label and help_text for public review button on studentproposal review page.
[Melange.git] / app / soc / views / models / org_app.py
blob6e6ddd8a973958ec30a1ba4fadc01354d10507d2
1 #!/usr/bin/python2.5
3 # Copyright 2009 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 Organization App profiles.
18 """
20 __authors__ = [
21 '"Lennard de Rijk" <ljvderijk@gmail.com>',
25 import os
27 from django import forms
28 from django.utils import simplejson
30 from soc.logic import accounts
31 from soc.logic import cleaning
32 from soc.logic import dicts
33 from soc.logic import mail_dispatcher
34 from soc.logic import models as model_logic
35 from soc.logic.models import program as program_logic
36 from soc.logic.models import org_app as org_app_logic
37 from soc.views import helper
38 from soc.views.helper import access
39 from soc.views.helper import decorators
40 from soc.views.helper import redirects
41 from soc.views.helper import responses
42 from soc.views.helper import widgets
43 from soc.views.models import group_app
44 from soc.views.models import program as program_view
47 class View(group_app.View):
48 """View methods for the Organization Application model.
49 """
51 def __init__(self, params=None):
52 """Defines the fields and methods required for the base View class
53 to provide the user with list, public, create, edit and delete views.
55 Params:
56 params: a dict with params for this View
57 """
59 rights = access.Checker(params)
60 rights['create'] = ['checkIsDeveloper']
61 rights['delete'] = [('checkCanEditGroupApp',
62 [org_app_logic.logic]),
63 ('checkIsActivePeriod', ['org_signup', 'scope_path'])]
64 rights['edit'] = [('checkCanEditGroupApp',
65 [org_app_logic.logic]),
66 ('checkIsActivePeriod', ['org_signup', 'scope_path'])]
67 rights['list'] = ['checkIsDeveloper']
68 rights['list_self'] = ['checkIsUser']
69 rights['show'] = ['allow']
70 rights['review'] = ['checkIsHostForProgramInScope',
71 ('checkCanReviewGroupApp', [org_app_logic.logic])]
72 rights['review_overview'] = ['checkIsHostForProgramInScope']
73 rights['bulk_accept'] = ['checkIsHostForProgramInScope']
74 rights['bulk_reject'] = ['checkIsHostForProgramInScope']
75 rights['apply'] = ['checkIsUser',
76 ('checkCanCreateOrgApp', ['org_signup']),
77 'checkIsNotStudentForProgramInScope']
79 new_params = {}
81 new_params['rights'] = rights
82 new_params['logic'] = org_app_logic.logic
84 new_params['scope_view'] = program_view
85 new_params['scope_redirect'] = redirects.getCreateRedirect
87 new_params['sidebar_grouping'] = 'Organizations'
89 new_params['list_key_order'] = [
90 'link_id', 'scope_path', 'name', 'home_page', 'email',
91 'description', 'why_applying','pub_mailing_list','irc_channel',
92 'member_criteria', 'prior_participation', 'prior_application',
93 'license_name', 'ideas', 'dev_mailing_list', 'contrib_template',
94 'contrib_disappears', 'member_disappears', 'encourage_contribs',
95 'continued_contribs']
97 patterns = [(r'^%(url_name)s/(?P<access_type>apply)/%(scope)s$',
98 'soc.views.models.%(module_name)s.create',
99 'Create an %(name_plural)s'),
100 (r'^%(url_name)s/(?P<access_type>bulk_accept)/%(scope)s$',
101 'soc.views.models.%(module_name)s.bulk_accept',
102 'Bulk Acceptation of %(name_plural)s'),
103 (r'^%(url_name)s/(?P<access_type>bulk_reject)/%(scope)s$',
104 'soc.views.models.%(module_name)s.bulk_reject',
105 'Bulk Rejection of %(name_plural)s'),]
107 new_params['extra_django_patterns'] = patterns
108 new_params['extra_key_order'] = ['admin_agreement',
109 'agreed_to_admin_agreement']
111 new_params['extra_dynaexclude'] = ['applicant', 'backup_admin', 'status',
112 'created_on', 'last_modified_on']
114 new_params['create_dynafields'] = [
115 {'name': 'link_id',
116 'base': forms.fields.CharField,
117 'label': 'Organization Link ID',
121 new_params['create_extra_dynaproperties'] = {
122 'scope_path': forms.fields.CharField(widget=forms.HiddenInput,
123 required=True),
124 'contrib_template': forms.fields.CharField(
125 widget=helper.widgets.FullTinyMCE(
126 attrs={'rows': 25, 'cols': 100})),
127 'description': forms.fields.CharField(
128 widget=helper.widgets.FullTinyMCE(
129 attrs={'rows': 25, 'cols': 100})),
130 'admin_agreement': forms.fields.Field(required=False,
131 widget=widgets.AgreementField),
132 'agreed_to_admin_agreement': forms.fields.BooleanField(
133 initial=False, required=True),
135 'clean_description': cleaning.clean_html_content('description'),
136 'clean_contrib_template': cleaning.clean_html_content(
137 'contrib_template'),
138 'clean_ideas': cleaning.clean_url('ideas'),
139 'clean': cleaning.validate_new_group('link_id', 'scope_path',
140 model_logic.organization, org_app_logic)}
142 # get rid of the clean method
143 new_params['edit_extra_dynaproperties'] = {
144 'clean': (lambda x: x.cleaned_data)}
146 new_params['name'] = "Organization Application"
147 new_params['name_plural'] = "Organization Applications"
148 new_params['name_short'] = "Org App"
149 new_params['url_name'] = "org_app"
150 new_params['group_name'] = "Organization"
151 new_params['group_url_name'] = 'org'
153 new_params['review_template'] = 'soc/org_app/review.html'
154 # TODO use a proper template that works for each program
155 new_params['accepted_mail_template'] = \
156 'soc/org_app/mail/accepted_gsoc2009.html'
157 new_params['rejected_mail_template'] = 'soc/org_app/mail/rejected.html'
159 params = dicts.merge(params, new_params)
161 super(View, self).__init__(params=params)
163 @ decorators.merge_params
164 def reviewOverview(self, request, access_type,
165 page_name=None, params=None, **kwargs):
166 """View that allows to see organization application review overview.
168 For Args see base.View.public().
171 params['list_template'] = 'soc/org_app/review_overview.html'
172 context = {
173 'bulk_accept_link': '/org_app/bulk_accept/%(scope_path)s' % (kwargs),
174 'bulk_reject_link': '/org_app/bulk_reject/%(scope_path)s' % (kwargs),}
176 return super(View, self).reviewOverview(request, access_type,
177 page_name=page_name, params=params, context=context, **kwargs)
179 def _editContext(self, request, context):
180 """See base.View._editContext.
183 entity = context['entity']
184 form = context['form']
186 if 'scope_path' in form.initial:
187 scope_path = form.initial['scope_path']
188 elif 'scope_path' in request.POST:
189 scope_path = request.POST['scope_path']
190 else:
191 del form.fields['admin_agreement']
192 return
194 entity = program_logic.logic.getFromKeyName(scope_path)
196 if not (entity and entity.org_admin_agreement):
197 return
199 agreement = entity.org_admin_agreement
201 content = agreement.content
202 params = {'url_name': 'document'}
204 widget = form.fields['admin_agreement'].widget
205 widget.text = content
206 widget.url = redirects.getPublicRedirect(agreement, params)
208 def _review(self, request, params, app_entity, status, **kwargs):
209 """Sends out an email if an org_app has been accepted or rejected.
211 For params see group_app.View._review().
214 if status == 'accepted' or status == 'rejected':
216 default_sender = mail_dispatcher.getDefaultMailSender()
218 if not default_sender:
219 # no default sender abort
220 return
221 else:
222 (sender_name, sender) = default_sender
224 # construct the contents of the email
225 user_entity = app_entity.applicant
226 to = accounts.denormalizeAccount(user_entity.account).email()
228 context = {'sender': sender,
229 'to': to,
230 'sender_name': sender_name,
231 'to_name': user_entity.name,
232 'program_name': app_entity.scope.name,
233 'org_app_name': app_entity.name}
235 if status == 'accepted':
236 # use the accepted template and subject
237 template = params['accepted_mail_template']
238 context['subject'] = 'Congratulations!'
239 context['HTTP_host'] = 'http://%s' % (os.environ['HTTP_HOST'])
240 elif status == 'rejected':
241 # use the rejected template and subject
242 template = params['rejected_mail_template']
243 context['subject'] = 'Thank you for your application'
245 # send out the constructed email
246 mail_dispatcher.sendMailFromTemplate(template, context)
248 @decorators.merge_params
249 @decorators.check_access
250 def bulkAccept(self, request, access_type,
251 page_name=None, params=None, **kwargs):
252 """Returns a HTTP Response containing JSON information needed
253 to bulk-accept orgs.
256 program_keyname = kwargs['scope_path']
257 return self._bulkReview(request, params, 'pre-accepted', 'accepted',
258 program_keyname)
260 @decorators.merge_params
261 @decorators.check_access
262 def bulkReject(self, request, access_type,
263 page_name=None, params=None, **kwargs):
264 """Returns a HTTP Response containing JSON information needed
265 to bulk-accept orgs.
268 program_keyname = kwargs['scope_path']
269 return self._bulkReview(request, params, 'pre-rejected', 'rejected',
270 program_keyname)
272 def _bulkReview(self, request, params, from_status, to_status,
273 program_keyname):
274 """Returns a HTTP Response containing JSON information needed
275 to bulk-review organization applications.
277 Args:
278 request: Standard Django HTTP Request object
279 params: Params for this view
280 from_status: The status for the applications which should
281 be reviewed (can be a list)
282 to_status: The status to which all applications should be changed to
283 program_keyname: The keyname for the program to which
284 the application belongs
287 # get the program entity from the keyname
288 program_entity = program_logic.logic.getFromKeyName(program_keyname)
290 # get all the organization applications for the
291 # given program and from_status
292 filter = {'scope': program_entity,
293 'status': from_status}
295 org_app_entities = params['logic'].getForFields(filter=filter)
297 # convert each application into a dictionary containing only the fields
298 # given by the dict_filter
299 dict_filter = ['link_id', 'name']
300 org_apps = [dicts.filter(i.toDict(), dict_filter) for i in org_app_entities]
302 to_json = {
303 'program' : program_entity.name,
304 'nr_applications' : len(org_apps),
305 'application_type' : params['name_plural'],
306 'applications': org_apps,
307 'link' : '/%s/review/%s/(link_id)?status=%s' %(
308 params['url_name'] ,program_entity.key().name(), to_status),
311 json = simplejson.dumps(to_json)
313 # use the standard JSON template to return our response
314 context = {'json': json}
315 template = 'soc/json.html'
317 return responses.respond(request, template, context)
320 view = View()
322 admin = decorators.view(view.admin)
323 bulk_accept = decorators.view(view.bulkAccept)
324 bulk_reject = decorators.view(view.bulkReject)
325 create = decorators.view(view.create)
326 delete = decorators.view(view.delete)
327 edit = decorators.view(view.edit)
328 list = decorators.view(view.list)
329 list_self = decorators.view(view.listSelf)
330 public = decorators.view(view.public)
331 export = decorators.view(view.export)
332 review = decorators.view(view.review)
333 review_overview = decorators.view(view.reviewOverview)