def add_attachment(note_id): if Note.find_by_id(note_id=note_id).author_uid != current_user.get_uid(): raise ForbiddenRequestError('Sorry, you are not the author of this note.') attachments = _get_attachments(request.files) if len(attachments) != 1: raise BadRequestError('A single attachment file must be supplied.') note = Note.add_attachment( note_id=note_id, attachment=attachments[0], ) note_json = note.to_api_json() return tolerant_jsonify( note_to_compatible_json( note=note_json, note_read=NoteRead.find_or_create(current_user.get_id(), note_id), attachments=note_json.get('attachments'), topics=note_json.get('topics'), ), )
def add_attachments(note_id): note = Note.find_by_id(note_id=note_id) if note.author_uid != current_user.get_uid(): raise ForbiddenRequestError('Sorry, you are not the author of this note.') attachments = get_note_attachments_from_http_post() attachment_limit = app.config['NOTES_ATTACHMENTS_MAX_PER_NOTE'] if len(attachments) + len(note.attachments) > attachment_limit: raise BadRequestError(f'No more than {attachment_limit} attachments may be uploaded at once.') for attachment in attachments: note = Note.add_attachment( note_id=note_id, attachment=attachment, ) return tolerant_jsonify( _boa_note_to_compatible_json( note=note, note_read=NoteRead.find_or_create(current_user.get_id(), note_id), ), )
def remove_attachment(note_id, attachment_id): existing_note = Note.find_by_id(note_id=note_id) if not existing_note: raise BadRequestError('Note id not found.') if existing_note.author_uid != current_user.get_uid( ) and not current_user.is_admin: raise ForbiddenRequestError( 'You are not authorized to remove attachments from this note.') note = Note.delete_attachment( note_id=note_id, attachment_id=int(attachment_id), ) note_json = note.to_api_json() return tolerant_jsonify( note_to_compatible_json( note=note_json, note_read=NoteRead.find_or_create(current_user.get_id(), note_id), attachments=note_json.get('attachments'), topics=note_json.get('topics'), ), )
def update_note(): params = request.form note_id = params.get('id', None) subject = params.get('subject', None) body = params.get('body', None) topics = get_note_topics_from_http_post() if not note_id or not subject: raise BadRequestError('Note requires \'id\' and \'subject\'') if Note.find_by_id(note_id=note_id).author_uid != current_user.get_uid(): raise ForbiddenRequestError( 'Sorry, you are not the author of this note.') note = Note.update( note_id=note_id, subject=subject, body=process_input_from_rich_text_editor(body), 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_advising_notes(sid): benchmark = get_benchmarker(f'get_advising_notes {sid}') benchmark('begin') notes_by_id = {} benchmark('begin SIS advising notes query') notes_by_id.update(get_sis_advising_notes(sid)) benchmark('begin ASC advising notes query') notes_by_id.update(get_asc_advising_notes(sid)) benchmark('begin non legacy advising notes query') notes_by_id.update(get_non_legacy_advising_notes(sid)) if not notes_by_id.values(): return None notes_read = NoteRead.get_notes_read_by_user(current_user.get_id(), notes_by_id.keys()) for note_read in notes_read: note_feed = notes_by_id.get(note_read.note_id) if note_feed: note_feed['read'] = True else: app.logger.error( f'DB query mismatch for note id {note_read.note_id}') benchmark('end') return list(notes_by_id.values())
def update_note(): params = request.form note_id = params.get('id', None) subject = params.get('subject', None) body = params.get('body', None) topics = _get_topics(params) 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_] if not note_id or not subject: raise BadRequestError('Note requires \'id\' and \'subject\'') if Note.find_by_id(note_id=note_id).author_uid != current_user.get_uid(): raise ForbiddenRequestError('Sorry, you are not the author of this note.') note = Note.update( note_id=note_id, subject=subject, body=process_input_from_rich_text_editor(body), topics=topics, attachments=_get_attachments(request.files, tolerate_none=True), delete_attachment_ids=delete_attachment_ids, ) 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 create_note(): params = request.form sid = params.get('sid', None) subject = params.get('subject', None) body = params.get('body', None) topics = _get_topics(params) if not sid or not subject: raise BadRequestError('Note creation requires \'subject\' and \'sid\'') if current_user.is_admin or not len(current_user.dept_codes): raise ForbiddenRequestError('Sorry, Admin users cannot create advising notes') author_profile = _get_author_profile() attachments = _get_attachments(request.files, tolerate_none=True) note = Note.create( **author_profile, subject=subject, body=process_input_from_rich_text_editor(body), topics=topics, sid=sid, attachments=attachments, ) 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 test_batch_note_creation_with_sids(self, app, client, fake_auth): """Batch note creation with list of SIDs.""" fake_auth.login(coe_advisor_uid) base_dir = app.config['BASE_DIR'] advisor = AuthorizedUser.find_by_uid(coe_advisor_uid) subject = f'Elevate Me Later {datetime.now().timestamp()}' sids = [ '960759268', '856024035', '370048698', '709706581', '518777297', '912902626', '466030628', '695508833', '729680066', '534614253', '329221239', '882981218', '734373851', '968319871', '824231751', '904338427', '849739234', '310798157', '301806363', '352212185', '3456789012', '5678901234', '11667051', '8901234567', '3456789012', '11667051', ] # Curated group curated_group_ids, sids_in_curated_groups = _get_curated_groups_ids_and_sids( advisor) # We need at least one curated_group SID that is NOT in the list o' sids above. sid_expected_in_curated_group = '7890123456' assert sid_expected_in_curated_group in sids_in_curated_groups assert sid_expected_in_curated_group not in sids # Cohort cohort_ids, sids_in_cohorts = _get_cohorts_ids_and_sids(advisor) # We need at least one cohort SID that is NOT in the list o' sids above. expected_sid_in_cohort = '9000000000' assert expected_sid_in_cohort not in sids assert expected_sid_in_cohort in sids_in_cohorts # List above has duplicates - verify that it is de-duped. distinct_sids = set(sids + sids_in_curated_groups + sids_in_cohorts) topics = ['Slanted', 'Enchanted'] _api_batch_note_create( app, client, author_id=advisor.id, subject=subject, body= 'Well you greet the tokens and stamps, beneath the fake oil burnin\' lamps', sids=sids, curated_group_ids=curated_group_ids, cohort_ids=cohort_ids, topics=topics, attachments=[ f'{base_dir}/fixtures/mock_advising_note_attachment_1.txt', f'{base_dir}/fixtures/mock_advising_note_attachment_2.txt', ], ) notes = Note.query.filter(Note.subject == subject).all() assert len(notes) == len(distinct_sids) matching_notes_read = NoteRead.get_notes_read_by_user( viewer_id=advisor.id, note_ids=[str(n.id) for n in notes]) assert len(notes) == len(matching_notes_read) for sid in distinct_sids: note = next((n for n in notes if n.sid == sid), None) assert note assert note.subject == subject assert note.author_uid == advisor.uid assert len(note.topics) == 2 topics = [t.topic for t in note.topics] assert 'Slanted' in topics assert 'Enchanted' in topics assert len(note.attachments) == 2
def mark_read(note_id): if NoteRead.find_or_create(current_user.get_id(), note_id): return tolerant_jsonify({'status': 'created'}, status=201) else: raise BadRequestError(f'Failed to mark note {note_id} as read by user {current_user.get_uid()}')
def get_note(note_id): note = Note.find_by_id(note_id=note_id) if not note: raise ResourceNotFoundError('Note not found') note_read = NoteRead.when_user_read_note(current_user.get_id(), str(note.id)) return tolerant_jsonify(_boa_note_to_compatible_json(note=note, note_read=note_read))
def test_batch_note_creation_with_sids(self, app, client, fake_auth, mock_note_template): """Batch note creation with list of SIDs.""" fake_auth.login(coe_advisor_uid) base_dir = app.config['BASE_DIR'] advisor = AuthorizedUser.find_by_uid(coe_advisor_uid) subject = f'Elevate Me Later {datetime.now().timestamp()}' # Curated group curated_group_ids, sids_in_curated_groups = _get_curated_groups_ids_and_sids( advisor) # We need at least one curated_group SID that is NOT in the list o' sids above. sid_expected_in_curated_group = '7890123456' assert sid_expected_in_curated_group in sids_in_curated_groups assert sid_expected_in_curated_group not in self.sids # Cohort cohort_ids, sids_in_cohorts = _get_cohorts_ids_and_sids(advisor) # We need at least one cohort SID that is NOT in the list o' sids above. expected_sid_in_cohort = '9000000000' assert expected_sid_in_cohort not in self.sids assert expected_sid_in_cohort in sids_in_cohorts # List above has duplicates - verify that it is de-duped. distinct_sids = set(self.sids + sids_in_curated_groups + sids_in_cohorts) topics = ['Slanted', 'Enchanted'] _api_batch_note_create( app=app, attachments=[ f'{base_dir}/fixtures/mock_advising_note_attachment_1.txt', f'{base_dir}/fixtures/mock_advising_note_attachment_2.txt', ], author_id=advisor.id, body= 'Well you greet the tokens and stamps, beneath the fake oil burnin\' lamps', client=client, cohort_ids=cohort_ids, curated_group_ids=curated_group_ids, sids=self.sids, subject=subject, template_attachment_ids=list( map(lambda a: a.id, mock_note_template.attachments)), topics=topics, ) notes = Note.query.filter(Note.subject == subject).all() assert len(notes) == len(distinct_sids) matching_notes_read = NoteRead.get_notes_read_by_user( viewer_id=advisor.id, note_ids=[str(n.id) for n in notes]) assert len(notes) == len(matching_notes_read) template_attachment_count = len(mock_note_template.attachments) assert template_attachment_count expected_attachment_count = template_attachment_count + 2 for sid in distinct_sids: note = next((n for n in notes if n.sid == sid), None) assert note assert note.subject == subject assert note.author_uid == advisor.uid assert len(note.topics) == 2 topics = [t.topic for t in note.topics] assert 'Slanted' in topics assert 'Enchanted' in topics assert len(note.attachments) == expected_attachment_count