app/soc/tasks/surveys.py
changeset 2595 4c00831ef55c
child 2601 1f575a1e82d5
equal deleted inserted replaced
2594:dd300af0e7df 2595:4c00831ef55c
       
     1 #!/usr/bin/python2.5
       
     2 #
       
     3 # Copyright 2009 the Melange authors.
       
     4 #
       
     5 # Licensed under the Apache License, Version 2.0 (the "License");
       
     6 # you may not use this file except in compliance with the License.
       
     7 # You may obtain a copy of the License at
       
     8 #
       
     9 #   http://www.apache.org/licenses/LICENSE-2.0
       
    10 #
       
    11 # Unless required by applicable law or agreed to in writing, software
       
    12 # distributed under the License is distributed on an "AS IS" BASIS,
       
    13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       
    14 # See the License for the specific language governing permissions and
       
    15 # limitations under the License.
       
    16 
       
    17 """Tasks related to Surveys.
       
    18 """
       
    19 
       
    20 __authors__ = [
       
    21   '"Lennard de Rijk" <ljvderijk@gmail.com>',
       
    22   ]
       
    23 
       
    24 
       
    25 import logging
       
    26 
       
    27 from google.appengine.api.labs import taskqueue
       
    28 
       
    29 from django import http
       
    30 
       
    31 
       
    32 def getDjangoURLPatterns():
       
    33   """Returns the URL patterns for the tasks in this module.
       
    34   """
       
    35 
       
    36   patterns = [(r'tasks/surveys/projects/send_reminder/spawn$',
       
    37                'soc.tasks.surveys.spawnRemindersForProjectSurvey'),
       
    38               (r'tasks/surveys/projects/send_reminder/send$',
       
    39                'soc.tasks.surveys.sendSurveyReminderForProject')]
       
    40 
       
    41   return patterns
       
    42 
       
    43 
       
    44 def spawnRemindersForProjectSurvey(request, *args, **kwargs):
       
    45   """Spawns tasks for each StudentProject in the given Program.
       
    46 
       
    47   Expects the following to be present in the POST dict:
       
    48     program_key: Specifies the program key name for which to loop over all the
       
    49                  StudentProjects for
       
    50     survey_key: specifies the key name for the ProjectSurvey to send reminders
       
    51                 for
       
    52     survey_type: either project or grading depending on the type of Survey
       
    53     project_key: optional to specifiy which project was the last for which a
       
    54                  task was spawn
       
    55 
       
    56   Args:
       
    57     request: Django Request object
       
    58   """
       
    59   
       
    60   from google.appengine.ext import db
       
    61 
       
    62   from soc.logic.models.program import logic as program_logic
       
    63   from soc.logic.models.student_project import logic as student_project_logic
       
    64 
       
    65   # set default batch size
       
    66   batch_size = 10
       
    67 
       
    68   post_dict = request.POST
       
    69 
       
    70   # retrieve the program_key and survey_key from POST data
       
    71   program_key = post_dict.get('program_key')
       
    72   survey_key = post_dict.get('survey_key')
       
    73   survey_type = post_dict.get('survey_type')
       
    74 
       
    75   if not (program_key and survey_key and survey_type):
       
    76     # invalid task data, log and return OK
       
    77     return logErrorAndReturnOK(
       
    78         'Invalid sendRemindersForProjectSurvey data: %s' % post_dict)
       
    79 
       
    80   # get the program for the given keyname
       
    81   program_entity = program_logic.getFromKeyName(program_key)
       
    82 
       
    83   if not program_entity:
       
    84     # invalid program specified, log and return OK
       
    85     return logErrorAndReturnOK('Invalid program specified: %s' % program_key)
       
    86 
       
    87   # check and retrieve the project_key that has been done last
       
    88   if 'project_key' in post_dict:
       
    89     project_start_key = post_dict['project_key']
       
    90   else:
       
    91     project_start_key = None
       
    92 
       
    93   # get all valid surveys from starting key
       
    94   fields = {'program': program_entity,
       
    95             'status': 'accepted'}
       
    96 
       
    97   if project_start_key:
       
    98     # retrieve the last project that was done
       
    99     project_start = student_project_logic.getFromKeyName(project_start_key)
       
   100 
       
   101     if not project_start:
       
   102       # invalid starting project key specified, log and return OK
       
   103       return logErrorAndReturnOK('Invalid Student Project Key specified: %s' %(
       
   104           project_start_key))
       
   105 
       
   106     fields['__key__ >'] = project_start.key()
       
   107 
       
   108   project_entities = student_project_logic.getForFields(fields,
       
   109                                                         limit=batch_size)
       
   110 
       
   111   for project_entity in project_entities:
       
   112     # pass along these params as POST to the new task
       
   113     task_params = {'survey_key': survey_key,
       
   114                    'survey_type': survey_type,
       
   115                    'project_key': project_entity.key().id_or_name()}
       
   116     task_url = '/tasks/surveys/projects/send_reminder/send'
       
   117 
       
   118     new_task = taskqueue.Task(params=task_params, url=task_url)
       
   119     new_task.add('mail')
       
   120 
       
   121   if len(project_entities) == batch_size:
       
   122     # spawn new task starting from the last
       
   123     new_project_start = project_entities[batch_size-1].key().id_or_name()
       
   124 
       
   125     # pass along these params as POST to the new task
       
   126     task_params = {'program_key': program_key,
       
   127                    'survey_key': survey_key,
       
   128                    'survey_type': survey_type,
       
   129                    'project_key': new_project_start}
       
   130     task_url = '/tasks/surveys/projects/send_reminder/spawn'
       
   131 
       
   132     new_task = taskqueue.Task(params=task_params, url=task_url)
       
   133     new_task.add()
       
   134 
       
   135   # return OK
       
   136   return http.HttpResponse()
       
   137 
       
   138 
       
   139 def sendSurveyReminderForProject(request, *args, **kwargs):
       
   140   """Sends a reminder mail for a given StudentProject and Survey.
       
   141 
       
   142   A reminder is only send if no record is on file for the given Survey and 
       
   143   StudentProject.
       
   144 
       
   145   Expects the following to be present in the POST dict:
       
   146     survey_key: specifies the key name for the ProjectSurvey to send reminders
       
   147                 for
       
   148     survey_type: either project or grading depending on the type of Survey
       
   149     project_key: key which specifies the project to send a reminder for
       
   150 
       
   151   Args:
       
   152     request: Django Request object
       
   153   """
       
   154 
       
   155   from soc.logic import mail_dispatcher
       
   156   from soc.logic.models.org_admin import logic as org_admin_logic
       
   157   from soc.logic.models.site import logic as site_logic
       
   158   from soc.logic.models.student_project import logic as student_project_logic
       
   159   from soc.logic.models.survey import grading_logic
       
   160   from soc.logic.models.survey import project_logic
       
   161   from soc.views.helper import redirects
       
   162 
       
   163   post_dict = request.POST
       
   164 
       
   165   project_key = post_dict.get('project_key')
       
   166   survey_key = post_dict.get('survey_key')
       
   167   survey_type = post_dict.get('survey_type')
       
   168 
       
   169   if not (project_key and survey_key and survey_type):
       
   170     # invalid task data, log and return OK
       
   171     return logErrorAndReturnOK(
       
   172         'Invalid sendSurveyReminderForProject data: %s' % post_dict)
       
   173 
       
   174   # set logic depending on survey type specified in POST
       
   175   if survey_type == 'project':
       
   176     survey_logic = project_logic
       
   177   elif survey_type == 'grading':
       
   178     survey_logic = grading_logic
       
   179 
       
   180   # retrieve the project and survey
       
   181   student_project = student_project_logic.getFromKeyName(project_key)
       
   182 
       
   183   if not student_project:
       
   184     # no existing project found, log and return OK
       
   185     return logErrorAndReturnOK('Invalid project specified %s:' % project_key)
       
   186 
       
   187   survey = survey_logic.getFromKeyName(survey_key)
       
   188 
       
   189   if not survey:
       
   190     # no existing survey found, log and return OK
       
   191     return logErrorAndReturnOK('Invalid survey specified %s:' % survey_key)
       
   192 
       
   193   # try to retrieve an existing record
       
   194   record_logic = survey_logic.getRecordLogic()
       
   195 
       
   196   fields = {'project': student_project,
       
   197             'survey': survey}
       
   198   record_entity = record_logic.getForFields(fields, unique=True)
       
   199 
       
   200   if not record_entity:
       
   201     # send reminder email because we found no record
       
   202 
       
   203     student_entity = student_project.student
       
   204     site_entity = site_logic.getSingleton()
       
   205 
       
   206     if survey_type == 'project':
       
   207       survey_url = redirects.getTakeSurveyRedirect(
       
   208           survey,{'url_name': 'project_survey'})
       
   209       to_role = student_entity
       
   210       mail_template = 'soc/project_survey/mail/reminder_gsoc.html'
       
   211     elif survey_type == 'grading':
       
   212       survey_url = redirects.getTakeSurveyRedirect(
       
   213           survey,{'url_name': 'grading_project_survey'})
       
   214       to_role = student_project.mentor
       
   215       mail_template = 'soc/grading_project_survey/mail/reminder_gsoc.html'
       
   216 
       
   217     # set the context for the mail template
       
   218     mail_context = {
       
   219         'student_name': student_entity.name(),
       
   220         'project_title': student_project.title,
       
   221         'survey_url': survey_url,
       
   222         'survey_end': survey.survey_end,
       
   223         'to_name': to_role.name(),
       
   224         'site_name': site_entity.site_name,
       
   225     }
       
   226 
       
   227     # set the sender
       
   228     (sender, sender_address) = mail_dispatcher.getDefaultMailSender()
       
   229     mail_context['sender'] = sender_address
       
   230     # set the receiver and subject
       
   231     mail_context['to'] = to_role.email
       
   232     mail_context['subject'] = 'Evaluation Survey "%s" Reminder' %(survey.title)
       
   233 
       
   234     # find all org admins for the project's organization
       
   235     org_entity = student_project.scope
       
   236 
       
   237     fields = {'scope': org_entity,
       
   238               'status': 'active'}
       
   239     org_admin_entities = org_admin_logic.getForFields(fields)
       
   240 
       
   241     # collect email addresses for all found org admins
       
   242     org_admin_addresses = []
       
   243 
       
   244     for org_admin_entity in org_admin_entities:
       
   245       org_admin_addresses.append(org_admin_entity.email)
       
   246 
       
   247     if org_admin_addresses:
       
   248       mail_context['cc'] = org_admin_addresses
       
   249 
       
   250     # send out the email
       
   251     mail_dispatcher.sendMailFromTemplate(mail_template, mail_context)
       
   252 
       
   253   # return OK
       
   254   return http.HttpResponse()
       
   255 
       
   256 
       
   257 def logErrorAndReturnOK(error_msg='Error found in Survey Task'):
       
   258   """Logs the given error message and returns a HTTP OK response.
       
   259 
       
   260   Args:
       
   261     error_msg: Error message to log
       
   262   """
       
   263   logging.error(error_msg)
       
   264   return http.HttpResponse()