# HG changeset patch # User Lennard de Rijk # Date 1236439368 0 # Node ID 3ec1a95184525ebe7b1f533923d65c790515f58a # Parent bfdef9380954f0770321ec664aee584f926cf4e1 Added the review capability to the student_proposal review page. Note that editing of reviews still is not allowed, and Students can't read/respond yet. Patch by: Lennard de Rijk Reviewed by: to-be-reviewed diff -r bfdef9380954 -r 3ec1a9518452 app/index.yaml --- a/app/index.yaml Sat Mar 07 15:19:53 2009 +0000 +++ b/app/index.yaml Sat Mar 07 15:22:48 2009 +0000 @@ -7,6 +7,12 @@ - name: score direction: desc +- kind: Review + properties: + - name: is_public + - name: scope + - name: modified + # AUTOGENERATED # This index.yaml is automatically updated whenever the dev_appserver diff -r bfdef9380954 -r 3ec1a9518452 app/soc/templates/soc/student_proposal/review.html --- a/app/soc/templates/soc/student_proposal/review.html Sat Mar 07 15:19:53 2009 +0000 +++ b/app/soc/templates/soc/student_proposal/review.html Sat Mar 07 15:22:48 2009 +0000 @@ -13,6 +13,7 @@ limitations under the License. {% endcomment %} {% load forms_helpers %} +{% load comments_helpers %} {% block header_title %} {{ page_name }} "{{ entity.title }}" from {{ student_name }} (Score: {{ entity.score }}) @@ -26,15 +27,21 @@ {% readonly_field_as_table_row "Mentor" mentor_name %} {% readonly_field_as_table_row "Possible Mentors" possible_mentors %} {% readonly_field_as_twoline_table_row entity.fields.abstract.label entity.abstract %} - {% readonly_field_as_twoline_table_row entity.fields.content.label entity.content %} + {% readonly_safe_field_as_twoline_table_row entity.fields.content.label entity.content %} {% readonly_field_as_table_row "Created on" entity.created_on %} {% readonly_field_as_table_row "Last Modified on" entity.last_modified_on %}


-Public Comments +Public Reviews +{% for review in public_reviews %} + {% as_review review %} +{% endfor %}
-Private Comments +Private Reviews +{% for review in private_reviews %} + {% as_review review %} +{% endfor %}
diff -r bfdef9380954 -r 3ec1a9518452 app/soc/views/models/student_proposal.py --- a/app/soc/views/models/student_proposal.py Sat Mar 07 15:19:53 2009 +0000 +++ b/app/soc/views/models/student_proposal.py Sat Mar 07 15:22:48 2009 +0000 @@ -183,7 +183,7 @@ }, {'name': 'comment', 'base': forms.CharField, - 'widget': forms.Textarea, + 'widget': widgets.FullTinyMCE(attrs={'rows': 10, 'cols': 40}), 'label': 'Comment', 'required': False, }, @@ -398,14 +398,6 @@ context = responses.getUniversalContext(request) responses.useJavaScript(context, params['js_uses_all']) context['page_name'] = page_name - - context['student_name'] = entity.scope.name() - - if entity.mentor: - context['mentor_name'] = entity.mentor.name() - else: - context['mentor_name'] = "No mentor assigned" - context['entity'] = entity context['entity_type'] = params['name'] context['entity_type_url'] = params['url_name'] @@ -454,6 +446,10 @@ if not form.is_valid(): # return the invalid form response + # get all the extra information that should be in the context + review_context = self._getDefaultReviewContext(entity, org_admin, mentor) + context = dicts.merge(context, review_context) + return self._constructResponse(request, entity=entity, context=context, form=form, params=params, template=params['review_template']) @@ -462,24 +458,20 @@ if org_admin: # org admin found, try to adjust the assigned mentor self._adjustMentor(entity, fields['mentor']) + reviewer = org_admin + else: + # might be None (if Host or Developer is commenting) + reviewer = mentor is_public = fields['public'] comment = fields['comment'] given_score = int(fields['score']) - if (org_admin or mentor) and (not is_public) and (given_score is not 0): + if reviewer and (not is_public) and (given_score is not 0): # if it is not a public comment and it's made by a member of the - # organization we score and display an additional message in the comment + # organization we update the score of the proposal new_score = given_score + entity.score - if org_admin: - name = org_admin.name() - elif mentor: - name = mentor.name() - - # TODO(ljvderijk) hook up comments - comment = '%s has given %i points \n %s' % (name, given_score, comment) - properties = {'score': new_score} # if the proposal is new we change it status to pending @@ -489,6 +481,10 @@ # update the proposal with the new score self._logic.updateEntityProperties(entity, properties) + # create the review entity + if comment or (given_score is not 0): + self._createReviewFor(entity, reviewer, comment, given_score, is_public) + # redirect to the same page return http.HttpResponseRedirect('') @@ -512,8 +508,36 @@ initial['mentor'] = entity.mentor.link_id context['form'] = form(initial) + + # get all the extra information that should be in the context + review_context = self._getDefaultReviewContext(entity, org_admin, mentor) + context = dicts.merge(context, review_context) + template = params['review_template'] + return responses.respond(request, template, context=context) + + def _getDefaultReviewContext(self, entity, org_admin, + mentor): + """Returns the default context for the review page + + Args: + entity: Student Proposal entity + org_admin: org admin entity for the current user/proposal (iff available) + mentor: mentor entity for the current user/proposal (iff available) + """ + + from soc.logic.models.review import logic as review_logic + + context = {} + + context['student_name'] = entity.scope.name() + + if entity.mentor: + context['mentor_name'] = entity.mentor.name() + else: + context['mentor_name'] = "No mentor assigned" + # set the possible mentors in the context possible_mentors = entity.possible_mentors @@ -523,11 +547,30 @@ mentor_names = [] for mentor_key in possible_mentors: - mentor = mentor_logic.logic.getFromKeyName(mentor_key.name()) - mentor_names.append(mentor.name()) + possible_mentor = mentor_logic.logic.getFromKeyName(mentor_key.name()) + mentor_names.append(possible_mentor.name()) context['possible_mentors'] = ', '.join(mentor_names) + # TODO(ljvderijk) listing of total given scores per mentor + # a dict with key as role.user ? + + # get the public reviews + fields = {'scope': entity, + 'is_public': True} + + order = ['modified'] + + query = review_logic.getQueryForFields(filter=fields, order=order) + context['public_reviews'] = review_logic.getAll(query) + + # get the private reviews + fields['is_public'] = False + + query = review_logic.getQueryForFields(filter=fields, order=order) + context['private_reviews'] = review_logic.getAll(query) + + # which button should we show to the mentor? if mentor: if mentor.key() in possible_mentors: # show "No longer willing to mentor" @@ -536,7 +579,7 @@ # show "I am willing to mentor" context['add_me_as_mentor'] = True - return responses.respond(request, template, context=context) + return context def _adjustPossibleMentors(self, entity, mentor, choice): """Adjusts the possible mentors list for a proposal. @@ -593,6 +636,43 @@ properties = {'mentor': mentor_entity} self._logic.updateEntityProperties(entity, properties) + def _createReviewFor(self, entity, reviewer, comment, score, is_public): + """Creates a review for the given proposal. + + Args: + entity: Student Proposal entity for which the review should be created + reviewer: A role entity of the reviewer (if possible, else None) + comment: The textual contents of the review + score: The score of the review (only used if the review is not public) + is_public: Determines if the review is a public review + + Returns: + - The newly created review + """ + + import time + + from soc.logic.models.review import logic as review_logic + + # create the fields for the review entity + fields = {'link_id': 't%i' %(time.time()), + 'scope': entity, + 'scope_path': entity.key().name(), + 'author': user_logic.logic.getForCurrentAccount(), + 'content': comment, + 'is_public': is_public, + 'reviewer': reviewer + } + + # add the given score if the review is not public + if not is_public: + fields['score'] = score + + key_name = review_logic.getKeyNameFromFields(fields) + + return review_logic.updateOrCreateFromKeyName(fields, key_name) + + view = View() admin = decorators.view(view.admin)