blob: 9c77f10f96186c318c22b799ee98b77e6e136489 [file] [log] [blame]
# Copyright 2009 the Melange authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Tasks related to Grading Survey Groups and Records.
"""
import datetime
import logging
from google.appengine.api import taskqueue
from google.appengine.ext import db
from django import http
from django.conf.urls.defaults import url
from soc.logic import mail_dispatcher
from soc.logic import site
from soc.tasks.helper import error_handler
from soc.modules.gsoc.logic import grading_record
from soc.modules.gsoc.logic import profile as profile_logic
from soc.modules.gsoc.models.grading_record import GSoCGradingRecord
from soc.modules.gsoc.models.grading_survey_group import GSoCGradingSurveyGroup
from soc.modules.gsoc.models.profile import GSoCProfile
from soc.modules.gsoc.models.project import GSoCProject
class GradingRecordTasks(object):
"""Tasks that are involved in dealing with GradingRecords.
"""
# batch size to use when going through GSoCProject entities
DEF_BATCH_SIZE = 25
def djangoURLPatterns(self):
"""Returns the URL patterns for the tasks in this module.
"""
patterns = [
url(r'tasks/gsoc/grading_record/update_records$',
self.updateRecordsForSurveyGroup),
url(r'tasks/gsoc/grading_record/update_projects$',
self.updateProjectsForSurveyGroup),
url(r'tasks/gsoc/grading_record/mail_result',
self.sendMailAboutGradingRecordResult)]
return patterns
def updateRecordsForSurveyGroup(self, request, *args, **kwargs):
"""Updates or creates GradingRecords for the given GradingSurveyGroup.
Expects the following to be present in the POST dict:
group_key: Specifies the GradingSurveyGroup key name.
cursor: optional to specify where the query should continue from.
Args:
request: Django Request object
"""
post_dict = request.POST
group_key = post_dict.get('group_key')
if not group_key:
# invalid task data, log and return OK
return error_handler.logErrorAndReturnOK(
'Invalid updateRecordForSurveyGroup data: %s' % post_dict)
# get the GradingSurveyGroup for the given key
survey_group = GSoCGradingSurveyGroup.get_by_id(int(group_key))
if not survey_group:
# invalid GradingSurveyGroup specified, log and return OK
return error_handler.logErrorAndReturnOK(
'Invalid GradingSurveyGroup specified: %s' % group_key)
q = GSoCProject.all()
q.filter('program', survey_group.program)
q.filter('status', 'accepted')
if 'cursor' in post_dict:
q.with_cursor(post_dict['cursor'])
# get the first batch_size number of projects
projects = q.fetch(self.DEF_BATCH_SIZE)
if not projects:
# task completed, update timestamp for last update complete
survey_group.last_update_complete = datetime.datetime.now()
survey_group.put()
return http.HttpResponse()
# update/create and batch put the new GradingRecords
grading_record.updateOrCreateRecordsFor(survey_group, projects)
# pass along these params as POST to the new task
task_params = {'group_key': group_key,
'cursor': q.cursor()}
new_task = taskqueue.Task(params=task_params, url=request.path)
new_task.add()
# task completed, return OK
return http.HttpResponse('OK')
def updateProjectsForSurveyGroup(self, request, *args, **kwargs):
"""Updates each GSoCProject for which a GradingRecord is found.
Expects the following to be present in the POST dict:
group_key: Specifies the GradingSurveyGroup key name.
cursor: Optional, specifies the cursor for the GadingRecord query.
send_mail: Optional, if this string evaluates to True mail will be send
for each GradingRecord that's processed.
Args:
request: Django Request object
"""
post_dict = request.POST
group_key = post_dict.get('group_key')
if not group_key:
# invalid task data, log and return OK
return error_handler.logErrorAndReturnOK(
'Invalid updateRecordForSurveyGroup data: %s' % post_dict)
# get the GradingSurveyGroup for the given keyname
survey_group = GSoCGradingSurveyGroup.get_by_id(int(group_key))
if not survey_group:
# invalid GradingSurveyGroup specified, log and return OK
return error_handler.logErrorAndReturnOK(
'Invalid GradingSurveyGroup specified: %s' % group_key)
q = GSoCGradingRecord.all()
q.filter('grading_survey_group', survey_group)
if 'cursor' in post_dict:
q.with_cursor(post_dict['cursor'])
# get the first batch_size number of GradingRecords
records = q.fetch(self.DEF_BATCH_SIZE)
if not records:
# we are done
return http.HttpResponse()
grading_record.updateProjectsForGradingRecords(records)
# check if we need to send an email for each GradingRecord
send_mail = post_dict.get('send_mail', '')
if send_mail:
# enqueue a task to send mail for each GradingRecord
for record in records:
# pass along these params as POST to the new task
task_params = {'record_key': str(record.key())}
task_url = '/tasks/gsoc/grading_record/mail_result'
mail_task = taskqueue.Task(params=task_params, url=task_url)
mail_task.add('mail')
# pass along these params as POST to the new task
task_params = {'group_key': group_key,
'cursor': q.cursor(),
'send_mail': send_mail}
new_task = taskqueue.Task(params=task_params, url=request.path)
new_task.add()
# task completed, return OK
return http.HttpResponse('OK')
def sendMailAboutGradingRecordResult(self, request, *args, **kwargs):
"""Sends out a mail about the result of one GradingRecord.
Expects the following to be present in the POST dict:
record_key: Specifies the key for the record to process.
Args:
request: Django Request object
"""
post_dict = request.POST
record_key = post_dict.get('record_key')
if not record_key:
# no GradingRecord key specified, log and return OK
error_handler.logErrorAndReturnOK(
'No valid record_key specified in POST data: %s' % request.POST)
record = GSoCGradingRecord.get(db.Key(record_key))
if not record:
# no valid GradingRecord key specified, log and return OK
error_handler.logErrorAndReturnOK(
'No valid GradingRecord key specified: %s' % record_key)
survey_group_entity = record.grading_survey_group
project_entity = record.parent()
student_entity = project_entity.parent()
org_entity = project_entity.org
site_entity = site.singleton()
mail_context = {
'survey_group': survey_group_entity,
'grading_record': record,
'project': project_entity,
'organization': org_entity,
'site_name': site_entity.site_name,
'to_name': student_entity.name()
}
# set the sender
(_, sender_address) = mail_dispatcher.getDefaultMailSender()
mail_context['sender'] = sender_address
# set the receiver and subject
mail_context['to'] = student_entity.email
mail_context['cc'] = []
mail_context['subject'] = '%s results processed for %s' %(
survey_group_entity.name, project_entity.title)
org_admins = profile_logic.getOrgAdmins(org_entity)
# collect all mentors
mentors = db.get(project_entity.mentors)
# add them all to the cc list
for org_member in org_admins + mentors:
mail_context['cc'].append(org_member.email)
# send out the email using a template
mail_template = 'modules/gsoc/grading_record/mail/result.html'
mail_dispatcher.sendMailFromTemplate(mail_template, mail_context)
# return OK
return http.HttpResponse()