コード例 #1
0
    def test_stream_zipped_bundle(self, app):
        with mock_legacy_note_attachment(app):
            sid = '9000000000'
            filename = 'advising_notes'
            stream = get_zip_stream(
                filename=filename,
                notes=get_advising_notes(sid),
                student={
                    'first_name': 'Wolfgang',
                    'last_name': 'Pauli-O\'Rourke',
                    'sid': sid,
                },
            )
            body = b''
            for chunk in stream:
                body += chunk
            zipfile = ZipFile(io.BytesIO(body), 'r')
            contents = {}
            for name in zipfile.namelist():
                contents[name] = zipfile.read(name)

            assert len(contents) == 2
            assert contents['dog_eaten_homework.pdf'] == b'When in the course of human events, it becomes necessarf arf woof woof woof'
            csv_rows = contents[f'{filename}.csv'].decode('utf-8').strip().split('\r\n')
            assert len(csv_rows) == 4
            assert csv_rows[0] == 'date_created,student_sid,student_name,author_uid,author_csid,author_name,subject,' \
                                  'topics,attachments,body,is_private,late_change_request_action,' \
                                  'late_change_request_status,late_change_request_term,late_change_request_course'
            assert csv_rows[1] == '2017-11-02,9000000000,Wolfgang Pauli-O\'Rourke,,700600500,,,,' \
                                  'dog_eaten_homework.pdf,I am confounded by this confounding student,False,,,,'
            assert csv_rows[2] == "2017-11-02,9000000000,Wolfgang Pauli-O'Rourke,,600500400,,,Ne Scéaw,," \
                                  'Is this student even on campus?,False,,,,'
            assert csv_rows[3] == "2020-12-05,9000000000,Wolfgang Pauli-O'Rourke,,,,,,,," \
                                  'False,Late Grading Basis Change,In Error,Fall 2020,' \
                                  '24460 PSYCH 110 - INTROD BIOL PSYCH 001'
コード例 #2
0
def download_notes_and_attachments(sid):
    students = data_loch.get_basic_student_data([sid])
    student = students[0] if students else None
    notes = get_advising_notes(sid) if student else None
    if not student or not notes:
        return Response('Not found', status=404)

    filename = '_'.join([
        'advising_notes',
        student.get('first_name', '').lower(),
        student.get('last_name', '').lower(),
        localize_datetime(utc_now()).strftime('%Y%m%d'),
    ])

    def generator():
        for chunk in get_zip_stream(filename=filename,
                                    notes=notes,
                                    student=student):
            yield chunk

    response = Response(stream_with_context(generator()),
                        mimetype='application/zip')
    encoding_safe_filename = urllib.parse.quote(
        f'{filename}.zip'.encode('utf8'))
    response.headers[
        'Content-Disposition'] = f'attachment; filename={encoding_safe_filename}'
    return response
コード例 #3
0
 def test_get_advising_notes_timestamp_format(self, app, fake_auth):
     fake_auth.login(coe_advisor)
     notes = get_advising_notes('9000000000')
     ucbconversion_note = notes[0]
     cs_note = notes[1]
     assert parse(ucbconversion_note['createdAt']) == parse('2017-11-02')
     assert ucbconversion_note['updatedAt'] is None
     assert parse(cs_note['createdAt']) == parse('2017-11-02T12:00:00+00')
     assert parse(cs_note['updatedAt']) == parse('2017-11-02T13:00:00+00')
コード例 #4
0
 def test_get_advising_notes_ucbconversion_attachment(self, app, fake_auth):
     fake_auth.login(coe_advisor)
     notes = get_advising_notes('11667051')
     assert notes[0]['attachments'] == [
         {
             'displayName': '11667051_00001_1.pdf',
             'id': '11667051_00001_1.pdf',
             'sisFilename': '11667051_00001_1.pdf',
         },
     ]
コード例 #5
0
 def test_get_advising_notes_cs_attachment(self, app, mock_advising_note, fake_auth):
     fake_auth.login(coe_advisor)
     notes = get_advising_notes('11667051')
     assert notes[1]['attachments'] == [
         {
             'id': '11667051_00002_2.jpeg',
             'sisFilename': '11667051_00002_2.jpeg',
             'displayName': 'brigitte_photo.jpeg',
         },
     ]
     boa_created_note = next((n for n in notes if n['id'] == mock_advising_note.id), None)
     assert boa_created_note
     assert boa_created_note['attachments'][0]['uploadedBy'] == mock_advising_note.author_uid
コード例 #6
0
def put_notifications(student):
    sid = student['sid']
    student['notifications'] = {
        'note': [],
        'alert': [],
        'hold': [],
        'requirement': [],
    }
    if app.config['FEATURE_FLAG_ADVISOR_APPOINTMENTS']:
        student['notifications']['appointment'] = []
        for appointment in Appointment.get_appointments_per_sid(sid) or []:
            student['notifications']['appointment'].append({
                **appointment.to_api_json(current_user.get_id()),
                **{
                    'message': appointment.details,
                    'type': 'appointment',
                },
            })

    # The front-end requires 'type', 'message' and 'read'. Optional fields: id, status, createdAt, updatedAt.
    for note in get_advising_notes(sid) or []:
        message = note['body']
        student['notifications']['note'].append({
            **note,
            **{
                'message': message.strip() if message else None,
                'type': 'note',
            },
        })
    for alert in Alert.current_alerts_for_sid(viewer_id=current_user.get_id(),
                                              sid=sid):
        student['notifications']['alert'].append({
            **alert,
            **{
                'id': alert['id'],
                'read': alert['dismissed'],
                'type': 'alert',
            },
        })
    for row in get_sis_holds(sid):
        hold = json.loads(row['feed'])
        reason = hold.get('reason', {})
        student['notifications']['hold'].append({
            **hold,
            **{
                'createdAt':
                hold.get('fromDate'),
                'message':
                join_if_present('. ', [
                    reason.get('description'),
                    reason.get('formalDescription')
                ]),
                'read':
                True,
                'type':
                'hold',
            },
        })
    degree_progress = student.get('sisProfile', {}).get('degreeProgress', {})
    if degree_progress:
        for key, requirement in degree_progress.get('requirements',
                                                    {}).items():
            student['notifications']['requirement'].append(
                {
                    **requirement,
                    **{
                        'type':
                        'requirement',
                        'message':
                        requirement['name'] + ' ' + requirement['status'],
                        'read':
                        True,
                    },
                })
コード例 #7
0
    def test_get_advising_notes(self, app, mock_advising_note, fake_auth):
        fake_auth.login(coe_advisor)
        notes = get_advising_notes('11667051')

        # Legacy SIS notes
        assert notes[0]['id'] == '11667051-00001'
        assert notes[0]['sid'] == '11667051'
        assert notes[0][
            'body'] == 'Brigitte is making athletic and moral progress'
        assert notes[0]['category'] == 'Quick Question'
        assert notes[0]['subcategory'] == 'Hangouts'
        assert notes[0]['appointmentId'] is None
        assert notes[0]['createdBy'] is None
        assert parse(
            notes[0]['createdAt']) == parse('2017-10-31T12:00:00+00:00')
        assert notes[0]['updatedBy'] is None
        assert notes[0]['updatedAt'] is None
        assert notes[0]['read'] is False
        assert notes[0]['topics'] == ['God Scéaw']
        assert notes[1]['id'] == '11667051-00002'
        assert notes[1]['sid'] == '11667051'
        assert notes[1][
            'body'] == 'Brigitte demonstrates a cavalier attitude toward university requirements'
        assert notes[1]['category'] == 'Evaluation'
        assert notes[1]['subcategory'] == ''
        assert notes[1]['appointmentId'] is None
        assert notes[1]['createdBy'] is None
        assert parse(notes[1]['createdAt']) == parse('2017-11-01T12:00:00+00')
        assert notes[1]['updatedBy'] is None
        assert notes[1]['updatedAt'] is None
        assert notes[1]['read'] is False
        assert notes[1]['topics'] == ['Earg Scéaw', 'Ofscéaw']

        # Legacy ASC notes
        assert notes[4]['id'] == '11667051-139362'
        assert notes[4]['sid'] == '11667051'
        assert notes[4]['body'] is None
        assert notes[4]['author']['uid'] == '1133399'
        assert notes[4]['author']['name'] == 'Lemmy Kilmister'
        assert notes[4]['topics'] == ['Academic', 'Other']
        assert notes[4]['createdAt']
        assert notes[4]['updatedAt'] is None
        assert notes[4]['read'] is False
        assert notes[5]['id'] == '11667051-139379'
        assert notes[5]['sid'] == '11667051'
        assert notes[5]['body'] is None
        assert notes[5]['author']['uid'] == '90412'
        assert notes[5]['author']['name'] == 'Ginger Baker'
        assert notes[5]['topics'] is None
        assert notes[5]['createdAt']
        assert notes[5]['updatedAt'] is None
        assert notes[5]['read'] is False

        # Legacy E&I notes
        assert notes[6]['id'] == '11667051-151620'
        assert notes[6]['sid'] == '11667051'
        assert notes[6]['body'] is None
        assert notes[6]['author']['uid'] == '1133398'
        assert notes[6]['author']['name'] == 'Charlie Christian'
        assert notes[6]['topics'] == ['Course Planning', 'Personal']
        assert notes[6]['createdAt']
        assert notes[6]['updatedAt'] is None
        assert notes[6]['read'] is False

        # Non-legacy note
        boa_created_note = next(
            (n for n in notes if n['id'] == mock_advising_note.id), None)
        assert boa_created_note['id']
        assert boa_created_note['author'][
            'uid'] == mock_advising_note.author_uid
        assert boa_created_note['sid'] == '11667051'
        assert boa_created_note[
            'subject'] == 'In France they kiss on main street'
        assert 'My darling dime store thief' in boa_created_note['body']
        assert boa_created_note['category'] is None
        assert boa_created_note['subcategory'] is None
        assert boa_created_note['appointmentId'] is None
        assert boa_created_note['createdBy'] is None
        assert boa_created_note['createdAt']
        assert boa_created_note['updatedBy'] is None
        assert boa_created_note['updatedAt'] is None
        assert boa_created_note['read'] is False
        assert boa_created_note['topics'] == []
        assert len(boa_created_note['attachments']) == 1
コード例 #8
0
    def test_get_advising_notes(self, app, mock_advising_note, fake_auth):
        fake_auth.login(coe_advisor)
        notes = get_advising_notes('11667051')

        # Legacy SIS notes
        assert notes[0]['id'] == '11667051-00001'
        assert notes[0]['sid'] == '11667051'
        assert notes[0]['body'] == 'Brigitte is making athletic and moral progress'
        assert notes[0]['category'] == 'Quick Question'
        assert notes[0]['subcategory'] == 'Hangouts'
        assert notes[0]['appointmentId'] is None
        assert notes[0]['createdBy'] is None
        assert parse(notes[0]['createdAt']) == parse('2017-10-31T12:00:00+00:00')
        assert notes[0]['updatedBy'] is None
        assert notes[0]['updatedAt'] is None
        assert notes[0]['read'] is False
        assert notes[0]['topics'] == ['God Scéaw']
        assert notes[0]['legacySource'] == 'SIS'
        assert notes[1]['id'] == '11667051-00002'
        assert notes[1]['sid'] == '11667051'
        assert notes[1]['body'] == 'Brigitte demonstrates a cavalier attitude toward university requirements'
        assert notes[1]['category'] == 'Evaluation'
        assert notes[1]['subcategory'] == ''
        assert notes[1]['appointmentId'] is None
        assert notes[1]['createdBy'] is None
        assert parse(notes[1]['createdAt']) == parse('2017-11-01T12:00:00+00')
        assert notes[1]['updatedBy'] is None
        assert notes[1]['updatedAt'] is None
        assert notes[1]['read'] is False
        assert notes[1]['topics'] == ['Earg Scéaw', 'Ofscéaw']
        assert notes[1]['legacySource'] == 'SIS'

        # Legacy ASC note without subject/body
        assert notes[4]['id'] == '11667051-139362'
        assert notes[4]['sid'] == '11667051'
        assert notes[4]['subject'] is None
        assert notes[4]['body'] is None
        assert notes[4]['author']['uid'] == '1133399'
        assert notes[4]['author']['name'] == 'Lemmy Kilmister'
        assert notes[4]['topics'] == ['Academic', 'Other']
        assert notes[4]['createdAt']
        assert notes[4]['updatedAt'] is None
        assert notes[4]['read'] is False
        assert notes[4]['legacySource'] == 'ASC'

        # Legacy ASC note with subject/body
        assert notes[5]['id'] == '11667051-139379'
        assert notes[5]['sid'] == '11667051'
        assert notes[5]['subject'] == 'Ginger Baker\'s Air Force'
        assert notes[5]['body'] == 'Bands led by drummers tend to leave a lot of space for drum solos'
        assert notes[5]['author']['uid'] == '90412'
        assert notes[5]['author']['name'] == 'Ginger Baker'
        assert notes[5]['topics'] is None
        assert notes[5]['createdAt']
        assert notes[5]['updatedAt'] is None
        assert notes[5]['read'] is False
        assert notes[5]['legacySource'] == 'ASC'

        # Legacy Data Science notes
        assert notes[6]['id'] == '11667051-20181003051208'
        assert notes[6]['sid'] == '11667051'
        assert notes[6]['body'] == 'Data that is loved tends to survive.'
        assert notes[6]['author']['email'] == '*****@*****.**'
        assert notes[6]['createdAt'] == '2018-10-04T00:12:08+00:00'
        assert notes[6]['topics'] == ['Declaring the major', 'Course planning', 'Domain Emphasis']
        assert notes[6]['legacySource'] == 'Data Science'

        # Legacy E&I notes
        assert notes[8]['id'] == '11667051-151620'
        assert notes[8]['sid'] == '11667051'
        assert notes[8]['body'] is None
        assert notes[8]['author']['uid'] == '1133398'
        assert notes[8]['author']['name'] == 'Charlie Christian'
        assert notes[8]['topics'] == ['Course Planning', 'Personal']
        assert notes[8]['createdAt']
        assert notes[8]['updatedAt'] is None
        assert notes[8]['read'] is False
        assert notes[8]['legacySource'] == 'CE3'

        # Non-legacy note
        boa_created_note = next((n for n in notes if n['id'] == mock_advising_note.id), None)
        assert boa_created_note['id']
        assert boa_created_note['author']['uid'] == mock_advising_note.author_uid
        assert boa_created_note['sid'] == '11667051'
        assert boa_created_note['subject'] == 'In France they kiss on main street'
        assert 'My darling dime store thief' in boa_created_note['body']
        assert boa_created_note['category'] is None
        assert boa_created_note['subcategory'] is None
        assert boa_created_note['appointmentId'] is None
        assert boa_created_note['createdBy'] is None
        assert boa_created_note['createdAt']
        assert boa_created_note['updatedBy'] is None
        assert boa_created_note['updatedAt'] is None
        assert boa_created_note['read'] is False
        assert boa_created_note['topics'] == []
        assert len(boa_created_note['attachments']) == 1
        assert 'legacySource' not in boa_created_note