def create_cohort(): params = request.get_json() if is_unauthorized_search(params): raise ForbiddenRequestError( 'You are unauthorized to access student data managed by other departments' ) label = util.get(params, 'label', None) if not label: raise BadRequestError('Cohort creation requires \'label\'') cohort = CohortFilter.create( advisor_ldap_uids=util.get(params, 'advisorLdapUids'), coe_prep_statuses=util.get(params, 'coePrepStatuses'), ethnicities=util.get(params, 'ethnicities'), genders=util.get(params, 'genders'), gpa_ranges=util.get(params, 'gpaRanges'), group_codes=util.get(params, 'groupCodes'), in_intensive_cohort=util.to_bool_or_none( params.get('inIntensiveCohort')), is_inactive_asc=util.to_bool_or_none(params.get('isInactiveAsc')), label=label, last_name_range=util.get(params, 'lastNameRange'), levels=util.get(params, 'levels'), majors=util.get(params, 'majors'), uid=current_user.get_id(), underrepresented=util.get(params, 'underrepresented'), unit_ranges=util.get(params, 'unitRanges'), ) return tolerant_jsonify(decorate_cohort(cohort))
def test_to_bool_or_none(self): """If None is not False in your use case then use this util.""" assert util.to_bool_or_none(None) is None assert util.to_bool_or_none('true') is True assert util.to_bool_or_none('false') is False assert util.to_bool_or_none('FALSE') is False assert util.to_bool_or_none('blargh') is None
def _update_or_create_authorized_user(memberships, profile, include_deleted=False): user_id = profile.get('id') automate_degree_progress_permission = profile.get( 'automateDegreeProgressPermission') can_access_canvas_data = to_bool_or_none( profile.get('canAccessCanvasData')) can_access_advising_data = to_bool_or_none( profile.get('canAccessAdvisingData')) degree_progress_permission = profile.get('degreeProgressPermission') if (automate_degree_progress_permission or degree_progress_permission ) and 'COENG' not in dept_codes_where_advising( {'departments': memberships}): raise errors.BadRequestError( 'Degree Progress feature is only available to the College of Engineering.' ) is_admin = to_bool_or_none(profile.get('isAdmin')) is_blocked = to_bool_or_none(profile.get('isBlocked')) if user_id: user = AuthorizedUser.update_user( automate_degree_progress_permission= automate_degree_progress_permission, can_access_advising_data=can_access_advising_data, can_access_canvas_data=can_access_canvas_data, degree_progress_permission=degree_progress_permission, include_deleted=include_deleted, is_admin=is_admin, is_blocked=is_blocked, user_id=user_id, ) UserSession.flush_cache_for_id(user_id=user_id) return user else: uid = profile.get('uid') if AuthorizedUser.get_id_per_uid(uid, include_deleted=True): raise errors.BadRequestError( f'User with UID {uid} is already in the BOA database.') calnet_user = calnet.get_calnet_user_for_uid(app, uid, skip_expired_users=True) if calnet_user and calnet_user.get('csid', None): return AuthorizedUser.create_or_restore( automate_degree_progress_permission= automate_degree_progress_permission, can_access_advising_data=can_access_advising_data, can_access_canvas_data=can_access_canvas_data, created_by=current_user.get_uid(), degree_progress_permission=degree_progress_permission, is_admin=is_admin, is_blocked=is_blocked, uid=uid, ) else: raise errors.BadRequestError('Invalid UID')
def create_topic(): params = request.json topic = params.get('topic', '').strip() available_in_notes = to_bool_or_none( params.get('availableInNotes')) or False available_in_appointments = to_bool_or_none( params.get('availableInAppointments')) or False if not topic or not (available_in_notes or available_in_appointments): raise BadRequestError('Required parameters are missing.') topic = Topic.create_topic( topic, available_in_notes=available_in_notes, available_in_appointments=available_in_appointments, ) return tolerant_jsonify(topic.to_api_json())
def get_admin_users(): params = request.get_json() ignore_deleted = to_bool_or_none(util.get(params, 'ignoreDeleted')) users = AuthorizedUser.get_admin_users( ignore_deleted=True if ignore_deleted is None else ignore_deleted) return tolerant_jsonify({ 'users': authorized_users_api_feed( users, sort_by=util.get(params, 'sortBy'), sort_descending=to_bool_or_none(util.get(params, 'sortDescending')), ), 'totalUserCount': len(users), })
def update_note(): params = request.form body = params.get('body', None) is_private = to_bool_or_none(params.get('isPrivate', False)) note_id = params.get('id', None) subject = params.get('subject', None) topics = get_note_topics_from_http_post() note = Note.find_by_id(note_id=note_id) if note_id else None if not note: raise ResourceNotFoundError('Note not found') if not subject: raise BadRequestError('Note subject is required') if note.author_uid != current_user.get_uid(): raise ForbiddenRequestError( 'Sorry, you are not the author of this note.') if (is_private is not note.is_private ) and not current_user.can_access_private_notes: raise ForbiddenRequestError( 'Sorry, you are not authorized to manage note privacy') note = Note.update( body=process_input_from_rich_text_editor(body), is_private=is_private, note_id=note_id, subject=subject, topics=topics, ) note_read = NoteRead.find_or_create(current_user.get_id(), note_id) return tolerant_jsonify( _boa_note_to_compatible_json(note=note, note_read=note_read))
def get_cohort(cohort_id): if is_unauthorized_search(request.args): raise ForbiddenRequestError( 'You are unauthorized to access student data managed by other departments' ) include_students = util.to_bool_or_none( util.get(request.args, 'includeStudents')) include_students = True if include_students is None else include_students order_by = util.get(request.args, 'orderBy', None) offset = util.get(request.args, 'offset', 0) limit = util.get(request.args, 'limit', 50) cohort = CohortFilter.find_by_id(int(cohort_id)) if cohort and can_view_cohort(current_user, cohort): cohort = decorate_cohort( cohort, order_by=order_by, offset=int(offset), limit=int(limit), include_alerts_for_uid=current_user.uid, include_profiles=True, include_students=include_students, ) return tolerant_jsonify(cohort) else: raise ResourceNotFoundError( f'No cohort found with identifier: {cohort_id}')
def update_note_template(): params = request.form note_template_id = params.get('id', None) subject = params.get('subject', None) if not subject: raise BadRequestError('Requires \'subject\'') body = params.get('body', None) topics = get_note_topics_from_http_post() delete_ids_ = params.get('deleteAttachmentIds') or [] delete_ids_ = delete_ids_ if isinstance( delete_ids_, list) else str(delete_ids_).split(',') delete_attachment_ids = [int(id_) for id_ in delete_ids_] note_template = NoteTemplate.find_by_id(note_template_id=note_template_id) if not note_template: raise ResourceNotFoundError('Template not found') if note_template.creator_id != current_user.get_id(): raise ForbiddenRequestError('Template not available.') note_template = NoteTemplate.update( attachments=get_note_attachments_from_http_post(tolerate_none=True), body=process_input_from_rich_text_editor(body), delete_attachment_ids=delete_attachment_ids, is_private=to_bool_or_none(params.get('isPrivate', False)), note_template_id=note_template_id, subject=subject, topics=topics, ) return tolerant_jsonify(note_template.to_api_json())
def create_or_update_user_profile(): params = request.get_json() profile = params.get('profile', None) memberships = params.get('memberships', None) delete_action = to_bool_or_none(util.get(params, 'deleteAction')) if not profile or not profile.get('uid') or memberships is None: raise errors.BadRequestError('Required parameters are missing') authorized_user = _update_or_create_authorized_user(memberships, profile, include_deleted=True) _delete_existing_memberships(authorized_user) _create_department_memberships(authorized_user, memberships) if delete_action is True and not authorized_user.deleted_at: AuthorizedUser.delete(authorized_user.uid) elif delete_action is False and authorized_user.deleted_at: AuthorizedUser.un_delete(authorized_user.uid) user_id = authorized_user.id UserSession.flush_cache_for_id(user_id) updated_user = AuthorizedUser.find_by_id(user_id, include_deleted=True) users_json = authorized_users_api_feed([updated_user]) return tolerant_jsonify(users_json and users_json[0])
def create_note_template(): params = request.form title = params.get('title', None) subject = params.get('subject', None) body = params.get('body', None) topics = get_note_topics_from_http_post() if not title or not subject: raise BadRequestError( 'Note creation requires \'subject\' and \'title\'') user_dept_codes = dept_codes_where_advising(current_user) if current_user.is_admin or not len(user_dept_codes): raise ForbiddenRequestError( 'Sorry, only advisors can create advising note templates') attachments = get_note_attachments_from_http_post(tolerate_none=True) note_template = NoteTemplate.create( attachments=attachments, body=process_input_from_rich_text_editor(body), creator_id=current_user.get_id(), is_private=to_bool_or_none(params.get('isPrivate', False)), subject=subject, title=title, topics=topics, ) return tolerant_jsonify(note_template.to_api_json())
def user_by_uid(uid): ignore_deleted = to_bool_or_none(util.get(request.args, 'ignoreDeleted')) user = _find_user_by_uid(uid, ignore_deleted) if user: users_feed = authorized_users_api_feed([user]) return tolerant_jsonify(users_feed[0]) else: raise errors.ResourceNotFoundError('User not found')
def create_notes(): benchmark = get_benchmarker('create_notes') params = request.form sids = _get_sids_for_note_creation() benchmark(f'SID count: {len(sids)}') body = params.get('body', None) is_private = to_bool_or_none(params.get('isPrivate', False)) subject = params.get('subject', None) topics = get_note_topics_from_http_post() if not sids or not subject: benchmark('end (BadRequest)') raise BadRequestError( 'Note creation requires \'subject\' and \'sids\'') dept_codes = dept_codes_where_advising(current_user) if current_user.is_admin or not len(dept_codes): benchmark('end (Forbidden)') raise ForbiddenRequestError( 'Sorry, only advisors can create advising notes') if is_private and not current_user.can_access_private_notes: benchmark('end (Forbidden)') raise ForbiddenRequestError( 'Sorry, you are not authorized to manage note privacy.') attachments = get_note_attachments_from_http_post(tolerate_none=True) benchmark(f'Attachment count: {len(attachments)}') body = process_input_from_rich_text_editor(body) template_attachment_ids = get_template_attachment_ids_from_http_post() if len(sids) == 1: note = Note.create( **_get_author_profile(), attachments=attachments, body=body, is_private=is_private, sid=sids[0], subject=subject, template_attachment_ids=template_attachment_ids, topics=topics, ) response = tolerant_jsonify( _boa_note_to_compatible_json(note, note_read=True)) else: response = tolerant_jsonify( Note.create_batch( **_get_author_profile(), attachments=attachments, author_id=current_user.to_api_json()['id'], body=body, is_private=is_private, sids=sids, subject=subject, template_attachment_ids=template_attachment_ids, topics=topics, ), ) benchmark('end') return response
def assign_course(course_id): params = request.get_json() course = DegreeProgressCourse.find_by_id(course_id) if course: # Get existing category assignment. If it's a placeholder then delete it at end of transaction. previous_category = DegreeProgressCategory.find_by_id( course.category_id) if course.category_id else None category_id = get_param(params, 'categoryId') category = DegreeProgressCategory.find_by_id( category_id) if category_id else None if category: if category.template_id != course.degree_check_id: raise BadRequestError( 'The category and course do not belong to the same degree_check instance.' ) children = DegreeProgressCategory.find_by_parent_category_id( parent_category_id=category_id) if next((c for c in children if c.category_type == 'Subcategory'), None): raise BadRequestError( 'A course cannot be assigned to a category with a subcategory.' ) course = DegreeProgressCourse.assign(category_id=category_id, course_id=course.id) else: # When user un-assigns a course we delete all copies of that course,. for copy_of_course in DegreeProgressCourse.get_courses( degree_check_id=course.degree_check_id, manually_created_at=course.manually_created_at, manually_created_by=course.manually_created_by, section_id=course.section_id, sid=course.sid, term_id=course.term_id, ): if copy_of_course.id != course.id: DegreeProgressCourseUnitRequirement.delete( copy_of_course.id) category = DegreeProgressCategory.find_by_id( copy_of_course.category_id) if category and 'Placeholder' in category.category_type: DegreeProgressCategory.delete(category.id) DegreeProgressCourse.delete(copy_of_course) ignore = to_bool_or_none(get_param(params, 'ignore')) course = DegreeProgressCourse.unassign(course_id=course.id, ignore=ignore) # If previous assignment was a "placeholder" category then delete it. if previous_category and 'Placeholder' in previous_category.category_type: DegreeProgressCategory.delete(previous_category.id) # Update updated_at date of top-level record DegreeProgressTemplate.refresh_updated_at(course.degree_check_id, current_user.get_id()) return tolerant_jsonify(course.to_api_json()) else: raise ResourceNotFoundError('Course not found.')
def get_student_by_uid(uid): profile_only = to_bool_or_none(request.args.get('profileOnly')) student = get_student_and_terms_by_uid(uid) if not student: raise ResourceNotFoundError('Unknown student') if not profile_only: put_notifications(student) _put_degree_checks_json(student) return tolerant_jsonify(student)
def all_users(): params = request.get_json() users, total_user_count = AuthorizedUser.get_users( blocked=to_bool_or_none(util.get(params, 'blocked')), deleted=to_bool_or_none(util.get(params, 'deleted')), dept_code=util.get(params, 'deptCode', None), role=util.get(params, 'role', None) or None, ) return tolerant_jsonify({ 'users': authorized_users_api_feed( users, sort_by=util.get(params, 'sortBy', 'lastName'), sort_descending=to_bool_or_none( util.get(params, 'sortDescending', False)), ), 'totalUserCount': total_user_count, })
def get_departments(): exclude_empty = to_bool_or_none( util.get(request.args, 'excludeEmpty', None)) api_json = [] for d in UniversityDept.get_all(exclude_empty=exclude_empty): api_json.append({ 'id': d.id, 'code': d.dept_code, 'name': d.dept_name, }) return tolerant_jsonify(api_json)
def get_all_topics(): include_appointments = app.config['FEATURE_FLAG_ADVISOR_APPOINTMENTS'] include_deleted = to_bool_or_none(request.args.get('includeDeleted')) if include_appointments: topics = Topic.get_all(include_deleted=include_deleted) else: topics = Topic.get_all(available_in_notes=True, include_deleted=include_deleted) if not app.config['FEATURE_FLAG_ADVISOR_APPOINTMENTS']: for index, topic in enumerate(topics): if not topic.available_in_notes: topics.pop(index) return tolerant_jsonify(_to_api_json(topics))
def to_base_json(self): c = self.filter_criteria c = c if isinstance(c, dict) else json.loads(c) user_uid = self.owner.uid if self.owner else None option_groups = CohortFilterOptions( user_uid, scope_for_criteria()).get_filter_option_groups() for label, option_group in option_groups.items(): for option in option_group: key = option['key'] if key in c: value = c.get(key) if option['type']['db'] == 'boolean': c[key] = util.to_bool_or_none(value) else: c[key] = value def _owner_to_json(owner): if not owner: return None return { 'uid': owner.uid, 'deptCodes': [ m.university_dept.dept_code for m in owner.department_memberships ], } return { 'id': self.id, 'domain': self.domain, 'name': self.name, 'code': self.id, 'criteria': c, 'owner': _owner_to_json(self.owner), 'teamGroups': athletics.get_team_groups(c.get('groupCodes')) if c.get('groupCodes') else [], 'alertCount': self.alert_count, }
def _create_department_memberships(authorized_user, memberships): for membership in [ m for m in memberships if m['role'] in ('advisor', 'director', 'scheduler') ]: university_dept = UniversityDept.find_by_dept_code(membership['code']) role = membership['role'] UniversityDeptMember.create_or_update_membership( university_dept_id=university_dept.id, authorized_user_id=authorized_user.id, role=role, automate_membership=to_bool_or_none( membership['automateMembership']), ) if role == 'scheduler': _delete_drop_in_advisor_status(authorized_user, university_dept.dept_code) UserSession.flush_cache_for_id(authorized_user.id)
def get_students(): params = request.get_json() if is_unauthorized_search(params): raise ForbiddenRequestError( 'You are unauthorized to access student data managed by other departments' ) results = query_students( advisor_ldap_uids=util.get(params, 'advisorLdapUids'), coe_prep_statuses=util.get(params, 'coePrepStatuses'), ethnicities=util.get(params, 'ethnicities'), genders=util.get(params, 'genders'), gpa_ranges=util.get(params, 'gpaRanges'), group_codes=util.get(params, 'groupCodes'), include_profiles=True, is_active_asc=_convert_asc_inactive_arg( util.get(params, 'isInactiveAsc')), in_intensive_cohort=util.to_bool_or_none( util.get(params, 'inIntensiveCohort')), last_name_range=_get_name_range_boundaries( util.get(params, 'lastNameRange')), levels=util.get(params, 'levels'), limit=util.get(params, 'limit', 50), majors=util.get(params, 'majors'), offset=util.get(params, 'offset', 0), order_by=util.get(params, 'orderBy', None), underrepresented=util.get(params, 'underrepresented'), unit_ranges=util.get(params, 'unitRanges'), ) if results is None: raise BadRequestError('Invalid search criteria') alert_counts = Alert.current_alert_counts_for_viewer(current_user.id) students = results['students'] if results else [] add_alert_counts(alert_counts, students) return tolerant_jsonify({ 'students': students, 'totalStudentCount': results['totalStudentCount'] if results else 0, })
def to_api_json( self, order_by=None, offset=0, limit=50, include_students=True, include_profiles=False, include_alerts_for_uid=None, ): c = self.filter_criteria c = c if isinstance(c, dict) else json.loads(c) advisor_ldap_uids = util.get(c, 'advisorLdapUids') if not isinstance(advisor_ldap_uids, list): advisor_ldap_uids = [advisor_ldap_uids ] if advisor_ldap_uids else None cohort_name = self.label cohort_json = { 'id': self.id, 'code': self.id, 'label': cohort_name, 'name': cohort_name, 'owners': [user.uid for user in self.owners], } coe_prep_statuses = c.get('coePrepStatuses') ethnicities = c.get('ethnicities') genders = c.get('genders') gpa_ranges = c.get('gpaRanges') group_codes = c.get('groupCodes') in_intensive_cohort = util.to_bool_or_none(c.get('inIntensiveCohort')) is_inactive_asc = util.to_bool_or_none(c.get('isInactiveAsc')) last_name_range = c.get('lastNameRange') levels = c.get('levels') majors = c.get('majors') team_groups = athletics.get_team_groups( group_codes) if group_codes else [] underrepresented = util.to_bool_or_none(c.get('underrepresented')) unit_ranges = c.get('unitRanges') cohort_json.update({ 'filterCriteria': { 'advisorLdapUids': advisor_ldap_uids, 'coePrepStatuses': coe_prep_statuses, 'ethnicities': ethnicities, 'genders': genders, 'gpaRanges': gpa_ranges, 'groupCodes': group_codes, 'inIntensiveCohort': in_intensive_cohort, 'isInactiveAsc': is_inactive_asc, 'lastNameRange': last_name_range, 'levels': levels, 'majors': majors, 'unitRanges': unit_ranges, 'underrepresented': underrepresented, }, 'teamGroups': team_groups, }) if not include_students and not include_alerts_for_uid and self.student_count is not None: # No need for a students query; return the database-stashed student count. cohort_json.update({ 'totalStudentCount': self.student_count, }) return cohort_json owner = self.owners[0] if len(self.owners) else None if owner and 'UWASC' in get_dept_codes(owner): is_active_asc = not is_inactive_asc else: is_active_asc = None if is_inactive_asc is None else not is_inactive_asc sids_only = not include_students results = query_students( advisor_ldap_uids=advisor_ldap_uids, coe_prep_statuses=coe_prep_statuses, ethnicities=ethnicities, genders=genders, gpa_ranges=gpa_ranges, group_codes=group_codes, in_intensive_cohort=in_intensive_cohort, include_profiles=(include_students and include_profiles), is_active_asc=is_active_asc, last_name_range=last_name_range, levels=levels, limit=limit, majors=majors, offset=offset, order_by=order_by, sids_only=sids_only, underrepresented=underrepresented, unit_ranges=unit_ranges, ) if results: # If the cohort is newly created or a cache refresh is underway, store the student count in the database # to save future queries. if self.student_count is None: self.update_student_count(results['totalStudentCount']) cohort_json.update({ 'totalStudentCount': results['totalStudentCount'], }) if include_students: cohort_json.update({ 'students': results['students'], }) if include_alerts_for_uid: alert_counts = Alert.include_alert_counts_for_students( viewer_uid=include_alerts_for_uid, cohort=results) cohort_json.update({ 'alerts': alert_counts, }) return cohort_json
def get_topics_for_notes(): include_deleted = to_bool_or_none(request.args.get('includeDeleted')) topics = Topic.get_all(available_in_notes=True, include_deleted=include_deleted) return tolerant_jsonify(_to_sorted_json(topics))
def get_all_topics(): include_deleted = to_bool_or_none(request.args.get('includeDeleted')) topics = Topic.get_all(include_deleted=include_deleted) return tolerant_jsonify(_to_sorted_json(topics))
def to_api_json( self, order_by=None, offset=0, limit=50, alert_offset=None, alert_limit=None, include_sids=False, include_students=True, include_profiles=False, include_alerts_for_user_id=None, ): benchmark = get_benchmarker(f'CohortFilter {self.id} to_api_json') benchmark('begin') c = self.filter_criteria c = c if isinstance(c, dict) else json.loads(c) coe_advisor_ldap_uids = util.get(c, 'coeAdvisorLdapUids') if not isinstance(coe_advisor_ldap_uids, list): coe_advisor_ldap_uids = [coe_advisor_ldap_uids ] if coe_advisor_ldap_uids else None cohort_name = self.name cohort_json = { 'id': self.id, 'code': self.id, 'name': cohort_name, 'owners': [], 'alertCount': self.alert_count, } for owner in self.owners: cohort_json['owners'].append({ 'uid': owner.uid, 'deptCodes': [ m.university_dept.dept_code for m in owner.department_memberships ], }) coe_ethnicities = c.get('coeEthnicities') coe_genders = c.get('coeGenders') coe_prep_statuses = c.get('coePrepStatuses') coe_probation = util.to_bool_or_none(c.get('coeProbation')) coe_underrepresented = util.to_bool_or_none( c.get('coeUnderrepresented')) cohort_owner_academic_plans = util.get(c, 'cohortOwnerAcademicPlans') entering_terms = c.get('enteringTerms') ethnicities = c.get('ethnicities') expected_grad_terms = c.get('expectedGradTerms') genders = c.get('genders') gpa_ranges = c.get('gpaRanges') group_codes = c.get('groupCodes') in_intensive_cohort = util.to_bool_or_none(c.get('inIntensiveCohort')) is_inactive_asc = util.to_bool_or_none(c.get('isInactiveAsc')) is_inactive_coe = util.to_bool_or_none(c.get('isInactiveCoe')) last_name_ranges = c.get('lastNameRanges') last_term_gpa_ranges = c.get('lastTermGpaRanges') levels = c.get('levels') majors = c.get('majors') midpoint_deficient_grade = util.to_bool_or_none( c.get('midpointDeficient')) team_groups = athletics.get_team_groups( group_codes) if group_codes else [] transfer = util.to_bool_or_none(c.get('transfer')) underrepresented = util.to_bool_or_none(c.get('underrepresented')) unit_ranges = c.get('unitRanges') cohort_json.update({ 'criteria': { 'coeAdvisorLdapUids': coe_advisor_ldap_uids, 'coeEthnicities': coe_ethnicities, 'coeGenders': coe_genders, 'coePrepStatuses': coe_prep_statuses, 'coeProbation': coe_probation, 'coeUnderrepresented': coe_underrepresented, 'cohortOwnerAcademicPlans': cohort_owner_academic_plans, 'enteringTerms': entering_terms, 'ethnicities': ethnicities, 'expectedGradTerms': expected_grad_terms, 'genders': genders, 'gpaRanges': gpa_ranges, 'groupCodes': group_codes, 'inIntensiveCohort': in_intensive_cohort, 'isInactiveAsc': is_inactive_asc, 'isInactiveCoe': is_inactive_coe, 'lastNameRanges': last_name_ranges, 'lastTermGpaRanges': last_term_gpa_ranges, 'levels': levels, 'majors': majors, 'midpointDeficient': midpoint_deficient_grade, 'transfer': transfer, 'unitRanges': unit_ranges, 'underrepresented': underrepresented, }, 'teamGroups': team_groups, }) if not include_students and not include_alerts_for_user_id and self.student_count is not None: # No need for a students query; return the database-stashed student count. cohort_json.update({ 'totalStudentCount': self.student_count, }) benchmark('end') return cohort_json benchmark('begin students query') sids_only = not include_students # Translate the "My Students" filter, if present, into queryable criteria. Although our database relationships allow # for multiple cohort owners, we assume a single owner here since the "My Students" filter makes no sense # in any other scenario. if cohort_owner_academic_plans: if self.owners: owner_sid = get_csid_for_uid(app, self.owners[0].uid) else: owner_sid = current_user.get_csid() advisor_plan_mappings = [{ 'advisor_sid': owner_sid, 'academic_plan_code': plan } for plan in cohort_owner_academic_plans] else: advisor_plan_mappings = None results = query_students( advisor_plan_mappings=advisor_plan_mappings, coe_advisor_ldap_uids=coe_advisor_ldap_uids, coe_ethnicities=coe_ethnicities, coe_genders=coe_genders, coe_prep_statuses=coe_prep_statuses, coe_probation=coe_probation, coe_underrepresented=coe_underrepresented, entering_terms=entering_terms, ethnicities=ethnicities, expected_grad_terms=expected_grad_terms, genders=genders, gpa_ranges=gpa_ranges, group_codes=group_codes, in_intensive_cohort=in_intensive_cohort, include_profiles=(include_students and include_profiles), is_active_asc=None if is_inactive_asc is None else not is_inactive_asc, is_active_coe=None if is_inactive_coe is None else not is_inactive_coe, last_name_ranges=last_name_ranges, last_term_gpa_ranges=last_term_gpa_ranges, levels=levels, limit=limit, majors=majors, midpoint_deficient_grade=midpoint_deficient_grade, offset=offset, order_by=order_by, sids_only=sids_only, transfer=transfer, underrepresented=underrepresented, unit_ranges=unit_ranges, ) benchmark('end students query') if results: # Cohort might have tens of thousands of SIDs. if include_sids: cohort_json['sids'] = results['sids'] cohort_json.update({ 'totalStudentCount': results['totalStudentCount'], }) # If the cohort is new or cache refresh is underway then store student_count and sids in the db. if self.student_count is None: self.update_sids_and_student_count( results['sids'], results['totalStudentCount']) if include_students: cohort_json.update({ 'students': results['students'], }) if include_alerts_for_user_id: benchmark('begin alerts query') alert_count_per_sid = Alert.include_alert_counts_for_students( viewer_user_id=include_alerts_for_user_id, group=results, offset=alert_offset, limit=alert_limit, ) benchmark('end alerts query') cohort_json.update({ 'alerts': alert_count_per_sid, }) if self.alert_count is None: alert_count = sum(student['alertCount'] for student in alert_count_per_sid) self.update_alert_count(alert_count) cohort_json.update({ 'alertCount': alert_count, }) benchmark('end') return cohort_json
def _is_service_announcement_published(): is_published = ToolSetting.get_tool_setting( 'SERVICE_ANNOUNCEMENT_IS_PUBLISHED') return False if is_published is None else to_bool_or_none(is_published)
def publish_service_announcement(): publish = to_bool_or_none(request.get_json().get('publish')) if publish is None: raise BadRequestError('API requires \'publish\' arg') ToolSetting.upsert('SERVICE_ANNOUNCEMENT_IS_PUBLISHED', publish) return tolerant_jsonify(_get_service_announcement())
def get_topics(): include_deleted = to_bool_or_none(request.args.get('includeDeleted')) topics = Topic.get_all(include_deleted=include_deleted) return tolerant_jsonify([topic.to_api_json() for topic in topics])