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})
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)
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)
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})
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)
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})
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})
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})
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})
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)