Beispiel #1
0
def updateReport():
    """
    Takes in a json of the form {'classId' : '123', 'email' : student_email, 'mark' : 90.00, 'comment' : "Great!"}

    Returns a "success" json
    """

    if request.json is None:
        abort(400)

    try:
        validate(instance=request.json, schema=SchemaFactory.report_update)
    except exceptions.ValidationError:
        abort(400)

    if not dbworker.validateAccessList(
        [dbworker.userTypeMap['admin'], dbworker.userTypeMap['instructor']]):
        abort(403)

    studentEmail = mailsane.normalize(request.json['email'])

    if studentEmail.error:
        abort(400)
    convClassId = ObjectId(request.json['classId'])
    dbworker.updateReport(
        convClassId,
        str(studentEmail),
        mark={} if 'mark' not in request.json else request.json['mark'],
        comments=''
        if 'comments' not in request.json else request.json['comments'],
        nextCourse=''
        if 'nextCourse' not in request.json else request.json['nextCourse'])

    return jsonify({'success': True})
Beispiel #2
0
def getClass():
    """
    Takes in a JSON of the form {'_id' : String}

    Returns all the information for a class including _id stringified

    {'result' : None/JSON, 'success' : Boolean}
    """

    if request.json is None or '_id' not in request.json:
        abort(400)

    if not dbworker.validateAccessList(
        [dbworker.userTypeMap['admin'], dbworker.userTypeMap['instructor']]):
        abort(401)

    try:
        validate(instance=request.json, schema=SchemaFactory.get_class)
    except exceptions.ValidationError:
        abort(400)

    try:
        cl = dbworker.getClass(ObjectId(request.json['_id']))
        if cl is None:
            abort(404)

        cl['_id'] = str(cl['_id'])
        return jsonify({'result': cl, 'success': True})
    except bson.errors.InvalidId:
        abort(400)
Beispiel #3
0
def getUserClasses(email):
    if not dbworker.validateAccessList([
            dbworker.userTypeMap['admin'], dbworker.userTypeMap['instructor'],
            dbworker.userTypeMap['student']
    ]):
        abort(403)

    email = mailsane.normalize(email)
    if email.error:
        abort(400)

    classes = {'instructor': [], 'student': []}
    for i in dbworker.mclient[dbworker.database]['classes'].find(
        {'instructors': str(email)}):
        tmp_id = i['_id']
        classes['instructor'].append({
            "id": str(tmp_id),
            "name": i['courseTitle'],
            "ongoing": i['ongoing']
        })

    for j in dbworker.mclient[dbworker.database]['classes'].find(
        {"students": str(email)}):
        tmp_id = j['_id']
        classes['student'].append({
            "id": str(tmp_id),
            "name": j['courseTitle'],
            "ongoing": j['ongoing']
        })
    return jsonify(classes)
Beispiel #4
0
def getHours():

    if not dbworker.validateAccessList([
            dbworker.userTypeMap['admin'], dbworker.userTypeMap['instructor'],
            dbworker.userTypeMap['volunteer']
    ]):
        abort(403)

    pre_email = request.args.get('user', default=None, type=str)

    email = None

    if pre_email is None:
        email = session.get('email')

        if email is None:
            abort(500)
    else:
        if not dbworker.validateAccessList([dbworker.userTypeMap['admin']]):
            abort(403)

        email = mailsane.normalize(pre_email)

        if email.error:
            abort(400)

    hours = dbworker.getHours(filt={"email": str(email)},
                              projection={
                                  '_id': 1,
                                  'dateTime': 1,
                                  'purpose': 1,
                                  'hours': 1,
                                  'paid': 1
                              })

    hours_list = []
    for doc in hours:
        doc['_id'] = str(doc['_id'])
        hours_list.append(doc)

    return jsonify({"hours": hours_list})
Beispiel #5
0
def getCriteria(class_id):
    if not dbworker.validateAccessList(
        [dbworker.userTypeMap['admin'], dbworker.userTypeMap['instructor']]):
        abort(401)

    try:
        cl = dbworker.getClass(ObjectId(class_id))
        if cl is None:
            abort(404)

        to_return = {
            "courseTitle": cl['courseTitle'],
            "markingSections": cl['markingSections']
        }
        to_return['_id'] = str(cl['_id'])
        return jsonify({'result': to_return, 'success': True})
    except bson.errors.InvalidId:
        abort(400)
Beispiel #6
0
def getStudentReport(class_id, email):
    """
    Return a report for a student for a specific class.
    Expected json is {"email": [email protected], "classId":"5e5ab2f6e7179a5e7ee4e81b"}
    """

    # try:
    #     validate(instance={"email":email, "classId":class_id}, schema=SchemaFactory.report_student)
    # except exceptions.ValidationError:
    #     abort(400)

    email = mailsane.normalize(email)

    if email.error:
        abort(400)

    if not dbworker.validateAccessList(
        [dbworker.userTypeMap['admin'], dbworker.userTypeMap['instructor']]):
        abort(403)

    # Must first convert classId string in to a ObjectId before executing query
    convClassId = ObjectId(class_id)

    # Verify: 'email' is an existing user in DB and 'convClassId' is the idea of an existing class
    us = dbworker.getUser(str(email))
    cl = dbworker.getClass(convClassId)
    if us is None or cl is None:
        abort(404)

    if us['userType'] != dbworker.userTypeMap['student']:
        abort(400)

    filt = {"classId": convClassId, "studentEmail": str(email)}
    proj = {'_id': 0}

    report = dbworker.getStudentReport(filt=filt, proj=proj)

    if report is None:
        abort(400)

    # Must convert ObjectId 'classId' into a string before responding
    report['classId'] = str(report['classId'])

    return jsonify({"report": report})
Beispiel #7
0
def genHours():
    # request.json['hours'] is currently a string that gets converted server side

    valid_access = [
        dbworker.userTypeMap['admin'], dbworker.userTypeMap['instructor'],
        dbworker.userTypeMap['volunteer']
    ]

    if not dbworker.validateAccessList(valid_access):
        abort(403)

    if request.json is None:
        abort(400)

    for x in ['purpose', 'paid', 'hours', 'dateTime']:
        if x not in request.json:
            abort(400)

    correctedTime = datetime.datetime.strptime(request.json['dateTime'],
                                               "%Y-%m-%dT%H:%M:%S.%fZ")

    email = session['email']

    if 'email' in request.json:
        email = mailsane.normalize(request.json['email'])
        if email.error:
            abort(400)

    hours = 0
    try:
        # Handle conversion from a string to a float
        hours = float(request.json['hours'])
    except:
        abort(400)

    if hours <= 0:
        abort(400)

    dbworker.addHoursLog(str(email), request.json['purpose'],
                         request.json['paid'], correctedTime, hours)

    return jsonify({'success': True})
Beispiel #8
0
def getUsers():
    """
    Returns a json of the form {'result' : list of users with emails, first and last names, 'success' : True}
    """
    if not dbworker.validateAccessList(
        [dbworker.userTypeMap['admin'], dbworker.userTypeMap['instructor']]):
        abort(403)

    uList = dbworker.getUsers(projection={
        '_id': 0,
        'email': 1,
        'firstName': 1,
        'lastName': 1,
        'userType': 1
    })

    fixedList = []
    for x in uList:
        fixedList.append(x)

    return jsonify({'result': fixedList, 'success': True})
Beispiel #9
0
def getUser():
    """
    Takes in a JSON of {'email'}

    Returns {'result' : {user information, no id or password}, 'success' : True}

    This method is not just usable by admins, but by instructors
    """
    if dbworker.validateAccessList(
        [dbworker.userTypeMap['admin'], dbworker.userTypeMap['instructor']]):
        pass
    else:
        abort(403)

    if request.json is None or 'email' not in request.json:
        abort(400)

    email = mailsane.normalize(request.json['email'])
    if email.error:
        abort(400)

    u = dbworker.getUser(str(email))
    if u is None:
        abort(405)

    u.pop('password')
    u.pop('_id')

    now = datetime.datetime.now()

    bday = now
    if 'birthday' in u:
        bday = u['birthday']

    delta = now - bday
    age = int(delta.total_seconds() / (31536000))

    u['age'] = age
    return jsonify({'result': u, 'success': True})
Beispiel #10
0
def getReport():
    """
    Return a PDF containing all worked/volunteer hours
    """
    report_params = request.json

    if report_params is None:
        abort(400)

    if 'email' not in report_params:
        report_params['email'] = session['email']

    try:
        validate(instance=report_params, schema=SchemaFactory.report_hours)
    except exceptions.ValidationError:
        abort(400)

    email = mailsane.normalize(report_params['email'])

    if email.error:
        abort(400)

    if not dbworker.validateAccessList([dbworker.userTypeMap['admin']
                                        ]) and str(email) != session['email']:
        # Allows admins to see everyones reports, users to see their own
        abort(403)

    paid_hrs = None

    filt = {"email": str(email)}
    proj = {'_id': 0, 'hours': 1}

    if 'paid' in request.json:
        filt['paid'] = True if request.json['paid'] else False
        paid_hrs = False if request.json['paid'] == 0 else True

    # Convert date ranges into datetime objects and insert into filter
    # Note: to enforce a specific date/time pattern you can also use strptime method:
    # datetime.datetime.strptime(request.json['startRange'], '%Y-%m-%d') (complete pattern: "%Y-%m-%dT%H:%M:%S.%fZ")
    if 'startRange' in report_params and 'endRange' in report_params:
        start_time_stamp = parse(report_params['startRange'])
        end_time_stamp = parse(report_params['endRange'])
        filt["dateTime"] = {'$gte': start_time_stamp, '$lte': end_time_stamp}
    elif 'startRange' in report_params:
        start_time_stamp = parse(report_params['startRange'])
        filt["dateTime"] = {'$gte': start_time_stamp}
    elif 'endRange' in report_params:
        end_time_stamp = parse(report_params['endRange'])
        filt["dateTime"] = {'$lte': end_time_stamp}

    hours = dbworker.getHours(filt=filt, projection=proj)

    hours_list = []
    for doc in hours:
        hours_list.append(float(doc["hours"]))

    file_name = reportgen.hours(email, hours_list, paid_hrs)

    # Once generated, report PDFs are currently stored in the 'app' folder of docker container
    resp_file = send_file(file_name, attachment_filename=file_name)

    if os.path.exists("app/" + file_name):
        os.remove("app/" + file_name)
        return resp_file

    abort(500)