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