app/soc/views/models/survey.py
changeset 2473 5cf0625dfa73
parent 2472 def87d97596d
child 2474 b8e25769880d
equal deleted inserted replaced
2472:def87d97596d 2473:5cf0625dfa73
    95     # TODO: read/write access needs to match survey
    95     # TODO: read/write access needs to match survey
    96     # TODO: usage requirements
    96     # TODO: usage requirements
    97 
    97 
    98     rights = access.Checker(params)
    98     rights = access.Checker(params)
    99     rights['any_access'] = ['allow']
    99     rights['any_access'] = ['allow']
   100     rights['show'] = [('checkIsSurveyReadable', survey_logic)]
   100     rights['show'] = [('checkIsSurveyWritable', survey_logic)]
   101     rights['create'] = ['checkIsUser']
   101     rights['create'] = ['checkIsUser']
   102     rights['edit'] = [('checkIsSurveyWritable', survey_logic)]
   102     rights['edit'] = [('checkIsSurveyWritable', survey_logic)]
   103     rights['delete'] = [('checkIsSurveyWritable', survey_logic)]
   103     rights['delete'] = ['checkIsDeveloper'] # TODO: fix deletion of Surveys
   104     rights['list'] = ['checkDocumentList']
   104     rights['list'] = ['checkDocumentList']
   105     rights['pick'] = ['checkDocumentPick']
   105     rights['pick'] = ['checkDocumentPick']
   106 
   106 
   107     new_params = {}
   107     new_params = {}
   108     new_params['logic'] = survey_logic
   108     new_params['logic'] = survey_logic
   189 
   189 
   190     return super(View, self).list(request, access_type, page_name=page_name,
   190     return super(View, self).list(request, access_type, page_name=page_name,
   191                                   params=params, filter=kwargs)
   191                                   params=params, filter=kwargs)
   192 
   192 
   193   def _public(self, request, entity, context):
   193   def _public(self, request, entity, context):
   194     """Survey taking and result display handler.
   194     """Add a preview version of the Survey to the page's context.
   195 
       
   196 
   195 
   197     Args:
   196     Args:
   198       request: the django request object
   197       request: the django request object
   199       entity: the entity to make public
   198       entity: the entity to make public
   200       context: the context object
   199       context: the context object
   201 
   200     """
   202 
   201 
   203     -- Taking Survey Pages Are Not 'Public' --
   202     # construct the form to be shown on the page
   204 
   203     # TODO(ljvderijk) Generate SurveyForm without passing along the logic
   205     For surveys, the "public" page is actually the access-protected
   204     survey_form = surveys.SurveyForm(survey_content=entity.survey_content,
   206     survey-taking page.
   205                                      survey_logic=self._params['logic'])
   207 
   206 
   208     -- SurveyProjectGroups --
   207     # TOOD(ljvderijk) pose question about the getFields method name and working
   209 
       
   210     Each survey can be taken once per user per project.
       
   211 
       
   212     This means that MidtermGSOC2009 can be taken once for a student
       
   213     for a project, and once for a mentor for each project they are
       
   214     mentoring.
       
   215 
       
   216     The project selected while taking a survey determines how this_user
       
   217     SurveyRecord will be linked to other SurveyRecords.
       
   218 
       
   219     --- Deadlines ---
       
   220 
       
   221     A survey_end can also be used as a conditional for updating values,
       
   222     we have a special read_only UI and a check on the POST handler for this.
       
   223     Passing read_only=True here allows one to fetch the read_only view.
       
   224     """
       
   225 
       
   226     # check ACL
       
   227     rights = self._params['rights']
       
   228     rights.checkIsSurveyReadable({'key_name': entity.key().name(),
       
   229                                   'prefix': entity.prefix,
       
   230                                   'scope_path': entity.scope_path,
       
   231                                   'link_id': entity.link_id,},
       
   232                                  'key_name')
       
   233 
       
   234     survey = entity
       
   235     user = user_logic.getForCurrentAccount()
       
   236 
       
   237     status = self.getStatus(request, context, user, survey)
       
   238     read_only, can_write, not_ready = status
       
   239 
       
   240     # If user can edit this survey and is requesting someone else's results,
       
   241     # in a read-only request, we fetch them.
       
   242     if can_write and read_only and 'user_results' in request.GET:
       
   243       user = user_logic.getFromKeyNameOr404(request.GET['user_results'])
       
   244 
       
   245     if not_ready and not can_write:
       
   246       context['notice'] = "No survey available."
       
   247       return False
       
   248     elif not_ready:
       
   249       return False
       
   250     else:
       
   251       # check for existing survey_record
       
   252       record_query = SurveyRecord.all(
       
   253       ).filter("user =", user
       
   254       ).filter("survey =", survey)
       
   255       # get project from GET arg
       
   256       if request._get.get('project'):
       
   257         import soc.models.student_project
       
   258         project = soc.models.student_project.StudentProject.get(
       
   259         request._get.get('project'))
       
   260         record_query = record_query.filter("project =", project)
       
   261       else:
       
   262         project = None
       
   263       survey_record = record_query.get()
       
   264 
       
   265       if len(request.POST) < 1 or read_only or not_ready:
       
   266          # not submitting completed survey OR we're ignoring late submission
       
   267         pass
       
   268       else:
       
   269         # save/update the submitted survey
       
   270         context['notice'] = "Survey Submission Saved"
       
   271         survey_record = survey_logic.updateSurveyRecord(user, survey,
       
   272         survey_record, request.POST)
       
   273     survey_content = survey.survey_content
       
   274 
       
   275     if not survey_record and read_only:
       
   276       # no recorded answers, we're either past survey_end or want to see answers
       
   277       is_same_user = user.key() == user_logic.getForCurrentAccount().key()
       
   278 
       
   279       if not can_write or not is_same_user:
       
   280         # If user who can edit looks at her own taking page, show the default
       
   281         # form as readonly. Otherwise, below, show nothing.
       
   282         context["notice"] = "There are no records for this survey and user."
       
   283         return False
       
   284 
       
   285     survey_form = surveys.SurveyForm(survey_content=survey_content,
       
   286                                      this_user=user,
       
   287                                      project=project,
       
   288                                      survey_logic=self._params['logic'],
       
   289                                      survey_record=survey_record,
       
   290                                      read_only=read_only,
       
   291                                      editing=False)
       
   292     survey_form.getFields()
   208     survey_form.getFields()
   293     if 'evaluation' in survey.taking_access:
   209 
   294       survey_form = surveys.getRoleSpecificFields(survey, user,
   210     context['survey_form'] = survey_form
   295                                   project, survey_form, survey_record)
   211 
   296 
   212     # return True to signal that the page may be displayed
   297     # set help and status text
       
   298     self.setHelpStatus(context, read_only,
       
   299     survey_record, survey_form, survey)
       
   300 
       
   301     if not context['survey_form']:
       
   302       access_tpl = "Access Error: This Survey Is Limited To %s"
       
   303       context["notice"] = access_tpl % string.capwords(survey.taking_access)
       
   304 
       
   305     context['read_only'] = read_only
       
   306     context['project'] = project
       
   307     return True
   213     return True
   308 
       
   309   def getStatus(self, request, context, user, survey):
       
   310     """Determine if we're past survey_end or before survey_start, check user rights.
       
   311     """
       
   312 
       
   313     read_only = (context.get("read_only", False) or
       
   314                  request.GET.get("read_only", False) or
       
   315                  request.POST.get("read_only", False)
       
   316                  )
       
   317     now = datetime.datetime.now()
       
   318 
       
   319     # check survey_end, see check for survey_start below
       
   320     if survey.survey_end and now > survey.survey_end:
       
   321       # are we already passed the survey_end?
       
   322       context["notice"] = "The Deadline For This Survey Has Passed"
       
   323       read_only = True
       
   324 
       
   325     # check if user can edit this survey
       
   326     params = dict(prefix=survey.prefix, scope_path=survey.scope_path)
       
   327     checker = access.rights_logic.Checker(survey.prefix)
       
   328     roles = checker.getMembership(survey.write_access)
       
   329     rights = self._params['rights']
       
   330     can_write = access.Checker.hasMembership(rights, roles, params)
       
   331 
       
   332 
       
   333     not_ready = False
       
   334     # check if we're past the survey_start date
       
   335     if survey.survey_start and now < survey.survey_start:
       
   336       not_ready = True
       
   337 
       
   338       # only users that can edit a survey should see it before survey_start
       
   339       if not can_write:
       
   340         context["notice"] = "There is no such survey available."
       
   341         return False
       
   342       else:
       
   343         context["notice"] = "This survey is not open for taking yet."
       
   344 
       
   345     return read_only, can_write, not_ready
       
   346 
       
   347   def setHelpStatus(self, context, read_only, survey_record, survey_form,
       
   348                     survey):
       
   349     """Set help_text and status for template use.
       
   350     """
       
   351 
       
   352     if not read_only:
       
   353       if not survey.survey_end:
       
   354         survey_end_text = ""
       
   355       else:
       
   356         survey_end_text = " by " + str(
       
   357       survey.survey_end.strftime("%A, %d. %B %Y %I:%M%p"))
       
   358 
       
   359       if survey_record:
       
   360         help_text = "Edit and re-submit this survey" + survey_end_text + "."
       
   361         status = "edit"
       
   362       else:
       
   363         help_text = "Please complete this survey" + survey_end_text + "."
       
   364         status = "create"
       
   365 
       
   366     else:
       
   367       help_text = "Read-only view."
       
   368       status = "view"
       
   369 
       
   370     survey_data = dict(survey_form=survey_form, status=status,
       
   371                                      help_text=help_text)
       
   372     context.update(survey_data)
       
   373 
   214 
   374   def _editContext(self, request, context):
   215   def _editContext(self, request, context):
   375     """Performs any required processing on the context for edit pages.
   216     """Performs any required processing on the context for edit pages.
   376 
   217 
   377     Args:
   218     Args: