Example #1
0
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)
Example #2
0
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)
Example #3
0
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)
Example #4
0
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)
Example #5
0
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)