app/soc/cron/student_proposal_mailer.py
changeset 2223 7b8b812aa146
child 2226 6159450c4767
equal deleted inserted replaced
2222:a91d55e9c9cd 2223:7b8b812aa146
       
     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 """Cron job handler for Student Proposal mailing.
       
    18 """
       
    19 
       
    20 __authors__ = [
       
    21     '"Lennard de Rijk" <ljvderijk@gmail.com>',
       
    22   ]
       
    23 
       
    24 
       
    25 import logging
       
    26 
       
    27 from soc.logic.models.job import logic as job_logic
       
    28 from soc.logic.models.priority_group import logic as priority_logic
       
    29 from soc.logic.models.program import logic as program_logic
       
    30 from soc.logic.models.student import logic as student_logic
       
    31 from soc.logic.models.student_proposal import logic as proposal_logic
       
    32 
       
    33 
       
    34 # amount of students to create jobs for before updating
       
    35 DEF_STUDENT_STEP_SIZE = 10
       
    36 
       
    37 # property text_data for a sendStudentProposalMail Job
       
    38 DEF_STUDENT_PROPOSAL_MAIL_TEXT_DATA_FMT = '%s/proposal_mail'
       
    39 
       
    40 
       
    41 def setupStudentProposalMailing(job_entity):
       
    42   """Job that setup jobs that will mail students if they have been accepted in
       
    43   a program with a GSoC-like workflow.
       
    44 
       
    45   Args:
       
    46     job_entity: a Job entity with key_data set to 
       
    47                 [program, last_completed_student]
       
    48   """
       
    49 
       
    50   from soc.cron.job import FatalJobError
       
    51 
       
    52 
       
    53   # retrieve the data we need to continue our work
       
    54   key_data = job_entity.key_data
       
    55   program_key = key_data[0]
       
    56   program_keyname = program_key.name()
       
    57 
       
    58   program_entity = program_logic.getFromKeyName(program_keyname)
       
    59 
       
    60   if not program_entity:
       
    61     raise FatalJobError('The program with key %s could not be found' % (
       
    62         program_keyname))
       
    63 
       
    64   student_fields = {'scope': program_entity}
       
    65 
       
    66   if len(key_data) >= 2:
       
    67     # start where we left off
       
    68     student_fields['__key__ >'] = key_data[1]
       
    69 
       
    70   students = student_logic.getForFields(student_fields,
       
    71                                         limit=DEF_STUDENT_STEP_SIZE)
       
    72 
       
    73   # set the default fields for the jobs we are going to create
       
    74   priority_group = priority_logic.getGroup(priority_logic.EMAIL)
       
    75   job_fields = {
       
    76       'priority_group': priority_group,
       
    77       'task_name': 'sendStudentProposalMail'}
       
    78 
       
    79   job_query_fields = job_fields.copy()
       
    80 
       
    81   while students:
       
    82     # for each student create a mailing job
       
    83     for student in students:
       
    84       text_data = DEF_STUDENT_PROPOSAL_MAIL_TEXT_DATA_FMT % (
       
    85           student.key().name())
       
    86 
       
    87       job_query_fields['text_data'] = text_data
       
    88       mail_job = job_logic.getForFields(job_query_fields, unique=True)
       
    89 
       
    90       if not mail_job:
       
    91         # this student did not receive mail yet
       
    92         job_fields['text_data'] = text_data
       
    93         job_fields['key_data'] = [student.key()]
       
    94         job_logic.updateOrCreateFromFields(job_fields)
       
    95 
       
    96     # update our own job
       
    97     last_student_key = students[-1].key()
       
    98 
       
    99     if len(key_data) >= 2:
       
   100       key_data[1] = last_student_key
       
   101     else:
       
   102       key_data.append(last_student_key)
       
   103 
       
   104     updated_job_fields = {'key_data': key_data}
       
   105     job_logic.updateEntityProperties(job_entity, updated_job_fields)
       
   106 
       
   107     # rinse and repeat
       
   108     student_fields['__key__ >'] = last_student_key
       
   109     students = student_logic.getForFields(student_fields,
       
   110                                           limit=DEF_STUDENT_STEP_SIZE)
       
   111 
       
   112   # we are finished
       
   113   return
       
   114 
       
   115 def sendStudentProposalMail(job_entity):
       
   116   """Job that will send out an email to a student that sent in a proposal
       
   117   that either got accepted or rejected.
       
   118 
       
   119   Args:
       
   120     job_entity: a Job entity with key_data set to [student_key]
       
   121   """
       
   122 
       
   123   from soc.cron.job import FatalJobError
       
   124 
       
   125 
       
   126   student_keyname = job_entity.key_data[0].name()
       
   127   student_entity = student_logic.getFromKeyName(student_keyname)
       
   128 
       
   129   if not student_entity:
       
   130     raise FatalJobError('The student with keyname %s does not exist!' % (
       
   131         student_keyname))
       
   132 
       
   133   # only students who have sent in a proposal will be mailed
       
   134   fields = {'scope': student_entity}
       
   135   proposal = proposal_logic.getForFields(fields, unique=True)
       
   136 
       
   137   if proposal:
       
   138     # check if the student has an accepted proposal
       
   139     fields['status'] = 'accepted'
       
   140     accepted_proposal = proposal_logic.getForFields(fields, unique=True)
       
   141 
       
   142     # TODO(ljvderijk) replace with real mail sending
       
   143     if accepted_proposal:
       
   144       logging.info('Sending acceptance mail to %s' % (student_entity.name()))
       
   145     else:
       
   146       logging.info('Sending rejectance mail to %s' % (student_entity.name()))
       
   147 
       
   148   # we are done here
       
   149   return
       
   150