app/soc/logic/models/survey.py
changeset 2764 6ed5a3e26692
parent 2689 18d8486fd411
equal deleted inserted replaced
2763:80d625f78176 2764:6ed5a3e26692
    41 from soc.models.project_survey import ProjectSurvey
    41 from soc.models.project_survey import ProjectSurvey
    42 from soc.models.survey import SurveyContent
    42 from soc.models.survey import SurveyContent
    43 from soc.models.survey_record import SurveyRecord
    43 from soc.models.survey_record import SurveyRecord
    44 from soc.models.work import Work
    44 from soc.models.work import Work
    45 
    45 
    46 #TODO(James): Ensure this facilitates variable # of surveys 
       
    47 GRADES = {'pass': True, 'fail': False}
       
    48 PROJECT_STATUSES = {
       
    49 'accepted': {True: 'mid_term_passed', False: 'mid_term_failed'},
       
    50 'mid_term_passed': {True: 'passed', False: 'final_failed'}
       
    51 }
       
    52 
    46 
    53 class Logic(work.Logic):
    47 class Logic(work.Logic):
    54   """Logic methods for the Survey model.
    48   """Logic methods for the Survey model.
    55   """
    49   """
    56 
    50 
   111     """Returns SurveyRecordLogic that belongs to this SurveyLogic.
   105     """Returns SurveyRecordLogic that belongs to this SurveyLogic.
   112     """
   106     """
   113 
   107 
   114     return self.record_logic
   108     return self.record_logic
   115 
   109 
   116   def getUserRole(self, user, survey, project):
       
   117     """Gets the role of a user for a project, used for SurveyRecordGroup.
       
   118 
       
   119     params:
       
   120       user: user taking survey
       
   121       survey: survey entity
       
   122       project: student project for this user
       
   123     """
       
   124 
       
   125     if survey.taking_access == 'mentor evaluation':
       
   126       mentors = self.getMentorforProject(user, project)
       
   127 
       
   128       if len(mentors) < 1 or len(mentors) > 1:
       
   129         logging.warning('Unable to determine mentor for \
       
   130         user %s. Results returned: %s ' % (
       
   131         user.key().name(), str(mentors)) )
       
   132         return False
       
   133 
       
   134       this_mentor = mentors[0]
       
   135 
       
   136     if survey.taking_access == 'student evaluation':
       
   137       students = self.getStudentforProject(user, project)
       
   138 
       
   139       if len(students) < 1 or len(students) > 1:
       
   140         logging.warning('Unable to determine student for \
       
   141         user %s. Results returned: %s ' % (
       
   142         user.key().name(), str(students)) )
       
   143         return False
       
   144 
       
   145   def getStudentforProject(self, user, project):
       
   146     """Get student projects for a given User.
       
   147 
       
   148     params:
       
   149       user = survey taking user
       
   150       project = survey taker's student project
       
   151     """
       
   152     from soc.logic.models.student import logic as student_logic
       
   153     import soc.models.student
       
   154 
       
   155     # TODO this should be done per Student or Program
       
   156     # TODO filter for accepted, midterm_passed, etc?
       
   157     user_students = student_logic.getForFields({'user': user}) 
       
   158     if not user_students: return []
       
   159     return set([project.student for project in sum(
       
   160     (list(s.student_projects.run())
       
   161     for s in user_students), []) if project.key() == project.key()])
       
   162 
       
   163   def getMentorforProject(self, user, project):
       
   164     """Get Student Projects that are being mentored by the given User.
       
   165 
       
   166     params:
       
   167       user = survey taking user
       
   168       project = survey taker's student project
       
   169     """
       
   170 
       
   171     from soc.logic.models.mentor import logic as mentor_logic
       
   172     import soc.models.mentor
       
   173 
       
   174     # TODO filter for accepted, midterm_passed, etc?
       
   175     # TODO this should be done a program basis not user
       
   176 
       
   177     user_mentors = mentor_logic.getForFields({'user': user}) 
       
   178 
       
   179     if not user_mentors:
       
   180       return []
       
   181 
       
   182     return set([project.mentor for project in sum(
       
   183             (list(mentor.student_projects.run())
       
   184              for mentor in user_mentors), [])
       
   185         if project.key() == project.key()])
       
   186 
       
   187   def activateGrades(self, survey):
       
   188     """Activates the grades on a Grading Survey.
       
   189 
       
   190     TODO(James) Fix this Docstring
       
   191 
       
   192     params:
       
   193       survey = survey entity
       
   194     """
       
   195     if survey.taking_access != "mentor evaluation":
       
   196       logging.error("Cannot grade survey %s with taking access %s"
       
   197       % (survey.key().name(), survey.taking_access))
       
   198       return False
       
   199 
       
   200     program = survey.scope or Program.get_by_key_name(survey.scope_path)
       
   201 
       
   202     for project in program.student_projects.fetch(1000):
       
   203       this_record_group = GradingRecord.all().filter(
       
   204       "project = ", project).filter(
       
   205       "initial_status = ", project.status).get()
       
   206 
       
   207       if not this_record_group:
       
   208          logging.warning('neither mentor nor student has \
       
   209          taken the survey for project %s' % project.key().name() )
       
   210          continue
       
   211 
       
   212       if not this_record_group.mentor_record:
       
   213         # student has taken survey, but not mentor
       
   214         logging.warning('not continuing without mentor record...')
       
   215         continue
       
   216 
       
   217       status_options = PROJECT_STATUSES.get(project.status)
       
   218 
       
   219       if not status_options:
       
   220         logging.warning('unable to find status options for project \
       
   221         status %s' % project.status)
       
   222         continue
       
   223 
       
   224       new_project_grade = this_record_group.mentor_record.grade
       
   225       new_project_status = status_options.get(new_project_grade)
       
   226 
       
   227       if getattr(this_record_group, 'final_status'):
       
   228          logging.warning('project %s record group should not \
       
   229          yet have a final status %s' % (
       
   230          project.key().name(), this_record_group.final_status ) )
       
   231          continue
       
   232 
       
   233       # assign the new status to the project and surveyrecordgroup
       
   234       project.status = new_project_status
       
   235       this_record_group.final_status = new_project_status
       
   236 
       
   237   def getKeyNameFromPath(self, path):
       
   238     """Gets survey key name from a request path.
       
   239 
       
   240     params:
       
   241       path = path of the current request
       
   242     """
       
   243 
       
   244     # TODO determine if kwargs in the request contains this information
       
   245     return '/'.join(path.split('/')[-4:]).split('?')[0]
       
   246 
       
   247   def getProjects(self, survey, user):
       
   248     """Get projects linking user to a program.
       
   249 
       
   250     Serves as access handler (since no projects == no access).
       
   251     And retrieves projects to choose from (if mentors have >1 projects).
       
   252 
       
   253     params:
       
   254       survey = survey entity
       
   255       user = survey taking user
       
   256     """
       
   257 
       
   258     this_program = survey.scope or Program.get_by_key_name(survey.scope_path)
       
   259 
       
   260 
       
   261     if 'mentor' in survey.taking_access:
       
   262       these_projects = self.getMentorProjects(user, this_program)
       
   263 
       
   264     elif 'student' in survey.taking_access:
       
   265       these_projects = self.getStudentProjects(user, this_program)
       
   266 
       
   267     logging.info(these_projects)
       
   268 
       
   269     if len(these_projects) == 0:
       
   270       return False
       
   271 
       
   272     return these_projects
       
   273 
       
   274   def getDebugUser(self, survey, this_program):
   110   def getDebugUser(self, survey, this_program):
   275     """Debugging method impersonates other roles.
   111     """Debugging method impersonates other roles.
   276 
   112 
   277     Tests taking survey, saving response, and grading.
   113     Tests taking survey, saving response, and grading.
   278 
   114 
   325     import soc.models.organization
   161     import soc.models.organization
   326     import soc.models.user
   162     import soc.models.user
   327     import soc.models.site
   163     import soc.models.site
   328 
   164 
   329     # use prefix to generate dict key
   165     # use prefix to generate dict key
   330     scope_types = {"program": soc.models.program.Program,
   166     scope_types = {
   331     "org": soc.models.organization.Organization,
   167         "program": soc.models.program.Program,
   332     "user": soc.models.user.User,
   168         "org": soc.models.organization.Organization,
   333     "site": soc.models.site.Site}
   169         "user": soc.models.user.User,
       
   170         "site": soc.models.site.Site}
   334 
   171 
   335     # determine the type of the scope
   172     # determine the type of the scope
   336     scope_type = scope_types.get(entity.prefix)
   173     scope_type = scope_types.get(entity.prefix)
   337 
   174 
   338     if not scope_type:
   175     if not scope_type: