Added Menu items for all three kinds of Surveys to the program menu.
authorJames Levy <jamesalexanderlevy@gmail.com>
Sun, 05 Jul 2009 11:32:26 +0200
changeset 2543 4c95d717a976
parent 2542 a9dec4763c6b
child 2544 8f3a8e066111
Added Menu items for all three kinds of Surveys to the program menu. The menu items turn red when the user has not taken the Survey yet. Patch by: James Levy, Lennard de Rijk Reviewed by: to-be-reviewed
app/soc/views/helper/access.py
app/soc/views/helper/redirects.py
app/soc/views/models/program.py
app/soc/views/models/survey.py
--- a/app/soc/views/helper/access.py	Sun Jul 05 00:57:03 2009 +0200
+++ b/app/soc/views/helper/access.py	Sun Jul 05 11:32:26 2009 +0200
@@ -1571,7 +1571,7 @@
 
   @denySidebar
   @allowDeveloper
-  def checkIsSurveyTakeable(self, django_args, survey_logic):
+  def checkIsSurveyTakeable(self, django_args, survey_logic, check_time=True):
     """Checks if the survey specified in django_args can be taken.
 
     Uses survey.taking_access to map that string onto a check. Also checks for
@@ -1586,6 +1586,8 @@
 
     Args:
       survey_logic: SurveyLogic instance (or subclass)
+      check_time: iff True checks if the current date is between the survey
+        start and end date.
     """
 
     if django_args['prefix'] != 'program':
@@ -1596,7 +1598,7 @@
     survey = survey_logic.getFromKeyFieldsOr404(django_args)
 
     # check if the survey can be taken now
-    if not timeline_helper.isActivePeriod(survey, 'survey'):
+    if check_time and not timeline_helper.isActivePeriod(survey, 'survey'):
       raise out_of_band.AccessViolation(message_fmt=DEF_PAGE_INACTIVE_MSG)
 
     # retrieve the role that is allowed to take this survey
--- a/app/soc/views/helper/redirects.py	Sun Jul 05 00:57:03 2009 +0200
+++ b/app/soc/views/helper/redirects.py	Sun Jul 05 11:32:26 2009 +0200
@@ -361,6 +361,21 @@
   return '/%s/list/%s/%s' % (url_name, prefix, entity.key().id_or_name())
 
 
+def getTakeSurveyRedirect(entity, info):
+  """Returns the redirect for taking a Survey .
+
+  Args:
+      entity: a Survey entity
+      info: a dictionary contain a survey and params entry
+  """
+
+  survey_entity = entity
+  params = info
+
+  return '/%s/take/%s' % (params['url_name'],
+                                     survey_entity.key().id_or_name())
+
+
 def getTakeProjectSurveyRedirect(entity, info):
   """Returns the redirect for taking a Survey for the given Student Project.
 
--- a/app/soc/views/models/program.py	Sun Jul 05 00:57:03 2009 +0200
+++ b/app/soc/views/models/program.py	Sun Jul 05 11:32:26 2009 +0200
@@ -52,7 +52,6 @@
 from soc.views.models import presence
 from soc.views.models import document as document_view
 from soc.views.models import sponsor as sponsor_view
-from soc.views.models import survey as survey_view
 from soc.views.sitemap import sidebar
 
 import soc.cache.logic
@@ -620,6 +619,10 @@
       params: a dict with params for this View.
     """
 
+    from soc.views.models import survey as survey_view
+    from soc.views.models import project_survey as project_survey_view
+    from soc.views.models import grading_project_survey as grading_survey_view
+
     logic = params['logic']
     rights = params['rights']
 
@@ -637,8 +640,12 @@
       if entity.status == 'visible':
         # show the documents for this program, even for not logged in users
         items += document_view.view.getMenusForScope(entity, params)
+        items += survey_view.view.getMenusForScope(entity, params, id, user)
+        items += project_survey_view.view.getMenusForScope(
+            entity, params, id, user)
+        items += grading_survey_view.view.getMenusForScope(
+            entity, params, id, user)
         items += self._getTimeDependentEntries(entity, params, id, user)
-
       try:
         # check if the current user is a host for this program
         rights.doCachedCheck('checkIsHostForProgram',
@@ -648,6 +655,11 @@
         if entity.status == 'invisible':
           # still add the document links so hosts can see how it looks like
           items += document_view.view.getMenusForScope(entity, params)
+          items += survey_view.view.getMenusForScope(entity, params, id, user)
+          items += project_survey_view.view.getMenusForScope(
+              entity, params, id, user)
+          items += grading_survey_view.view.getMenusForScope(
+              entity, params, id, user)
           items += self._getTimeDependentEntries(entity, params, id, user)
 
         items += [(redirects.getReviewOverviewRedirect(
--- a/app/soc/views/models/survey.py	Sun Jul 05 00:57:03 2009 +0200
+++ b/app/soc/views/models/survey.py	Sun Jul 05 11:32:26 2009 +0200
@@ -35,6 +35,7 @@
 
 from soc.logic import cleaning
 from soc.logic import dicts
+from soc.logic.helper import timeline
 from soc.logic.models.survey import logic as survey_logic
 from soc.logic.models.user import logic as user_logic
 from soc.models.survey import Survey
@@ -93,9 +94,6 @@
       params: a dict with params for this View
     """
 
-    # TODO: read/write access needs to match survey
-    # TODO: usage requirements
-
     rights = access.Checker(params)
     rights['any_access'] = ['allow']
     rights['show'] = [('checkIsSurveyWritable', survey_logic)]
@@ -285,6 +283,7 @@
       fields['survey_content'] = survey_content
 
     fields['modified_by'] = user
+
     super(View, self)._editPost(request, entity, fields)
 
   def loadSurveyContent(self, schema, survey_fields, entity):
@@ -639,6 +638,7 @@
     """
     pass
 
+
   def setHelpAndStatus(self, context, survey, survey_record):
     """Get help_text and status for template use.
 
@@ -807,6 +807,94 @@
 
     return entity, context
 
+  def getMenusForScope(self, entity, params, id, user):
+    """List featured surveys if after the survey_start date 
+    and before survey_end an iff the current user has the right taking access.
+
+    Args:
+      entity: entity which is the scope for a Survey
+      params: params from the requesting View
+      id: GAE user instance for the current user
+      user: User entity from the current user
+    """
+
+    # only list surveys for registered users
+    if not user:
+      return []
+
+    survey_params = self.getParams().copy()
+    survey_logic = survey_params['logic']
+    record_logic = survey_logic.getRecordLogic()
+
+    # filter all featured surveys for the given entity
+    filter = {
+        'prefix' : params['url_name'],
+        'scope_path': entity.key().id_or_name(),
+        'is_featured': True,
+        }
+
+    survey_entities = survey_logic.getForFields(filter)
+    submenus = []
+
+    # get the rights checker
+    rights = self._params['rights']
+    rights.setCurrentUser(id, user)
+
+    # cache ACL
+    survey_rights = {}
+
+    # add a link to all featured active surveys the user can take
+    for survey_entity in survey_entities:
+
+      if survey_entity.taking_access not in survey_rights:
+        # we have not determined if this user has the given type of access
+
+        # check if the current user is allowed to visit the take Survey page
+        allowed_to_take = False
+
+        rights.checkIsSurveyTakeable(
+            {'key_name': survey_entity.key().name(),
+             'prefix': survey_entity.prefix,
+             'scope_path': survey_entity.scope_path,
+             'link_id': survey_entity.link_id,
+             'user': user},
+            survey_logic,
+            check_time=False)
+        allowed_to_take = True
+        # cache ACL for a given entity.taking_access
+        survey_rights[survey_entity.taking_access] = allowed_to_take
+
+        if not allowed_to_take:
+          # not allowed to take this survey
+          continue
+
+      elif not survey_rights[survey_entity.taking_access]:
+        # we already determined that the user doens't have access to this type
+        continue
+
+      if not timeline.isActivePeriod(survey_entity, 'survey'):
+        # this survey is not active right now
+        continue
+
+      # check if any SurveyRecord is available for this survey
+      filter = {'survey': survey_entity,
+                'user': user}
+
+      survey_record = record_logic.getForFields(filter, unique=True)
+
+      if survey_record:
+        taken_status = ""
+      else:
+        # no SurveyRecord available so we mark the survey as new
+        taken_status = "(new)"
+
+      submenu = (redirects.getTakeSurveyRedirect(survey_entity, survey_params),
+                 'Survey ' + taken_status + ': ' + survey_entity.short_name,
+                 'show')
+
+      submenus.append(submenu)
+    return submenus
+
 
 view = View()