def practice_choose_topic(course_id): """ Present a list of topics for them to choose from the given course """ user_id = session['user_id'] try: course = Courses2.get_course(course_id) except KeyError: course = None abort(404) try: topics = Courses2.get_topics_list(course_id) except KeyError: topics = [] abort(404) members = None for topic in topics: if topic['visibility'] == 2: # course only if not members: members = Courses.get_users(course_id) if not user_id in members: topics.remove(topic) return render_template( "practicecourse.html", courses=Setup.get_sorted_courselist(), canpreview=check_perm(user_id, course_id, "questionpreview"), topics=topics, course=course )
def practice_choose_topic(course_id): """ Present a list of topics for them to choose from the given course """ user_id = session['user_id'] try: course = Courses2.get_course(course_id) except KeyError: course = None abort(404) try: topics = Courses2.get_topics_list(course_id) except KeyError: topics = [] abort(404) members = None for topic in topics: if topic['visibility'] == 2: # course only if not members: members = Courses.get_users(course_id) if user_id not in members: topics.remove(topic) return render_template( "practicecourse.html", courses=Setup.get_sorted_courselist(), canpreview=check_perm(user_id, course_id, "questionpreview"), topics=topics, course=course )
def cadmin_top(course_id): """ Present top level course admin page """ course = Courses2.get_course(course_id) if not course: abort(404) user_id = session['user_id'] is_sysadmin = check_perm(user_id, -1, 'sysadmin') topics = Courses2.get_topics_list(course_id) exams = [ Exams.get_exam_struct(exam_id, course_id) for exam_id in Courses.get_exams(course_id, prev_years=False) ] exams.sort(key=lambda y: y['start_epoch'], reverse=True) groups = Courses.get_groups(course_id) choosegroups = [ group for group in Groups.all_groups() if group.id not in groups ] return render_template("courseadmin_top.html", course=course, topics=topics, exams=exams, choosegroups=choosegroups, groups=groups, is_sysadmin=is_sysadmin)
def cadmin_top(course_id): """ Present top level course admin page """ course = Courses2.get_course(course_id) if not course: abort(404) user_id = session['user_id'] is_sysadmin = check_perm(user_id, -1, 'sysadmin') topics = Courses2.get_topics_list(course_id) exams = [Exams.get_exam_struct(exam_id, course_id) for exam_id in Courses.get_exams(course_id, prev_years=False)] exams.sort(key=lambda y: y['start_epoch'], reverse=True) groups = Courses.get_groups(course_id) choosegroups = [group for group in Groups.all_groups() if group.id not in groups] return render_template( "courseadmin_top.html", course=course, topics=topics, exams=exams, choosegroups=choosegroups, groups=groups, is_sysadmin=is_sysadmin )
def admin_course_save(course_id): """ accept saved settings """ form = request.form cancel_edit = form.get("cancel_edit", False) if cancel_edit: flash("Course edits cancelled") return redirect(url_for("admin_courses")) changed = False course = Courses2.get_course(course_id) groups = Courses.get_groups(course_id) for g_id, group in groups.iteritems(): if form.get('delgroup_%s' % g_id): changed = True flash("Removing group %s" % group.name, "info") Courses.del_group(int(g_id), course_id) if 'course_name' in form: name = form['course_name'] if not name == course['name']: changed = True Courses.set_name(course_id, name) if 'course_title' in form: title = form['course_title'] if not title == course['title']: changed = True Courses.set_title(course_id, title) if 'course_active' in form: active = form['course_active'] if active == '1' or active == 1: active = True else: active = False if not (active == course['active']): changed = True Courses.set_active(course_id, active) addbtn = form.get('group_addbtn') if addbtn: newgroup = form.get('addgroup', None) if newgroup: Courses.add_group(newgroup, course_id) changed = True group = Groups.Group(newgroup) flash("Group %s added." % group.name) if changed: Courses2.reload_if_needed() flash("Course changes saved!") return redirect(url_for("admin_course", course_id=course_id)) course = Courses2.get_course(course_id) course['size'] = len(Courses.get_users(course_id)) return redirect(url_for("admin_courses"))
def cadmin_edittopics(course_id): """ Present a page to view and edit all topics, including hidden. """ course = None try: course = Courses2.get_course(course_id) except KeyError: abort(404) if not course: abort(404) topics = Courses2.get_topics_list(course_id) return render_template("courseadmin_edittopics.html", course=course, topics=topics)
def cadmin_edit_topic(course_id, topic_id): """ Present a page to view and edit a topic, including adding/editing questions and setting some parameters. """ user_id = session['user_id'] if not course_id: abort(404) course = Courses2.get_course(course_id) topic = { 'id': topic_id, 'position': Topics.get_pos(topic_id), 'name': Topics.get_name(topic_id) } questions = [question for question in Topics.get_qts(topic_id).values()] for question in questions: question['embed_id'] = DB.get_qt_embedid(question['id']) if question['embed_id']: question['embed_url'] = "%s/embed/question/%s/question.html" % \ (OaConfig.parentURL, question['embed_id']) else: question['embed_url'] = None question['editor'] = DB.get_qt_editor(question['id']) all_courses = Courses2.get_course_list() all_courses = [crse for crse in all_courses if satisfy_perms(user_id, int(crse['id']), ("questionedit", "courseadmin", "sysadmin"))] all_courses.sort(lambda f, s: cmp(f['name'], s['name'])) all_course_topics = [] for crse in all_courses: topics = Courses.get_topics_all(crse['id'], numq=False) if topics: all_course_topics.append({'course': crse['name'], 'topics': topics}) questions.sort(key=lambda k: k['position']) return render_template( "courseadmin_edittopic.html", course=course, topic=topic, questions=questions, all_course_topics=all_course_topics )
def setup_usersummary(view_id): """ Show an account summary for the given user account. """ user_id = session['user_id'] if not check_perm(user_id, -1, "useradmin"): flash("You do not have User Administration access.") return redirect(url_for('setup_top')) is_sysadmin = check_perm(user_id, -1, 'sysadmin') user = Users2.get_user(view_id) examids = Exams.get_exams_done(view_id) exams = [] for examid in examids: exam = Exams.get_exam_struct(examid) started = General.human_date(exam['start']) exam['started'] = started exam['viewable'] = satisfy_perms(user_id, exam['cid'], ("viewmarks", )) exams.append(exam) exams.sort(key=lambda x: x['start_epoch'], reverse=True) course_ids = Users2.get_courses(view_id) courses = [] for course_id in course_ids: courses.append(Courses2.get_course(course_id)) user_is_admin = check_perm(view_id, 0, 'sysadmin') return render_template('setup_usersummary.html', user=user, exams=exams, courses=courses, is_sysadmin=is_sysadmin, user_is_admin=user_is_admin)
def cadmin_create_exam(course_id): """ Provide a form to create/edit a new assessment """ course = Courses2.get_course(course_id) if not course: abort(404) topics = CourseAdmin.get_create_exam_q_list(course_id) today = datetime.now() return render_template( "exam_edit.html", course=course, topics=topics, # defaults exam={ 'id': 0, 'start_date': int(date_from_py2js(today)+86400000), # tomorrow 'end_date': int(date_from_py2js(today)+90000000), # tomorrow + hour 'start_hour': int(today.hour), 'end_hour': int(today.hour + 1), 'start_minute': int(today.minute), 'end_minute': int(today.minute), 'duration': 60, 'title': "Assessment", 'archived': 1, } )
def cadmin_create_exam(course_id): """ Provide a form to create/edit a new assessment """ course = Courses2.get_course(course_id) if not course: abort(404) topics = CourseAdmin.get_create_exam_q_list(course_id) today = datetime.now() return render_template( "exam_edit.html", course=course, topics=topics, # defaults exam={ 'id': 0, 'start_date': int(date_from_py2js(today) + 86400000), # tomorrow 'end_date': int(date_from_py2js(today) + 90000000), # tomorrow + hour 'start_hour': int(today.hour), 'end_hour': int(today.hour + 1), 'start_minute': int(today.minute), 'end_minute': int(today.minute), 'duration': 60, 'title': "Assessment", 'archived': 1 })
def cadmin_assign_coord(course_id): """ Set someone as course coordinator """ cur_user = session['user_id'] course = Courses2.get_course(course_id) if not course: abort(404) if "coord" not in request.form: abort(400) new_uname = sanitize_username(request.form['coord']) try: new_uid = Users2.uid_by_uname(new_uname) except KeyError: flash("User '%s' Not Found" % new_uname) else: if not new_uid: flash("User '%s' Not Found" % new_uname) else: L.info( "courseadmin: user %s assigned as coordinator to course %s by %s" % (new_uid, course_id, cur_user)) Permissions.add_perm(new_uid, course_id, 3) # courseadmin Permissions.add_perm(new_uid, course_id, 4) # coursecoord flash("%s can now control the course." % (new_uname, )) return redirect(url_for('cadmin_config', course_id=course_id))
def cadmin_assign_coord(course_id): """ Set someone as course coordinator """ course = Courses2.get_course(course_id) if not course: abort(404) if not "coord" in request.form: abort(400) new_uname = request.form["coord"] # TODO: Sanitize username try: new_uid = Users2.uid_by_uname(new_uname) except KeyError: flash("User '%s' Not Found" % new_uname) else: if not new_uid: flash("User '%s' Not Found" % new_uname) else: Permissions.add_perm(new_uid, course_id, 3) # courseadmin Permissions.add_perm(new_uid, course_id, 4) # coursecoord flash("%s can now control the course." % (new_uname,)) return redirect(url_for("cadmin_config", course_id=course_id))
def cadmin_export_csv(course_id, exam_id, group_id): """ Send the group results as a CSV file """ course = Courses2.get_course(course_id) if not course: abort(404) exam = Exams.get_exam_struct(exam_id, course_id) if not exam: abort(404) if not int(exam["cid"]) == int(course_id): flash("Assessment %s does not belong to this course." % int(exam_id)) return redirect(url_for("cadmin_top", course_id=course_id)) group = Groups.Group(g_id=group_id) output = Spreadsheets.exam_results_as_spreadsheet(course_id, group, exam_id) response = make_response(output) response.headers.add( "Content-Type", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=utf-8" ) response.headers.add( "Content-Disposition", 'attachment; filename="OASIS_%s_%s_Results.xlsx"' % (course["title"], exam["title"]) ) return response
def cadmin_export_csv(course_id, exam_id, group_id): """ Send the group results as a CSV file """ course = Courses2.get_course(course_id) if not course: abort(404) exam = Exams.get_exam_struct(exam_id, course_id) if not exam: abort(404) if not int(exam['cid']) == int(course_id): flash("Assessment %s does not belong to this course." % int(exam_id)) return redirect(url_for('cadmin_top', course_id=course_id)) group = Groups.Group(g_id=group_id) output = Spreadsheets.exam_results_as_spreadsheet(course_id, group, exam_id) response = make_response(output) response.headers.add( 'Content-Type', "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet; charset=utf-8" ) response.headers.add( 'Content-Disposition', 'attachment; filename="OASIS_%s_%s_Results.xlsx"' % (course.title, exam.title)) return response
def cadmin_edit_exam(course_id, exam_id): """ Provide a form to edit an assessment """ course = Courses2.get_course(course_id) if not course: abort(404) exam = Exams.get_exam_struct(exam_id, course_id) if not exam: abort(404) if not int(exam['cid']) == int(course_id): flash("Assessment %s does not belong to this course." % int(exam_id)) return redirect(url_for('cadmin_top', course_id=course_id)) exam['start_date'] = int(date_from_py2js(exam['start'])) exam['end_date'] = int(date_from_py2js(exam['end'])) exam['start_hour'] = int(exam['start'].hour) exam['end_hour'] = int(exam['end'].hour) exam['start_minute'] = int(exam['start'].minute) exam['end_minute'] = int(exam['end'].minute) return render_template( "exam_edit.html", course=course, exam=exam )
def cadmin_assign_coord(course_id): """ Set someone as course coordinator """ cur_user = session['user_id'] course = Courses2.get_course(course_id) if not course: abort(404) if "coord" not in request.form: abort(400) new_uname = sanitize_username(request.form['coord']) try: new_uid = Users2.uid_by_uname(new_uname) except KeyError: flash("User '%s' Not Found" % new_uname) else: if not new_uid: flash("User '%s' Not Found" % new_uname) else: L.info("courseadmin: user %s assigned as coordinator to course %s by %s" % (new_uid, course_id, cur_user)) Permissions.add_perm(new_uid, course_id, 3) # courseadmin Permissions.add_perm(new_uid, course_id, 4) # coursecoord flash("%s can now control the course." % (new_uname,)) return redirect(url_for('cadmin_config', course_id=course_id))
def cadmin_view_topic(course_id, topic_id): """ Present a page to view a topic, including basic stats """ user_id = session['user_id'] if not course_id: abort(404) course = Courses2.get_course(course_id) topic = { 'id': topic_id, 'position': Topics.get_pos(topic_id), 'name': Topics.get_name(topic_id) } questions = [question for question in Topics.get_qts(topic_id).values()] for question in questions: question['embed_id'] = DB.get_qt_embedid(question['id']) if question['embed_id']: question['embed_url'] = "%s/embed/question/%s/question.html" % \ (OaConfig.parentURL, question['embed_id']) else: question['embed_url'] = None question['editor'] = DB.get_qt_editor(question['id']) all_courses = [ crse for crse in Courses2.get_course_list() if satisfy_perms(user_id, int(crse['id']), ("questionedit", "courseadmin", "sysadmin")) ] all_courses.sort(lambda f, s: cmp(f['name'], s['name'])) all_course_topics = [] for crse in all_courses: topics = Courses.get_topics_all(crse['id'], numq=False) if topics: all_course_topics.append({ 'course': crse['name'], 'topics': topics }) questions.sort(key=lambda k: k['position']) return render_template( "courseadmin_viewtopic.html", course=course, topic=topic, questions=questions, all_course_topics=all_course_topics, )
def practice_choose_question(topic_id): """ Present a list of questions for them to choose from the given topic """ user_id = session['user_id'] try: course_id = Topics.get_course_id(topic_id) except KeyError: course_id = None abort(404) topics = [] try: topics = Courses2.get_topics_list(course_id) except KeyError: abort(404) try: course = Courses2.get_course(course_id) except KeyError: course = None abort(404) topictitle = Topics.get_name(topic_id) questions = Practice.get_sorted_questions(course_id, topic_id, user_id) thistopic = Topics.get_topic(topic_id) members = [] if thistopic['visibility'] == 2: # course only if not members: members = Courses.get_users(course_id) if not user_id in members: abort(404) for topic in topics: if topic['visibility'] == 2: # course only if not members: members = Courses.get_users(course_id) if not user_id in members: topics.remove(topic) return render_template( "practicetopic.html", canpreview=check_perm(user_id, course_id, "questionpreview"), topics=topics, topic_id=topic_id, course=course, topictitle=topictitle, questions=questions )
def practice_choose_question(topic_id): """ Present a list of questions for them to choose from the given topic """ user_id = session['user_id'] try: course_id = Topics.get_course_id(topic_id) except KeyError: course_id = None abort(404) topics = [] try: topics = Courses2.get_topics_list(course_id) except KeyError: abort(404) try: course = Courses2.get_course(course_id) except KeyError: course = None abort(404) topictitle = Topics.get_name(topic_id) questions = Practice.get_sorted_questions(course_id, topic_id, user_id) thistopic = Topics.get_topic(topic_id) members = [] if thistopic['visibility'] == 2: # course only if not members: members = Courses.get_users(course_id) if user_id not in members: abort(404) for topic in topics: if topic['visibility'] == 2: # course only if not members: members = Courses.get_users(course_id) if user_id not in members: topics.remove(topic) return render_template( "practicetopic.html", canpreview=check_perm(user_id, course_id, "questionpreview"), topics=topics, topic_id=topic_id, course=course, topictitle=topictitle, questions=questions )
def practice_do_question(topic_id, qt_id): """ Show them a question and allow them to fill in some answers """ user_id = session['user_id'] try: course_id = Topics.get_course_id(topic_id) except KeyError: course_id = None abort(404) try: course = Courses2.get_course(course_id) except KeyError: course = None abort(404) topictitle = "UNKNOWN" try: topictitle = Topics.get_name(topic_id) except KeyError: abort(404) try: qtemplate = DB.get_qtemplate(qt_id) except KeyError: qtemplate = None abort(404) questions = Practice.get_sorted_questions(course_id, topic_id, user_id) q_title = qtemplate['title'] q_pos = DB.get_qtemplate_topic_pos(qt_id, topic_id) blocked = Practice.is_q_blocked(user_id, course_id, topic_id, qt_id) if blocked: return render_template( "practicequestionblocked.html", mesg=blocked, topictitle=topictitle, topic_id=topic_id, qt_id=qt_id, course=course, q_title=q_title, questions=questions, q_pos=q_pos, ) try: q_id = Practice.get_practice_q(qt_id, user_id) except (ValueError, TypeError), err: log(ERROR, "ERROR 1001 (%s,%s) %s" % (qt_id, user_id, err)) return render_template( "practicequestionerror.html", mesg="Error generating question.", topictitle=topictitle, topic_id=topic_id, qt_id=qt_id, course=course, q_title=q_title, questions=questions, q_pos="?", )
def setup_myprofile(): """ Show an account summary for the current user account. """ user_id = session['user_id'] user = Users2.get_user(user_id) course_ids = Users2.get_courses(user_id) courses = [] for course_id in course_ids: courses.append(Courses2.get_course(course_id)) return render_template('setup_myprofile.html', user=user, courses=courses)
def practice_mark_question(topic_id, question_id): """ Mark the submitted question answersjust wa """ user_id = session['user_id'] course_id = Topics.get_course_id(topic_id) if not course_id: abort(404) course = Courses2.get_course(course_id) if not course: abort(404) topictitle = "UNKNOWN" try: topictitle = Topics.get_name(topic_id) except KeyError: abort(404) qt_id = DB.get_q_parent(question_id) q_title = DB.get_qt_name(qt_id) questions = Practice.get_sorted_questions(course_id, topic_id, user_id) q_pos = DB.get_qtemplate_topic_pos(qt_id, topic_id) blocked = Practice.is_q_blocked(user_id, course_id, topic_id, qt_id) if blocked: return render_template( "practicequestionblocked.html", mesg=blocked, topictitle=topictitle, topic_id=topic_id, qt_id=qt_id, course=course, q_title=q_title, questions=questions, q_pos=q_pos, ) marking = Practice.mark_q(user_id, topic_id, question_id, request) prev_id, next_id = Practice.get_next_prev(qt_id, topic_id) # TODO: need next_pos and prev_pos return render_template( "practicemarkquestion.html", topictitle=topictitle, topic_id=topic_id, qt_id=qt_id, course=course, q_title=q_title, questions=questions, q_pos=q_pos, q_id=question_id, marking=marking, next_id=next_id, prev_id=prev_id )
def practice_mark_question(topic_id, question_id): """ Mark the submitted question answersjust wa """ user_id = session['user_id'] course_id = Topics.get_course_id(topic_id) if not course_id: abort(404) course = Courses2.get_course(course_id) if not course: abort(404) topictitle = "UNKNOWN" try: topictitle = Topics.get_name(topic_id) except KeyError: abort(404) qt_id = DB.get_q_parent(question_id) q_title = DB.get_qt_name(qt_id) questions = Practice.get_sorted_questions(course_id, topic_id, user_id) q_pos = DB.get_qtemplate_topic_pos(qt_id, topic_id) blocked = Practice.is_q_blocked(user_id, course_id, topic_id, qt_id) if blocked: return render_template( "practicequestionblocked.html", mesg=blocked, topictitle=topictitle, topic_id=topic_id, qt_id=qt_id, course=course, q_title=q_title, questions=questions, q_pos=q_pos, ) marking = Practice.mark_q(user_id, topic_id, question_id, request) prev_id, next_id = Practice.get_next_prev(qt_id, topic_id) return render_template( "practicemarkquestion.html", topictitle=topictitle, topic_id=topic_id, qt_id=qt_id, course=course, q_title=q_title, questions=questions, q_pos=q_pos, q_id=question_id, marking=marking, next_id=next_id, prev_id=prev_id )
def cadmin_exam_viewmarked(course_id, exam_id, student_uid): """ Show a student's marked assessment results """ course = Courses2.get_course(course_id) try: exam = Exams.get_exam_struct(exam_id, course_id) except KeyError: exam = {} abort(404) results, examtotal = Assess.render_own_marked_exam(student_uid, exam_id) if examtotal is False: status = 0 else: status = 1 marktime = Exams.get_mark_time(exam_id, student_uid) firstview = Exams.get_student_start_time(exam_id, student_uid) submittime = Exams.get_submit_time(exam_id, student_uid) try: datemarked = General.human_date(marktime) except AttributeError: datemarked = None try: datefirstview = General.human_date(firstview) except AttributeError: datefirstview = None try: datesubmit = General.human_date(submittime) except AttributeError: datesubmit = None user = Users2.get_user(student_uid) if submittime and firstview: taken = submittime-firstview takenmins = (taken.seconds/60) else: takenmins = None return render_template( "cadmin_markedresult.html", course=course, exam=exam, results=results, examtotal=examtotal, datesubmit=datesubmit, datemarked=datemarked, datefirstview=datefirstview, taken=takenmins, user=user, status=status )
def cadmin_view_topic(course_id, topic_id): """ Present a page to view a topic, including basic stats """ user_id = session["user_id"] if not course_id: abort(404) course = Courses2.get_course(course_id) topic = {"id": topic_id, "position": Topics.get_pos(topic_id), "name": Topics.get_name(topic_id)} questions = [question for question in Topics.get_qts(topic_id).values()] for question in questions: question["embed_id"] = DB.get_qt_embedid(question["id"]) if question["embed_id"]: question["embed_url"] = "%s/embed/question/%s/question.html" % (OaConfig.parentURL, question["embed_id"]) else: question["embed_url"] = None question["editor"] = DB.get_qt_editor(question["id"]) all_courses = Courses2.get_course_list() all_courses = [ crse for crse in all_courses if satisfy_perms(user_id, int(crse["id"]), ("questionedit", "courseadmin", "sysadmin")) ] all_courses.sort(lambda f, s: cmp(f["name"], s["name"])) all_course_topics = [] for crse in all_courses: topics = Courses.get_topics_all(crse["id"], numq=False) if topics: all_course_topics.append({"course": crse["name"], "topics": topics}) questions.sort(key=lambda k: k["position"]) return render_template( "courseadmin_viewtopic.html", course=course, topic=topic, questions=questions, all_course_topics=all_course_topics, )
def cadmin_exam_results(course_id, exam_id): """ View the results of an assessment """ course = Courses2.get_course(course_id) if not course: abort(404) exam = Exams.get_exam_struct(exam_id, course_id) if not exam: abort(404) if not int(exam['cid']) == int(course_id): flash("Assessment %s does not belong to this course." % int(exam_id)) return redirect(url_for('cadmin_top', course_id=course_id)) exam['start_date'] = int(date_from_py2js(exam['start'])) exam['end_date'] = int(date_from_py2js(exam['end'])) exam['start_hour'] = int(exam['start'].hour) exam['end_hour'] = int(exam['end'].hour) exam['start_minute'] = int(exam['start'].minute) exam['end_minute'] = int(exam['end'].minute) groups = [Groups.Group(g_id=g_id) for g_id in Groups.active_by_course(course_id)] results = {} uids = set([]) totals = {} for group in groups: results[group.id] = Exams.get_marks(group, exam_id) for user_id in results[group.id]: uids.add(user_id) if user_id not in totals: totals[user_id] = 0.0 for qt, val in results[group.id][user_id].iteritems(): totals[user_id] += val['score'] questions = Exams.get_qts_list(exam_id) users = {} for uid in uids: users[uid] = Users2.get_user(uid) return render_template( "cadmin_examresults.html", course=course, exam=exam, results=results, groups=groups, users=users, questions=questions, when=datetime.now().strftime("%H:%m, %a %d %b %Y"), totals=totals )
def cadmin_exam_viewmarked(course_id, exam_id, student_uid): """ Show a student's marked assessment results """ course = Courses2.get_course(course_id) try: exam = Exams.get_exam_struct(exam_id, course_id) except KeyError: exam = {} abort(404) results, examtotal = Assess.render_own_marked_exam(student_uid, exam_id) if examtotal is False: status = 0 else: status = 1 marktime = Exams.get_mark_time(exam_id, student_uid) firstview = Exams.get_student_start_time(exam_id, student_uid) submittime = Exams.get_submit_time(exam_id, student_uid) try: datemarked = General.human_date(marktime) except AttributeError: datemarked = None try: datefirstview = General.human_date(firstview) except AttributeError: datefirstview = None try: datesubmit = General.human_date(submittime) except AttributeError: datesubmit = None user = Users2.get_user(student_uid) if submittime and firstview: taken = submittime - firstview takenmins = (taken.seconds / 60) else: takenmins = None return render_template("cadmin_markedresult.html", course=course, exam=exam, results=results, examtotal=examtotal, datesubmit=datesubmit, datemarked=datemarked, datefirstview=datefirstview, taken=takenmins, user=user, status=status)
def setup_myprofile(): """ Show an account summary for the current user account. """ user_id = session['user_id'] user = Users2.get_user(user_id) course_ids = Users2.get_courses(user_id) courses = [] for course_id in course_ids: courses.append(Courses2.get_course(course_id)) return render_template( 'setup_myprofile.html', user=user, courses=courses )
def cadmin_exam_unsubmit(course_id, exam_id, student_uid): """ "unsubmit" the student's assessment and reset their timer so they can log back on and have another attempt. """ course = Courses2.get_course(course_id) try: exam = Exams.get_exam_struct(exam_id, course.id) except KeyError: exam = {} abort(404) Exams.unsubmit(exam_id, student_uid) user = Users2.get_user(student_uid) flash("""Assessment for %s unsubmitted and timer reset.""" % user["uname"]) return redirect(url_for("cadmin_exam_viewmarked", course_id=course.id, exam_id=exam["id"], student_uid=student_uid))
def cadmin_view_qtemplate_history(course_id, topic_id, qt_id): """ Show the practice history of the question template. """ if not course_id: abort(404) course = Courses2.get_course(course_id) topic = {"id": topic_id, "position": Topics.get_pos(topic_id), "name": Topics.get_name(topic_id)} qtemplate = DB.get_qtemplate(qt_id) year = datetime.now().year years = range(year, year - 6, -1) return render_template( "courseadmin_viewqtemplate.html", course=course, topic=topic, qtemplate=qtemplate, years=years )
def cadmin_exam_results(course_id, exam_id): """ View the results of an assessment """ course = Courses2.get_course(course_id) if not course: abort(404) exam = Exams.get_exam_struct(exam_id, course_id) if not exam: abort(404) if not int(exam['cid']) == int(course_id): flash("Assessment %s does not belong to this course." % int(exam_id)) return redirect(url_for('cadmin_top', course_id=course_id)) exam['start_date'] = int(date_from_py2js(exam['start'])) exam['end_date'] = int(date_from_py2js(exam['end'])) exam['start_hour'] = int(exam['start'].hour) exam['end_hour'] = int(exam['end'].hour) exam['start_minute'] = int(exam['start'].minute) exam['end_minute'] = int(exam['end'].minute) groups = [ Groups.Group(g_id=g_id) for g_id in Groups.active_by_course(course_id) ] results = {} uids = set([]) totals = {} for group in groups: results[group.id] = Exams.get_marks(group, exam_id) for user_id in results[group.id]: uids.add(user_id) if user_id not in totals: totals[user_id] = 0.0 for qt, val in results[group.id][user_id].iteritems(): totals[user_id] += val['score'] questions = Exams.get_qts_list(exam_id) users = {} for uid in uids: users[uid] = Users2.get_user(uid) return render_template("cadmin_examresults.html", course=course, exam=exam, results=results, groups=groups, users=users, questions=questions, when=datetime.now().strftime("%H:%m, %a %d %b %Y"), totals=totals)
def cadmin_prev_assessments(course_id): """ Show a list of older assessments.""" course = Courses2.get_course(course_id) if not course: abort(404) exams = [ Exams.get_exam_struct(exam_id, course_id) for exam_id in DB.get_course_exam_all(course_id, prev_years=True) ] years = [exam["start"].year for exam in exams] years = list(set(years)) years.sort(reverse=True) exams.sort(key=lambda y: y["start_epoch"]) return render_template("courseadmin_previousassessments.html", course=course, exams=exams, years=years)
def cadmin_permissions(course_id): """ Present a page for them to assign permissions to the course""" course = Courses2.get_course(course_id) permlist = Permissions.get_course_perms(course_id) perms = {} for uid, pid in permlist: # (uid, permission) if not uid in perms: user = Users2.get_user(uid) perms[uid] = {"uname": user["uname"], "fullname": user["fullname"], "pids": []} perms[uid]["pids"].append(pid) return render_template( "courseadmin_permissions.html", perms=perms, course=course, pids=[5, 10, 14, 11, 8, 9, 15, 2] )
def get_sorted_courselist(with_stats=False, only_active=True): """Return a list of courses suitable for choosing one to edit [ ('example101', { coursedict }), ('sorted302', { coursedict } ) ] """ courses = Courses2.get_course_dict(only_active=only_active) inorder = [] for cid, course in courses.iteritems(): if with_stats: course['students'] = Courses.get_users(cid) course['size'] = len(course['students']) inorder.append((course['name'], course)) inorder.sort() return inorder
def admin_course(course_id): """ Present page to administer settings for a given course""" course = Courses2.get_course(course_id) course['size'] = len(Courses.get_users(course_id)) groups = Courses.get_groups(course_id) choosegroups = [group for g_id, group in Groups.enrolment_groups().iteritems() if not g_id in groups] return render_template( "cadmin_course.html", course=course, groups=groups, choosegroups=choosegroups )
def admin_course(course_id): """ Present page to administer settings for a given course""" course = Courses2.get_course(course_id) course['size'] = len(Courses.get_users(course_id)) groups = Courses.get_groups(course_id) choosegroups = [group for g_id, group in Groups.enrolment_groups().iteritems() if g_id not in groups] return render_template( "cadmin_course.html", course=course, groups=groups, choosegroups=choosegroups )
def practice_choose_question_stats(topic_id): """ Present a list of questions for them to choose from the given topic, and show some statistics on how they're doing. """ user_id = session['user_id'] course_id = Topics.get_course_id(topic_id) if not course_id: abort(404) topics = Courses2.get_topics_list(course_id) course = Courses2.get_course(course_id) topictitle = Topics.get_name(topic_id) questions = Practice.get_sorted_qlist_wstats(course_id, topic_id, user_id) return render_template( "practicetopicstats.html", canpreview=check_perm(user_id, course_id, "questionpreview"), topics=topics, topic_id=topic_id, course=course, topictitle=topictitle, questions=questions )
def cadmin_activate(course_id): """ Mark the course as active """ course = None try: course = Courses2.get_course(course_id) except KeyError: abort(404) if not course: abort(404) Courses.set_active(course_id, True) flash("Course %s marked as active" % (course['name'])) return redirect(url_for("cadmin_config", course_id=course_id))
def cadmin_group_detach(course_id, group_id): """ Mark the course as inactive """ course = None try: course = Courses2.get_course(course_id) except KeyError: abort(404) if not course: abort(404) group = Groups.Group(g_id=group_id) Courses.del_group(group_id, course_id) flash("Group %s removed from course" % (group.name,)) return redirect(url_for("cadmin_config", course_id=course_id))
def cadmin_edit_exam_submit(course_id, exam_id): """ Provide a form to edit an assessment """ user_id = session["user_id"] course = Courses2.get_course(course_id) if not course: abort(404) if "exam_cancel" in request.form: flash("Assessment editing cancelled.") return redirect(url_for("cadmin_top", course_id=course_id)) exam_id = CourseAdmin.exam_edit_submit(request, user_id, course_id, exam_id) exam = Exams.get_exam_struct(exam_id, course_id) flash("Assessment saved.") return render_template("exam_edit_submit.html", course=course, exam=exam)
def cadmin_group_detach(course_id, group_id): """ Mark the course as inactive """ course = None try: course = Courses2.get_course(course_id) except KeyError: abort(404) if not course: abort(404) group = Groups.Group(g_id=group_id) Courses.del_group(group_id, course_id) flash("Group %s removed from course" % (group.name, )) return redirect(url_for("cadmin_config", course_id=course_id))
def cadmin_edit_exam_submit(course_id, exam_id): """ Provide a form to edit an assessment """ user_id = session['user_id'] course = Courses2.get_course(course_id) if not course: abort(404) if "exam_cancel" in request.form: flash("Assessment editing cancelled.") return redirect(url_for('cadmin_top', course_id=course_id)) exam_id = CourseAdmin.exam_edit_submit(request, user_id, course_id, exam_id) exam = Exams.get_exam_struct(exam_id, course_id) flash("Assessment saved.") return render_template("exam_edit_submit.html", course=course, exam=exam)
def cadmin_config_submit(course_id): """ Allow some course configuration """ course = Courses2.get_course(course_id) if not course: abort(404) form = request.form if "cancel" in form: flash("Cancelled edit") return redirect(url_for("cadmin_top", course_id=course_id)) saved = False new_name = form.get('name', course['name']) existing = Courses.get_course_by_name(new_name) if not new_name == course['name']: if not (3 <= len(new_name) <= 20): flash("Course Name must be between 3 and 20 characters.") elif existing: flash("There is already a course called %(name)s" % existing) else: Courses.set_name(course['id'], new_name) saved = True new_title = form.get('title', course['title']) if not new_title == course['title']: if not (3 <= len(new_title) <= 100): flash("Course Title must be between 3 and 100 characters.") else: Courses.set_title(course['id'], new_title) saved = True practice_visibility = form.get('practice_visibility', course['practice_visibility']) if not (practice_visibility == course['practice_visibility']): saved = True Courses.set_prac_vis(course_id, practice_visibility) if saved: flash("Changes Saved") else: flash("No changes made.") return redirect(url_for("cadmin_config", course_id=course_id))
def cadmin_editgroup(course_id, group_id): """ Present a page for editing a group, membership, etc. """ group = None try: group = Groups.Group(group_id) except KeyError: abort(404) if not group: abort(404) course = Courses2.get_course(course_id) if not course: abort(404) ulist = group.members() members = [Users2.get_user(uid) for uid in ulist] return render_template("courseadmin_editgroup.html", course=course, group=group, members=members)
def cadmin_prev_assessments(course_id): """ Show a list of older assessments.""" course = Courses2.get_course(course_id) if not course: abort(404) exams = [ Exams.get_exam_struct(exam_id, course_id) for exam_id in DB.get_course_exam_all(course_id, prev_years=True) ] years = [exam['start'].year for exam in exams] years = list(set(years)) years.sort(reverse=True) exams.sort(key=lambda y: y['start_epoch']) return render_template("courseadmin_previousassessments.html", course=course, exams=exams, years=years)
def cadmin_edittopics_save(course_id): """ Accept a submitted topics page and save it.""" course = None try: course = Courses2.get_course(course_id) except KeyError: abort(404) if not course: abort(404) if "cancel" in request.form: flash("Changes Cancelled!") return redirect(url_for('cadmin_top', course_id=course_id)) if CourseAdmin.do_topic_update(course, request): flash("Changes Saved!") else: flash("Error Saving!") return redirect(url_for('cadmin_edittopics', course_id=course_id))
def cadmin_permissions(course_id): """ Present a page for them to assign permissions to the course""" course = Courses2.get_course(course_id) permlist = Permissions.get_course_perms(course_id) perms = {} for uid, pid in permlist: # (uid, permission) if uid not in perms: user = Users2.get_user(uid) perms[uid] = { 'uname': user['uname'], 'fullname': user['fullname'], 'pids': [] } perms[uid]['pids'].append(pid) return render_template("courseadmin_permissions.html", perms=perms, course=course, pids=[5, 10, 14, 11, 8, 9, 15, 2])
def cadmin_view_qtemplate_history(course_id, topic_id, qt_id): """ Show the practice history of the question template. """ if not course_id: abort(404) course = Courses2.get_course(course_id) topic = { 'id': topic_id, 'position': Topics.get_pos(topic_id), 'name': Topics.get_name(topic_id) } qtemplate = DB.get_qtemplate(qt_id) year = datetime.now().year years = range(year, year - 6, -1) return render_template("courseadmin_viewqtemplate.html", course=course, topic=topic, qtemplate=qtemplate, years=years)
def cadmin_remove_coord(course_id, coordname): """ Remove someone as course coordinator """ course = Courses2.get_course(course_id) if not course: abort(404) try: new_uid = Users2.uid_by_uname(coordname) except KeyError: flash("User '%s' Not Found" % coordname) else: if not new_uid: flash("User '%s' Not Found" % coordname) else: Permissions.delete_perm(new_uid, course_id, 3) # courseadmin Permissions.delete_perm(new_uid, course_id, 4) # coursecoord flash("%s can no longer control the course." % (coordname, )) return redirect(url_for('cadmin_config', course_id=course_id))
def cadmin_config(course_id): """ Allow some course configuration """ course = Courses2.get_course(course_id) if not course: abort(404) user_id = session['user_id'] is_sysadmin = check_perm(user_id, -1, 'sysadmin') coords = [ Users2.get_user(perm[0]) for perm in Permissions.get_course_perms(course_id) if perm[1] == 3 ] # course_coord groups = Courses.get_groups(course_id) choosegroups = [ group for group in Groups.all_groups() if group.id not in groups ] return render_template("courseadmin_config.html", course=course, coords=coords, choosegroups=choosegroups, groups=groups, is_sysadmin=is_sysadmin)
def cadmin_edit_exam(course_id, exam_id): """ Provide a form to edit an assessment """ course = Courses2.get_course(course_id) if not course: abort(404) exam = Exams.get_exam_struct(exam_id, course_id) if not exam: abort(404) if not int(exam['cid']) == int(course_id): flash("Assessment %s does not belong to this course." % int(exam_id)) return redirect(url_for('cadmin_top', course_id=course_id)) exam['start_date'] = int(date_from_py2js(exam['start'])) exam['end_date'] = int(date_from_py2js(exam['end'])) exam['start_hour'] = int(exam['start'].hour) exam['end_hour'] = int(exam['end'].hour) exam['start_minute'] = int(exam['start'].minute) exam['end_minute'] = int(exam['end'].minute) return render_template("exam_edit.html", course=course, exam=exam)
def practice_do_question_id(topic_id, qt_id): """ Show them a question and allow them to fill in some answers """ user_id = session['user_id'] try: course_id = Topics.get_course_id(topic_id) except KeyError: course_id = None abort(404) try: course = Courses2.get_course(course_id) except KeyError: course = None abort(404) topictitle = "UNKNOWN" try: topictitle = Topics.get_name(topic_id) except KeyError: abort(404) qtemplate = DB.get_qtemplate(qt_id) questions = Practice.get_sorted_questions(course_id, topic_id, user_id) q_title = qtemplate['title'] q_pos = DB.get_qtemplate_topic_pos(qt_id, topic_id) blocked = Practice.is_q_blocked(user_id, course_id, topic_id, qt_id) if blocked: return render_template( "practicequestionblocked.html", mesg=blocked, topictitle=topictitle, topic_id=topic_id, qt_id=qt_id, course=course, q_title=q_title, questions=questions, q_pos=q_pos, ) try: q_id = Practice.get_practice_q(qt_id, user_id) except (ValueError, TypeError) as err: L.error("ERROR 1001 (%s,%s) %s" % (qt_id, user_id, err)) return render_template( "practicequestionerror.html", mesg="Error generating question.", topictitle=topictitle, topic_id=topic_id, qt_id=qt_id, course=course, q_title=q_title, questions=questions, q_pos=q_pos, ) if not q_id > 0: L.error("ERROR 1002 (%s,%s) Question not generated" % (qt_id, user_id)) return render_template( "practicequestionerror.html", mesg="Error generating question.", topictitle=topictitle, topic_id=topic_id, qt_id=qt_id, course=course, q_title=q_title, questions=questions, q_pos=q_pos, ) q_body = General.render_q_html(q_id) q_body = q_body.replace(r"\240", u" ") # TODO: why is this here? return render_template( "practicedoquestion.html", q_body=q_body, topictitle=topictitle, topic_id=topic_id, qt_id=qt_id, course=course, q_title=q_title, questions=questions, q_pos=q_pos, q_id=q_id, )