예제 #1
0
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'),
        ),
    )
예제 #2
0
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),
        ),
    )
예제 #3
0
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'),
        ), )
예제 #4
0
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))
예제 #5
0
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())
예제 #6
0
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))
예제 #7
0
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))
예제 #8
0
    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
예제 #9
0
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()}')
예제 #10
0
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))
예제 #11
0
    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