def getAssessResults(): if not auth.user: # can't query for user's answers if we don't know who the user is, so just load from local storage return "" course = request.vars.course div_id = request.vars.div_id event = request.vars.event if request.vars.sid: # retrieving results for grader sid = request.vars.sid else: sid = auth.user.username response.headers['content-type'] = 'application/json' # Identify the correct event and query the database so we can load it from the server if event == "fillb": rows = db((db.fitb_answers.div_id == div_id) & (db.fitb_answers.course_name == course) & (db.fitb_answers.sid == sid)).select(db.fitb_answers.answer, db.fitb_answers.timestamp, orderby=~db.fitb_answers.timestamp).first() if not rows: return "" # server doesn't have it so we load from local storage instead # res = { 'answer': rows.answer, 'timestamp': str(rows.timestamp) } do_server_feedback, feedback = is_server_feedback(div_id, course) if do_server_feedback: correct, res_update = fitb_feedback(rows.answer, feedback) res.update(res_update) return json.dumps(res) elif event == "mChoice": rows = db((db.mchoice_answers.div_id == div_id) & (db.mchoice_answers.course_name == course) & (db.mchoice_answers.sid == sid)).select(db.mchoice_answers.answer, db.mchoice_answers.timestamp, db.mchoice_answers.correct, orderby=~db.mchoice_answers.timestamp).first() if not rows: return "" res = {'answer': rows.answer, 'timestamp': str(rows.timestamp), 'correct': rows.correct} return json.dumps(res) elif event == "dragNdrop": rows = db((db.dragndrop_answers.div_id == div_id) & (db.dragndrop_answers.course_name == course) & (db.dragndrop_answers.sid == sid)).select(db.dragndrop_answers.answer, db.dragndrop_answers.timestamp, db.dragndrop_answers.correct, db.dragndrop_answers.minHeight, orderby=~db.dragndrop_answers.timestamp).first() if not rows: return "" res = {'answer': rows.answer, 'timestamp': str(rows.timestamp), 'correct': rows.correct, 'minHeight': str(rows.minHeight)} return json.dumps(res) elif event == "clickableArea": rows = db((db.clickablearea_answers.div_id == div_id) & (db.clickablearea_answers.course_name == course) & (db.clickablearea_answers.sid == sid)).select(db.clickablearea_answers.answer, db.clickablearea_answers.timestamp, db.clickablearea_answers.correct, orderby=~db.clickablearea_answers.timestamp).first() if not rows: return "" res = {'answer': rows.answer, 'timestamp': str(rows.timestamp), 'correct': rows.correct} return json.dumps(res) elif event == "timedExam": rows = db((db.timed_exam.reset == None) & (db.timed_exam.div_id == div_id) & (db.timed_exam.course_name == course) & (db.timed_exam.sid == sid)).select(db.timed_exam.correct, db.timed_exam.incorrect, db.timed_exam.skipped, db.timed_exam.time_taken, db.timed_exam.timestamp, db.timed_exam.reset, orderby=~db.timed_exam.timestamp).first() if not rows: return "" res = {'correct': rows.correct, 'incorrect': rows.incorrect, 'skipped': str(rows.skipped), 'timeTaken': str(rows.time_taken), 'timestamp': str(rows.timestamp), 'reset': str(rows.reset)} return json.dumps(res) elif event == "parsons": rows = db((db.parsons_answers.div_id == div_id) & (db.parsons_answers.course_name == course) & (db.parsons_answers.sid == sid)).select(db.parsons_answers.answer, db.parsons_answers.source, db.parsons_answers.timestamp, orderby=~db.parsons_answers.timestamp).first() if not rows: return "" res = {'answer': rows.answer, 'source': rows.source, 'timestamp': str(rows.timestamp)} return json.dumps(res) elif event == "shortanswer": row = db((db.shortanswer_answers.sid == sid) & (db.shortanswer_answers.div_id == div_id) & (db.shortanswer_answers.course_name == course)).select().first() if not row: return "" res = {'answer': row.answer, 'timestamp': str(row.timestamp)} return json.dumps(res)
def hsblog(): setCookie = False if auth.user: sid = auth.user.username compareAndUpdateCookieData(sid) setCookie = True # we set our own cookie anyway to eliminate many of the extraneous anonymous # log entries that come from auth timing out even but the user hasn't reloaded # the page. else: if request.cookies.has_key('ipuser'): sid = request.cookies['ipuser'].value setCookie = True else: sid = str(uuid.uuid1().int)+"@"+request.client setCookie = True act = request.vars.act div_id = request.vars.div_id event = request.vars.event course = request.vars.course # Get the current time, rounded to the nearest second -- this is how time time will be stored in the database. ts = datetime.datetime.utcnow() ts -= datetime.timedelta(microseconds=ts.microsecond) tt = request.vars.time if not tt: tt = 0 try: db.useinfo.insert(sid=sid,act=act[0:512],div_id=div_id,event=event,timestamp=ts,course_id=course) except: logger.debug('failed to insert log record for {} in {} : {} {} {}'.format(sid, course, div_id, event, act)) if event == 'timedExam' and (act == 'finish' or act == 'reset'): logger.debug(act) if act == 'reset': r = 'T' else: r = None try: db.timed_exam.insert(sid=sid, course_name=course, correct=int(request.vars.correct), incorrect=int(request.vars.incorrect), skipped=int(request.vars.skipped), time_taken=int(tt), timestamp=ts, div_id=div_id,reset=r) except Exception as e: logger.debug('failed to insert a timed exam record for {} in {} : {}'.format(sid, course, div_id)) logger.debug('correct {} incorrect {} skipped {} time {}'.format(request.vars.correct, request.vars.incorrect, request.vars.skipped, request.vars.time)) logger.debug('Error: {}'.format(e.message)) # Produce a default result. res = dict(log=True, timestamp=str(ts)) # Process this event. if event == 'mChoice' and auth.user: # # has user already submitted a correct answer for this question? # if db((db.mchoice_answers.sid == sid) & # (db.mchoice_answers.div_id == div_id) & # (db.mchoice_answers.course_name == auth.user.course_name) & # (db.mchoice_answers.correct == 'T')).count() == 0: answer = request.vars.answer correct = request.vars.correct db.mchoice_answers.insert(sid=sid,timestamp=ts, div_id=div_id, answer=answer, correct=correct, course_name=course) elif event == "fillb" and auth.user: answer_json = request.vars.answer correct = request.vars.correct # Grade on the server if needed. do_server_feedback, feedback = is_server_feedback(div_id, course) if do_server_feedback: correct, res_update = fitb_feedback(answer_json, feedback) res.update(res_update) # Save this data. db.fitb_answers.insert(sid=sid, timestamp=ts, div_id=div_id, answer=answer_json, correct=correct, course_name=course) elif event == "dragNdrop" and auth.user: # if db((db.dragndrop_answers.sid == sid) & # (db.dragndrop_answers.div_id == div_id) & # (db.dragndrop_answers.course_name == auth.user.course_name) & # (db.dragndrop_answers.correct == 'T')).count() == 0: answers = request.vars.answer minHeight = request.vars.minHeight correct = request.vars.correct db.dragndrop_answers.insert(sid=sid, timestamp=ts, div_id=div_id, answer=answers, correct=correct, course_name=course, minHeight=minHeight) elif event == "clickableArea" and auth.user: # if db((db.clickablearea_answers.sid == sid) & # (db.clickablearea_answers.div_id == div_id) & # (db.clickablearea_answers.course_name == auth.user.course_name) & # (db.clickablearea_answers.correct == 'T')).count() == 0: correct = request.vars.correct db.clickablearea_answers.insert(sid=sid, timestamp=ts, div_id=div_id, answer=act, correct=correct, course_name=course) elif event == "parsons" and auth.user: # if db((db.parsons_answers.sid == sid) & # (db.parsons_answers.div_id == div_id) & # (db.parsons_answers.course_name == auth.user.course_name) & # (db.parsons_answers.correct == 'T')).count() == 0: correct = request.vars.correct answer = request.vars.answer source = request.vars.source db.parsons_answers.insert(sid=sid, timestamp=ts, div_id=div_id, answer=answer, source=source, correct=correct, course_name=course) elif event == "codelensq" and auth.user: # if db((db.codelens_answers.sid == sid) & # (db.codelens_answers.div_id == div_id) & # (db.codelens_answers.course_name == auth.user.course_name) & # (db.codelens_answers.correct == 'T')).count() == 0: correct = request.vars.correct answer = request.vars.answer source = request.vars.source db.codelens_answers.insert(sid=sid, timestamp=ts, div_id=div_id, answer=answer, source=source, correct=correct, course_name=course) elif event == "shortanswer" and auth.user: # for shortanswers just keep the latest?? -- the history will be in useinfo db.shortanswer_answers.update_or_insert((db.shortanswer_answers.sid == sid) & (db.shortanswer_answers.div_id == div_id) & (db.shortanswer_answers.course_name == course), sid=sid, answer=act, div_id=div_id, timestamp=ts, course_name=course) response.headers['content-type'] = 'application/json' if setCookie: response.cookies['ipuser'] = sid response.cookies['ipuser']['expires'] = 24*3600*90 response.cookies['ipuser']['path'] = '/' return json.dumps(res)
def hsblog(): setCookie = False if auth.user: sid = auth.user.username compareAndUpdateCookieData(sid) setCookie = ( True ) # we set our own cookie anyway to eliminate many of the extraneous anonymous # log entries that come from auth timing out even but the user hasn't reloaded # the page. else: if "ipuser" in request.cookies: sid = request.cookies["ipuser"].value setCookie = True else: sid = str(uuid.uuid1().int) + "@" + request.client setCookie = True act = request.vars.get("act", "") div_id = request.vars.div_id event = request.vars.event course = request.vars.course # Get the current time, rounded to the nearest second -- this is how time time will be stored in the database. ts = datetime.datetime.utcnow() ts -= datetime.timedelta(microseconds=ts.microsecond) tt = request.vars.time if not tt: tt = 0 try: db.useinfo.insert( sid=sid, act=act[0:512], div_id=div_id, event=event, timestamp=ts, course_id=course, ) except Exception as e: logger.error( "failed to insert log record for {} in {} : {} {} {}".format( sid, course, div_id, event, act ) ) logger.error("Details: {}".format(e)) if event == "timedExam" and (act == "finish" or act == "reset"): logger.debug(act) if act == "reset": r = "T" else: r = None try: db.timed_exam.insert( sid=sid, course_name=course, correct=int(request.vars.correct), incorrect=int(request.vars.incorrect), skipped=int(request.vars.skipped), time_taken=int(tt), timestamp=ts, div_id=div_id, reset=r, ) except Exception as e: logger.debug( "failed to insert a timed exam record for {} in {} : {}".format( sid, course, div_id ) ) logger.debug( "correct {} incorrect {} skipped {} time {}".format( request.vars.correct, request.vars.incorrect, request.vars.skipped, request.vars.time, ) ) logger.debug("Error: {}".format(e.message)) # Produce a default result. res = dict(log=True, timestamp=str(ts)) # Process this event. if event == "mChoice" and auth.user: # # has user already submitted a correct answer for this question? # if db((db.mchoice_answers.sid == sid) & # (db.mchoice_answers.div_id == div_id) & # (db.mchoice_answers.course_name == auth.user.course_name) & # (db.mchoice_answers.correct == 'T')).count() == 0: answer = request.vars.answer correct = request.vars.correct db.mchoice_answers.insert( sid=sid, timestamp=ts, div_id=div_id, answer=answer, correct=correct, course_name=course, ) elif event == "fillb" and auth.user: answer_json = request.vars.answer correct = request.vars.correct # Grade on the server if needed. do_server_feedback, feedback = is_server_feedback(div_id, course) if do_server_feedback: correct, res_update = fitb_feedback(answer_json, feedback) res.update(res_update) # Save this data. db.fitb_answers.insert( sid=sid, timestamp=ts, div_id=div_id, answer=answer_json, correct=correct, course_name=course, ) elif event == "dragNdrop" and auth.user: # if db((db.dragndrop_answers.sid == sid) & # (db.dragndrop_answers.div_id == div_id) & # (db.dragndrop_answers.course_name == auth.user.course_name) & # (db.dragndrop_answers.correct == 'T')).count() == 0: answers = request.vars.answer minHeight = request.vars.minHeight correct = request.vars.correct db.dragndrop_answers.insert( sid=sid, timestamp=ts, div_id=div_id, answer=answers, correct=correct, course_name=course, minHeight=minHeight, ) elif event == "clickableArea" and auth.user: # if db((db.clickablearea_answers.sid == sid) & # (db.clickablearea_answers.div_id == div_id) & # (db.clickablearea_answers.course_name == auth.user.course_name) & # (db.clickablearea_answers.correct == 'T')).count() == 0: correct = request.vars.correct db.clickablearea_answers.insert( sid=sid, timestamp=ts, div_id=div_id, answer=act, correct=correct, course_name=course, ) elif event == "parsons" and auth.user: # if db((db.parsons_answers.sid == sid) & # (db.parsons_answers.div_id == div_id) & # (db.parsons_answers.course_name == auth.user.course_name) & # (db.parsons_answers.correct == 'T')).count() == 0: correct = request.vars.correct answer = request.vars.answer source = request.vars.source db.parsons_answers.insert( sid=sid, timestamp=ts, div_id=div_id, answer=answer, source=source, correct=correct, course_name=course, ) elif event == "codelensq" and auth.user: # if db((db.codelens_answers.sid == sid) & # (db.codelens_answers.div_id == div_id) & # (db.codelens_answers.course_name == auth.user.course_name) & # (db.codelens_answers.correct == 'T')).count() == 0: correct = request.vars.correct answer = request.vars.answer source = request.vars.source db.codelens_answers.insert( sid=sid, timestamp=ts, div_id=div_id, answer=answer, source=source, correct=correct, course_name=course, ) elif event == "shortanswer" and auth.user: # for shortanswers just keep the latest?? -- the history will be in useinfo db.shortanswer_answers.update_or_insert( (db.shortanswer_answers.sid == sid) & (db.shortanswer_answers.div_id == div_id) & (db.shortanswer_answers.course_name == course), sid=sid, answer=act, div_id=div_id, timestamp=ts, course_name=course, ) elif event == "lp_build" and auth.user: ret, new_fields = db.lp_answers._validate_fields( dict(sid=sid, timestamp=ts, div_id=div_id, course_name=course) ) if not ret.errors: do_server_feedback, feedback = is_server_feedback(div_id, course) if do_server_feedback: try: code_snippets = json.loads(request.vars.answer)["code_snippets"] except Exception: code_snippets = [] result = lp_feedback(code_snippets, feedback) # If an error occurred or we're not testing, pass the answer through. res.update(result) # Record the results in the database. correct = result.get("correct") answer = result.get("answer", {}) answer["code_snippets"] = code_snippets ret = db.lp_answers.validate_and_insert( sid=sid, timestamp=ts, div_id=div_id, answer=json.dumps(answer), correct=correct, course_name=course, ) if ret.errors: res.setdefault("errors", []).append(ret.errors.as_dict()) else: res["errors"] = ["No feedback provided."] else: res.setdefault("errors", []).append(ret.errors.as_dict()) response.headers["content-type"] = "application/json" if setCookie: response.cookies["ipuser"] = sid response.cookies["ipuser"]["expires"] = 24 * 3600 * 90 response.cookies["ipuser"]["path"] = "/" return json.dumps(res)