def test_course_creation(self):
     c = self.make_standard_course()
     self.session.add(c)
     c = datamodels.get_course_by_code("ABC123")
     c2 = datamodels.get_course_by_slug("abc-123")
     self.assertEqual(c.title, "Foo Course")
     self.assertEqual(c, c2)
Exemple #2
0
def view(course_slug, lesson_slug, segment_slug, institute=""):
    """
    Retrieves and displays a particular course, with the specified lesson
    and segment set to be active.
    """

    segment = datamodels.find_segment_by_slugs(course_slug, lesson_slug,
                                               segment_slug)
    if not segment:
        return abort(404)

    course = datamodels.get_course_by_slug(course_slug)
    lesson = datamodels.get_lesson_by_slugs(course_slug, lesson_slug)
    data = {
        "students":
        get_students_progress(lesson.course),
        "active_lesson":
        lesson,
        "active_segment":
        segment,
        "survey_individual_responses":
        get_survey_individual_responses(segment),
        "survey_response":
        get_survey_response_for_student(get_current_user(), segment, session),
        "course_progress":
        get_course_progress(lesson.course),
        "course":
        course,
        "form":
        AjaxCSRFTokenForm(),
    }
    return render_template("course.html", **data)
Exemple #3
0
def retrieve(user, course_slug=None, institute=""):
    """
    Retrieve a course edit view for a course given by course_slug parameter.

    :param user: a User instance passed by decorator
    :param course_slug: a unique course
    :param institute: an institute subdomain
    :return: html response
    """
    course = datamodels.get_course_by_slug(course_slug)
    if not course or not user.teaches(course):
        raise abort(404,
                    "No such course or you don't have permissions to edit it")

    data = {
        "course": course,
        "teachers":
        [render_teacher(obj, course) for obj in course.instructors],
        "introduction": course.intro_lesson,
        "lessons": course.normal_lessons,
        "form": AjaxCSRFTokenForm(),
        "cover_image": course.cover_image_url,
        "add_lesson_form": AddLessonForm(),
    }

    return render_template("course_edit.html", **data)
Exemple #4
0
def enroll(course_slug, institute=""):
    """
    Enroll a user into a course.
    """
    course = datamodels.get_course_by_slug(course_slug)
    if course is None:
        return abort(404)

    course_code = request.form.get("course_code", "")

    if (course.visibility == "code"
            and course_code.lower() != course.course_code.lower()):
        flash("Wrong course code")
        return redirect("/course/{}".format(course.slug))

    user = get_current_user()
    if course.guest_access and not user:  # Guest access for not log in user
        sess = session.get("enrollments", "[]")
        data = json.loads(sess)
        if course.id in data:
            return redirect(course.lessons[0].permalink)
        else:
            data.append(course.id)
            session["enrollments"] = json.dumps(data)
    elif not course.guest_access and not user:
        return redirect("/login")
    else:
        course.enroll(user)

    flash("You are now enrolled in {}".format(course.title))
    return redirect(course.lessons[0].permalink)
 def test_student_enrollment(self):
     u = self.makeUser(id=1)
     self.session.add(u)
     c = self.make_standard_course(slug="abc")
     self.session.add(c)
     self.session.commit()
     c.enroll(u)
     u2 = datamodels.get_user(1)
     u3 = self.makeUser(id=2, email="*****@*****.**", username="******")
     self.session.add(u3)
     c.enroll(u3)
     self.assertEqual(len(u2.courses), 1)
     self.assertEqual(u2.courses[0].id, 1)
     self.assertEqual(u2.course_enrollments[0].access_level, CourseAccess.student)
     c2 = datamodels.get_course_by_slug("abc")
     self.assertEqual(len(c2.students), 2)
Exemple #6
0
def view(slug, institute=""):
    """
    Retrieves and displays a course based on course slug.
    """

    course = datamodels.get_course_by_slug(slug)
    user = get_current_user()
    if course is None or course.draft and not (user and user.teaches(course)):
        return redirect("/404")
    elif course.draft and len(course.lessons) == 0:
        return redirect("/course/{}/edit".format(course.slug))
    return render_template(
        "course_intro.html",
        course=course,
        form=LoginForm(),
        number_of_resources=course.number_of_resources,
    )
Exemple #7
0
def change_course_slug(user, course_slug=None, institute=""):
    course = datamodels.get_course_by_slug(course_slug)

    if not course or not user.teaches(course):
        raise abort(404,
                    "No such course or you don't have permissions to edit it")

    if not AjaxCSRFTokenForm(request.form).validate():
        return jsonify({
            "success": False,
            "message": "CSRF token required"
        }), 400

    db = datamodels.get_session()
    if request.method == "POST":
        if "slug" in request.form:
            slug = request.form["slug"]
            c = datamodels.Course.find_by_slug(slug)
            if c and course.id != c.id:
                return make_response(
                    jsonify({
                        "success": False,
                        "message": "Use different slug for this course.",
                    }),
                    400,
                )
            if not slug:
                return (
                    jsonify({
                        "success": False,
                        "message": "Slug can't be empty"
                    }),
                    400,
                )
            course.slug = slug
            db.add(course)
            db.commit()

    return jsonify({"redirect_url": "/course/{}/edit".format(course.slug)})
Exemple #8
0
def add_teacher(user, course_slug=None, institute=""):
    course = datamodels.get_course_by_slug(course_slug)

    if not course or not user.teaches(course):
        raise abort(404,
                    "No such course or you don't have permissions to edit it")

    if not course or not user.teaches(course):
        raise abort(404,
                    "No such course or you don't have permissions to edit it")

    new_teacher = (datamodels.User.find_by_email(request.form["teacher_email"])
                   if "teacher_email" in request.form else None)
    if not new_teacher:
        return (
            jsonify({
                "success": False,
                "message": "Can't find that email sorry!"
            }),
            400,
        )

    if new_teacher.id in [teacher.id for teacher in course.instructors]:
        return (
            jsonify({
                "success": False,
                "message": "That user is already a teacher"
            }),
            400,
        )

    course.add_instructor(new_teacher)

    return jsonify({
        "success": True,
        "message": "Successfully added!",
        "teacher": render_teacher(new_teacher, course),
    })
Exemple #9
0
def remove_teacher(user, course_slug=None, teacher_id=None, institute=""):
    course = datamodels.get_course_by_slug(course_slug)

    if not course or not user.teaches(course):
        raise abort(404,
                    "No such course or you don't have permissions to edit it")

    if user.id == teacher_id:
        return jsonify({
            "success": False,
            "message": "You can't remove yourself"
        }), 400

    if not datamodels.get_user(teacher_id):
        return jsonify({"success": False, "message": "No such teacher"}), 400

    removed = course.remove_teacher(teacher_id)

    return jsonify({
        "success": removed,
        "teacher_id": teacher_id,
        "message": "Teacher removed"
    })
Exemple #10
0
def edit(user, course_slug=None, institute=""):
    """
    Edit a course via Ajax requests.

    :param user: a User instance passed by decorator
    :param course_slug: a unique course
    :param institute: an institute subdomain
    :return: json response
    """
    course = datamodels.get_course_by_slug(course_slug)

    if not course or not user.teaches(course):
        raise abort(404,
                    "No such course or you don't have permissions to edit it")

    if institute:
        institute = datamodels.Institute.find_by_slug(institute)

    db = datamodels.get_session()

    if not AjaxCSRFTokenForm(request.form).validate():
        return jsonify({
            "success": False,
            "message": "CSRF token required"
        }), 400

    if "year" in request.form:
        try:
            year = int(request.form["year"])
        except ValueError:
            return make_response(
                jsonify({
                    "success": False,
                    "message": "Year must be a number"
                }), 400)
        course_year = datetime(year=year, month=12, day=31).date()
        course.year = course_year
    if "amount" in request.form:
        try:
            amount = int(float(request.form["amount"]) * 100)
        except ValueError:
            return (
                jsonify({
                    "success": False,
                    "message": "Amount is not a valid number"
                }),
                400,
            )

        course.amount = amount
    if "skill_level" in request.form:
        course.skill_level = request.form["skill_level"]
    if "workload_summary" in request.form:
        course.workload_summary = request.form["workload_summary"]
    if "workload_title" in request.form:
        course.workload_title = request.form["workload_title"]
    if "workload_subtitle" in request.form:
        course.workload_subtitle = request.form["workload_subtitle"]
    if "who_its_for" in request.form:
        course.target_audience = request.form["who_its_for"]
    if "course_summary" in request.form:
        course.summary_html = request.form["course_summary"]
    if "course_name" in request.form:
        course.title = request.form["course_name"]
    if "course_description" in request.form:
        course.info = request.form["course_description"]
    if "course_code" in request.form:
        c = datamodels.Course.find_by_code(request.form["course_code"])
        if c and course.id != c.id:
            return make_response(
                jsonify({
                    "success": False,
                    "message": "Use different course code."
                }),
                400,
            )
        course.course_code = request.form["course_code"]
    if "cover_image" in request.form:
        file = request.files["file"]

        try:
            filename = generate_thumbnail(file, "cover")
        except ValueError as e:
            return jsonify({"success": False, "message": str(e)}), 400

        course.cover_image = filename

    db.add(course)
    db.commit()

    return jsonify({"success": True})