def accept_proposals(request, *args, **kwargs): """Accept proposals for an organization """ params = request.POST # Setup an artifical request deadline timelimit = int(params["timelimit"]) timekeeper = Timekeeper(timelimit) # Query proposals based on status org = org_logic.getFromKeyName(params["orgkey"]) proposals = student_proposal_logic.getProposalsToBeAcceptedForOrg(org) # Accept proposals try: for remain, proposal in timekeeper.iterate(proposals): logging.info("accept %s %s %s", remain, org.key(), proposal.key()) accept_proposal(proposal) accept_proposal_email(proposal) # Requeue this task for continuation except DeadlineExceededError: taskqueue.add(url=request.path, params=params) return responses.terminateTask() # Reject remaining proposals taskqueue.add(url=params["nextpath"], params=params) return responses.terminateTask()
def accept_proposals(request, *args, **kwargs): """Accept proposals for an organization """ params = request.POST # Setup an artifical request deadline timelimit = int(params["timelimit"]) timekeeper = Timekeeper(timelimit) # Query proposals based on status org = org_logic.getFromKeyName(params["orgkey"]) proposals = student_proposal_logic.getProposalsToBeAcceptedForOrg(org) # Accept proposals try: for remain, proposal in timekeeper.iterate(proposals): logging.info("accept %s %s %s", remain, org.key(), proposal.key()) accept_proposal(proposal) accept_proposal_email(proposal) # Requeue this task for continuation except DeadlineExceededError: taskqueue.add(url=request.path, params=params) return responses.terminateTask() # Reject remaining proposals taskqueue.add(url=params["nextpath"], params=params) return responses.terminateTask()
def getListProposalsData(self, request, rp_params, mp_params, p_params, org_entity): """Returns the list data for listProposals. """ from soc.modules.gsoc.logic.models.ranker_root import logic \ as ranker_root_logic from soc.modules.gsoc.logic.models.student_proposal import logic \ as sp_logic from soc.modules.gsoc.models import student_proposal from soc.modules.gsoc.views.helper import list_info as list_info_helper from soc.modules.gsoc.views.models import student_proposal \ as student_proposal_view idx = request.GET.get('idx', '') idx = int(idx) if idx.isdigit() else -1 args = order = [] if idx == 0: # retrieve the ranker fields = { 'link_id': student_proposal.DEF_RANKER_NAME, 'scope': org_entity } ranker_root = ranker_root_logic.getForFields(fields, unique=True) ranker = ranker_root_logic.getRootFromEntity(ranker_root) keys = [] # only when the program allows allocations # to be seen we should color the list if org_entity.scope.allocations_visible: proposals = sp_logic.getProposalsToBeAcceptedForOrg(org_entity) keys = [i.key() for i in proposals] # show the amount of slots assigned on the webpage context['slots_visible'] = True # TODO(ljvderijk) once sorting with IN operator is fixed, # make this list show more filter = {'org': org_entity, 'status': 'pending'} params = rp_params # order by descending score order = ['-score'] args = [ranker, keys] elif idx == 1: # check if the current user is a mentor user_entity = user_logic.getForCurrentAccount() fields = { 'user': user_entity, 'scope': org_entity, } mentor_entity = mentor_logic.getForFields(fields, unique=True) filter = { 'org': org_entity, 'mentor': mentor_entity, 'status': 'pending' } params = mp_params elif idx == 2: filter = {'org': org_entity} params = p_params else: return responses.jsonErrorResponse(request, "idx not valid") contents = helper.lists.getListData(request, params, filter, 'public', order=order, args=args) json = simplejson.dumps(contents) return responses.jsonResponse(request, json)
def calculate(request, *args, **kwargs): """Calculates the duplicate proposals in a given program for a student on a per Organization basis. Expects the following to be present in the POST dict: program_key: Specifies the program key name for which to find the duplicate proposals org_cursor: Specifies the organization datastore cursor from which to start the processing of finding the duplicate proposals Args: request: Django Request object """ from soc.modules.gsoc.logic.models.student_proposal import logic \ as sp_logic post_dict = request.POST program_key = post_dict.get('program_key') if not program_key: # invalid task data, log and return OK return error_handler.logErrorAndReturnOK('Invalid program key: %s' % post_dict) 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) fields = {'scope': program_entity, 'slots >': 0, 'status': 'active'} # get the organization and update the cursor if possible q = org_logic.getQueryForFields(fields) # retrieve the org_cursor from POST data org_cursor = post_dict.get('org_cursor') if org_cursor: org_cursor = str(org_cursor) q.with_cursor(org_cursor) result = q.fetch(1) # update the cursor org_cursor = q.cursor() if result: org_entity = result[0] # get all the proposals likely to be accepted in the program accepted_proposals = sp_logic.getProposalsToBeAcceptedForOrg( org_entity) for ap in accepted_proposals: student_entity = ap.scope proposal_duplicate = pd_logic.getForFields( {'student': student_entity}, unique=True) if proposal_duplicate and ap.key( ) not in proposal_duplicate.duplicates: # non-counted (to-be) accepted proposal found pd_fields = { 'duplicates': proposal_duplicate.duplicates + [ap.key()], } pd_fields['is_duplicate'] = len(pd_fields['duplicates']) >= 2 if org_entity.key() not in proposal_duplicate.orgs: pd_fields['orgs'] = proposal_duplicate.orgs + [ org_entity.key() ] proposal_duplicate = pd_logic.updateEntityProperties( proposal_duplicate, pd_fields) else: pd_fields = { 'program': program_entity, 'student': student_entity, 'orgs': [org_entity.key()], 'duplicates': [ap.key()], 'is_duplicate': False } proposal_duplicate = pd_logic.updateOrCreateFromFields( pd_fields) # Adds a new task that performs duplicate calculation for # the next organization. task_params = { 'program_key': program_key, 'org_cursor': unicode(org_cursor) } task_url = '/tasks/gsoc/proposal_duplicates/calculate' new_task = taskqueue.Task(params=task_params, url=task_url) new_task.add() else: # There aren't any more organizations to process. So delete # all the proposals for which there are not more than one # proposal for duplicates property. pd_logic.deleteAllForProgram(program_entity, non_dupes_only=True) # update the proposal duplicate status and its timestamp pds_entity = pds_logic.getOrCreateForProgram(program_entity) new_fields = { 'status': 'idle', 'calculated_on': datetime.datetime.now() } pds_logic.updateEntityProperties(pds_entity, new_fields) # return OK return http.HttpResponse()
def getListProposalsData(self, request, params_collection, org_entity): """Returns the list data for listProposals. Args: request: HTTPRequest object params_collection: List of list Params indexed with the idx of the list org_entity: GSoCOrganization entity for which the lists are generated """ from soc.modules.gsoc.logic.models.proposal_duplicates import logic \ as pd_logic from soc.modules.gsoc.logic.models.ranker_root import logic \ as ranker_root_logic idx = lists.getListIndex(request) # default list settings args = [] visibility = None if idx == 0: filter = {'org': org_entity, 'status': 'new'} elif idx == 1: # retrieve the ranker fields = { 'link_id': student_proposal.DEF_RANKER_NAME, 'scope': org_entity } ranker_root = ranker_root_logic.getForFields(fields, unique=True) ranker = ranker_root_logic.getRootFromEntity(ranker_root) status = {} program_entity = org_entity.scope # only when the program allows allocations # we show that proposals are likely to be # accepted or rejected if program_entity.allocations_visible: proposals = sp_logic.getProposalsToBeAcceptedForOrg(org_entity) duplicate_proposals = [] # get all the duplicate entities if duplicates can be shown # to the organizations and make a list of all such proposals. if program_entity.duplicates_visible: duplicate_properties = { 'orgs': org_entity, 'is_duplicate': True } duplicates = pd_logic.getForFields(duplicate_properties) for duplicate in duplicates: duplicate_proposals.extend(duplicate.duplicates) for proposal in proposals: proposal_key = proposal.key() if proposal.status == 'pending' and proposal_key in duplicate_proposals: status[proposal_key] = """<strong><font color="red"> Duplicate</font></strong>""" else: status[proposal_key] = """<strong><font color="green"> Pending acceptance</font><strong>""" filter = { 'org': org_entity, 'status': ['accepted', 'pending', 'rejected'] } # some extras for the list args = [ranker, status] visibility = 'review' elif idx == 2: # check if the current user is a mentor user_entity = user_logic.getCurrentUser() fields = { 'user': user_entity, 'scope': org_entity, 'status': ['active', 'inactive'] } mentor_entity = mentor_logic.getForFields(fields, unique=True) filter = { 'org': org_entity, 'mentor': mentor_entity, 'status': ['pending', 'accepted', 'rejected'] } elif idx == 3: filter = {'org': org_entity, 'status': 'invalid'} else: return lists.getErrorResponse(request, "idx not valid") params = params_collection[idx] contents = helper.lists.getListData(request, params, filter, visibility=visibility, args=args) return lists.getResponse(request, contents)
def getListProposalsData(self, request, params_collection, org_entity): """Returns the list data for listProposals. Args: request: HTTPRequest object params_collection: List of list Params indexed with the idx of the list org_entity: GSoCOrganization entity for which the lists are generated """ from soc.modules.gsoc.logic.models.proposal_duplicates import logic \ as pd_logic from soc.modules.gsoc.logic.models.ranker_root import logic \ as ranker_root_logic idx = lists.getListIndex(request) # default list settings args = [] visibility = None if idx == 0: filter = {'org': org_entity, 'status': 'new'} elif idx == 1: # retrieve the ranker fields = {'link_id': student_proposal.DEF_RANKER_NAME, 'scope': org_entity} ranker_root = ranker_root_logic.getForFields(fields, unique=True) ranker = ranker_root_logic.getRootFromEntity(ranker_root) status = {} program_entity = org_entity.scope # only when the program allows allocations # we show that proposals are likely to be # accepted or rejected if program_entity.allocations_visible: proposals = sp_logic.getProposalsToBeAcceptedForOrg(org_entity) duplicate_proposals = [] # get all the duplicate entities if duplicates can be shown # to the organizations and make a list of all such proposals. if program_entity.duplicates_visible: duplicate_properties = { 'orgs': org_entity, 'is_duplicate': True } duplicates = pd_logic.getForFields(duplicate_properties) for duplicate in duplicates: duplicate_proposals.extend(duplicate.duplicates) for proposal in proposals: proposal_key = proposal.key() if proposal.status == 'pending' and proposal_key in duplicate_proposals: status[proposal_key] = """<strong><font color="red"> Duplicate</font></strong>""" else: status[proposal_key] = """<strong><font color="green"> Pending acceptance</font><strong>""" filter = {'org': org_entity, 'status': ['accepted','pending','rejected']} # some extras for the list args = [ranker, status] visibility = 'review' elif idx == 2: # check if the current user is a mentor user_entity = user_logic.getCurrentUser() fields = {'user': user_entity, 'scope': org_entity, 'status': ['active', 'inactive']} mentor_entity = mentor_logic.getForFields(fields, unique=True) filter = {'org': org_entity, 'mentor': mentor_entity, 'status': ['pending', 'accepted', 'rejected']} elif idx == 3: filter = {'org': org_entity, 'status': 'invalid'} else: return lists.getErrorResponse(request, "idx not valid") params = params_collection[idx] contents = helper.lists.getListData(request, params, filter, visibility=visibility, args=args) return lists.getResponse(request, contents)
def assignedProposals(self, request, access_type, page_name=None, params=None, filter=None, **kwargs): """Returns a JSON dict containing all the proposals that would have a slot assigned for a specific set of orgs. The request.GET limit and offset determines how many and which organizations should be returned. For params see base.View.public(). Returns: JSON object with a collection of orgs and proposals. Containing identification information and contact information. """ get_dict = request.GET if not (get_dict.get('limit') and get_dict.get('offset')): return self.json(request, {}) try: limit = max(0, int(get_dict['limit'])) offset = max(0, int(get_dict['offset'])) except ValueError: return self.json(request, {}) program_entity = program_logic.getFromKeyFieldsOr404(kwargs) fields = {'scope': program_entity, 'slots >': 0, 'status': 'active'} org_entities = org_logic.logic.getForFields(fields, limit=limit, offset=offset) orgs_data = {} proposals_data = [] # for each org get the proposals who will be assigned a slot for org in org_entities: org_data = {'name': org.name} fields = {'scope': org, 'status': 'active', 'user': org.founder} org_admin = org_admin_logic.getForFields(fields, unique=True) if org_admin: # pylint: disable-msg=E1103 org_data['admin_name'] = org_admin.name() org_data['admin_email'] = org_admin.email proposals = student_proposal_logic.getProposalsToBeAcceptedForOrg( org, step_size=program_entity.max_slots) if not proposals: # nothing to accept, next organization continue # store information about the org orgs_data[org.key().id_or_name()] = org_data # store each proposal in the dictionary for proposal in proposals: student_entity = proposal.scope proposals_data.append({ 'key_name': proposal.key().id_or_name(), 'proposal_title': proposal.title, 'student_key': student_entity.key().id_or_name(), 'student_name': student_entity.name(), 'student_contact': student_entity.email, 'org_key': org.key().id_or_name() }) # return all the data in JSON format data = {'orgs': orgs_data, 'proposals': proposals_data} return self.json(request, data)
def assignedProposals(self, request, access_type, page_name=None, params=None, filter=None, **kwargs): """Returns a JSON dict containing all the proposals that would have a slot assigned for a specific set of orgs. The request.GET limit and offset determines how many and which organizations should be returned. For params see base.View.public(). Returns: JSON object with a collection of orgs and proposals. Containing identification information and contact information. """ get_dict = request.GET if not (get_dict.get('limit') and get_dict.get('offset')): return self.json(request, {}) try: limit = max(0, int(get_dict['limit'])) offset = max(0, int(get_dict['offset'])) except ValueError: return self.json(request, {}) program_entity = program_logic.getFromKeyFieldsOr404(kwargs) fields = {'scope': program_entity, 'slots >': 0, 'status': 'active'} org_entities = org_logic.getForFields(fields, limit=limit, offset=offset) orgs_data = {} proposals_data = [] # for each org get the proposals who will be assigned a slot for org in org_entities: org_data = {'name': org.name} fields = {'scope': org, 'status': 'active', 'user': org.founder} org_admin = org_admin_logic.getForFields(fields, unique=True) if org_admin: # pylint: disable=E1103 org_data['admin_name'] = org_admin.name() org_data['admin_email'] = org_admin.email proposals = student_proposal_logic.getProposalsToBeAcceptedForOrg( org, step_size=program_entity.max_slots) if not proposals: # nothing to accept, next organization continue # store information about the org orgs_data[org.key().id_or_name()] = org_data # store each proposal in the dictionary for proposal in proposals: student_entity = proposal.scope proposals_data.append( {'key_name': proposal.key().id_or_name(), 'proposal_title': proposal.title, 'student_key': student_entity.key().id_or_name(), 'student_name': student_entity.name(), 'student_contact': student_entity.email, 'org_key': org.key().id_or_name() }) # return all the data in JSON format data = {'orgs': orgs_data, 'proposals': proposals_data} return self.json(request, data)
def calculate(request, *args, **kwargs): """Calculates the duplicate proposals in a given program for a student on a per Organization basis. Expects the following to be present in the POST dict: program_key: Specifies the program key name for which to find the duplicate proposals org_cursor: Specifies the organization datastore cursor from which to start the processing of finding the duplicate proposals Args: request: Django Request object """ from soc.modules.gsoc.logic.models.student_proposal import logic \ as sp_logic post_dict = request.POST program_key = post_dict.get('program_key') if not program_key: # invalid task data, log and return OK return error_handler.logErrorAndReturnOK( 'Invalid program key: %s' % post_dict) 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) fields = {'scope': program_entity, 'slots >': 0, 'status': 'active'} # get the organization and update the cursor if possible q = org_logic.getQueryForFields(fields) # retrieve the org_cursor from POST data org_cursor = post_dict.get('org_cursor') if org_cursor: org_cursor = str(org_cursor) q.with_cursor(org_cursor) result = q.fetch(1) # update the cursor org_cursor = q.cursor() if result: org_entity = result[0] # get all the proposals likely to be accepted in the program accepted_proposals = sp_logic.getProposalsToBeAcceptedForOrg(org_entity) for ap in accepted_proposals: student_entity = ap.scope proposal_duplicate = pd_logic.getForFields({'student': student_entity}, unique=True) if proposal_duplicate and ap.key() not in proposal_duplicate.duplicates: # non-counted (to-be) accepted proposal found pd_fields = { 'duplicates': proposal_duplicate.duplicates + [ap.key()], } pd_fields['is_duplicate'] = len(pd_fields['duplicates']) >= 2 if org_entity.key() not in proposal_duplicate.orgs: pd_fields['orgs'] = proposal_duplicate.orgs + [org_entity.key()] proposal_duplicate = pd_logic.updateEntityProperties( proposal_duplicate, pd_fields) else: pd_fields = { 'program': program_entity, 'student': student_entity, 'orgs':[org_entity.key()], 'duplicates': [ap.key()], 'is_duplicate': False } proposal_duplicate = pd_logic.updateOrCreateFromFields(pd_fields) # Adds a new task that performs duplicate calculation for # the next organization. task_params = {'program_key': program_key, 'org_cursor': unicode(org_cursor)} task_url = '/tasks/gsoc/proposal_duplicates/calculate' new_task = taskqueue.Task(params=task_params, url=task_url) new_task.add() else: # There aren't any more organizations to process. So delete # all the proposals for which there are not more than one # proposal for duplicates property. pd_logic.deleteAllForProgram(program_entity, non_dupes_only=True) # update the proposal duplicate status and its timestamp pds_entity = pds_logic.getOrCreateForProgram(program_entity) new_fields = {'status': 'idle', 'calculated_on': datetime.datetime.now()} pds_logic.updateEntityProperties(pds_entity, new_fields) # return OK return http.HttpResponse()