Beispiel #1
0
def task_overview(course_id, assignment_id, task_id):
    if current_user.role == "USER":
        app.logger.info("student attempted access to task overview. id: "+str(current_user.get_id()))
        return redirect(url_for("index"))  
    form = None
    if request.method == "POST":
        app.logger.info("attempting answer update")
        form = AnswerForm(request.form)
        
        if not request.form.get("reveal_after") and not form.validate():
            app.logger.info("form validation failed")
            pass
        else:
            app.logger.info("updating answer for "+str(task_id))
            reveal = None
            if not request.form.get("reveal_after"):
                app.logger.info("custom date for reveal "+str(task_id))
                reveal = pytz.timezone("Europe/Helsinki").localize(form.reveal.data)
            files_to_delete = request.form.getlist("del_files", int)
            description = None
            if form.description.data:
                description=form.description.data

            db.update_answer(current_user.get_id(), task_id, request.files.getlist("files"), description, reveal=reveal, files_to_delete=files_to_delete )
            app.logger.info("update success, redirecting")
            form = None
            return redirect(url_for("task_overview", course_id=course_id, assignment_id=assignment_id, task_id=task_id))
            

    app.logger.info("viewing task overview")
    assignment = db.select_assignment(assignment_id, task_id=task_id)
    if not assignment:
        return redirect(url_for("index"))
    if assignment.deadline is None:
        deadline_not_passed = True
    else:
        deadline_not_passed = assignment.deadline.astimezone(pytz.utc) > datetime.datetime.now(pytz.utc)
    
    try:
        task = assignment.tasks[0] #all assigs have at least 1 task, so will only happen for manual urls
    except:
        return redirect(url_for("index"))
    
    db.set_submits(assignment,current_user.get_id(), task_id=task.id)
    
    task.files = db.select_file_details(task_id=task_id)
    db.set_task_answer(task, for_student=False)
    assignment.set_timezones("Europe/Helsinki")
    
    if form is None:
        form = AnswerForm()
    submits = db.get_all_submits(assignment_id, task_id=task.id, convert_to_timezone = "Europe/Helsinki", join_feedback=True)
    all_students = db.select_students(course_id, current_user.get_id())
    student_ids_with_submits = [s.id for s in all_students if submits.get(s.id)]
    student_ids_with_submits.append("id"+str(task_id))
    
    session.pop("next_list", None)
    session["next_list"] = student_ids_with_submits
    print(submits)
    return render_template("/teacher/overview/task.html",course_id=course_id, task = task, assignment=assignment, deadline_not_passed=deadline_not_passed, form = form, students = all_students, submits = submits) 
Beispiel #2
0
def assignment_overview(course_id, assignment_id):
    if current_user.role == "USER":
        return redirect(url_for("index"))   
    assign = db.select_assignment(assignment_id)
    for t in assign.tasks:
        db.set_task_answer(t, for_student=False)
    assign.set_timezones("Europe/Helsinki")
    return render_template("/teacher/overview/assignment.html", assignment = assign) 
Beispiel #3
0
def view_assig(course_id,
               assignment_id):  #TODO rights validations (remember reveal)
    assignment = db.select_assignment(assignment_id)
    db.set_submits(assignment, current_user.get_id())
    for t in assignment.tasks:
        db.set_task_answer(t, for_student=True)
    assignment.set_timezones("Europe/Helsinki")
    return render_template("/student/assignment/view.html",
                           assignment=assignment)
Beispiel #4
0
def grade_student(course_id, assignment_id, task_id, student_id):
    app.logger.info("grading student %s, task %s", student_id, task_id)
    assignment = db.select_assignment(assignment_id, task_id=task_id)

    student_list = session.get("next_list")
    this_student = db.get_user_by_id(student_id)
    student_dic = db.select_submits([student_id], [task_id],
                                    set_feedback=True).get(int(student_id))
    if student_dic:
        submit = student_dic.get(int(task_id))
    else:
        submit = None

    if not student_list:
        submits = db.get_all_submits(assignment_id,
                                     task_id=task_id,
                                     convert_to_timezone="Europe/Helsinki")
        all_students = db.select_students(course_id, current_user.get_id())
        student_ids_with_submits = [
            s.id for s in all_students if submits.get(s.id)
        ]
        student_ids_with_submits.append("id" + str(task_id))
        session["next_list"] = student_ids_with_submits
        student_list = student_ids_with_submits

    if int(student_list[len(student_list) - 1][2:]) == int(task_id):
        student_id = find_next_student(student_list, student_id)

        if student_id is not None:
            next_url = url_for("grade_student",
                               course_id=course_id,
                               assignment_id=assignment_id,
                               task_id=task_id,
                               student_id=student_id)
        else:
            next_url = url_for("task_overview",
                               course_id=course_id,
                               assignment_id=assignment_id,
                               task_id=task_id)

    task = assignment.tasks[0]
    feedback = db.select_feedback(current_user.get_id(), submit_id=submit.id)
    return render_template("/teacher/grade/task.html",
                           feedback=feedback,
                           assignment=assignment,
                           task=task,
                           next_url=next_url,
                           submit=submit,
                           this_student=this_student,
                           comment_target="s:" + str(submit.id))
Beispiel #5
0
def view_task(course_id, assignment_id, task_id):
    if request.method == "GET":
        assignment = db.select_assignment(assignment_id, task_id=task_id)

        if assignment.deadline is None:
            deadline_not_passed = True
        else:
            deadline_not_passed = assignment.deadline.astimezone(
                pytz.utc) > datetime.datetime.now(pytz.utc)

        try:
            task = assignment.tasks[
                0]  #all assigs have at least 1 task, so will only happen for manual urls
        except:
            return redirect(url_for("index"))

        db.set_submits(assignment, current_user.get_id(), task_id=task.id)

        task.files = db.select_file_details(task_id=task.id)
        db.set_task_answer(task, for_student=True)
        assignment.set_timezones("Europe/Helsinki")
        submit = assignment.submits[0]
        points = ""
        if submit:
            feedback = db.select_feedback(current_user.get_id(),
                                          submit_id=submit.id)
            if feedback:
                points = feedback.points
        return render_template("/student/assignment/view_task.html",
                               course_id=course_id,
                               task=task,
                               assignment=assignment,
                               deadline_not_passed=deadline_not_passed,
                               comment_target="ts:" + str(task_id),
                               points=points)
    else:
        if current_user.role != "USER":
            return redirect(url_for("index"))
        files = request.files.getlist("files")
        db.update_submit(current_user.get_id(), task_id, assignment_id, files)
        return redirect(
            url_for("view_task",
                    course_id=course_id,
                    assignment_id=assignment_id,
                    task_id=task_id))
def test_large_answer_insert_and_update(db_test_client):
    from application import db
    visible_reveal = pytz.utc.localize(
        datetime.datetime.utcnow()) - datetime.timedelta(minutes=1)
    teacher = insert_users(db, 1, roles=["TEACHER"])[0]
    course_id, _ = db.insert_course(
        Course("something", "somthing", visible_reveal, visible_reveal),
        teacher.id)
    f = generate_random_file()
    file_name = secure_filename(get_random_unicode(30))
    werk_file = FileStorage(f, file_name)
    assignment_id = db.insert_assignment(teacher.id, course_id, "somthing",
                                         random_datetime(), visible_reveal,
                                         [werk_file])
    werk_file.close()
    all_answers = []
    visible_answers = []
    visible_tasks = []
    correct_files = FileMultiDict()
    for _ in range(100):
        task_id = db.insert_task(teacher.id, assignment_id,
                                 get_random_unicode(20), 20, [])
        hidden = random.randint(0, 1)
        if not hidden:
            visible_tasks.append(task_id)
            reveal = visible_reveal
        else:
            reveal = random_datetime()
        files = []
        for i in range(3):
            f = generate_random_file(length=10)
            file_name = str(task_id) + "t" + str(i)
            werk_file = FileStorage(f, file_name)
            files.append(werk_file)
            correct_files.add_file(task_id, werk_file, werk_file.filename)
        desc = get_random_unicode(30)
        id = db.update_answer(teacher.id, task_id, files, desc, reveal=reveal)

        answer = Answer(id, desc, reveal.replace(tzinfo=None),
                        db.select_file_details(answer_id=id))
        all_answers.append(answer)
        if not hidden:
            visible_answers.append(answer)

    for f in files:
        f.close()
    assignment = db.select_assignment(assignment_id, for_student=False)
    all_db_answers = []
    case = unittest.TestCase()
    assert len(assignment.tasks) == 100
    for t in assignment.tasks:
        assert isinstance(t, Task)
        db.set_task_answer(t, for_student=False)
        assert t.answer is not None
        a = t.answer
        assert isinstance(a, Answer)
        assert len(a.files) == 3
        correct_filenames = [
            file.filename for file in correct_files.getlist(t.id)
        ]
        assert len(correct_filenames) == 3
        db_filenames = [file.name for file in a.files]

        case.assertCountEqual(db_filenames, correct_filenames)
        all_db_answers.append(a)

    assert len(all_answers) == len(all_db_answers)
    case.maxDiff = None
    case.assertCountEqual(all_answers, all_db_answers)
    assignment = db.select_assignment(assignment_id, for_student=True)
    assert len(assignment.tasks) == 100

    db_visibles = []
    for t in assignment.tasks:
        assert isinstance(t, Task)
        db.set_task_answer(t, for_student=True)
        if t.id not in visible_tasks:
            assert t.answer is None
            continue
        assert t.answer is not None
        db_visibles.append(t.answer)
        a = t.answer
        assert isinstance(a, Answer)
        assert len(a.files) == 3
        correct_filenames = [
            file.filename for file in correct_files.getlist(t.id)
        ]
        assert len(correct_filenames) == 3
        db_filenames = [file.name for file in a.files]

        case.assertCountEqual(db_filenames, correct_filenames)

    case.assertCountEqual(db_visibles, visible_answers)
def test_simple_answer(db_test_client):
    from application import db

    reveal = pytz.utc.localize(
        datetime.datetime.utcnow()) - datetime.timedelta(minutes=1)
    teacher = insert_users(db, 1, roles=["TEACHER"])[0]
    student = insert_users(db, 1, roles=["USER"])[0]
    c_id, code = db.insert_course(Course("something", "something", reveal),
                                  teacher.id)
    db.enlist_student(code, student.id)
    f = generate_random_file()
    file_name = secure_filename(get_random_unicode(30))
    werk_file = FileStorage(f, file_name)
    a_id = db.insert_assignment(teacher.id, c_id, "ksakas", reveal, reveal,
                                [werk_file])
    t_id = db.insert_task(teacher.id, a_id, "something", 3, [werk_file])
    werk_file.close()
    files = []
    correct_files = FileMultiDict()
    for _ in range(5):
        f = generate_random_file()
        file_name = secure_filename(get_random_unicode(30))
        werk_file = FileStorage(f, file_name)
        files.append(werk_file)
        correct_files.add_file(file_name, werk_file)

    description = get_random_unicode(100)
    db.update_answer(teacher.id,
                     t_id,
                     files,
                     description,
                     reveal=random_datetime())

    assignment = db.select_assignment(a_id, task_id=t_id)

    assert assignment.name == "ksakas"

    assert len(assignment.tasks) == 1
    t = assignment.tasks[0]
    assert isinstance(t, Task)
    db.set_task_answer(assignment.tasks[0], for_student=False)

    assert t.answer is not None
    assert isinstance(t.answer, Answer)
    assert t.answer.description == description

    assert len(t.answer.files) == 5

    for db_f in t.answer.files:
        assert isinstance(db_f, File)
        c_f = correct_files.get(db_f.name)

        bin_file, name = db.get_file(db_f.id)
        assert name == db_f.name, "shouldn't fail... " + str(
            type(name)) + "  " + str(type(db_f.name))
        c_f.seek(0)
        assert bin_file == c_f.read()
        c_f.close()

    db.set_task_answer(t, for_student=True)
    assert t.answer is None
Beispiel #8
0
def test_simple_assignment(db_test_client, a_files=[], t_files=[]):
    from application import db
    from .course_test import test_course_insert
    id, code = test_course_insert(db_test_client)
    student = db.get_user("oppilas", "oppilas")
    teacher = db.get_user("opettaja", "opettaja")

    assert student is not None
    assert teacher is not None

    db.enlist_student(code, student.id)

    visible_a_name = get_random_unicode(30)
    reveal = random_datetime()
    deadline = random_datetime(start=reveal)

    a_id = db.insert_assignment(teacher.id, id, visible_a_name, deadline,
                                reveal, a_files)

    points = random.randint(5, 20)
    t_desc = get_random_unicode(30)

    t_id = db.insert_task(teacher.id, a_id, t_desc, points, t_files)

    with db.engine.connect() as conn:
        sql = select([db.assignment]).where(db.assignment.c.id == a_id)
        rs = conn.execute(sql)
        row = rs.first()
        assert row is not None
        assert row[db.assignment.c.id] == a_id
        assert row[db.assignment.c.name] == visible_a_name
        assert pytz.utc.localize(row[db.assignment.c.deadline]) == deadline
        assert pytz.utc.localize(row[db.assignment.c.reveal]) == reveal

        sql = select([db.task]).where(db.task.c.id == t_id)
        rs = conn.execute(sql)
        row = rs.first()

        assert row is not None
        assert row[db.task.c.id] == t_id
        assert row[db.task.c.description] == t_desc
        assert row[db.task.c.points] == points
        assert row[db.task.c.assignment_id] == a_id

        null = db.select_assignment(28128218)
        assert null is None

        a = db.select_assignment(a_id)
        assert isinstance(a, Assignment)
        assert len(a.tasks) == 1

        assert a.id == a_id
        assert a.name == visible_a_name
        assert a.deadline == deadline
        assert a.reveal == reveal

        t = a.tasks[0]

        assert isinstance(t, Task)
        assert t.id == t_id
        assert t.description == t_desc
        assert t.points == points
        assert t.assignment_id == a_id

        null = db.select_assignment(a_id, for_student=True)
        assert null is None