def checkIsAfterEvent(self, django_args, event_name, key_name_arg): """Checks if the given event has taken place for the given program. Args: django_args: a dictionary with django's arguments event_name: the name of the event which is checked key_name_arg: the entry in django_args that specifies the given program keyname. If none is given the key_name is constructed from django_args itself. Raises: AccessViolationResponse: * if no active Program is found * if the event has not taken place yet """ if key_name_arg and key_name_arg in django_args: key_name = django_args[key_name_arg] else: key_name = program_logic.getKeyNameFromFields(django_args) program_entity = program_logic.getFromKeyName(key_name) if not program_entity or ( program_entity.status in ['inactive', 'invalid']): raise out_of_band.AccessViolation(message_fmt=DEF_SCOPE_INACTIVE_MSG) if timeline_helper.isAfterEvent(program_entity.timeline, event_name): return raise out_of_band.AccessViolation(message_fmt=DEF_PAGE_INACTIVE_MSG)
def checkIsHostForProgramInScope(self, django_args): """Checks if the user is a host for the specified program. Args: django_args: a dictionary with django's arguments """ program = program_logic.getFromKeyName(django_args['scope_path']) if not program or program.status == 'invalid': raise out_of_band.AccessViolation(message_fmt=DEF_NO_ACTIVE_PROGRAM_MSG) django_args = {'scope_path': program.scope_path} self.checkHasActiveRoleForScope(django_args, host_logic)
def runTimelineConversionUpdate(request, entities, context, *args, **kwargs): """AppEngine Task that converts Timelines into GSoCTimelines. It also updates all GSoCPrograms with a reference to the new GSoCTimeline. Args: request: Django Request object entities: list of Timeline entities to convert context: the context of this task """ from soc.modules.gsoc.models.timeline import GSoCTimeline from soc.modules.gsoc.logic.models.program import logic as program_logic # get all the properties that are part of each Timeline timeline_model = timeline_logic.getModel() timeline_properties = timeline_model.properties().keys() # use this to store all the new GSoCTimelines and GSoCPrograms gsoc_timelines = [] gsoc_programs = [] for entity in entities: gsoc_properties = {} for timeline_property in timeline_properties: # copy over all the information from the timeline entity gsoc_properties[timeline_property] = getattr( entity, timeline_property) gsoc_program = program_logic.getFromKeyName(entity.key().id_or_name()) gsoc_properties['scope'] = gsoc_program.scope # create the new GSoCTimeline entity and prepare it to be stored gsoc_timeline_entity = GSoCTimeline(key_name=entity.key().name(), **gsoc_properties) gsoc_timelines.append(gsoc_timeline_entity) # set the timeline for the GSoCProgram entity and prepare it for storage gsoc_program.timeline = gsoc_timeline_entity gsoc_programs.append(gsoc_program) # store all the new GSoCTimelines and GSoCPrograms db.put(gsoc_timelines) db.put(gsoc_programs) # task completed, return return
def runTimelineConversionUpdate(request, entities, context, *args, **kwargs): """AppEngine Task that converts Timelines into GSoCTimelines. It also updates all GSoCPrograms with a reference to the new GSoCTimeline. Args: request: Django Request object entities: list of Timeline entities to convert context: the context of this task """ from soc.modules.gsoc.models.timeline import GSoCTimeline from soc.modules.gsoc.logic.models.program import logic as program_logic # get all the properties that are part of each Timeline timeline_model = timeline_logic.getModel() timeline_properties = timeline_model.properties().keys() # use this to store all the new GSoCTimelines and GSoCPrograms gsoc_timelines = [] gsoc_programs = [] for entity in entities: gsoc_properties = {} for timeline_property in timeline_properties: # copy over all the information from the timeline entity gsoc_properties[timeline_property] = getattr(entity, timeline_property) gsoc_program = program_logic.getFromKeyName(entity.key().id_or_name()) gsoc_properties['scope'] = gsoc_program.scope # create the new GSoCTimeline entity and prepare it to be stored gsoc_timeline_entity = GSoCTimeline(key_name=entity.key().name(), **gsoc_properties) gsoc_timelines.append(gsoc_timeline_entity) # set the timeline for the GSoCProgram entity and prepare it for storage gsoc_program.timeline = gsoc_timeline_entity gsoc_programs.append(gsoc_program) # store all the new GSoCTimelines and GSoCPrograms db.put(gsoc_timelines) db.put(gsoc_programs) # task completed, return return
def startSpam(): """Creates the job that is responsible for sending mails. """ from soc.logic.models.job import logic as job_logic from soc.logic.models.priority_group import logic as priority_logic from soc.logic.models.program import logic as program_logic program_entity = program_logic.getFromKeyName('google/gsoc2009') priority_group = priority_logic.getGroup(priority_logic.EMAIL) job_fields = { 'priority_group': priority_group, 'task_name': 'setupStudentProposalMailing', 'key_data': [program_entity.key()]} job_logic.updateOrCreateFromFields(job_fields)
def _runSurveyUpdate(entities, logic): """AppEngine Task that updates Survey entities. Args: entities: list of Survey entities to update logic: concrete logic instance which the surveys are to be updated for Returns: A list of pairs that maps the old surveys with the corresponding new ones. """ from soc.modules.gsoc.logic.models.program import logic as program_logic # get all the properties that are part of each Document survey_model = logic.getModel() survey_properties = survey_model.properties().keys() new_surveys = [] for entity in entities: new_survey_properties = {} for survey_property in survey_properties: # copy over all the information from the Survey entity new_survey_properties[survey_property] = getattr( entity, survey_property) new_survey_properties['prefix'] = 'gsoc_program' new_survey_properties['scope'] = program_logic.getFromKeyName( entity.scope.key().id_or_name()) new_survey_key = logic.getKeyNameFromFields(new_survey_properties) new_survey = survey_model(key_name=new_survey_key, **new_survey_properties) # force the prefix to gsoc_program before saving it for storage new_survey.prefix = 'gsoc_program' new_surveys.append(new_survey) # batch put the new Surveys db.put(new_surveys) # task completed, return return
def startSpam(): """Creates the job that is responsible for sending mails. """ from soc.logic.models.job import logic as job_logic from soc.logic.models.priority_group import logic as priority_logic from soc.logic.models.program import logic as program_logic program_entity = program_logic.getFromKeyName('google/gsoc2009') priority_group = priority_logic.getGroup(priority_logic.EMAIL) job_fields = { 'priority_group': priority_group, 'task_name': 'setupStudentProposalMailing', 'key_data': [program_entity.key()] } job_logic.updateOrCreateFromFields(job_fields)
def _runSurveyUpdate(entities, logic): """AppEngine Task that updates Survey entities. Args: entities: list of Survey entities to update logic: concrete logic instance which the surveys are to be updated for Returns: A list of pairs that maps the old surveys with the corresponding new ones. """ from soc.modules.gsoc.logic.models.program import logic as program_logic # get all the properties that are part of each Document survey_model = logic.getModel() survey_properties = survey_model.properties().keys() new_surveys = [] for entity in entities: new_survey_properties = {} for survey_property in survey_properties: # copy over all the information from the Survey entity new_survey_properties[survey_property] = getattr(entity, survey_property) new_survey_properties['prefix'] = 'gsoc_program' new_survey_properties['scope'] = program_logic.getFromKeyName( entity.scope.key().id_or_name()) new_survey_key = logic.getKeyNameFromFields(new_survey_properties) new_survey = survey_model(key_name=new_survey_key, **new_survey_properties) # force the prefix to gsoc_program before saving it for storage new_survey.prefix = 'gsoc_program' new_surveys.append(new_survey) # batch put the new Surveys db.put(new_surveys) # task completed, return return
def runStudentProposalUpdate(request, entities, context, *args, **kwargs): """AppEngine Task that updates StudentProposal entities. Args: request: Django Request object entities: list of StudentProposal entities to update context: the context of this task """ from soc.modules.gsoc.logic.models.mentor import logic as mentor_logic from soc.modules.gsoc.logic.models.organization import logic as org_logic from soc.modules.gsoc.logic.models.program import logic as program_logic from soc.modules.gsoc.logic.models.student import logic as student_logic for entity in entities: entity.scope = student_logic.getFromKeyName( entity.scope.key().id_or_name()) entity.org = org_logic.getFromKeyName(entity.org.key().id_or_name()) entity.program = program_logic.getFromKeyName( entity.program.key().id_or_name()) if entity.mentor: entity.mentor = mentor_logic.getFromKeyName( entity.mentor.key().id_or_name()) old_mentors = entity.possible_mentors new_mentors = [] for old_mentor in old_mentors: new_mentor = mentor_logic.getFromKeyName(old_mentor.id_or_name()) new_mentors.append(new_mentor.key()) entity.possible_mentors = new_mentors # store all StudentProposal db.put(entities) # task completed, return return
def runGradingSurveyGroupUpdate(request, entities, context, *args, **kwargs): """AppEngine Task that updates GradingSurveyGroup entities. Args: request: Django Request object entities: list of Document entities to update context: the context of this task """ from soc.modules.gsoc.logic.models.program import logic as program_logic for entity in entities: entity.scope = program_logic.getFromKeyName( entity.scope.key().id_or_name()) survey_attrs = ['grading_survey', 'student_survey'] for survey_attr in survey_attrs: survey = getattr(entity, survey_attr) # update if the survey field is defined and its prefix is 'program' if not survey or not survey.prefix == 'program': continue survey_key_name = 'gsoc_' + survey.key().id_or_name() if survey_attr == 'student_survey': logic = project_survey_logic else: logic = grading_survey_logic new_survey = logic.getFromKeyName(survey_key_name) setattr(entity, survey_attr, new_survey) db.put(entities) # task completed, return return
def runDocumentUpdate(request, entities, context, *args, **kwargs): """AppEngine Task that updates Document entities. Args: request: Django Request object entities: list of Document entities to update context: the context of this task """ from soc.modules.gsoc.logic.models.organization import logic as org_logic from soc.modules.gsoc.logic.models.program import logic as program_logic # get all the properties that are part of each Document document_model = document_logic.getModel() document_properties = document_model.properties().keys() # use this to store all the new Documents and Presences documents = [] presences = [] for entity in entities: if entity.prefix not in ['org', 'program']: # we do not want to convert this Document continue new_document_properties = {} for document_property in document_properties: # copy over all the information from the Document entity new_document_properties[document_property] = getattr(entity, document_property) if entity.prefix == 'org': new_document_prefix = 'gsoc_org' presence_entity = org_logic.getFromKeyName(entity.scope_path) elif entity.prefix == 'program': new_document_prefix = 'gsoc_program' presence_entity = program_logic.getFromKeyName(entity.scope_path) new_document_properties['prefix'] = new_document_prefix new_document_properties['scope'] = presence_entity new_document_properties['home_for'] = presence_entity if entity.home_for else None # create the new Document entity and prepare it to be stored new_document_entity = document_model( key_name=document_logic.getKeyNameFromFields(new_document_properties), **new_document_properties) documents.append(new_document_entity) if entity.home_for: # update the presence for which this document was the home page presence_entity.home = new_document_entity presences.append(presence_entity) # store all the new Documents and updated Presences db.put(documents) db.put(presences) # task completed, return return
def spawnRemindersForProjectSurvey(request, *args, **kwargs): """Spawns tasks for each StudentProject in the given Program. Expects the following to be present in the POST dict: program_key: Specifies the program key name for which to loop over all the StudentProjects for survey_key: specifies the key name for the ProjectSurvey to send reminders for survey_type: either project or grading depending on the type of Survey project_key: optional to specify which project was the last for which a task was spawn Args: request: Django Request object """ from google.appengine.ext import db from soc.logic.models.program import logic as program_logic from soc.logic.models.student_project import logic as student_project_logic # set default batch size batch_size = 10 post_dict = request.POST # retrieve the program_key and survey_key from POST data program_key = post_dict.get('program_key') survey_key = post_dict.get('survey_key') survey_type = post_dict.get('survey_type') if not (program_key and survey_key and survey_type): # invalid task data, log and return OK return error_handler.logErrorAndReturnOK( 'Invalid sendRemindersForProjectSurvey data: %s' % post_dict) # get the program for the given keyname program_entity = program_logic.getFromKeyName(program_key) if not program_entity: # invalid program specified, log and return OK return error_handler.logErrorAndReturnOK( 'Invalid program specified: %s' % program_key) # check and retrieve the project_key that has been done last if 'project_key' in post_dict: project_start_key = post_dict['project_key'] else: project_start_key = None # get all valid StudentProjects from starting key fields = {'program': program_entity, 'status': 'accepted'} if project_start_key: # retrieve the last project that was done project_start = student_project_logic.getFromKeyName(project_start_key) if not project_start: # invalid starting project key specified, log and return OK return error_handler.logErrorAndReturnOK( 'Invalid Student Project Key specified: %s' %(project_start_key)) fields['__key__ >'] = project_start.key() project_entities = student_project_logic.getForFields(fields, limit=batch_size) for project_entity in project_entities: # pass along these params as POST to the new task task_params = {'survey_key': survey_key, 'survey_type': survey_type, 'project_key': project_entity.key().id_or_name()} task_url = '/tasks/surveys/projects/send_reminder/send' new_task = taskqueue.Task(params=task_params, url=task_url) new_task.add('mail') if len(project_entities) == batch_size: # spawn new task starting from the last new_project_start = project_entities[batch_size-1].key().id_or_name() # pass along these params as POST to the new task task_params = {'program_key': program_key, 'survey_key': survey_key, 'survey_type': survey_type, 'project_key': new_project_start} task_url = '/tasks/surveys/projects/send_reminder/spawn' new_task = taskqueue.Task(params=task_params, url=task_url) new_task.add() # return OK return http.HttpResponse()
def setupStudentProposalMailing(job_entity): """Job that setup jobs that will mail students if they have been accepted in a program with a GSoC-like workflow. Args: job_entity: a Job entity with key_data set to [program, last_completed_student] """ from soc.cron.job import FatalJobError # retrieve the data we need to continue our work key_data = job_entity.key_data program_key = key_data[0] program_keyname = program_key.name() program_entity = program_logic.getFromKeyName(program_keyname) if not program_entity: raise FatalJobError('The program with key %s could not be found' % ( program_keyname)) student_fields = {'scope': program_entity} if len(key_data) >= 2: # start where we left off student_fields['__key__ >'] = key_data[1] students = student_logic.getForFields(student_fields, limit=DEF_STUDENT_STEP_SIZE) # set the default fields for the jobs we are going to create priority_group = priority_logic.getGroup(priority_logic.EMAIL) job_fields = { 'priority_group': priority_group, 'task_name': 'sendStudentProposalMail'} job_query_fields = job_fields.copy() while students: # for each student create a mailing job for student in students: job_query_fields['key_data'] = student.key() mail_job = job_logic.getForFields(job_query_fields, unique=True) if not mail_job: # this student did not receive mail yet job_fields['key_data'] = [student.key()] job_logic.updateOrCreateFromFields(job_fields) # update our own job last_student_key = students[-1].key() if len(key_data) >= 2: key_data[1] = last_student_key else: key_data.append(last_student_key) updated_job_fields = {'key_data': key_data} job_logic.updateEntityProperties(job_entity, updated_job_fields) # rinse and repeat student_fields['__key__ >'] = last_student_key students = student_logic.getForFields(student_fields, limit=DEF_STUDENT_STEP_SIZE) # we are finished return
def setupStudentProposalMailing(job_entity): """Job that setup jobs that will mail students if they have been accepted in a program with a GSoC-like workflow. Args: job_entity: a Job entity with key_data set to [program, last_completed_student] """ from soc.cron.job import FatalJobError # retrieve the data we need to continue our work key_data = job_entity.key_data program_key = key_data[0] program_keyname = program_key.name() program_entity = program_logic.getFromKeyName(program_keyname) if not program_entity: raise FatalJobError('The program with key %s could not be found' % (program_keyname)) student_fields = {'scope': program_entity} if len(key_data) >= 2: # start where we left off student_fields['__key__ >'] = key_data[1] students = student_logic.getForFields(student_fields, limit=DEF_STUDENT_STEP_SIZE) # set the default fields for the jobs we are going to create priority_group = priority_logic.getGroup(priority_logic.EMAIL) job_fields = { 'priority_group': priority_group, 'task_name': 'sendStudentProposalMail' } job_query_fields = job_fields.copy() while students: # for each student create a mailing job for student in students: job_query_fields['key_data'] = student.key() mail_job = job_logic.getForFields(job_query_fields, unique=True) if not mail_job: # this student did not receive mail yet job_fields['key_data'] = [student.key()] job_logic.updateOrCreateFromFields(job_fields) # update our own job last_student_key = students[-1].key() if len(key_data) >= 2: key_data[1] = last_student_key else: key_data.append(last_student_key) updated_job_fields = {'key_data': key_data} job_logic.updateEntityProperties(job_entity, updated_job_fields) # rinse and repeat student_fields['__key__ >'] = last_student_key students = student_logic.getForFields(student_fields, limit=DEF_STUDENT_STEP_SIZE) # we are finished return