def getCurrentTimeline(self, timeline, org_app): """Return where we are currently on the timeline. """ if timeline_helper.isActivePeriod(org_app, 'survey'): return 'org_signup_period' elif timeline_helper.isActivePeriod(timeline, 'student_signup'): return 'student_signup_period' elif timeline_helper.isActivePeriod(timeline, 'program'): return 'program_period' return 'offseason'
def getCurrentTimeline(self, timeline, org_app): """Return where we are currently on the timeline. """ if timeline_helper.isActivePeriod(org_app, "survey"): return "org_signup_period" elif timeline_helper.isActivePeriod(timeline, "student_signup"): return "student_signup_period" elif timeline_helper.isActivePeriod(timeline, "program"): return "program_period" return "offseason"
def checkIsActivePeriod(self, django_args, period_name, key_name_arg): """Checks if the given period is active for the given program. Args: django_args: a dictionary with django's arguments period_name: the name of the period 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 period is not active """ 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.isActivePeriod(program_entity.timeline, period_name): return raise out_of_band.AccessViolation(message_fmt=DEF_PAGE_INACTIVE_MSG)
def _getStudentEntries(self, program_entity, student_entity, params, id, user, prefix): """Returns a list with menu items for students in a specific program. """ items = [] timeline_entity = program_entity.timeline if timeline_helper.isActivePeriod(timeline_entity, 'student_signup') and \ student_entity.status == 'active': items += [('/gsoc/student_proposal/list_orgs/%s' % (student_entity.key().id_or_name()), "Submit your Student Proposal", 'any_access')] if timeline_helper.isAfterEvent(timeline_entity, 'student_signup_start'): items += [(redirects.getListSelfRedirect( student_entity, {'url_name': prefix + '/student_proposal'}), "List my Student Proposals", 'any_access')] if timeline_helper.isAfterEvent( timeline_entity, 'accepted_students_announced_deadline'): # add a link to show all projects items += [(redirects.getListProjectsRedirect( program_entity, {'url_name': prefix + '/student'}), "List my Student Projects", 'any_access')] items += super(View, self)._getStudentEntries(program_entity, student_entity, params, id, user, prefix) return items
def _getStudentEntries(self, program_entity, student_entity, params, id, user): """Returns a list with menu items for students in a specific program. """ items = [] timeline_entity = program_entity.timeline if timeline_helper.isActivePeriod(timeline_entity, 'student_signup'): items += [('/student_proposal/list_orgs/%s' % ( student_entity.key().id_or_name()), "Submit your Student Proposal", 'any_access')] if timeline_helper.isAfterEvent(timeline_entity, 'student_signup_start'): items += [(redirects.getListSelfRedirect(student_entity, {'url_name':'student_proposal'}), "List my Student Proposals", 'any_access')] items += [(redirects.getEditRedirect(student_entity, {'url_name': 'student'}), "Edit my Student Profile", 'any_access')] if timeline_helper.isAfterEvent(timeline_entity, 'accepted_students_announced_deadline'): # add a link to show all projects items += [(redirects.getListProjectsRedirect(program_entity, {'url_name':'student'}), "List my Student Projects", 'any_access')] return items
def testIsActivePeriod(self): """Tests if a correct boolean is returned if the current DateTime is between period_start and period_end. """ # program is going on. self.timeline.program_start = datetime.utcnow() - timedelta(10) self.timeline.program_end = datetime.utcnow() + timedelta(10) self.assertTrue(timeline.isActivePeriod(self.timeline, "program")) # program will start. self.timeline.program_start = datetime.utcnow() + timedelta(10) self.timeline.program_end = datetime.utcnow() + timedelta(20) self.assertFalse(timeline.isActivePeriod(self.timeline, "program")) # program has ended. self.timeline.program_start = datetime.utcnow() - timedelta(20) self.timeline.program_end = datetime.utcnow() - timedelta(10) self.assertFalse(timeline.isActivePeriod(self.timeline, "program")) # student sign up period will start self.timeline.student_signup_start = datetime.utcnow() + timedelta(10) self.timeline.student_signup_end = datetime.utcnow() + timedelta(30) self.assertFalse(timeline.isActivePeriod(self.timeline, "student_signup")) # student sign up period has not ended. self.timeline.student_signup_start = datetime.utcnow() - timedelta(10) self.timeline.student_signup_end = datetime.utcnow() + timedelta(20) self.assertTrue(timeline.isActivePeriod(self.timeline, "student_signup")) # student sign up period has already ended. self.timeline.student_signup_start = datetime.utcnow() - timedelta(30) self.timeline.student_signup_end = datetime.utcnow() - timedelta(20) self.assertFalse(timeline.isActivePeriod(self.timeline, "student_signup")) # event not in the timeline. self.assertFalse(timeline.isActivePeriod(self.timeline, "other_event"))
def getUniversalContext(request): """Constructs a template context dict will many common variables defined. Args: request: the Django HTTP request object Returns: a new context dict containing: { 'request': the Django HTTP request object passed in by the caller 'account': the logged-in Google Account if there is one 'user': the User entity corresponding to the Google Account in context['account'] 'is_admin': True if users.is_current_user_admin() is True 'is_debug': True if system.isDebug() is True 'sign_in': a Google Account login URL 'sign_out': a Google Account logout URL 'sidebar_menu_html': an HTML string that renders the sidebar menu } """ account = accounts.getCurrentAccount() user = None is_admin = False context = {} context['request'] = request if account: user = user_logic.getForAccount(account) is_admin = user_logic.isDeveloper(account=account, user=user) context['account'] = account context['user'] = user context['is_admin'] = is_admin context['is_local'] = system.isLocal() context['is_debug'] = system.isDebug() context['sign_in'] = users.create_login_url(request.path) context['sign_out'] = users.create_logout_url(request.path) context['sidebar_menu_items'] = callback.getCore().getSidebar(account, user) context['gae_version'] = system.getAppVersion() context['soc_release'] = system.getMelangeVersion() settings = site.logic.getSingleton() context['ga_tracking_num'] = settings.ga_tracking_num context['gmaps_api_key'] = settings.gmaps_api_key context['site_name'] = settings.site_name context['site_notice'] = settings.site_notice context['tos_link'] = redirects.getToSRedirect(settings) context['in_maintenance'] = timeline.isActivePeriod(site, 'maintenance') return context
def _getStudentEntries(self, gci_program_entity, student_entity, params, id, user, prefix): """Returns a list with menu items for students in a specific program. """ items = [] timeline_entity = gci_program_entity.timeline # this check is done because of the GCI student registration # specification mentioned in previous method, a user can have # a task and hence task listed without being a student if student_entity: items += super(View, self)._getStudentEntries(gci_program_entity, student_entity, params, id, user, prefix) if timeline_helper.isActivePeriod(timeline_entity, 'program'): items += [(gci_redirects.getSubmitFormsRedirect( student_entity, {'url_name': 'gci/student'}), "Submit Forms", 'any_access')] else: # add a sidebar entry for the user to register as student if not # since he has completed one task filter = { 'user': user, 'program': gci_program_entity, 'status': 'AwaitingRegistration' } if gci_task_logic.logic.getForFields(filter, unique=True): if timeline_helper.isActivePeriod(timeline_entity, 'student_signup'): # this user does not have a role yet for this program items += [(redirects.getStudentApplyRedirect( gci_program_entity, {'url_name': 'gci/student'}), "Register as a Student", 'any_access')] return items
def listSelf(self, request, access_type, page_name=None, params=None, **kwargs): """View that lists all the OrgAppRecords you have access to. For Args see base.View().public(). """ survey_logic = params['logic'] entity = survey_logic.getFromKeyFieldsOr404(kwargs) list_params = params['record_list_params'].copy() if timeline_helper.isActivePeriod(entity, 'survey'): info = {'url_name': params['url_name'], 'survey': entity} list_params['self_row_extra'] = lambda entity: { 'link': redirects.getRetakeOrgAppSurveyRedirect(entity, info) } else: list_params['self_row_extra'] = lambda entity: { 'link': redirects.getViewSurveyRecordRedirect(entity, params) } ma_params = list_params.copy() ma_params['list_description'] = \ 'List of Applications for which you are Main Admin.' ba_params = list_params.copy() ba_params['list_description'] = \ 'List of Applications for which your are Backup Admin.' if lists.isDataRequest(request): return self._getListSelfData(request, entity, ma_params, ba_params) ma_list = lists.getListGenerator(request, ma_params, visibility='self', idx=0) ba_list = lists.getListGenerator(request, ba_params, visibility='self', idx=1) contents = [ma_list, ba_list] return self._list(request, list_params, contents, page_name)
def _getStudentEntries(self, gci_program_entity, student_entity, params, id, user, prefix): """Returns a list with menu items for students in a specific program. """ items = [] timeline_entity = gci_program_entity.timeline # this check is done because of the GCI student registration # specification mentioned in previous method, a user can have # a task and hence task listed without being a student if student_entity: items += super(View, self)._getStudentEntries( gci_program_entity, student_entity, params, id, user, prefix) if timeline_helper.isActivePeriod(timeline_entity, 'program'): items += [ (gci_redirects.getSubmitFormsRedirect( student_entity, {'url_name': 'gci/student'}), "Submit Forms", 'any_access') ] else: # add a sidebar entry for the user to register as student if not # since he has completed one task filter = { 'user': user, 'program': gci_program_entity, 'status': 'AwaitingRegistration' } if gci_task_logic.logic.getForFields(filter, unique=True): if timeline_helper.isActivePeriod(timeline_entity, 'student_signup'): # this user does not have a role yet for this program items += [(redirects.getStudentApplyRedirect( gci_program_entity, {'url_name': 'gci/student'}), "Register as a Student", 'any_access')] return items
def view_wrapper(request, *args, **kwds): """View decorator wrapper method. """ try: site = site_logic.getSingleton() # don't redirect admins, or if we're at /maintenance already no_redirect = user_logic.isDeveloper() or request.path == "/maintenance" if (not no_redirect) and timeline.isActivePeriod(site, "maintenance"): return http.HttpResponseRedirect("/maintenance") return func(request, *args, **kwds) except DeadlineExceededError, exception: logging.exception(exception) return http.HttpResponseRedirect("/soc/content/deadline_exceeded.html")
def checkCanStudentPropose(self, django_args, key_location, check_limit): """Checks if the program for this student accepts proposals. Args: django_args: a dictionary with django's arguments key_location: the key for django_args in which the key_name from the student is stored check_limit: iff true checks if the student reached the apps_tasks_limit for the given program. """ from soc.logic.helper import timeline as timeline_helper self.checkIsUser(django_args) if django_args.get('seed'): key_name = django_args['seed'][key_location] else: key_name = django_args[key_location] student_entity = student_logic.getFromKeyName(key_name) if not student_entity or student_entity.status == 'invalid': raise out_of_band.AccessViolation( message_fmt=DEF_SIGN_UP_AS_STUDENT_MSG) program_entity = student_entity.scope if not timeline_helper.isActivePeriod(program_entity.timeline, 'student_signup'): raise out_of_band.AccessViolation( message_fmt=access.DEF_PAGE_INACTIVE_MSG) if check_limit: # count all studentproposals by the student fields = {'scope': student_entity} proposal_query = student_proposal_logic.getQueryForFields(fields) if proposal_query.count() >= program_entity.apps_tasks_limit: # too many proposals access denied raise out_of_band.AccessViolation( message_fmt=DEF_MAX_PROPOSALS_REACHED) return
def checkCanStudentPropose(self, django_args, key_location, check_limit): """Checks if the program for this student accepts proposals. Args: django_args: a dictionary with django's arguments key_location: the key for django_args in which the key_name from the student is stored check_limit: iff true checks if the student reached the apps_tasks_limit for the given program. """ from soc.logic.helper import timeline as timeline_helper self.checkIsUser(django_args) if django_args.get('seed'): key_name = django_args['seed'][key_location] else: key_name = django_args[key_location] student_entity = student_logic.getFromKeyName(key_name) if not student_entity or student_entity.status == 'invalid': raise out_of_band.AccessViolation( message_fmt=DEF_SIGN_UP_AS_STUDENT_MSG) program_entity = student_entity.scope if not timeline_helper.isActivePeriod(program_entity.timeline, 'student_signup'): raise out_of_band.AccessViolation(message_fmt=access.DEF_PAGE_INACTIVE_MSG) if check_limit: # count all studentproposals by the student fields = {'scope': student_entity} proposal_query = student_proposal_logic.getQueryForFields(fields) if proposal_query.count() >= program_entity.apps_tasks_limit: # too many proposals access denied raise out_of_band.AccessViolation(message_fmt=DEF_MAX_PROPOSALS_REACHED) return
def listSelf(self, request, access_type, page_name=None, params=None, **kwargs): """View that lists all the OrgAppRecords you have access to. For Args see base.View().public(). """ survey_logic = params['logic'] entity = survey_logic.getFromKeyFieldsOr404(kwargs) list_params = params['record_list_params'].copy() if timeline_helper.isActivePeriod(entity, 'survey'): info = {'url_name': params['url_name'], 'survey':entity} list_params['self_row_extra'] = lambda entity: { 'link': redirects.getRetakeOrgAppSurveyRedirect(entity, info) } else: list_params['self_row_extra'] = lambda entity: { 'link': redirects.getViewSurveyRecordRedirect(entity, params) } ma_params = list_params.copy() ma_params['list_description'] = \ 'List of Applications for which you are Main Admin.' ba_params = list_params.copy() ba_params['list_description'] = \ 'List of Applications for which your are Backup Admin.' if lists.isDataRequest(request): return self._getListSelfData(request, entity, ma_params, ba_params) ma_list = lists.getListGenerator(request, ma_params, visibility='self', idx=0) ba_list = lists.getListGenerator(request, ba_params, visibility='self', idx=1) contents = [ma_list, ba_list] return self._list(request, list_params, contents, page_name)
def _getStudentEntries(self, program_entity, student_entity, params, id, user, prefix): """Returns a list with menu items for students in a specific program. """ items = [] timeline_entity = program_entity.timeline if timeline_helper.isActivePeriod(timeline_entity, 'student_signup') and \ student_entity.status == 'active': items += [('/gsoc/student_proposal/list_orgs/%s' % ( student_entity.key().id_or_name()), "Submit your Student Proposal", 'any_access')] if timeline_helper.isAfterEvent(timeline_entity, 'student_signup_start'): items += [(redirects.getListSelfRedirect(student_entity, {'url_name': prefix + '/student_proposal'}), "List my Student Proposals", 'any_access')] if timeline_helper.isAfterEvent(timeline_entity, 'accepted_students_announced_deadline'): # add a link to show all projects items += [(redirects.getListProjectsRedirect(program_entity, {'url_name': prefix + '/student'}), "List my Student Projects", 'any_access')] if timeline_helper.isBeforeEvent(program_entity.timeline, 'program_end') \ and student_entity.status == 'active': items += [(redirects.getManageRedirect(student_entity, {'url_name': prefix + '/student'}), "Resign as a Student", 'any_access')] items += super(View, self)._getStudentEntries(program_entity, student_entity, params, id, user, prefix) return items
def testIsActivePeriod(self): """Tests if a correct boolean is returned if the current DateTime is between period_start and period_end. """ #program is going on. self.timeline.program_start = datetime.utcnow() - timedelta(10) self.timeline.program_end = datetime.utcnow() + timedelta(10) self.assertTrue(timeline.isActivePeriod(self.timeline, 'program')) #program will start. self.timeline.program_start = datetime.utcnow() + timedelta(10) self.timeline.program_end = datetime.utcnow() + timedelta(20) self.assertFalse(timeline.isActivePeriod(self.timeline, 'program')) #program has ended. self.timeline.program_start = datetime.utcnow() - timedelta(20) self.timeline.program_end = datetime.utcnow() - timedelta(10) self.assertFalse(timeline.isActivePeriod(self.timeline, 'program')) #student sign up period will start self.timeline.student_signup_start = datetime.utcnow() + timedelta(10) self.timeline.student_signup_end = datetime.utcnow() + timedelta(30) self.assertFalse( timeline.isActivePeriod(self.timeline, 'student_signup')) #student sign up period has not ended. self.timeline.student_signup_start = datetime.utcnow() - timedelta(10) self.timeline.student_signup_end = datetime.utcnow() + timedelta(20) self.assertTrue( timeline.isActivePeriod(self.timeline, 'student_signup')) #student sign up period has already ended. self.timeline.student_signup_start = datetime.utcnow() - timedelta(30) self.timeline.student_signup_end = datetime.utcnow() - timedelta(20) self.assertFalse( timeline.isActivePeriod(self.timeline, 'student_signup')) #event not in the timeline. self.assertFalse(timeline.isActivePeriod(self.timeline, 'other_event'))
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 _getTimeDependentEntries(self, gci_program_entity, params, id, user): """Returns a list with time dependent menu items. """ items = [] timeline_entity = gci_program_entity.timeline # add show ranking item if timeline_helper.isAfterEvent(timeline_entity, 'tasks_publicly_visible'): items += [(gci_redirects.getShowRankingRedirect( gci_program_entity, {'url_name': 'gci/program'}), 'Show Ranking', 'any_access')] mentor_entity = None org_admin_entity = None org_app_survey = org_app_logic.getForProgram(gci_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': 'gci/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' : 'gci/org_app'}), "List My Organization Applications", 'any_access')] # get the student entity for this user and program filter = {'user': user, 'scope': gci_program_entity, 'status': ['active', 'inactive']} student_entity = gci_student_logic.logic.getForFields(filter, unique=True) # students can register after successfully completing their first # task. So if a user has completed one task he is still a student filter = { 'user': user, 'program': gci_program_entity, } has_completed_task = gci_task_logic.logic.getForFields( filter, unique=True) if student_entity or (user and has_completed_task): items += self._getStudentEntries(gci_program_entity, student_entity, params, id, user, 'gci') else: # get mentor and org_admin entity for this user and program filter = { 'user': user, 'program': gci_program_entity, 'status': 'active' } mentor_entity = gci_mentor_logic.logic.getForFields(filter, unique=True) org_admin_entity = gci_org_admin_logic.logic.getForFields( filter, unique=True) if timeline_helper.isAfterEvent( timeline_entity, 'accepted_organization_announced_deadline'): if mentor_entity or org_admin_entity: items += self._getOrganizationEntries( gci_program_entity, org_admin_entity, mentor_entity, params, id, user) if timeline_helper.isBeforeEvent(timeline_entity, 'program_end'): # add apply to become a mentor link items += [ ('/gci/org/apply_mentor/%s' % ( gci_program_entity.key().id_or_name()), "Apply to become a Mentor", 'any_access')] if timeline_helper.isAfterEvent( timeline_entity, 'accepted_organization_announced_deadline'): url = redirects.getAcceptedOrgsRedirect( gci_program_entity, params) # add a link to list all the organizations items += [(url, "List participating Organizations", 'any_access')] user_fields = { 'user': user, 'status': 'active' } host_entity = host_logic.getForFields(user_fields, unique=True) # for org admins this link should be visible only after accepted # organizations are announced and for other public after the tasks # are public but for program host it must be visible always if (host_entity or ((org_admin_entity or mentor_entity) and timeline_helper.isAfterEvent( timeline_entity, 'tasks_publicly_visible')) or (timeline_helper.isAfterEvent( timeline_entity, 'tasks_publicly_visible'))): url = gci_redirects.getListAllTasksRedirect( gci_program_entity, params) # add a link to list all the organizations items += [(url, "List all tasks", 'any_access')] if user: # add a link to show all tasks of interest items += [(gci_redirects.getListMyTasksRedirect( gci_program_entity, params), 'List my Tasks', 'any_access')] return items
def _getTimeDependentEntries(self, program_entity, params, id, user): """Returns a list with time dependent menu items. """ items = [] #TODO(ljvderijk) Add more timeline dependent entries timeline_entity = program_entity.timeline if timeline_helper.isActivePeriod(timeline_entity, 'org_signup'): # add the organization signup link items += [ (redirects.getApplyRedirect(program_entity, {'url_name': 'org_app'}), "Apply to become an Organization", 'any_access')] if user and timeline_helper.isAfterEvent(timeline_entity, 'org_signup_start'): filter = { 'applicant': user, 'scope': program_entity, } if org_app_logic.logic.getForFields(filter, unique=True): # add the 'List my Organization Applications' link items += [ (redirects.getListSelfRedirect(program_entity, {'url_name' : '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'} student_entity = student_logic.logic.getForFields(filter, unique=True) if student_entity: items += self._getStudentEntries(program_entity, student_entity, params, id, user) # get mentor and org_admin entity for this user and program filter = {'user': user, 'program': program_entity, 'status': 'active'} mentor_entity = mentor_logic.logic.getForFields(filter, unique=True) org_admin_entity = org_admin_logic.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 += [('/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: # add apply to become a mentor link items += [('/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':'program'}), "List all student projects", 'any_access')] return items
class View(survey_view.View): """View methods for the ProjectSurvey 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 """ new_params = {} new_params['logic'] = org_app_logic new_params['name'] = "Org Application Survey" new_params['url_name'] = 'org_app' new_params['extra_dynaexclude'] = ['taking_access'] new_params['survey_take_form'] = OrgAppSurveyForm new_params['survey_record_form'] = OrgAppRecordForm new_params['extra_django_patterns'] = [ (r'^%(url_name)s/(?P<access_type>list_self)/%(key_fields)s$', '%(module_package)s.%(module_name)s.list_self', 'Overview of %(name_plural)s Taken by You'), ] params = dicts.merge(params, new_params, sub_merge=True) super(View, self).__init__(params=params) @decorators.check_access def create(self, request, access_type, page_name=None, params=None, **kwargs): """Displays the create page for this entity type. If an OrgAppSurvey already exists it will redirect to the edit page. """ params = dicts.merge(params, self._params) program_view = params['scope_view'] program_logic = program_view.getParams()['logic'] program_entity = program_logic.getFromKeyName(kwargs['scope_path']) org_app = org_app_logic.getForProgram(program_entity) if org_app: # redirect to edit page return http.HttpResponseRedirect( redirects.getEditRedirect(org_app, params)) else: # show create page return super(View, self).create(request, access_type, page_name=page_name, params=params, **kwargs) def _getSurveyRecordFor(self, survey, request, params): """Returns the SurveyRecord for the given Survey and request. This method also take the ID specified as GET param into account when querying for the SurveyRecord. For params see survey.View._getSurveyRecordFor(). """ get_dict = request.GET record_id = get_dict.get('id', None) survey_logic = params['logic'] record_logic = survey_logic.getRecordLogic() if not record_id or not record_id.isdigit(): return None else: return record_logic.getFromIDOr404(int(record_id)) def _takeGet(self, request, template, context, params, entity, record, **kwargs): """Hooking into the view for the take's page GET request. For params see survey.View._takeGet(). """ # the form action should contain the requested record if record: context['form_action'] = "?id=%s" % (request.GET['id']) def _takePost(self, request, params, entity, record, properties): """Hook into the view for the take's page POST request. For params see survey.View._takePost(). """ from soc.logic.models.user import logic as user_logic if not record: # creating a new record user_entity = user_logic.getForCurrentAccount() properties['main_admin'] = user_entity if properties['agreed_to_tos']: properties['agreed_to_admin_agreement'] = True # remove fields we don't need to store in the SurveyRecord properties.pop('tos') properties.pop('agreed_to_tos') def _getRedirectOnSuccessfulTake(self, request, params, survey, record): """Returns a path to which the user should be redirected after successfully taking a OrgAppSurvey. """ return request.path + '?id=' + str(record.key().id_or_name()) @decorators.merge_params @decorators.check_access def list_self(self, request, access_type, page_name=None, params=None, **kwargs): """View that lists all the OrgRecords you have access to. For Args see base.View().public(). """ from soc.logic.models.user import logic as user_logic survey_logic = params['logic'] record_logic = survey_logic.getRecordLogic() try: entity = survey_logic.getFromKeyFieldsOr404(kwargs) except out_of_band.Error, error: return responses.errorResponse(error, request, template=params['error_public']) # get the context for this webpage context = responses.getUniversalContext(request) responses.useJavaScript(context, params['js_uses_all']) context['entity'] = entity list_contents = [] user_entity = user_logic.getForCurrentAccount() list_params = params.copy() list_params['logic'] = record_logic list_params[ 'list_heading'] = 'soc/org_app_survey/list/records_heading.html' list_params['list_row'] = 'soc/org_app_survey/list/records_row.html' if timeline_helper.isActivePeriod(entity, 'survey'): info = {'url_name': list_params['url_name'], 'survey': entity} list_params['public_row_extra'] = lambda entity: { 'link': redirects.getRetakeOrgAppSurveyRedirect(entity, info) } else: list_params['public_row_extra'] = lambda entity: { 'link': redirects.getViewSurveyRecordRedirect( entity, list_params) } fields = {'survey': entity, 'main_admin': user_entity} list_params['list_description'] = \ 'List of Applications for which you are Main Admin.' main_list = lists.getListContent(request, list_params, fields, need_content=True, idx=0) # TODO(LIST) if main_list: list_contents.append(main_list) fields = {'survey': entity, 'backup_admin': user_entity} list_params['list_description'] = \ 'List of Applications for which your are Backup Admin.' backup_list = lists.getListContent(request, list_params, fields, need_content=True, idx=1) if backup_list: list_contents.append(backup_list) return self._list(request, list_params, list_contents, page_name, context)
def getUniversalContext(request): """Constructs a template context dict will many common variables defined. Args: request: the Django HTTP request object Returns: a new context dict containing: { 'request': the Django HTTP request object passed in by the caller 'account': the logged-in Google Account if there is one 'user': the User entity corresponding to the Google Account in context['account'] 'is_admin': True if users.is_current_user_admin() is True 'is_debug': True if system.isDebug() is True 'sign_in': a Google Account login URL 'sign_out': a Google Account logout URL 'sidebar_menu_html': an HTML string that renders the sidebar menu } """ core = callback.getCore() context = core.getRequestValue('context', {}) if context: return context account = accounts.getCurrentAccount() user = None is_admin = False context['request'] = request if account: user = user_logic.getForAccount(account) is_admin = user_logic.isDeveloper(account=account, user=user) context['account'] = account context['user'] = user context['is_admin'] = is_admin context['is_local'] = system.isLocal() context['is_debug'] = system.isDebug() context['sign_in'] = users.create_login_url(request.path) context['sign_out'] = users.create_logout_url(request.path) context['sidebar_menu_items'] = core.getSidebar(account, user) context['gae_version'] = system.getAppVersion() context['soc_release'] = system.getMelangeVersion() settings = site.logic.getSingleton() context['ga_tracking_num'] = settings.ga_tracking_num context['gmaps_api_key'] = settings.gmaps_api_key context['site_name'] = settings.site_name context['site_notice'] = settings.site_notice context['tos_link'] = redirects.getToSRedirect(settings) context['in_maintenance'] = timeline.isActivePeriod( settings, 'maintenance') # Only one xsrf_token is generated per request. xsrf_secret_key = site.logic.getXsrfSecretKey(settings) context['xsrf_token'] = xsrfutil.getGeneratedTokenForCurrentUser( xsrf_secret_key) core.setRequestValue('context', context) return context
def checkCanOrgAdminOrMentorEdit(self, django_args, key_location, check_limit): """Checks if the mentors can create task for this program, and obeys the task quota limit assigned for their org when check_limit is True. Args: django_args: a dictionary with django's arguments. key_location: the key for django_args in which the key_name of the org is stored. check_limit: iff true checks if the organization reached the task quota limit for the given program. """ import settings self.checkIsUser(django_args) user_account = user_logic.logic.getCurrentUser() if key_location not in django_args: raise out_of_band.AccessViolation(message_fmt=DEF_NEED_ROLE_MSG) filter = { 'user': user_account, 'scope_path': django_args[key_location], 'status': 'active' } role_entity = gci_org_admin_logic.logic.getForFields(filter, unique=True) if not role_entity: role_entity = gci_mentor_logic.logic.getForFields(filter, unique=True) if not role_entity: raise out_of_band.AccessViolation( message_fmt=DEF_SIGN_UP_AS_OA_MENTOR_MSG) # pylint: disable=E1103 program_entity = role_entity.program if not timeline_helper.isActivePeriod(program_entity.timeline, 'program'): raise out_of_band.AccessViolation( message_fmt=DEF_PAGE_INACTIVE_MSG) # pylint: disable=E1103 org_entity = role_entity.scope if settings.GCI_TASK_QUOTA_LIMIT_ENABLED and check_limit: # count all tasks from this organization fields = {'scope': org_entity} task_query = gci_task_logic.logic.getQueryForFields(fields) if task_query.count() >= org_entity.task_quota_limit: # too many tasks access denied raise out_of_band.AccessViolation( message_fmt=DEF_MAX_TASKS_REACHED_MSG) if 'link_id' in django_args: task_entity = gci_task_logic.logic.getFromKeyFieldsOr404( django_args) if task_entity.status not in [ 'Unapproved', 'Unpublished', 'Open', 'ClaimRequested', 'Reopened' ]: # task is claimed at least once raise out_of_band.AccessViolation( message_fmt=DEF_CANT_EDIT_MSG) return
def getMenusForScope(self, entity, params, id, user): """List featured surveys if after the survey_start date and before survey_end an iff the current user has the right taking access. Args: entity: entity which is the scope for a Survey params: params from the requesting View id: GAE user instance for the current user user: User entity from the current user """ # only list surveys for registered users if not user: return [] survey_params = self.getParams().copy() survey_logic = survey_params['logic'] record_logic = survey_logic.getRecordLogic() # filter all featured surveys for the given entity filter = { 'prefix' : params['url_name'], 'scope_path': entity.key().id_or_name(), 'is_featured': True, } survey_entities = survey_logic.getForFields(filter) submenus = [] # get the rights checker rights = self._params['rights'] rights.setCurrentUser(id, user) # cache ACL survey_rights = {} # add a link to all featured active surveys the user can take for survey_entity in survey_entities: if survey_entity.taking_access not in survey_rights: # we have not determined if this user has the given type of access # check if the current user is allowed to visit the take Survey page allowed_to_take = False try: rights.checkIsSurveyTakeable( {'key_name': survey_entity.key().name(), 'prefix': survey_entity.prefix, 'scope_path': survey_entity.scope_path, 'link_id': survey_entity.link_id, 'user': user}, survey_logic, check_time=False) allowed_to_take = True except: pass # cache ACL for a given entity.taking_access survey_rights[survey_entity.taking_access] = allowed_to_take if not allowed_to_take: # not allowed to take this survey continue elif not survey_rights[survey_entity.taking_access]: # we already determined that the user doens't have access to this type continue if not timeline.isActivePeriod(survey_entity, 'survey'): # this survey is not active right now continue # check if any SurveyRecord is available for this survey filter = {'survey': survey_entity, 'user': user} survey_record = record_logic.getForFields(filter, unique=True) if survey_record: taken_status = "" else: # no SurveyRecord available so we mark the survey as new taken_status = "(new)" submenu = (redirects.getTakeSurveyRedirect(survey_entity, survey_params), 'Survey ' + taken_status + ': ' + survey_entity.short_name, 'show') submenus.append(submenu) return submenus
def _getTimeDependentEntries(self, ghop_program_entity, params, id, user): """Returns a list with time dependent menu items. """ from soc.modules.ghop.logic.models.org_app_survey import logic as \ org_app_logic items = [] timeline_entity = ghop_program_entity.timeline org_app_survey = org_app_logic.getForProgram(ghop_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': 'ghop/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': 'ghop/org_app'}), "List My Organization Applications", 'any_access')] # get the student entity for this user and program filter = { 'user': user, 'scope': ghop_program_entity, 'status': ['active', 'inactive'] } student_entity = ghop_student_logic.logic.getForFields(filter, unique=True) if student_entity: items += self._getStudentEntries(ghop_program_entity, student_entity, params, id, user, 'ghop') else: # if a user has a task assigned, he or she still may list it filter = { 'user': user, 'program': ghop_program_entity, } if user and ghop_task_logic.logic.getForFields(filter, unique=True): items += [(ghop_redirects.getListStudentTasksRedirect( ghop_program_entity, {'url_name': 'ghop/student'}), "List my Tasks", 'any_access')] filter['status'] = 'AwaitingRegistration' if ghop_task_logic.logic.getForFields(filter, unique=True): if timeline_helper.isActivePeriod(timeline_entity, 'student_signup'): # this user does not have a role yet for this program items += [('/ghop/student/apply/%s' % (ghop_program_entity.key().id_or_name()), "Register as a Student", 'any_access')] # get mentor and org_admin entity for this user and program filter = { 'user': user, 'program': ghop_program_entity, 'status': 'active' } mentor_entity = ghop_mentor_logic.logic.getForFields(filter, unique=True) org_admin_entity = ghop_org_admin_logic.logic.getForFields( filter, unique=True) if mentor_entity or org_admin_entity: items += self._getOrganizationEntries(ghop_program_entity, org_admin_entity, mentor_entity, params, id, user) if timeline_helper.isAfterEvent(timeline_entity, 'org_signup_start'): url = redirects.getAcceptedOrgsRedirect(ghop_program_entity, params) # add a link to list all the organizations items += [(url, "List participating Organizations", 'any_access')] return items
def checkCanOrgAdminOrMentorEdit(self, django_args, key_location, check_limit): """Checks if the mentors can create task for this program, and obeys the task quota limit assigned for their org when check_limit is True. Args: django_args: a dictionary with django's arguments. key_location: the key for django_args in which the key_name of the org is stored. check_limit: iff true checks if the organization reached the task quota limit for the given program. """ import settings self.checkIsUser(django_args) user_account = user_logic.logic.getCurrentUser() if key_location not in django_args: raise out_of_band.AccessViolation( message_fmt=DEF_NEED_ROLE_MSG) filter = { 'user': user_account, 'scope_path': django_args[key_location], 'status': 'active' } role_entity = gci_org_admin_logic.logic.getForFields(filter, unique=True) if not role_entity: role_entity = gci_mentor_logic.logic.getForFields(filter, unique=True) if not role_entity: raise out_of_band.AccessViolation( message_fmt=DEF_SIGN_UP_AS_OA_MENTOR_MSG) # pylint: disable=E1103 program_entity = role_entity.program if not timeline_helper.isActivePeriod(program_entity.timeline, 'program'): raise out_of_band.AccessViolation(message_fmt=DEF_PAGE_INACTIVE_MSG) # pylint: disable=E1103 org_entity = role_entity.scope if settings.GCI_TASK_QUOTA_LIMIT_ENABLED and check_limit: # count all tasks from this organization fields = {'scope': org_entity} task_query = gci_task_logic.logic.getQueryForFields(fields) if task_query.count() >= org_entity.task_quota_limit: # too many tasks access denied raise out_of_band.AccessViolation( message_fmt=DEF_MAX_TASKS_REACHED_MSG) if 'link_id' in django_args: task_entity = gci_task_logic.logic.getFromKeyFieldsOr404(django_args) if task_entity.status not in ['Unapproved', 'Unpublished', 'Open', 'ClaimRequested', 'Reopened']: # task is claimed at least once raise out_of_band.AccessViolation(message_fmt=DEF_CANT_EDIT_MSG) return
def _getTimeDependentEntries(self, gci_program_entity, params, id, user): """Returns a list with time dependent menu items. """ items = [] timeline_entity = gci_program_entity.timeline # add show ranking item if timeline_helper.isAfterEvent(timeline_entity, 'tasks_publicly_visible'): items += [(gci_redirects.getShowRankingRedirect( gci_program_entity, {'url_name': 'gci/program'}), 'Show Ranking', 'any_access')] mentor_entity = None org_admin_entity = None org_app_survey = org_app_logic.getForProgram(gci_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': 'gci/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': 'gci/org_app'}), "List My Organization Applications", 'any_access')] # get the student entity for this user and program filter = { 'user': user, 'scope': gci_program_entity, 'status': ['active', 'inactive'] } student_entity = gci_student_logic.logic.getForFields(filter, unique=True) # students can register after successfully completing their first # task. So if a user has completed one task he is still a student filter = { 'user': user, 'program': gci_program_entity, } has_completed_task = gci_task_logic.logic.getForFields(filter, unique=True) if student_entity or (user and has_completed_task): items += self._getStudentEntries(gci_program_entity, student_entity, params, id, user, 'gci') else: # get mentor and org_admin entity for this user and program filter = { 'user': user, 'program': gci_program_entity, 'status': 'active' } mentor_entity = gci_mentor_logic.logic.getForFields(filter, unique=True) org_admin_entity = gci_org_admin_logic.logic.getForFields( filter, unique=True) if timeline_helper.isAfterEvent( timeline_entity, 'accepted_organization_announced_deadline'): if mentor_entity or org_admin_entity: items += self._getOrganizationEntries( gci_program_entity, org_admin_entity, mentor_entity, params, id, user) if timeline_helper.isBeforeEvent(timeline_entity, 'program_end'): # add apply to become a mentor link items += [('/gci/org/apply_mentor/%s' % (gci_program_entity.key().id_or_name()), "Apply to become a Mentor", 'any_access')] if timeline_helper.isAfterEvent( timeline_entity, 'accepted_organization_announced_deadline'): url = redirects.getAcceptedOrgsRedirect(gci_program_entity, params) # add a link to list all the organizations items += [(url, "List participating Organizations", 'any_access')] user_fields = {'user': user, 'status': 'active'} host_entity = host_logic.getForFields(user_fields, unique=True) # for org admins this link should be visible only after accepted # organizations are announced and for other public after the tasks # are public but for program host it must be visible always if (host_entity or ((org_admin_entity or mentor_entity) and timeline_helper.isAfterEvent( timeline_entity, 'tasks_publicly_visible')) or (timeline_helper.isAfterEvent(timeline_entity, 'tasks_publicly_visible'))): url = gci_redirects.getListAllTasksRedirect( gci_program_entity, params) # add a link to list all the organizations items += [(url, "List all tasks", 'any_access')] if user: # add a link to show all tasks of interest items += [(gci_redirects.getListMyTasksRedirect( gci_program_entity, params), 'List my Tasks', 'any_access')] return items
def getMenusForScope(self, entity, params, id, user): """List featured surveys if after the survey_start date and before survey_end an iff the current user has the right taking access. Args: entity: entity which is the scope for a Survey params: params from the requesting View id: GAE user instance for the current user user: User entity from the current user """ # only list surveys for registered users if not user: return [] survey_params = self.getParams().copy() survey_logic = survey_params['logic'] record_logic = survey_logic.getRecordLogic() # filter all featured surveys for the given entity filter = { 'prefix': params['document_prefix'], 'scope_path': entity.key().id_or_name(), 'is_featured': True, } survey_entities = survey_logic.getForFields(filter) submenus = [] # get the rights checker rights = self._params['rights'] rights.setCurrentUser(id, user) # cache ACL survey_rights = {} # add a link to all featured active surveys the user can take for survey_entity in survey_entities: if survey_entity.taking_access not in survey_rights: # we have not determined if this user has the given type of access # check if the current user is allowed to visit the take Survey page allowed_to_take = False try: rights.checkIsSurveyTakeable( { 'key_name': survey_entity.key().name(), 'prefix': survey_entity.prefix, 'scope_path': survey_entity.scope_path, 'link_id': survey_entity.link_id, 'user': user }, survey_logic, check_time=False) allowed_to_take = True except: pass # cache ACL for a given entity.taking_access survey_rights[survey_entity.taking_access] = allowed_to_take if not allowed_to_take: # not allowed to take this survey continue elif not survey_rights[survey_entity.taking_access]: # we already determined that the user doens't have access to this type continue if not timeline.isActivePeriod(survey_entity, 'survey'): # this survey is not active right now continue # check if any SurveyRecord is available for this survey filter = {'survey': survey_entity, 'user': user} survey_record = record_logic.getForFields(filter, unique=True) if survey_record: taken_status = "" else: # no SurveyRecord available so we mark the survey as new taken_status = "(new)" submenu = (redirects.getTakeSurveyRedirect(survey_entity, survey_params), 'Survey ' + taken_status + ': ' + survey_entity.short_name, 'show') submenus.append(submenu) return submenus
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