blob: a6060c9af62232306b6693f1677d1e2186c09856 [file] [log] [blame]
#!/usr/bin/env python2.5
#
# 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 slot assignment for organizations"""
import logging
from django.utils import simplejson
from google.appengine.api import taskqueue
from google.appengine.runtime import DeadlineExceededError
from soc.tasks import responses
from soc.tasks.helper.timekeeper import Timekeeper
from soc.modules.gsoc.models.program import GSoCProgram
from soc.modules.gsoc.models.organization import GSoCOrganization
from soc.modules.gsoc.models.student_proposal import StudentProposal
def getDjangoURLPatterns():
"""Returns the URL patterns for the tasks in this module"""
patterns = [
(r'gsoc/tasks/assignslots/assign$',
r'soc.modules.gsoc.tasks.slot_assignment.assignSlots'),
(r'gsoc/tasks/assignslots/program$',
r'soc.modules.gsoc.tasks.slot_assignment.assignProgramSlots'),
]
return patterns
def assignProgramSlots(request, *args, **kwargs):
"""Assign slots for organizations within a program
Gets the slot assignment data as a JSON string from the program
and enqueues a task to process the slot assignments
POST Args:
programkey: the key of the program to operate upon
"""
program = None
params = request.REQUEST
# Query the program entity
try:
program = GSoCProgram.get_by_key_name(params["programkey"])
except KeyError:
logging.error("programkey not in params")
return responses.terminateTask()
if not program:
logging.error("no such program '%s'" % params["programkey"])
return responses.terminateTask()
if not program.slots_allocation:
logging.error("empty slots_allocation")
return responses.terminateTask()
# Enqueue a task to assign the slots
taskqueue.add(
url = "/gsoc/tasks/assignslots/assign",
params = {
'programkey': params["programkey"],
})
# Return successful
return responses.terminateTask()
def assignSlots(request, *args, **kwargs):
"""Sets the slots attribute for each organization entity
POST Args:
slots: an org_key:num_slots JSON dictionary
"""
# Setup an artifical request deadline
timelimit = int(request.REQUEST.get("timelimit", 20000))
timekeeper = Timekeeper(timelimit)
program_key = request.REQUEST.get("programkey")
last_key = request.REQUEST.get("lastkey", "")
program = GSoCProgram.get_by_key_name(program_key)
# Copy for modification below
params = request.POST.copy()
params["timelimit"] = timelimit
# Parse the JSON org:slots dictionary
slots = simplejson.loads(program.slots_allocation)
org_keys = [i for i in sorted(slots.keys()) if i > last_key]
logging.info(org_keys)
# Assign slots for each organization
try:
for clock, org_key in timekeeper.iterate(org_keys):
logging.info("%s %s %s", request.path, clock, org_key)
org_slots = slots[org_key]
# Get the organization entity
org_key = '/'.join([program_key, org_key])
org = GSoCOrganization.get_by_key_name(org_key)
if not org:
logging.error("no such org '%s'/'%s'" % (program_key, org_key))
continue
# Count proposals and mentors
org.slots = int(org_slots['slots'])
org.nr_applications, org.nr_mentors = countProposals(org)
# Update the organization entity
org.put()
# Mark the organization as done
last_key = org_key
# Requeue this task for continuation
except DeadlineExceededError:
params["lastkey"] = last_key
taskqueue.add(url=request.path, params=params)
# Exit this task successfully
return responses.terminateTask()
def countProposals(org):
proposals = StudentProposal.all().filter('org', org).fetch(1000)
mentors = [p.mentor for p in proposals if p.mentor]
return len(proposals), len(mentors)