def _constructFilterForProjectSelection(self, survey, params): """Returns the filter needed for the Project selection view. Constructs a filter that returns all valid projects for which the current user is the mentor. Only for the projects in the program given by the survey's scope of course. For args see project_survey.View._constructFilterForProjectSelection(). """ from soc.modules.gsoc.logic.models.mentor import logic as mentor_logic survey_logic = params['logic'] user_entity = user_logic.getCurrentUser() # get the mentor entities for the current user and program fields = {'user': user_entity, 'program': survey_logic.getScope(survey), 'status': 'active'} mentor_entities = mentor_logic.getForFields(fields) # TODO: Ensure that this doesn't break when someone is a mentor for # a lot of organizations. fields = {'mentor': mentor_entities, 'status': 'accepted'} return fields
def _editPost(self, request, entity, fields): """See base.View._editPost(). """ if not entity: fields['link_id'] = 't%i' % (int(time.time()*100)) else: fields['link_id'] = entity.link_id # fill in the scope via call to super super(View, self)._editPost(request, entity, fields) # editing a project so set the program, student and mentor field if entity: organization = entity.scope else: organization = fields['scope'] fields['program'] = organization.scope filter = {'scope': fields['program'], 'link_id': fields['student_id']} fields['student'] = student_logic.logic.getForFields(filter, unique=True) filter = {'scope': organization, 'link_id': fields['mentor_id'], 'status': 'active'} fields['mentor'] = mentor_logic.getForFields(filter, unique=True)
def _editPost(self, request, entity, fields): """See base.View._editPost(). """ if not entity: fields['link_id'] = 't%i' % (int(time.time()*100)) else: fields['link_id'] = entity.link_id # fill in the scope via call to super super(View, self)._editPost(request, entity, fields) # editing a project so set the program, student and mentor field if entity: organization = entity.scope else: organization = fields['scope'] fields['program'] = organization.scope filter = {'scope': fields['program'], 'link_id': fields['student_id']} fields['student'] = student_logic.logic.getForFields(filter, unique=True) filter = {'scope': organization, 'link_id': fields['mentor_id'], 'status': 'active'} fields['mentor'] = mentor_logic.getForFields(filter, unique=True)
def _getResultsViewRecordFields(self, survey, allowed_to_read): """Get the Results View filter for ProjectSurveyRecords. For args see survey.View()._getResultsViewRecordFields() Returns: Returns the dictionary containing the fields to filter on """ from soc.modules.gsoc.logic.models.mentor import logic as mentor_logic from soc.modules.gsoc.logic.models.org_admin import logic as \ org_admin_logic if allowed_to_read: return super(View, self)._getResultsViewRecordFields(survey, allowed_to_read) fields = {'survey': survey} user_entity = user_logic.getCurrentUser() program_entity = survey.scope role_fields = {'user': user_entity, 'program': program_entity, 'status': ['active', 'inactive']} org_admins = org_admin_logic.getForFields(role_fields) mentors = mentor_logic.getForFields(role_fields) organizations = {} if org_admins: for org_admin in org_admins: # for each org admin store the organization org_scope = org_admin.scope org_key_name = org_scope.key().id_or_name() organizations[org_key_name] = org_scope if mentors: for mentor in mentors: # for each mentor store the organization # This will allow the user to view the GradingProjectSurvey Records # listing for projects which he might have no further access to. org_scope = mentor.scope org_key_name = org_scope.key().id_or_name() organizations[org_key_name] = org_scope if organizations: # filter on all the found organizations fields['org'] = organizations.values() else: # This user is no org admin or mentor and should only see # his/her own records. fields['user'] = user_entity return fields
def _manageSetMentor(self, request, template, context, params, entity, form): """Handles the POST request for changing a Projects's mentor. Args: template: the template used for this view entity: the student project entity form: instance of the form used to set the mentor rest: see base.View.public() """ if not form.is_valid(): context['mentor_edit_form'] = form # add an a fresh additional mentors form context['additional_mentor_form'] = params[ 'additional_mentor_form']() return responses.respond(request, template, context) _, fields = forms_helper.collectCleanedFields(form) # get the mentor from the form fields = { 'link_id': fields['mentor_id'], 'scope': entity.scope, 'status': 'active' } mentor = mentor_logic.getForFields(fields, unique=True) # update the project with the assigned mentor fields = {'mentor': mentor} additional_mentors = entity.additional_mentors # pylint: disable=E1103 if additional_mentors and mentor.key() in additional_mentors: # remove the mentor that is now becoming the primary mentor additional_mentors.remove(mentor.key()) fields['additional_mentors'] = additional_mentors # update the project with the new mentor and possible # new set of additional mentors project_logic.updateEntityProperties(entity, fields) # redirect to the same page redirect = request.path return http.HttpResponseRedirect(redirect)
def _manageSetMentor(self, request, template, context, params, entity, form): """Handles the POST request for changing a Projects's mentor. Args: template: the template used for this view entity: the student project entity form: instance of the form used to set the mentor rest: see base.View.public() """ if not form.is_valid(): context['mentor_edit_form'] = form # add an a fresh additional mentors form context['additional_mentor_form'] = params['additional_mentor_form']() return responses.respond(request, template, context) _, fields = forms_helper.collectCleanedFields(form) # get the mentor from the form fields = {'link_id': fields['mentor_id'], 'scope': entity.scope, 'status': 'active'} mentor = mentor_logic.getForFields(fields, unique=True) # update the project with the assigned mentor fields = {'mentor': mentor} additional_mentors = entity.additional_mentors # pylint: disable=E1103 if additional_mentors and mentor.key() in additional_mentors: # remove the mentor that is now becoming the primary mentor additional_mentors.remove(mentor.key()) fields['additional_mentors'] = additional_mentors # update the project with the new mentor and possible # new set of additional mentors project_logic.updateEntityProperties(entity, fields) # redirect to the same page redirect = request.path return http.HttpResponseRedirect(redirect)
def _manageAddAdditionalMentor(self, request, template, context, params, entity, form): """Handles the POST request for changing a Projects's additional mentors. Args: template: the template used for this view entity: the student project entity form: instance of the form used to add an additional mentor rest: see base.View.public() """ if not form.is_valid(): context['additional_mentor_form'] = form # add a fresh edit mentor form initial = {'mentor_id': entity.mentor.link_id} context['mentor_edit_form'] = params['mentor_edit_form']( initial=initial) return responses.respond(request, template, context) _, fields = forms_helper.collectCleanedFields(form) # get the mentor from the form fields = { 'link_id': fields['mentor_id'], 'scope': entity.scope, 'status': 'active' } mentor = mentor_logic.getForFields(fields, unique=True) # add this mentor to the additional mentors if not entity.additional_mentors: additional_mentors = [mentor.key()] else: additional_mentors = entity.additional_mentors additional_mentors.append(mentor.key()) fields = {'additional_mentors': additional_mentors} project_logic.updateEntityProperties(entity, fields) # redirect to the same page redirect = request.path return http.HttpResponseRedirect(redirect)
def _manageAddAdditionalMentor(self, request, template, context, params, entity, form): """Handles the POST request for changing a Projects's additional mentors. Args: template: the template used for this view entity: the student project entity form: instance of the form used to add an additional mentor rest: see base.View.public() """ if not form.is_valid(): context['additional_mentor_form'] = form # add a fresh edit mentor form initial = {'mentor_id': entity.mentor.link_id} context['mentor_edit_form'] = params['mentor_edit_form'](initial=initial) return responses.respond(request, template, context) _, fields = forms_helper.collectCleanedFields(form) # get the mentor from the form fields = {'link_id': fields['mentor_id'], 'scope': entity.scope, 'status': 'active'} mentor = mentor_logic.getForFields(fields, unique=True) # add this mentor to the additional mentors if not entity.additional_mentors: additional_mentors = [mentor.key()] else: additional_mentors = entity.additional_mentors additional_mentors.append(mentor.key()) fields = {'additional_mentors': additional_mentors} project_logic.updateEntityProperties(entity, fields) # redirect to the same page redirect = request.path return http.HttpResponseRedirect(redirect)
def manageGet(self, request, template, context, params, entity, **kwargs): """Handles the GET request for the project's manage page. Args: template: the template used for this view entity: the student project entity rest: see base.View.public() """ get_dict = request.GET if 'remove' in get_dict and entity.status == 'accepted': # get the mentor to remove fields = {'link_id': get_dict['remove'], 'scope': entity.scope} mentor = mentor_logic.getForFields(fields, unique=True) additional_mentors = entity.additional_mentors # pylint: disable=E1103 if additional_mentors and mentor.key() in additional_mentors: # remove the mentor from the additional mentors list additional_mentors.remove(mentor.key()) fields = {'additional_mentors': additional_mentors} project_logic.updateEntityProperties(entity, fields) # redirect to the same page without GET arguments redirect = request.path return http.HttpResponseRedirect(redirect) if project_logic.canChangeMentors(entity): # populate forms with the current mentors set initial = {'mentor_id': entity.mentor.link_id} context['mentor_edit_form'] = params['mentor_edit_form']( initial=initial) context['additional_mentor_form'] = params[ 'additional_mentor_form']() return responses.respond(request, template, context)
def manageGet(self, request, template, context, params, entity, **kwargs): """Handles the GET request for the project's manage page. Args: template: the template used for this view entity: the student project entity rest: see base.View.public() """ get_dict = request.GET if 'remove' in get_dict and entity.status == 'accepted': # get the mentor to remove fields = {'link_id': get_dict['remove'], 'scope': entity.scope} mentor = mentor_logic.getForFields(fields, unique=True) additional_mentors = entity.additional_mentors # pylint: disable=E1103 if additional_mentors and mentor.key() in additional_mentors: # remove the mentor from the additional mentors list additional_mentors.remove(mentor.key()) fields = {'additional_mentors': additional_mentors} project_logic.updateEntityProperties(entity, fields) # redirect to the same page without GET arguments redirect = request.path return http.HttpResponseRedirect(redirect) if project_logic.canChangeMentors(entity): # populate forms with the current mentors set initial = {'mentor_id': entity.mentor.link_id} context['mentor_edit_form'] = params['mentor_edit_form'](initial=initial) context['additional_mentor_form'] = params['additional_mentor_form']() return responses.respond(request, template, context)
def checkRoleAndStatusForStudentProposal(self, django_args, allowed_roles, role_status, proposal_status): """Checks if the current user has access to the given proposal. Args: django_args: a dictionary with django's arguments allowed_roles: list with names for the roles allowed to pass access check role_status: list with states allowed for the role proposal_status: a list with states allowed for the proposal Raises: AccessViolationResponse: - If there is no proposal found - If the proposal is not in one of the required states. - If the user does not have any ofe the required roles """ self.checkIsUser(django_args) # bail out with 404 if no proposal is found proposal_entity = student_proposal_logic.getFromKeyFieldsOr404( django_args) if not proposal_entity.status in proposal_status: # this proposal can not be accessed at the moment raise out_of_band.AccessViolation( message_fmt=access.DEF_NO_ACTIVE_ENTITY_MSG) user_entity = self.user if 'proposer' in allowed_roles: # check if this proposal belongs to the current user student_entity = proposal_entity.scope if (user_entity.key() == student_entity.user.key()) and (student_entity.status in role_status): return filter = {'user': user_entity, 'status': role_status} if 'host' in allowed_roles: # check if the current user is a host for this proposal's program filter['scope'] = proposal_entity.program.scope if host_logic.getForFields(filter, unique=True): return if 'org_admin' in allowed_roles: # check if the current user is an admin for this proposal's org filter['scope'] = proposal_entity.org if org_admin_logic.getForFields(filter, unique=True): return if 'mentor' in allowed_roles: # check if the current user is a mentor for this proposal's org filter['scope'] = proposal_entity.org if mentor_logic.getForFields(filter, unique=True): return # no roles found, access denied raise out_of_band.AccessViolation(message_fmt=access.DEF_NEED_ROLE_MSG)
def _getTimeDependentEntries(self, program_entity, params, id, user): """Returns a list with time dependent menu items. """ items = [] timeline_entity = program_entity.timeline org_app_survey = org_app_logic.getForProgram(program_entity) if org_app_survey and \ timeline_helper.isActivePeriod(org_app_survey, 'survey'): # add the organization signup link items += [ (redirects.getTakeSurveyRedirect( org_app_survey, {'url_name': 'gsoc/org_app'}), "Apply to become an Organization", 'any_access')] if user and org_app_survey and timeline_helper.isAfterEvent( org_app_survey, 'survey_start'): main_admin_fields = { 'main_admin': user, 'survey': org_app_survey, } backup_admin_fields = { 'backup_admin': user, 'survey': org_app_survey } org_app_record_logic = org_app_logic.getRecordLogic() if org_app_record_logic.getForFields(main_admin_fields, unique=True) or \ org_app_record_logic.getForFields(backup_admin_fields, unique=True): # add the 'List my Organization Applications' link items += [ (redirects.getListSelfRedirect(org_app_survey, {'url_name' : 'gsoc/org_app'}), "List My Organization Applications", 'any_access')] # get the student entity for this user and program filter = { 'user': user, 'scope': program_entity, 'status': ['active', 'inactive'] } student_entity = student_logic.getForFields(filter, unique=True) if student_entity: items += self._getStudentEntries(program_entity, student_entity, params, id, user, 'gsoc') # get mentor and org_admin entity for this user and program filter = { 'user': user, 'program': program_entity, 'status': ['active', 'inactive'] } mentor_entity = mentor_logic.getForFields(filter, unique=True) org_admin_entity = org_admin_logic.getForFields(filter, unique=True) if mentor_entity or org_admin_entity: items += self._getOrganizationEntries(program_entity, org_admin_entity, mentor_entity, params, id, user) if not (student_entity or mentor_entity or org_admin_entity): if timeline_helper.isActivePeriod(timeline_entity, 'student_signup'): # this user does not have a role yet for this program items += [ ('/gsoc/student/apply/%s' % (program_entity.key().id_or_name()), "Register as a Student", 'any_access')] deadline = 'accepted_organization_announced_deadline' if timeline_helper.isAfterEvent(timeline_entity, deadline): url = redirects.getAcceptedOrgsRedirect(program_entity, params) # add a link to list all the organizations items += [(url, "List participating Organizations", 'any_access')] if not student_entity and \ timeline_helper.isBeforeEvent(timeline_entity, 'program_end'): # add apply to become a mentor link items += [ ('/gsoc/org/apply_mentor/%s' % (program_entity.key().id_or_name()), "Apply to become a Mentor", 'any_access')] deadline = 'accepted_students_announced_deadline' if timeline_helper.isAfterEvent(timeline_entity, deadline): items += [(redirects.getListProjectsRedirect(program_entity, {'url_name':'gsoc/program'}), "List all Student Projects", 'any_access')] return items
def _enableMentorManagement(self, entity, params, context): """Sets the data required to manage mentors for a StudentProject. Args: entity: StudentProject entity to manage params: params dict for the manage view context: context for the manage view """ context['can_manage_mentors'] = True # get all mentors for this organization fields = {'scope': entity.scope, 'status': 'active'} mentors = mentor_logic.getForFields(fields) choices = [(mentor.link_id,'%s (%s)' %(mentor.name(), mentor.link_id)) for mentor in mentors] # create the form that org admins will use to reassign a mentor dynafields = [ {'name': 'mentor_id', 'base': forms.ChoiceField, 'label': 'Primary Mentor', 'required': True, 'passthrough': ['required', 'choices', 'label'], 'choices': choices, },] dynaproperties = params_helper.getDynaFields(dynafields) mentor_edit_form = dynaform.newDynaForm( dynabase = params['dynabase'], dynaproperties = dynaproperties, ) params['mentor_edit_form'] = mentor_edit_form additional_mentors = entity.additional_mentors # we want to show the names of the additional mentors in the context # therefore they need to be resolved to entities first additional_mentors_context = [] for mentor_key in additional_mentors: mentor_entity = mentor_logic.getFromKeyName( mentor_key.id_or_name()) additional_mentors_context.append(mentor_entity) context['additional_mentors'] = additional_mentors_context # all mentors who are not already an additional mentor or # the primary mentor are allowed to become an additional mentor possible_additional_mentors = [m for m in mentors if (m.key() not in additional_mentors) and (m.key() != entity.mentor.key())] # create the information to be shown on the additional mentor form additional_mentor_choices = [ (mentor.link_id,'%s (%s)' %(mentor.name(), mentor.link_id)) for mentor in possible_additional_mentors] dynafields = [ {'name': 'mentor_id', 'base': forms.ChoiceField, 'label': 'Co-Mentor', 'required': True, 'passthrough': ['required', 'choices', 'label'], 'choices': additional_mentor_choices, },] dynaproperties = params_helper.getDynaFields(dynafields) additional_mentor_form = dynaform.newDynaForm( dynabase = params['dynabase'], dynaproperties = dynaproperties, ) params['additional_mentor_form'] = additional_mentor_form
def checkRoleAndStatusForStudentProposal(self, django_args, allowed_roles, role_status, proposal_status): """Checks if the current user has access to the given proposal. Args: django_args: a dictionary with django's arguments allowed_roles: list with names for the roles allowed to pass access check role_status: list with states allowed for the role proposal_status: a list with states allowed for the proposal Raises: AccessViolationResponse: - If there is no proposal found - If the proposal is not in one of the required states. - If the user does not have any ofe the required roles """ self.checkIsUser(django_args) # bail out with 404 if no proposal is found proposal_entity = student_proposal_logic.getFromKeyFieldsOr404(django_args) if not proposal_entity.status in proposal_status: # this proposal can not be accessed at the moment raise out_of_band.AccessViolation( message_fmt=access.DEF_NO_ACTIVE_ENTITY_MSG) user_entity = self.user if 'proposer' in allowed_roles: # check if this proposal belongs to the current user student_entity = proposal_entity.scope if (user_entity.key() == student_entity.user.key()) and ( student_entity.status in role_status): return filter = {'user': user_entity, 'status': role_status} if 'host' in allowed_roles: # check if the current user is a host for this proposal's program filter['scope'] = proposal_entity.program.scope if host_logic.getForFields(filter, unique=True): return if 'org_admin' in allowed_roles: # check if the current user is an admin for this proposal's org filter['scope'] = proposal_entity.org if org_admin_logic.getForFields(filter, unique=True): return if 'mentor' in allowed_roles: # check if the current user is a mentor for this proposal's org filter['scope'] = proposal_entity.org if mentor_logic.getForFields(filter, unique=True): return # no roles found, access denied raise out_of_band.AccessViolation( message_fmt=access.DEF_NEED_ROLE_MSG)
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 _getTimeDependentEntries(self, program_entity, params, id, user): """Returns a list with time dependent menu items. """ from soc.modules.gsoc.logic.models.org_app_survey import logic as \ org_app_logic items = [] timeline_entity = program_entity.timeline org_app_survey = org_app_logic.getForProgram(program_entity) if org_app_survey and \ timeline_helper.isActivePeriod(timeline_entity, 'org_signup'): # add the organization signup link items += [ (redirects.getTakeSurveyRedirect(org_app_survey, {'url_name': 'gsoc/org_app'}), "Apply to become an Organization", 'any_access') ] if user and org_app_survey and timeline_helper.isAfterEvent( timeline_entity, 'org_signup_start'): main_admin_fields = { 'main_admin': user, 'survey': org_app_survey, } backup_admin_fields = { 'backup_admin': user, 'survey': org_app_survey } org_app_record_logic = org_app_logic.getRecordLogic() if org_app_record_logic.getForFields(main_admin_fields, unique=True) or \ org_app_record_logic.getForFields(backup_admin_fields, unique=True): # add the 'List my Organization Applications' link items += [(redirects.getListSelfRedirect( org_app_survey, {'url_name': 'gsoc/org_app'}), "List My Organization Applications", 'any_access')] # get the student entity for this user and program filter = { 'user': user, 'scope': program_entity, 'status': ['active', 'inactive'] } student_entity = student_logic.getForFields(filter, unique=True) if student_entity: items += self._getStudentEntries(program_entity, student_entity, params, id, user, 'gsoc') # get mentor and org_admin entity for this user and program filter = { 'user': user, 'program': program_entity, 'status': ['active', 'inactive'] } mentor_entity = mentor_logic.getForFields(filter, unique=True) org_admin_entity = org_admin_logic.getForFields(filter, unique=True) if mentor_entity or org_admin_entity: items += self._getOrganizationEntries(program_entity, org_admin_entity, mentor_entity, params, id, user) if user and not (student_entity or mentor_entity or org_admin_entity): if timeline_helper.isActivePeriod(timeline_entity, 'student_signup'): # this user does not have a role yet for this program items += [('/gsoc/student/apply/%s' % (program_entity.key().id_or_name()), "Register as a Student", 'any_access')] deadline = 'accepted_organization_announced_deadline' if timeline_helper.isAfterEvent(timeline_entity, deadline): url = redirects.getAcceptedOrgsRedirect(program_entity, params) # add a link to list all the organizations items += [(url, "List participating Organizations", 'any_access')] if not student_entity and \ timeline_helper.isBeforeEvent(timeline_entity, 'program_end'): # add apply to become a mentor link items += [('/gsoc/org/apply_mentor/%s' % (program_entity.key().id_or_name()), "Apply to become a Mentor", 'any_access')] deadline = 'accepted_students_announced_deadline' if timeline_helper.isAfterEvent(timeline_entity, deadline): items += [(redirects.getListProjectsRedirect( program_entity, {'url_name': 'gsoc/program'}), "List all Student Projects", 'any_access')] return items
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)
class View(organization.View): """View methods for the Organization model. """ def __init__(self, params=None): """Defines the fields and methods required for the base View class to provide the user with list, public, create, edit and delete views. Params: params: a dict with params for this View """ rights = access.GSoCChecker(params) rights['any_access'] = ['allow'] rights['show'] = ['allow'] rights['create'] = ['checkIsDeveloper'] rights['edit'] = [('checkHasRoleForKeyFieldsAsScope', org_admin_logic), ('checkGroupIsActiveForLinkId', org_logic)] rights['delete'] = ['checkIsDeveloper'] rights['home'] = ['allow'] rights['public_list'] = ['allow'] rights['applicant'] = [('checkIsOrgAppAccepted', org_app_logic)] rights['apply_mentor'] = ['checkIsUser'] rights['list_requests'] = [('checkHasRoleForKeyFieldsAsScope', org_admin_logic)] rights['list_roles'] = [('checkHasRoleForKeyFieldsAsScope', org_admin_logic)] rights['list_proposals'] = [ ('checkHasAny', [[('checkHasRoleForKeyFieldsAsScope', [org_admin_logic, ['active', 'inactive']]), ('checkHasRoleForKeyFieldsAsScope', [mentor_logic, ['active', 'inactive']])]]) ] new_params = {} new_params['logic'] = org_logic new_params['rights'] = rights new_params['scope_view'] = program_view new_params['name'] = "GSoC Organization" new_params['module_name'] = "organization" new_params['sidebar_grouping'] = 'Organizations' new_params['module_package'] = 'soc.modules.gsoc.views.models' new_params['url_name'] = 'gsoc/org' new_params['document_prefix'] = 'gsoc_org' new_params['mentor_role_name'] = 'gsoc_mentor' new_params['mentor_url_name'] = 'gsoc/mentor' new_params['org_admin_role_name'] = 'gsoc_org_admin' patterns = [] patterns += [ (r'^org_tags/(?P<access_type>pick)$', '%(module_package)s.%(module_name)s.pick_suggested_tags', "Pick a list of suggested tags."), ] new_params['extra_django_patterns'] = patterns new_params['extra_dynaexclude'] = [ 'slots', 'slots_calculated', 'nr_applications', 'nr_mentors' ] new_params['create_extra_dynaproperties'] = { 'tags': widgets.ReferenceField( required=False, reference_url='org_tags', label=ugettext('Tags'), help_text=ugettext("A list of comma seperated tags"), example_text="e.g. python, django, appengine", filter=['scope_path'], group="1. Public Info"), 'clean_tags': gsoc_cleaning.cleanTagsList('tags', gsoc_cleaning.COMMA_SEPARATOR), 'contrib_template': forms.fields.CharField(widget=helper.widgets.FullTinyMCE( attrs={ 'rows': 25, 'cols': 100 })), 'clean_contrib_template': cleaning.clean_html_content('contrib_template'), 'clean_facebook': cleaning.clean_url('facebook'), 'clean_twitter': cleaning.clean_url('twitter'), 'clean_blog': cleaning.clean_url('blog'), } new_params['org_app_logic'] = org_app_logic params = dicts.merge(params, new_params, sub_merge=True) super(View, self).__init__(params) self._params['public_field_keys'].append('tags') self._params['public_field_names'].append("Tags") self._params['public_field_extra'] = lambda entity: { 'ideas': lists.urlize(entity.ideas, 'Click Here'), 'tags': entity.tags_string(entity.org_tag), } self._params['select_field_extra'] = self._params['public_field_extra'] def _editGet(self, request, entity, form): """See base.View._editGet(). """ if entity.org_tag: form.fields['tags'].initial = entity.tags_string(entity.org_tag) return super(View, self)._editGet(request, entity, form) def _editPost(self, request, entity, fields): """See base.View._editPost(). """ super(View, self)._editPost(request, entity, fields) fields['org_tag'] = { 'tags': fields['tags'], 'scope': entity.scope if entity else fields['scope'] } @decorators.check_access def pickSuggestedTags(self, request, access_type, page_name=None, params=None, **kwargs): """Returns a JSON representation of a list of organization tags that are suggested for a given GSoCProgram in scope. """ if 'scope_path' not in request.GET: data = [] else: program = program_logic.getFromKeyName( request.GET.get('scope_path')) if not program: data = [] else: fun = soc.cache.logic.cache(OrgTag.get_for_custom_query) suggested_tags = fun(OrgTag, filter={'scope': program}, order=None) # TODO: this should be refactored after the issue with autocompletion # is resolved data = simplejson.dumps({ 'data': [{ 'link_id': item['tag'] } for item in [dicts.toDict(tag, ['tag']) for tag in suggested_tags]], 'autocomplete_options': { 'multiple': True, 'selectFirst': False } }) return self.json(request, data, False) # TODO (dhans): merge common items with the GCI module in a single function def _getExtraMenuItems(self, role_description, params=None): """Used to create the specific Organization menu entries. For args see group.View._getExtraMenuItems(). """ submenus = [] group_entity = role_description['group'] program_entity = group_entity.scope roles = role_description['roles'] mentor_entity = roles.get('gsoc_mentor') admin_entity = roles.get('gsoc_org_admin') is_active_mentor = mentor_entity and mentor_entity.status == 'active' is_active_admin = admin_entity and admin_entity.status == 'active' if admin_entity or mentor_entity: # add a link to view all the student proposals submenu = (redirects.getListProposalsRedirect( group_entity, params), "Manage Student Proposals", 'any_access') submenus.append(submenu) # add a link to manage student projects after they have been announced if timeline_helper.isAfterEvent( program_entity.timeline, 'accepted_students_announced_deadline'): submenu = (redirects.getManageOverviewRedirect( group_entity, {'url_name': 'gsoc/student_project'}), "Manage Student Projects", 'any_access') submenus.append(submenu) if is_active_admin: # add a link to the management page submenu = (redirects.getListRolesRedirect(group_entity, params), "Manage Admins and Mentors", 'any_access') submenus.append(submenu) # add a link to invite an org admin submenu = (redirects.getInviteRedirectForRole( group_entity, 'gsoc/org_admin'), "Invite an Admin", 'any_access') submenus.append(submenu) # add a link to invite a member submenu = (redirects.getInviteRedirectForRole( group_entity, 'gsoc/mentor'), "Invite a Mentor", 'any_access') submenus.append(submenu) # add a link to the request page submenu = (redirects.getListRequestsRedirect(group_entity, params), "List Requests and Invites", 'any_access') submenus.append(submenu) # add a link to the edit page submenu = (redirects.getEditRedirect(group_entity, params), "Edit Organization Profile", 'any_access') submenus.append(submenu) if is_active_admin or is_active_mentor: submenu = (redirects.getCreateDocumentRedirect( group_entity, params['document_prefix']), "Create a New Document", 'any_access') submenus.append(submenu) submenu = (redirects.getListDocumentsRedirect( group_entity, params['document_prefix']), "List Documents", 'any_access') submenus.append(submenu) if is_active_admin: # add a link to the resign page submenu = (redirects.getManageRedirect( roles['gsoc_org_admin'], {'url_name': 'gsoc/org_admin'}), "Resign as Admin", 'any_access') submenus.append(submenu) # add a link to the edit page submenu = (redirects.getEditRedirect( roles['gsoc_org_admin'], {'url_name': 'gsoc/org_admin'}), "Edit My Admin Profile", 'any_access') submenus.append(submenu) if is_active_mentor: # add a link to the resign page submenu = (redirects.getManageRedirect( roles['gsoc_mentor'], {'url_name': 'gsoc/mentor'}), "Resign as Mentor", 'any_access') submenus.append(submenu) # add a link to the edit page submenu = (redirects.getEditRedirect(roles['gsoc_mentor'], {'url_name': 'gsoc/mentor'}), "Edit My Mentor Profile", 'any_access') submenus.append(submenu) return submenus 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) @decorators.merge_params @decorators.check_access def listProposals(self, request, access_type, page_name=None, params=None, **kwargs): """Lists all proposals for the organization given in kwargs. For params see base.View.public(). """ from soc.modules.gsoc.logic.models.proposal_duplicates_status import \ logic as ds_logic try: org_entity = self._logic.getFromKeyFieldsOr404(kwargs) except out_of_band.Error, error: return helper.responses.errorResponse( error, request, template=params['error_public']) program_entity = org_entity.scope is_after_deadline = timeline_helper.isAfterEvent( program_entity.timeline, 'accepted_students_announced_deadline') if is_after_deadline: redirect_fun = redirects.getProposalCommentRedirect else: redirect_fun = redirects.getReviewRedirect context = {} context['entity'] = org_entity # whether or not the amount of slots assigned should be shown context['slots_visible'] = org_entity.scope.allocations_visible # used to check the status of the duplicate process context['duplicate_status'] = ds_logic.getOrCreateForProgram( org_entity.scope) program_entity = org_entity.scope page_name = '%s %s (%s)' % (page_name, org_entity.name, program_entity.short_name) list_params = student_proposal_view.view.getParams().copy() list_params['list_template'] = 'soc/student_proposal/list_for_org.html' np_params = list_params.copy() # new proposals description = ugettext('List of new %s sent to %s') % ( np_params['name_plural'], org_entity.name) np_params['list_description'] = description np_params['public_row_extra'] = lambda entity: { 'link': redirect_fun(entity, np_params), } rp_params = list_params.copy() # ranked proposals rp_params['review_field_keys'] = [ 'rank', 'title', 'student', 'mentor', 'score', 'status', 'last_modified_on', 'abstract', 'content', 'additional_info', 'created_on' ] rp_params['review_field_hidden'] = [ 'abstract', 'content', 'additional_info', 'created_on' ] rp_params['review_field_names'] = [ 'Rank', 'Title', 'Student', 'Mentor', 'Score', 'Status', 'Last Modified On', 'Abstract', 'Content', 'Additional Info', 'Created On' ] rp_params['review_field_no_filter'] = ['status'] rp_params['review_field_prefetch'] = ['scope', 'mentor', 'program'] rp_params['review_field_extra'] = lambda entity, ranker, status: { 'rank': ranker.FindRanks([[entity.score]])[0] + 1, 'student': entity.scope.name(), 'mentor': entity.mentor.name() if entity.mentor else '%s Proposed' % len(entity.possible_mentors), 'status': status.get(entity.key(), '<font color="red">Pending rejection</font>') if ( entity.program.allocations_visible \ and entity.status == 'pending') else entity.status, } rp_params['review_row_action'] = { "type": "redirect_custom", "parameters": dict(new_window=True), } rp_params['review_row_extra'] = lambda entity, *args: { 'link': redirect_fun(entity, rp_params) } rp_params['review_field_props'] = { "score": { "sorttype": "integer", }, "rank": { "sorttype": "integer", }, } rp_params['review_conf_min_num'] = 50 description = ugettext('%s already under review sent to %s') % ( rp_params['name_plural'], org_entity.name) rp_params['list_description'] = description mp_params = list_params.copy() # proposals mentored by current user description = ugettext('List of %s sent to %s you are mentoring') % ( mp_params['name_plural'], org_entity.name) mp_params['list_description'] = description mp_params['public_row_extra'] = lambda entity: { 'link': redirect_fun(entity, mp_params) } ip_params = list_params.copy() # invalid proposals ip_params['list_description'] = ugettext( 'List of invalid %s sent to %s ') % (ip_params['name_plural'], org_entity.name) ip_params['public_row_extra'] = lambda entity: { 'link': redirect_fun(entity, ip_params) } if lists.isDataRequest(request): # retrieving data for a list return self.getListProposalsData( request, [np_params, rp_params, mp_params, ip_params], org_entity) # fill contents for all the needed lists contents = [] # check if there are new proposals if so show them in a separate list fields = {'org': org_entity, 'status': 'new'} new_proposal = sp_logic.getForFields(fields, unique=True) if new_proposal: # we should add this list because there is a new proposal np_list = helper.lists.getListGenerator(request, np_params, idx=0) contents.append(np_list) order = ['-score'] # the list of proposals that have been reviewed should always be shown rp_list = helper.lists.getListGenerator(request, rp_params, order=order, visibility='review', idx=1) contents.append(rp_list) # check whether the current user is a mentor for the organization user_entity = user_logic.getCurrentUser() fields = { 'user': user_entity, 'scope': org_entity, 'status': ['active', 'inactive'] } mentor_entity = mentor_logic.getForFields(fields, unique=True) if mentor_entity: # show the list of all proposals that this user is mentoring mp_list = helper.lists.getListGenerator(request, mp_params, idx=2) contents.append(mp_list) # check if there are invalid proposals if so show them in a separate list fields = {'org': org_entity, 'status': 'invalid'} invalid_proposal = sp_logic.getForFields(fields, unique=True) if invalid_proposal: ip_list = helper.lists.getListGenerator(request, ip_params, idx=3) contents.append(ip_list) return self._list(request, list_params, contents, page_name, context)
def _enableMentorManagement(self, entity, params, context): """Sets the data required to manage mentors for a StudentProject. Args: entity: StudentProject entity to manage params: params dict for the manage view context: context for the manage view """ context['can_manage_mentors'] = True # get all mentors for this organization fields = {'scope': entity.scope, 'status': 'active'} mentors = mentor_logic.getForFields(fields) choices = [(mentor.link_id,'%s (%s)' %(mentor.name(), mentor.link_id)) for mentor in mentors] # create the form that org admins will use to reassign a mentor dynafields = [ {'name': 'mentor_id', 'base': forms.ChoiceField, 'label': 'Primary Mentor', 'required': True, 'passthrough': ['required', 'choices', 'label'], 'choices': choices, },] dynaproperties = params_helper.getDynaFields(dynafields) mentor_edit_form = dynaform.newDynaForm( dynabase = params['dynabase'], dynaproperties = dynaproperties, ) params['mentor_edit_form'] = mentor_edit_form additional_mentors = entity.additional_mentors # we want to show the names of the additional mentors in the context # therefore they need to be resolved to entities first additional_mentors_context = [] for mentor_key in additional_mentors: mentor_entity = mentor_logic.getFromKeyName( mentor_key.id_or_name()) additional_mentors_context.append(mentor_entity) context['additional_mentors'] = additional_mentors_context # all mentors who are not already an additional mentor or # the primary mentor are allowed to become an additional mentor possible_additional_mentors = [m for m in mentors if (m.key() not in additional_mentors) and (m.key() != entity.mentor.key())] # create the information to be shown on the additional mentor form additional_mentor_choices = [ (mentor.link_id,'%s (%s)' %(mentor.name(), mentor.link_id)) for mentor in possible_additional_mentors] dynafields = [ {'name': 'mentor_id', 'base': forms.ChoiceField, 'label': 'Co-Mentor', 'required': True, 'passthrough': ['required', 'choices', 'label'], 'choices': additional_mentor_choices, },] dynaproperties = params_helper.getDynaFields(dynafields) additional_mentor_form = dynaform.newDynaForm( dynabase = params['dynabase'], dynaproperties = dynaproperties, ) params['additional_mentor_form'] = additional_mentor_form