fixed critical errors related to survey subclassing and renaming of deadline and opening properties, and surveys in sidebar are now marked as such and have a red color if untaken
authorjames@jamess-macbook-air.local
Tue, 30 Jun 2009 03:02:53 -0700
changeset 2455 a023b71ce125
parent 2454 849956450d69
child 2458 467ec0cf3ece
fixed critical errors related to survey subclassing and renaming of deadline and opening properties, and surveys in sidebar are now marked as such and have a red color if untaken
app/soc/content/js/menu-081108.js
app/soc/logic/models/survey.py
app/soc/views/models/survey.py
--- a/app/soc/content/js/menu-081108.js	Tue Jun 30 00:06:53 2009 +0200
+++ b/app/soc/content/js/menu-081108.js	Tue Jun 30 03:02:53 2009 -0700
@@ -1,12 +1,22 @@
 $(function() {
-  $('#side #menu li.expandable > a').dblclick(function() {
+
+   var new_item_text = "(new)"
+   $('#menu li.expandable').find('a').each(function(){
+     if ($(this).text().indexOf(new_item_text) > -1)
+     $(this).css('color', 'red');
+   });
+   
+   $('#side #menu li.expandable > a').dblclick(function() {
     window.location = $(this).attr('href');
   })
   $('#side #menu li.expandable > span').toggle(function() {
-    $(this).find("img").attr('src', '/soc/content/images/plus.gif').end().parent().children("ul").toggle();
+    $(this).find("img").attr('src', '/soc/content/images/plus.gif')
+    .end().parent().children("ul").toggle();
   }, function() {
-    $(this).find("img").attr('src', '/soc/content/images/minus.gif').end().parent().children("ul").toggle();
+    $(this).find("img").attr('src', '/soc/content/images/minus.gif')
+    .end().parent().children("ul").toggle();
     return false;
   });
-  $('#side #menu li.expandable > span').contents().before('<img src="/soc/content/images/minus.gif" />');
+  $('#side #menu li.expandable > span').contents()
+  .before('<img src="/soc/content/images/minus.gif" />');
 });  
--- a/app/soc/logic/models/survey.py	Tue Jun 30 00:06:53 2009 +0200
+++ b/app/soc/logic/models/survey.py	Tue Jun 30 03:02:53 2009 -0700
@@ -430,7 +430,58 @@
     super(Logic, self).__init__(model=model, base_model=base_model,
                                 scope_logic=scope_logic)
 
+class ResultsLogic(work.Logic):
+  """Logic methods for the Survey model
+  """
+
+  def __init__(self, model=SurveyRecord,
+               base_model=Work, scope_logic=linkable_logic):
+    """Defines the name, key_name and model for this entity.
+    """
+
+    super(ResultsLogic, self).__init__(model=model, base_model=base_model,
+                                scope_logic=scope_logic)
+
+  def getKeyValuesFromEntity(self, entity):
+    """See base.Logic.getKeyNameValues.
+    """
+
+    return [entity.prefix, entity.scope_path, entity.link_id]
+
+  def getKeyValuesFromFields(self, fields):
+    """See base.Logic.getKeyValuesFromFields.
+    """
+
+    return [fields['prefix'], fields['scope_path'], fields['link_id']]
+
+  def getKeyFieldNames(self):
+    """See base.Logic.getKeyFieldNames.
+    """
+
+    return ['prefix', 'scope_path', 'link_id']
+
+  def isDeletable(self, entity):
+    """See base.Logic.isDeletable.
+    """
+
+    return not entity.home_for
+
+  def _updateField(self, entity, entity_properties, name):
+    """Special logic for role. If state changes to active we flush the sidebar.
+    """
+
+    value = entity_properties[name]
+
+    if (name == 'is_featured') and (entity.is_featured != value):
+      sidebar.flush()
+
+    home_for = entity.home_for
+    if (name != 'home_for') and home_for:
+      home.flush(home_for)
+    return True
+
 
 logic = Logic()
 project_logic = ProjectLogic()
 grading_logic = GradingProjectLogic()
+results_logic = ResultsLogic()
--- a/app/soc/views/models/survey.py	Tue Jun 30 00:06:53 2009 +0200
+++ b/app/soc/views/models/survey.py	Tue Jun 30 03:02:53 2009 -0700
@@ -22,28 +22,23 @@
   '"James Levy" <jamesalexanderlevy@gmail.com>',
   ]
 
-
 import csv
 import datetime
 import re
 import StringIO
 import string
-
-from google.appengine.ext import db
-
 from django import forms
 from django import http
 from django.utils import simplejson
 
+from google.appengine.ext import db
+
 from soc.cache import home
 from soc.logic import cleaning
 from soc.logic import dicts
+from soc.logic.models.survey import logic as survey_logic
+from soc.logic.models.survey import results_logic
 from soc.logic.models.survey import GRADES
-from soc.logic.models.survey import logic as survey_logic
-from soc.logic.models.survey import project_logic
-from soc.logic.models.survey import grading_logic
-from soc.logic.models.survey_record import logic as results_logic
-from soc.logic.models.survey_record import updateSurveyRecord
 from soc.logic.models.user import logic as user_logic
 from soc.models.survey import Survey
 from soc.models.survey_record import SurveyRecord
@@ -102,15 +97,15 @@
 
     rights = access.Checker(params)
     rights['any_access'] = ['allow']
-    rights['show'] = [('checkIsSurveyReadable', survey_logic)]
+    rights['show'] = ['checkIsSurveyReadable']
     rights['create'] = ['checkIsUser']
-    rights['edit'] = [('checkIsSurveyWritable', survey_logic)]
-    rights['delete'] = [('checkIsSurveyWritable', survey_logic)]
+    rights['edit'] = ['checkIsSurveyWritable']
+    rights['delete'] = ['checkIsSurveyWritable']
     rights['list'] = ['checkDocumentList']
     rights['pick'] = ['checkDocumentPick']
+    rights['grade'] = ['checkIsSurveyGradable']
 
     new_params = {}
-    # TODO(ajaksu) pass logic in a way views can use them
     new_params['logic'] = survey_logic
     new_params['rights'] = rights
 
@@ -127,6 +122,9 @@
         (r'^%(url_name)s/(?P<access_type>results)/%(scope)s$',
          'soc.views.models.%(module_name)s.results',
          'View survey results for %(name)s'),
+        (r'^%(url_name)s/(?P<access_type>show)/user/(?P<link_id>)\w+$',
+         'soc.views.models.%(module_name)s.results',
+         'View survey results for user'),
         ]
 
     new_params['export_content_type'] = 'text/text'
@@ -198,11 +196,13 @@
   def _public(self, request, entity, context):
     """Survey taking and result display handler.
 
+
     Args:
       request: the django request object
       entity: the entity to make public
       context: the context object
 
+
     -- Taking Survey Pages Are Not 'Public' --
 
     For surveys, the "public" page is actually the access-protected
@@ -221,7 +221,7 @@
 
     --- Deadlines ---
 
-    A deadline can also be used as a conditional for updating values,
+    A survey_end can also be used as a conditional for updating values,
     we have a special read_only UI and a check on the POST handler for this.
     Passing read_only=True here allows one to fetch the read_only view.
     """
@@ -271,12 +271,12 @@
       else:
         # save/update the submitted survey
         context['notice'] = "Survey Submission Saved"
-        survey_record = updateSurveyRecord(user, survey, survey_record,
-                                           request.POST)
+        survey_record = survey_logic.updateSurveyRecord(user, survey,
+        survey_record, request.POST)
     survey_content = survey.survey_content
 
     if not survey_record and read_only:
-      # no recorded answers, we're either past deadline or want to see answers
+      # no recorded answers, we're either past survey_end or want to see answers
       is_same_user = user.key() == user_logic.getForCurrentAccount().key()
 
       if not can_write or not is_same_user:
@@ -309,7 +309,7 @@
     return True
 
   def getStatus(self, request, context, user, survey):
-    """Determine if the survey is available for taking, check user rights.
+    """Determine if we're past survey_end or before survey_start, check user rights.
     """
 
     read_only = (context.get("read_only", False) or
@@ -318,9 +318,9 @@
                  )
     now = datetime.datetime.now()
 
-    # check survey end date, see check for start below
+    # check survey_end, see check for survey_start below
     if survey.survey_end and now > survey.survey_end:
-      # are we already passed the deadline?
+      # are we already passed the survey_end?
       context["notice"] = "The Deadline For This Survey Has Passed"
       read_only = True
 
@@ -331,12 +331,13 @@
     rights = self._params['rights']
     can_write = access.Checker.hasMembership(rights, roles, params)
 
+
     not_ready = False
-    # check if we're past the start date
+    # check if we're past the survey_start date
     if survey.survey_start and now < survey.survey_start:
       not_ready = True
 
-      # only users that can edit a survey should see it before it can be taken
+      # only users that can edit a survey should see it before survey_start
       if not can_write:
         context["notice"] = "There is no such survey available."
         return False
@@ -352,16 +353,16 @@
 
     if not read_only:
       if not survey.survey_end:
-        deadline_text = ""
+        survey_end_text = ""
       else:
-        deadline_text = " by " + str(
+        survey_end_text = " by " + str(
       survey.survey_end.strftime("%A, %d. %B %Y %I:%M%p"))
 
       if survey_record:
-        help_text = "Edit and re-submit this survey" + deadline_text + "."
+        help_text = "Edit and re-submit this survey" + survey_end_text + "."
         status = "edit"
       else:
-        help_text = "Please complete this survey" + deadline_text + "."
+        help_text = "Please complete this survey" + survey_end_text + "."
         status = "create"
 
     else:
@@ -640,13 +641,13 @@
 
     params['edit_form'] = HelperForm(params['edit_form'])
     if entity.survey_end and datetime.datetime.now() > entity.survey_end:
-      # are we already passed the survey end date?
-      context["passed_deadline"] = True
+      # are we already passed the survey_end?
+      context["passed_survey_end"] = True
 
     return super(View, self).editGet(request, entity, context, params=params)
 
   def getMenusForScope(self, entity, params):
-    """List featured surveys iff after they are availble to be taken.
+    """List featured surveys if after the survey_start date and before survey_end.
     """
 
     # only list surveys for registered users
@@ -686,26 +687,28 @@
         survey_rights[entity.read_access] = can_read
 
         if not can_read:
-          continue
+          pass#continue
 
       elif not survey_rights[entity.read_access]:
-        continue
+        pass#continue
 
-      # omit if either before start or after end
+      # omit if either before survey_start or after survey_end
       if entity.survey_start and entity.survey_start > now:
-        continue
+        pass#continue
 
       if entity.survey_end and entity.survey_end < now:
-        continue
+        pass#continue
 
+      taken_status = ""
+      taken_status = "(new)"
       #TODO only if a document is readable it might be added
       submenu = (redirects.getPublicRedirect(entity, self._params),
-                 entity.short_name, 'show')
+      'Survey ' +  taken_status + ': ' + entity.short_name,
+      'show')
 
       submenus.append(submenu)
     return submenus
 
-  # TODO the following two methods should move to GradingProjectSurvey
   def activate(self, request, **kwargs):
     """This is a hack to support the 'Enable grades' button.
     """
@@ -729,47 +732,55 @@
     """View for SurveyRecord and SurveyRecordGroup.
     """
 
-    entity, context = self.getContextEntity(request, page_name, params, kwargs)
-
-    if context is None:
-      # user cannot see this page, return error response
-      return entity
-
-    can_write = False
-    rights = self._params['rights']
-    try:
-      rights.checkIsSurveyWritable({'key_name': entity.key().name(),
-                                    'prefix': entity.prefix,
-                                    'scope_path': entity.scope_path,
-                                    'link_id': entity.link_id,},
-                                   'key_name')
-      can_write = True
-    except out_of_band.AccessViolation:
-      pass
-
     user = user_logic.getForCurrentAccount()
 
-    filter = self._params.get('filter') or {}
-
-    # if user can edit the survey, show everyone's results
-    if can_write:
-      filter['survey'] = entity
+    # TODO(ajaksu) use the named parameter link_id from the re
+    if request.path == '/survey/show/user/' + user.link_id:
+      records = tuple(user.surveys_taken.run())
+      context = responses.getUniversalContext(request)
+      context['content'] = records[0].survey.survey_content
+      responses.useJavaScript(context, params['js_uses_all'])
+      context['page_name'] = u'Your survey records.'
     else:
-      filter.update({'user': user, 'survey': entity})
+      entity, context = self.getContextEntity(request, page_name,
+                                              params, kwargs)
 
-    limit = self._params.get('limit') or 1000
-    offset = self._params.get('offset') or 0
-    order = self._params.get('order') or []
-    idx = self._params.get('idx') or 0
+      if context is None:
+        # user cannot see this page, return error response
+        return entity
+      context['content'] = entity.survey_content
+      can_write = False
+      rights = self._params['rights']
+      try:
+        rights.checkIsSurveyWritable({'key_name': entity.key().name(),
+                                      'prefix': entity.prefix,
+                                      'scope_path': entity.scope_path,
+                                      'link_id': entity.link_id,},
+                                     'key_name')
+        can_write = True
+      except out_of_band.AccessViolation:
+        pass
 
-    records = results_logic.getForFields(filter=filter, limit=limit,
-                                      offset=offset, order=order)
+      filter = self._params.get('filter') or {}
+
+      # if user can edit the survey, show everyone's results
+      if can_write:
+        filter['survey'] = entity
+      else:
+        filter.update({'user': user, 'survey': entity})
+
+      limit = self._params.get('limit') or 1000
+      offset = self._params.get('offset') or 0
+      order = self._params.get('order') or []
+      idx = self._params.get('idx') or 0
+
+      records = results_logic.getForFields(filter=filter, limit=limit,
+                                        offset=offset, order=order)
 
     updates = dicts.rename(params, params['list_params'])
     context.update(updates)
 
     context['results'] = records, records
-    context['content'] = entity.survey_content
 
     template = 'soc/survey/results_page.html'
     return responses.respond(request, template, context=context)
@@ -911,13 +922,13 @@
   properties = leading + survey.survey_content.orderedProperties()
 
   try:
-    first = survey.getRecords().run().next()
+    first = survey.survey_records.run().next()
   except StopIteration:
     # bail out early if survey_records.run() is empty
     return header, survey.link_id
 
   # generate results list
-  recs = survey.getRecords().run()
+  recs = survey.survey_records.run()
   recs = _get_records(recs, properties)
 
   # write results to CSV