Added the review capability to the student_proposal review page.
authorLennard de Rijk <ljvderijk@gmail.com>
Sat, 07 Mar 2009 15:22:48 +0000
changeset 1715 3ec1a9518452
parent 1714 bfdef9380954
child 1716 a387bb7a39d4
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
app/index.yaml
app/soc/templates/soc/student_proposal/review.html
app/soc/views/models/student_proposal.py
--- 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
--- 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 %}
  </table>
 </p>
 <hr>
-<b>Public Comments</b>
+<b>Public Reviews</b>
+{% for review in public_reviews %}
+  {% as_review review %}
+{% endfor %}
 <hr>
-<b>Private Comments</b>
+<b>Private Reviews</b>
+{% for review in private_reviews %}
+  {% as_review review %}
+{% endfor %}
 <hr>
 
 <form method="POST">
--- 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)