28 from django import forms |
28 from django import forms |
29 from django import http |
29 from django import http |
30 |
30 |
31 from soc.logic import cleaning |
31 from soc.logic import cleaning |
32 from soc.logic import dicts |
32 from soc.logic import dicts |
|
33 from soc.logic.models import mentor as mentor_logic |
33 from soc.logic.models import organization as org_logic |
34 from soc.logic.models import organization as org_logic |
|
35 from soc.logic.models import org_admin as org_admin_logic |
34 from soc.logic.models import student as student_logic |
36 from soc.logic.models import student as student_logic |
35 from soc.logic.models import user as user_logic |
37 from soc.logic.models import user as user_logic |
|
38 from soc.views import helper |
|
39 from soc.views import out_of_band |
36 from soc.views.helper import access |
40 from soc.views.helper import access |
37 from soc.views.helper import decorators |
41 from soc.views.helper import decorators |
38 from soc.views.helper import dynaform |
42 from soc.views.helper import dynaform |
39 from soc.views.helper import params as params_helper |
43 from soc.views.helper import params as params_helper |
40 from soc.views.helper import redirects |
44 from soc.views.helper import redirects |
|
45 from soc.views.helper import responses |
41 from soc.views.helper import widgets |
46 from soc.views.helper import widgets |
42 from soc.views.models import base |
47 from soc.views.models import base |
43 from soc.views.models import student as student_view |
48 from soc.views.models import student as student_view |
44 |
49 |
45 import soc.logic.models.student_proposal |
50 import soc.logic.models.student_proposal |
96 (r'^%(url_name)s/(?P<access_type>list_self)/%(scope)s$', |
103 (r'^%(url_name)s/(?P<access_type>list_self)/%(scope)s$', |
97 'soc.views.models.%(module_name)s.list_self', |
104 'soc.views.models.%(module_name)s.list_self', |
98 'List my %(name_plural)s'), |
105 'List my %(name_plural)s'), |
99 (r'^%(url_name)s/(?P<access_type>list_orgs)/%(scope)s$', |
106 (r'^%(url_name)s/(?P<access_type>list_orgs)/%(scope)s$', |
100 'soc.views.models.%(module_name)s.list_orgs', |
107 'soc.views.models.%(module_name)s.list_orgs', |
101 'List my %(name_plural)s') |
108 'List my %(name_plural)s'), |
|
109 (r'^%(url_name)s/(?P<access_type>review)/%(key_fields)s$', |
|
110 'soc.views.models.%(module_name)s.review', |
|
111 'Review %(name)s'), |
102 ] |
112 ] |
103 |
113 |
104 new_params['extra_django_patterns'] = patterns |
114 new_params['extra_django_patterns'] = patterns |
105 |
115 |
106 new_params['extra_dynaexclude'] = ['org', 'program', 'score', |
116 new_params['extra_dynaexclude'] = ['org', 'program', 'score', |
107 'status', 'mentor', 'link_id',] |
117 'status', 'mentor', 'link_id', |
|
118 'possible_mentors'] |
108 |
119 |
109 new_params['create_extra_dynaproperties'] = { |
120 new_params['create_extra_dynaproperties'] = { |
110 'content': forms.fields.CharField(required=True, |
121 'content': forms.fields.CharField(required=True, |
111 widget=widgets.FullTinyMCE(attrs={'rows': 25, 'cols': 100})), |
122 widget=widgets.FullTinyMCE(attrs={'rows': 25, 'cols': 100})), |
112 'scope_path': forms.CharField(widget=forms.HiddenInput, |
123 'scope_path': forms.CharField(widget=forms.HiddenInput, |
147 dynaform=self._params['create_form'], |
159 dynaform=self._params['create_form'], |
148 dynaproperties=dynaproperties) |
160 dynaproperties=dynaproperties) |
149 |
161 |
150 params['student_create_form'] = student_create_form |
162 params['student_create_form'] = student_create_form |
151 |
163 |
|
164 # create the special form for mentors |
|
165 dynafields = [ |
|
166 {'name': 'score', |
|
167 'base': forms.ChoiceField, |
|
168 'label': 'Score', |
|
169 'initial': 0, |
|
170 'required': False, |
|
171 'passthrough': ['initial', 'required', 'choices'], |
|
172 'choices': [(-4,'-4: Wow. This. Sucks.'), |
|
173 (-3,'-3: Needs a lot of work'), |
|
174 (-2,'-2: This is bad'), |
|
175 (-1,'-1: I dont like this'), |
|
176 (0,'0: No score'), |
|
177 (1,'1: Might have potential'), |
|
178 (2,'2: Good'), |
|
179 (3,'3: Almost there'), |
|
180 (4,'4: Made. Of. Awesome.')] |
|
181 }, |
|
182 {'name': 'comment', |
|
183 'base': forms.CharField, |
|
184 'widget': forms.Textarea, |
|
185 'label': 'Comment', |
|
186 'required': False, |
|
187 }, |
|
188 {'name': 'public', |
|
189 'base': forms.BooleanField, |
|
190 'label': 'Public comment', |
|
191 'initial': False, |
|
192 'required': False, |
|
193 }, |
|
194 ] |
|
195 |
|
196 dynaproperties = params_helper.getDynaFields(dynafields) |
|
197 |
|
198 mentor_review_form = dynaform.newDynaForm(dynamodel=None, dynabase=helper.forms.BaseForm, |
|
199 dynainclude=None, dynaexclude=None, dynaproperties=dynaproperties) |
|
200 params['mentor_review_form'] = mentor_review_form |
|
201 |
|
202 # TODO see if autocomplete can be used for this field |
|
203 dynafields = [ |
|
204 {'name': 'mentor', |
|
205 'base': forms.CharField, |
|
206 'label': 'Assign Mentor (Link ID)', |
|
207 'required': False |
|
208 }, |
|
209 ] |
|
210 |
|
211 dynaproperties = params_helper.getDynaFields(dynafields) |
|
212 |
|
213 admin_review_form = dynaform.extendDynaForm(dynaform=mentor_review_form, dynaproperties=dynaproperties) |
|
214 |
|
215 params['admin_review_form'] = admin_review_form |
152 |
216 |
153 def _editGet(self, request, entity, form): |
217 def _editGet(self, request, entity, form): |
154 """See base.View._editGet(). |
218 """See base.View._editGet(). |
155 """ |
219 """ |
156 |
220 |
306 list_params = params.copy() |
370 list_params = params.copy() |
307 list_params['list_description'] = 'List of my %(name_plural)s' % list_params |
371 list_params['list_description'] = 'List of my %(name_plural)s' % list_params |
308 |
372 |
309 return self.list(request, access_type=access_type, page_name=page_name, |
373 return self.list(request, access_type=access_type, page_name=page_name, |
310 params=list_params, filter=filter, **kwargs) |
374 params=list_params, filter=filter, **kwargs) |
|
375 |
|
376 |
|
377 @decorators.merge_params |
|
378 @decorators.check_access |
|
379 def review(self, request, access_type, |
|
380 page_name=None, params=None, **kwargs): |
|
381 """View that allows Organization Admins and Mentors to review the proposal. |
|
382 |
|
383 For Args see base.View.public(). |
|
384 """ |
|
385 |
|
386 try: |
|
387 entity = self._logic.getFromKeyFieldsOr404(kwargs) |
|
388 except out_of_band.Error, error: |
|
389 return helper.responses.errorResponse( |
|
390 error, request, template=params['error_public']) |
|
391 |
|
392 # get the context for this webpage |
|
393 context = responses.getUniversalContext(request) |
|
394 responses.useJavaScript(context, params['js_uses_all']) |
|
395 context['page_name'] = page_name |
|
396 |
|
397 context['student_name'] = entity.scope.name() |
|
398 |
|
399 if entity.mentor: |
|
400 context['mentor_name'] = entity.mentor.name() |
|
401 else: |
|
402 context['mentor_name'] = "No mentor assigned" |
|
403 |
|
404 context['entity'] = entity |
|
405 context['entity_type'] = params['name'] |
|
406 context['entity_type_url'] = params['url_name'] |
|
407 |
|
408 # get the roles important for reviewing an application |
|
409 filter = {'user': user_logic.logic.getForCurrentAccount(), |
|
410 'scope': entity.org, |
|
411 'status': 'active',} |
|
412 |
|
413 org_admin_entity = org_admin_logic.logic.getForFields(filter, unique=True) |
|
414 mentor_entity = mentor_logic.logic.getForFields(filter, unique=True) |
|
415 |
|
416 # check if the current user is a mentor and wants to change his role for this app |
|
417 choice = request.GET.get('mentor') |
|
418 if mentor_entity and choice: |
|
419 self._adjustPossibleMentors(entity, mentor_entity, choice) |
|
420 |
|
421 # set the possible mentors in the context |
|
422 possible_mentors = entity.possible_mentors |
|
423 |
|
424 if not possible_mentors: |
|
425 context['possible_mentors'] = "None" |
|
426 else: |
|
427 mentor_names = [] |
|
428 |
|
429 for mentor_key in possible_mentors: |
|
430 mentor = mentor_logic.logic.getFromKeyName(mentor_key.name()) |
|
431 mentor_names.append(mentor.name()) |
|
432 |
|
433 context['possible_mentors'] = ', '.join(mentor_names) |
|
434 |
|
435 # decide which form to use |
|
436 if org_admin_entity: |
|
437 form = params['admin_review_form'] |
|
438 else: |
|
439 form = params['mentor_review_form'] |
|
440 |
|
441 if request.method == 'POST': |
|
442 return self.reviewPost(request, context, params, entity, |
|
443 form, org_admin_entity, mentor_entity, **kwargs) |
|
444 else: |
|
445 # request.method == 'GET' |
|
446 return self.reviewGet(request, context, params, entity, |
|
447 form, org_admin_entity, mentor_entity, **kwargs) |
|
448 |
|
449 def reviewPost(self, request, context, params, entity, form, |
|
450 org_admin, mentor, **kwargs): |
|
451 """Handles the POST request for the proposal review view. |
|
452 |
|
453 Args: |
|
454 entity: the student proposal entity |
|
455 form: the form to use in this view |
|
456 org_admin: org admin entity for the current user/proposal (iff available) |
|
457 mentor: mentor entity for the current user/proposal (iff available) |
|
458 rest: see base.View.public() |
|
459 """ |
|
460 # populate the form using the POST data |
|
461 form = form(request.POST) |
|
462 |
|
463 if not form.is_valid(): |
|
464 # return the invalid form response |
|
465 return self._constructResponse(request, entity=entity, context=context, |
|
466 form=form, params=params, template=params['review_template']) |
|
467 |
|
468 fields = form.cleaned_data |
|
469 |
|
470 if org_admin: |
|
471 # org admin found, try to adjust the assigned mentor |
|
472 self._adjustMentor(entity, fields['mentor']) |
|
473 |
|
474 is_public = fields['public'] |
|
475 comment = fields['comment'] |
|
476 given_score = int(fields['score']) |
|
477 |
|
478 if not is_public and given_score is not 0: |
|
479 # if it is not a public comment we use the score and display |
|
480 # an additional message in the comment |
|
481 new_score = given_score + entity.score |
|
482 |
|
483 name = 'Someone' |
|
484 |
|
485 if org_admin: |
|
486 name = org_admin.name() |
|
487 elif mentor: |
|
488 name = mentor.name() |
|
489 |
|
490 # TODO(ljvderijk) hook up comments |
|
491 comment = '%s has given %i points \n %s' %(name, given_score, comment) |
|
492 |
|
493 # update the proposal with the new score |
|
494 self._logic.updateEntityProperties(entity, {'score': new_score}) |
|
495 |
|
496 # redirect to the same page |
|
497 return http.HttpResponseRedirect('') |
|
498 |
|
499 def reviewGet(self, request, context, params, entity, form, |
|
500 org_admin, mentor, **kwargs): |
|
501 """Handles the GET request for the proposal review view. |
|
502 |
|
503 Args: |
|
504 entity: the student proposal entity |
|
505 form: the form to use in this view |
|
506 org_admin: org admin entity for the current user/proposal (iff available) |
|
507 mentor: mentor entity for the current user/proposal (iff available) |
|
508 rest: see base.View.public() |
|
509 """ |
|
510 |
|
511 initial = {} |
|
512 |
|
513 if org_admin and entity.mentor: |
|
514 initial['mentor'] = entity.mentor.link_id |
|
515 |
|
516 context['form'] = form(initial) |
|
517 template = params['review_template'] |
|
518 context['mentor'] = mentor |
|
519 |
|
520 return responses.respond(request, template, context=context) |
|
521 |
|
522 def _adjustPossibleMentors(self, entity, mentor, choice): |
|
523 """Adjusts the possible mentors list for a proposal. |
|
524 |
|
525 Args: |
|
526 entity: Student Proposal entity |
|
527 mentor: Mentor entity |
|
528 choice: 1 means want to mentor, 0 do not want to mentor |
|
529 """ |
|
530 possible_mentors = entity.possible_mentors |
|
531 |
|
532 if choice == '1': |
|
533 # add the mentor to possible mentors list if not already in |
|
534 if mentor.key() not in possible_mentors: |
|
535 possible_mentors.append(mentor.key()) |
|
536 fields = {'possible_mentors': possible_mentors} |
|
537 self._logic.updateEntityProperties(entity, fields) |
|
538 elif choice == '0': |
|
539 # remove the mentor from the possible mentors list |
|
540 if mentor.key() in possible_mentors: |
|
541 possible_mentors.remove(mentor.key()) |
|
542 fields = {'possible_mentors': possible_mentors} |
|
543 self._logic.updateEntityProperties(entity, fields) |
|
544 |
|
545 def _adjustMentor(self, entity, mentor_id): |
|
546 """Changes the mentor to the given link_id. |
|
547 |
|
548 Args: |
|
549 entity: Student Proposal entity |
|
550 mentor_id: Link ID of the mentor that needs to be assigned |
|
551 Iff not given then removes the assigned mentor |
|
552 """ |
|
553 |
|
554 if entity.mentor and entity.mentor.link_id == mentor_id: |
|
555 # no need to change |
|
556 return |
|
557 |
|
558 if mentor_id: |
|
559 # try to locate the mentor |
|
560 fields = {'link_id': mentor_id, |
|
561 'scope': entity.org, |
|
562 'status': 'active'} |
|
563 |
|
564 mentor_entity = mentor_logic.logic.getForFields(fields, unique=True) |
|
565 |
|
566 if not mentor_entity: |
|
567 # no mentor found, do not update |
|
568 return |
|
569 else: |
|
570 # reset to None |
|
571 mentor_entity = None |
|
572 |
|
573 # update the proposal |
|
574 properties = {'mentor': mentor_entity} |
|
575 self._logic.updateEntityProperties(entity, properties) |
311 |
576 |
312 view = View() |
577 view = View() |
313 |
578 |
314 admin = decorators.view(view.admin) |
579 admin = decorators.view(view.admin) |
315 apply = decorators.view(view.apply) |
580 apply = decorators.view(view.apply) |