Example #1
0
    def setUp(self):
        with app.app_context():
            self.session = datamodels.get_session()
            self.set_basic_course()

            self.l1 = self.make_standard_course_lesson(title="lesson 1",
                                                       course=self.course,
                                                       order=1)
            self.session.add(self.l1)
            self.session.commit()
            self.l1s0 = self.make_segment(self.l1,
                                          title="Segment Intro",
                                          order=0,
                                          slug="segment-intro")
            self.session.add(self.l1s0)
            self.session.commit()

            self.students = []
            for i in range(1, self.number_of_students + 1):
                student = self.makeUser(
                    id=i + 1,
                    email="student_{}@fitzroyacademy.com".format(i),
                    username="******".format(i))
                self.session.add(student)
                self.session.commit()
                self.students.append(student)
                self.course.enroll(student)
Example #2
0
def course_delete_segment(user,
                          course,
                          course_slug,
                          lesson_id,
                          segment_id,
                          institute=""):
    lesson = datamodels.Course.find_lesson_by_course_slug_and_id(
        course.slug, lesson_id)
    segment = datamodels.Segment.find_by_id(segment_id)
    if segment and lesson and segment.lesson_id == lesson_id:
        db = datamodels.get_session()
        db.delete(segment)
        db.commit()

        list_of_items = [
            l.id for l in lesson.get_ordered_segments() if l.order != 0
        ]  # do not reorder intro segment

        if list_of_items:
            datamodels.Segment.reorder_items(list_of_items)

        return jsonify({
            "success_url":
            "/course/{}/lessons/{}/edit".format(course_slug, lesson_id)
        })

    return jsonify({
        "success": False,
        "message": "Couldn't delete segment"
    }), 400
Example #3
0
    def setUp(self):
        with app.app_context():
            self.session = datamodels.get_session()

        self.user = self.makeUser()
        self.session.add(self.user)
        self.session.commit()
Example #4
0
def copy_resource(user,
                  course,
                  course_slug,
                  lesson_id,
                  resource_id,
                  institute=""):
    lesson = datamodels.Course.find_lesson_by_course_slug_and_id(
        course.slug, lesson_id)
    resource = datamodels.Resource.find_by_id(resource_id)

    if not lesson or resource and resource.lesson_id != lesson.id:
        flash("Lesson or resource do not match course or lesson")
        return redirect("/course/{}/edit".format(course.slug))

    resource_copy = clone_model(resource)
    resource_copy.title = resource.title + "_copy"
    resource_copy.slug = slugify(resource_copy.title)
    resource_copy.order = len(lesson.resources) + 1

    if resource_copy.slug:
        db = datamodels.get_session()
        db.add(resource_copy)
        db.commit()

        flash("Resource duplicated")

    return redirect("/course/{}/lessons/{}/edit".format(
        course.slug, lesson_id))
Example #5
0
def edit(user, institute=""):
    """
    Edit the current user.
    """

    data = {"errors": [], "message": "Error while saving data"}
    db = datamodels.get_session()

    if "profile_picture" in request.form:
        form = AjaxCSRFTokenForm(request.form)
        if form.validate():
            file = request.files["file"]

            try:
                filename = generate_thumbnail(file, "square_l")
            except ValueError as e:
                data["errors"].append(str(e))
                return jsonify(data), 400
            if not filename:
                data["errors"].append("Couldn't upload picture.")
            else:
                user.profile_picture = filename
                db.add(user)
                db.commit()
        else:
            data["errors"].append("Missing CSRF token")

        if data["errors"]:
            return jsonify(data), 400
        else:
            return jsonify({"message": "Changes saved", "errors": []})

    form = EditUserForm(request.form)
    if form.validate():
        try:
            user.email = form.email.data.lower()
            user.first_name = form.first_name.data
            user.last_name = form.last_name.data
            user.username = form.username.data
            if form.password.data:
                setattr(user, "password", form.password.data)

            db.add(user)
            db.commit()
        except IntegrityError:
            db.rollback()
            data["errors"].append("Wrong email address or username")
        except ValueError as e:
            data["errors"].append(str(e))
    else:
        data["errors"] = form.errors

    if data["errors"]:
        data["message"] = "Error while saving data"
        return jsonify(data), 400
    else:
        data["message"] = "Changes saved"
        return jsonify(data)
Example #6
0
def callback(institute=""):
    """
    Handle the Auth0 callback after login.
    """
    # Handles response from token endpoint
    last_page = request.args.get("last_page", "")
    data = {"errors": [], "last_page": last_page, "form": []}
    try:
        # Look for the current user
        current_app.auth0.authorize_access_token()
        resp = current_app.auth0.get('userinfo')
        userinfo = resp.json()
        db = datamodels.get_session()
        user = datamodels.get_user_by_auth0_id(userinfo['sub'])
        if user is None:
            user = datamodels.get_user_by_email(userinfo['email'])
            if user is not None:
                # User is registered with email, but hasn't signed in w/ Auth0 yet
                user.auth0_id = userinfo['sub']
                db.commit()
            elif user is None:
                # Register a new user.
                try:
                    user = datamodels.User()
                    user.email = user.username = userinfo['email']
                    user.first_name = userinfo['given_name']
                    user.last_name = userinfo['family_name']
                    user.auth0_id = userinfo['sub']
                    db.add(user)
                    db.commit()
                except Exception as e:
                    data["errors"].append("{}".format(e))
                    return render_template("welcome.html", **data)
                if "enrollments" in session:
                    d = get_session_data(session, "enrollments")
                    for course_id in d:
                        course = datamodels.Course.find_by_id(int(course_id))
                        if course:
                            course.enroll(user)
                if "anon_progress" in session:
                    d = get_session_data(session, "anon_progress")
                    merge_anonymous_data(user.id, d)
                    session.pop("anon_progress")
                if "anon_surveys" in session:
                    d = get_session_data(session, "anon_surveys")
                    merge_anonymous_surveys_data(user.id, d)
                    session.pop("anon_surveys")
        session["user_id"] = user.id
        session['jwt_payload'] = userinfo
        session['profile'] = {
            'user_id': userinfo['sub'],
            'name': userinfo['name'],
            'picture': userinfo['picture']
        }
    except Exception as e:
        data["errors"].append("{}".format(e))
        return render_template("welcome.html", **data)
    return redirect(last_page or "/")
Example #7
0
def _base_total_query(course, group_by):
    session = get_session()
    queryset = session.query(func.sum(SegmentUserProgress.progress), *group_by). \
        join(Segment, SegmentUserProgress.segment_id == Segment.id).join(Lesson, Lesson.id == Segment.lesson_id). \
        join(CourseEnrollment,
             (SegmentUserProgress.user_id == CourseEnrollment.user_id) & (Lesson.course_id == CourseEnrollment.course_id)). \
        filter(Lesson.course_id == course.id). \
        filter(CourseEnrollment.access_level == CourseAccess.student)

    return queryset
    def setUp(self):
        with app.app_context():
            self.session = datamodels.get_session()

            self.survey_1 = {
                "survey_id":
                "some_long_id",
                "survey_template_version":
                "1.0",
                "question":
                "How do you feel about the course?",
                "free_text_minlength":
                30,
                "free_text_entry":
                "Why do you feel that way?",
                "free_text_require":
                False,
                "survey_type":
                "emoji",
                "survey_type_name":
                "Happiness",
                "survey_type_description":
                "3 faces, from angry to happy, with labels.",
                "survey_type_icon":
                "https://some-fancy-url-with-very-fancy-icon",
                "survey_type_icon_type":
                "url",
                "answer_template": {
                    "survey_id": "",
                    "free_text_response": "",
                    "chosen_answer": ""
                },
                "choice_questions": [{
                    "icon": "https://again-again-and-so-on.png",
                    "icon_type": "url",
                    "single_word": "Terrible",
                    "short_sentence": "I feel terrible",
                    "id": ""
                }, {
                    "icon": "https://again-again-and-so-on-2.png",
                    "icon_type": "url",
                    "single_word": "Bad",
                    "short_sentence": "I feel pretty bad",
                    "id": ""
                }, {
                    "icon": "https://again-again-and-so-on-3.png",
                    "icon_type": "url",
                    "single_word": "Amazing",
                    "short_sentence": "OMG I feel amazing!",
                    "id": ""
                }]
            }

            self.survey_types = ["plain_text", "points_scale", "emoji"]
Example #9
0
def add_resource(user,
                 course,
                 course_slug,
                 lesson_id,
                 resource_id=None,
                 institute=""):
    lesson = datamodels.Course.find_lesson_by_course_slug_and_id(
        course.slug, lesson_id)
    if not lesson:
        return abort(404)

    if resource_id:
        instance = datamodels.Resource.find_by_id(resource_id)
        if not lesson or instance and instance.lesson_id != lesson.id:
            return abort(404)
    else:
        instance = datamodels.Resource(lesson=lesson,
                                       order=len(lesson.resources) + 1)

    errors = []
    form = AddResourceForm(request.form)
    if form.validate():
        instance.url = form.resource_url.data
        instance.title = form.resource_title.data
        instance.type = getattr(ResourceTypeEnum, form.resource_type.data)
        instance.slug = slugify(form.resource_title.data)
        instance.description = form.resource_description.data
        instance.featured = form.resource_featured.data

        db = datamodels.get_session()
        db.add(instance)
        db.commit()

        return jsonify({
            "html":
            render_resource_list_element(course=course,
                                         lesson=lesson,
                                         resource=instance),
            "message":
            "Resource updated" if resource_id else "Resource created",
            "id":
            instance.id,
        })
    else:
        errors = [error for error in form.errors.values()]

    return (
        jsonify({
            "message": "There were errors when saving resource data",
            "errors": errors
        }),
        400,
    )
Example #10
0
def course_add_edit_intro_lesson(user, course, course_slug, institute=""):
    form = AjaxCSRFTokenForm(request.form)
    intro_lesson = course.intro_lesson

    if form.validate() and "intro_lesson" in request.form:
        db = datamodels.get_session()

        slug = "intro-lesson"
        if (datamodels.get_lesson_by_slugs(course.slug, "intro-lesson")
                is not None and not intro_lesson):
            slug = slug + "-" + str(uuid4())[:3]
        if intro_lesson:
            segment = intro_lesson.intro_segment
            set_segment_video_url(segment, request.form["segment_url"])
            html = ""
        else:
            intro_lesson = datamodels.Lesson(
                title="Intro lesson",
                slug=slug,
                description="Intro lesson video",
                order=0,
                course=course,
            )

            db.add(intro_lesson)

            segment = datamodels.Segment(
                lesson=intro_lesson,
                order=0,
                type="video",
                title="Introduction",
                barrier=SegmentBarrierEnum.normal,
                video_type=VideoTypeEnum.standard,
                url=request.form["segment_url"],
                duration_seconds=0,
                slug="intro-segment",
            )
            set_segment_video_url(segment, request.form["segment_url"])
            html = render_intro(segment)

        db.add(segment)
        db.commit()
        return jsonify({
            "message":
            "Intro lesson {}".format("updated" if not html else "added"),
            "html":
            html,
        })
    else:
        return jsonify({"message": "Couldn't create intro lesson"}), 400
Example #11
0
def change_slug(user, institute=""):
    institute = datamodels.Institute.find_by_slug(institute)

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

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

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

    protocol = "https" if request.url.startswith("https") else "http"

    return jsonify({
        "redirect_url":
        "{}://{}.{}/institute/edit".format(protocol, slug,
                                           current_app.config["SERVER_NAME"])
    })
Example #12
0
def edit(user, course, course_slug, lesson_id, institute=""):
    lesson = datamodels.Course.find_lesson_by_course_slug_and_id(
        course.slug, lesson_id)
    if not lesson:
        raise abort(404, "No such lesson")

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

    if "title" in request.form:
        slug = slugify(request.form["title"])
        if datamodels.get_lesson_by_slugs(course_slug, slug) is not None:
            return (
                jsonify({
                    "success": False,
                    "message": "Use different lesson name"
                }),
                400,
            )
        lesson.title = request.form["title"]
        lesson.slug = slug
    if "description" in request.form:
        lesson.description = request.form["description"]
        if 3 > len(lesson.description) > 140:
            return (
                jsonify({
                    "success":
                    False,
                    "message":
                    "Description should be no more than 140 characters.",
                }),
                400,
            )
    if "further_reading" in request.form:
        lesson.further_reading = request.form["further_reading"]
    if "cover_image" in request.form:
        cover_image = request.files["file"]
        filename = generate_thumbnail(cover_image, "cover")
        lesson.cover_image = filename

    db = datamodels.get_session()
    db.add(lesson)
    db.commit()
    return jsonify({"success": True})
Example #13
0
def add(user):

    form = AddInstituteForm(request.form)
    data = {"form": form}

    if not user.super_admin:
        flash("You are not authorized to access this page.")
        return redirect("/")

    if request.method == "POST":
        if form.validate():
            slug = slugify(form.name.data)

            if datamodels.Institute.find_by_slug(slug):
                slug = slug[:46] + "-" + str(uuid4())[:3]

            institute = datamodels.Institute(name=form.name.data,
                                             description=form.description.data,
                                             slug=slug)

            if "cover_image" in request.files:
                file = request.files["cover_image"]

                filename = generate_thumbnail(file, "cover")
                if not filename:
                    flash("Couldn't save cover image")
                else:
                    institute.cover_image = filename

            db = datamodels.get_session()
            db.add(institute)
            institute.add_admin(user)
            db.commit()

            protocol = "https" if request.url.startswith("https") else "http"

            return redirect("{}://{}.{}/institute/edit".format(
                protocol, slug, current_app.config["SERVER_NAME"]))
        else:
            for key, value in form.errors.items():
                flash("Field {}: {}".format(key, ",".join(value)))
            data["errors"] = form.errors
    return render_template("partials/institute/_add.html", **data)
Example #14
0
def submit_segment_survey(institute=""):
    """
    Handle submitting survey by a student.
    """
    segment_id = request.form.get("segment_id", 0)
    segment = datamodels.Segment.find_by_id(segment_id)

    if not segment or segment.type != datamodels.SegmentType.survey:
        return jsonify({"message": "No such survey."}), 400

    free_text = request.form.get("free_text", "")
    chosen_answer = request.form.get("question_id", "")

    survey_response = datamodels.SegmentSurveyResponse(survey=segment)
    user = get_current_user()

    try:
        survey_response_data = survey_response.validate_data(
            free_text=free_text, chosen_answer=chosen_answer)
    except ValueError as e:
        return jsonify({"message": str(e)}), 400

    if user:
        try:
            survey_response.save_response_for_user(user)
            segment.save_user_progress(user, 100)
        except ValueError:
            return jsonify(
                {"message": "You have already answered this question"}), 400
    else:
        data = get_session_data(session, "anon_surveys")
        data[segment_id] = survey_response_data
        set_session_data(session, "anon_surveys", data)

        data = get_session_data(session, "anon_progress")
        data[segment_id] = 100
        set_session_data(session, "anon_progress", data)
        db = datamodels.get_session()
        db.rollback()

    return jsonify({"message": "Survey response saved"})
Example #15
0
    def setUp(self):
        with app.app_context():
            self.session = datamodels.get_session()

            self.course = self.make_standard_course(guest_access=True)
            self.session.add(self.course)

            self.l0 = self.make_standard_course_lesson(title="Intro lesson",
                                                       course=self.course,
                                                       order=0)
            self.l1 = self.make_standard_course_lesson(title="lesson 1",
                                                       course=self.course,
                                                       order=1)
            self.l2 = self.make_standard_course_lesson(title="lesson 2",
                                                       course=self.course,
                                                       order=1)
            self.session.add(self.l0)
            self.session.add(self.l1)
            self.session.add(self.l2)

            self.l0s0 = self.make_segment(self.l0,
                                          title="Intro segment",
                                          order=0,
                                          slug="intro-segment")
            self.l0s1 = self.make_segment(self.l0,
                                          title="Segment l0l1",
                                          order=1,
                                          slug="segment-1")
            self.l1s1 = self.make_segment(self.l1,
                                          title="Intro segment l1",
                                          order=0,
                                          slug="intro-segment-l1")
            self.l1s2 = self.make_segment(self.l1,
                                          title="Segment l1s1",
                                          order=1,
                                          slug="segment-1")
            self.session.add(self.l0s0)
            self.session.add(self.l0s1)
            self.session.add(self.l1s1)
            self.session.add(self.l1s2)
            self.session.commit()
Example #16
0
def course_delete_lesson(user, course, course_slug, lesson_id, institute=""):

    lesson = datamodels.Course.find_lesson_by_course_slug_and_id(
        course.slug, lesson_id)
    if lesson:
        db = datamodels.get_session()
        db.delete(lesson)
        db.commit()

        list_of_lessons = [
            l.id for l in datamodels.Lesson.get_ordered_items() if l.order != 0
        ]
        if list_of_lessons:
            datamodels.Lesson.reorder_items(list_of_lessons)

        return jsonify({"success_url": "/course/{}/edit".format(course_slug)})

    return jsonify({
        "success": False,
        "message": "Couldn't delete lesson"
    }), 400
    def setUp(self):
        with app.app_context():
            self.session = datamodels.get_session()
            self.set_basic_course()

            self.lesson1 = self.make_standard_course_lesson(
                course=self.course, title="First lesson", order=1)
            self.lesson2 = self.make_standard_course_lesson(
                course=self.course, title="Second lesson", order=2)
            self.session.add(self.lesson1)
            self.session.add(self.lesson2)
            self.l1s1 = self.make_segment(self.lesson1,
                                          title="Segment Intro",
                                          order=0)
            self.l1s2 = self.make_segment(self.lesson1,
                                          title="Segment 1",
                                          order=1)
            self.l2s1 = self.make_segment(self.lesson2,
                                          title="Segment Intro",
                                          order=0)
            self.session.commit()
Example #18
0
def add(user, course, course_slug, lesson_id=None, institute=""):
    form = AddLessonForm(request.form)

    if form.validate():
        lesson = datamodels.Lesson(course=course,
                                   order=len(course.lessons) + 1)
        lesson.title = form.title.data
        lesson.description = form.description.data
        lesson.slug = slugify(form.title.data)

        db = datamodels.get_session()
        db.add(lesson)
        db.commit()

        return redirect("/course/{}/lessons/{}/edit".format(
            course.slug, lesson.id))
    else:
        for error in form.errors:
            flash(error)

    return redirect("/course/{}/edit".format(course.slug))
Example #19
0
def set_options(user,
                course,
                course_slug=None,
                option=None,
                on_or_off=False,
                institute=""):
    """ Set course options. """
    if not course or not user.teaches(course):
        raise abort(404,
                    "No such course or you don't have permissions to edit it")

    value = None

    if option == "draft":
        if on_or_off == "live" and len(course.lessons) == 0:
            return jsonify({
                "success": False,
                "message": "Add lessons first."
            }), 400
        value = on_or_off == "draft"
    elif option in ["guest_access", "paid"]:
        value = on_or_off in ["ON", "on", "paid"]
    elif option == "visibility" and on_or_off in [
            "public", "code", "institute"
    ]:
        value = on_or_off

    if value is None:
        return jsonify({
            "success": False,
            "message": "Unknown option setting."
        }), 400

    setattr(course, option, value)

    db = datamodels.get_session()
    db.add(course)
    db.commit()

    return jsonify({"success": True})
Example #20
0
def add_lesson_qa(user,
                  course,
                  course_slug,
                  lesson_id,
                  qa_id=None,
                  institute=""):
    lesson = datamodels.Course.find_lesson_by_course_slug_and_id(
        course.slug, lesson_id)

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

    if not lesson:
        return jsonify({"message": "Wrong lesson or course"}), 400

    form = LessonQAForm(data=request.form)

    if form.validate():
        # get instance of LessonQA
        qa = datamodels.LessonQA.find_by_lesson_and_id(lesson_id, qa_id)
        if qa is None and qa_id:
            return jsonify({"message": "Wrong question or lesson"}), 400

        if not qa:
            qa = datamodels.LessonQA(lesson=lesson,
                                     order=len(lesson.questions) + 1)

        qa.answer = form.answer.data
        qa.question = form.question.data

        db = datamodels.get_session()
        db.add(qa)
        db.commit()

        return jsonify({
            "message": "Question saved",
            "html": render_question_answer(course, lesson, qa),
        })

    return jsonify({"message": "Error saving questions"}), 400
Example #21
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)})
Example #22
0
def reseed():
    session = datamodels.get_session()

    for student in stubs.students:
        user = copy.deepcopy(student)
        password = user.pop("password")
        u = datamodels.User(**user)
        u.password = password
        session.add(u)
    session.commit()

    c = datamodels.Course(
        title="Into to Social Enterprise",
        slug="fitzroy-academy",
        course_code="abc123",
        target_audience="Super early stage social enterprise founders, starting your first business or a new project from scratch.",
        skill_level="Introduction.",
        visibility="public",
        info="Start here! Basic business models and customer discovery, to pitching for investment. тЭдя╕П ЁЯЪА",
        workload_summary="This course will take 20-30 hours on average, and is best done in teams.",
        summary_html="""
        <p><strong>Go from zero to one:</strong> From a basic idea to early customers, business models and getting the numbers right.</p>
        <p>We don't need any previous business experience, but by the end you'll cover quite complex topics like financial modelling, </p>
        <p><strong>On the social impact</strong> side of things, you'll define your impact model, look into creating behaviour
        change that lasts, and maybe even think about partnering with another organisation to create impact.</p>
        """,
        cover_image="/static/assets/images/lessons/customer-interviews.jpg",
        guest_access=True,
        draft=False,
        workload_title="",
        workload_subtitle="",
    )
    session.add(c)
    session.commit()

    c.add_instructor(datamodels.get_user(1))  # Homer
    c.add_instructor(datamodels.get_user(2))  # Marge

    c.enroll(datamodels.get_user(3))  # Bart
    c.enroll(datamodels.get_user(4))  # Lisa
    c.enroll(datamodels.get_user(5))  # Maggie
    session.add(c)
    session.commit()

    for i, lesson in enumerate(stubs.lessons):
        lesson = copy.deepcopy(lesson)
        resources = lesson.pop("resources")
        segments = lesson.pop("segments")
        lesson.pop("id")
        lesson.pop("course_id")
        lesson["language"] = "en"
        new_lesson = datamodels.Lesson(**lesson)
        new_lesson.course = c
        c.lessons.append(new_lesson)
        session.add(new_lesson)
        session.commit()
        for j, segment in enumerate(segments):
            segment = copy.deepcopy(segment)
            segment["duration_seconds"] = get_seconds(segment.pop("duration"))
            segment.pop("lesson_id")
            segment.pop("course_id")
            segment.pop("template")  # ultimately derived from external URL
            segment["slug"] = segment.pop("id")
            segment["language"] = "en"
            segment["type"] = SegmentType.video
            s = datamodels.Segment(**segment)
            new_lesson.segments.append(s)
            s.lesson = new_lesson
            session.add(s)
        for j, resource in enumerate(resources):
            resource = copy.deepcopy(resource)
            resource["language"] = resource.pop("lang")
            resource["slug"] = resource.pop("id")
            resource["order"] = j
            r = datamodels.Resource(**resource)
            r.lesson = new_lesson
            new_lesson.resources.append(r)
            session.add(r)
        session.commit()

    for user_progress in stubs.user_segment_progress:
        user = datamodels.User.find_by_email(user_progress["email"])
        for lesson in user_progress["lessons"]:
            for slug, progress in lesson["progress"].items():
                # we can search segments by slug because in stubs segments slugs are unique
                segment = (
                    datamodels.Segment.objects()
                    .filter(datamodels.Segment.slug == slug)
                    .first()
                )
                datamodels.SegmentUserProgress.save_user_progress(
                    segment.id, user.id, progress
                )

    # default institute, whitout subdomain
    fitz_institute = datamodels.Institute(name="Fitzroyacademy", logo="", slug="")

    session.add(fitz_institute)
    session.commit()

    fitz_institute.add_admin(datamodels.get_user(1))  # Homer

    institute1 = datamodels.Institute(name="Jedi Temple", logo="", slug="jeditemple")

    session.add(institute1)
    session.commit()

    institute1.add_admin(datamodels.get_user(3))  # Bart
    session.commit()
 def setUp(self):
     with app.app_context():
         self.session = datamodels.get_session()
Example #24
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})
Example #25
0
def edit(user, institute=""):

    if not institute:
        return (
            jsonify({
                "success": False,
                "message": "Well, no. You can't edit this institute. :)",
            }),
            400,
        )

    institute = datamodels.Institute.find_by_slug(institute)

    if not institute or (not user.super_admin
                         and not institute.is_admin(user)):
        raise abort(
            404, "No such institute 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 "name" in request.form and request.form["name"] != "":
        institute.name = request.form["name"]
    if "description" in request.form:
        institute.description = request.form["description"]
    if "for_who" in request.form:
        institute.for_who = request.form["for_who"]
    if "location" in request.form:
        institute.location = request.form["location"]
    if "cover_image" in request.form:
        file = request.files["file"]

        filename = generate_thumbnail(file, "cover")
        if not filename:
            return (
                jsonify({
                    "success":
                    False,
                    "message":
                    "Couldn't upload picture. Try again or use different file format",
                }),
                400,
            )

        institute.cover_image = filename
    if "logo" in request.form:
        file = request.files["file"]

        filename = generate_thumbnail(file, "square_m")
        if not filename:
            return (
                jsonify({
                    "success":
                    False,
                    "message":
                    "Couldn't upload picture. Try again or use different file format",
                }),
                400,
            )

        institute.logo = filename

    db.add(institute)
    db.commit()

    return jsonify({"success": True})
    def setUp(self):
        with app.app_context():
            self.session = datamodels.get_session()

            self.course = self.make_standard_course(guest_access=True)
            self.session.add(self.course)

            self.user = self.makeUser(
                email="*****@*****.**", id=1, username="******"
            )
            self.session.add(self.user)
            self.session.commit()
            self.course.enroll(self.user)

            self.l0 = self.make_standard_course_lesson(
                title="Intro lesson", course=self.course, order=0
            )
            self.session.add(self.l0)
            self.l0s0 = self.make_segment(
                self.l0,
                title="Intro segment",
                order=0,
                slug="intro-segment",
                seg_type="video",
            )
            self.session.add(self.l0s0)

            self.l1 = self.make_standard_course_lesson(
                title="lesson 1", course=self.course, order=1
            )
            self.session.add(self.l1)
            self.l1s1 = self.make_segment(
                self.l1,
                title="Intro segment l1",
                order=0,
                slug="intro-segment-l1",
                seg_type="text",
            )
            self.l1s2 = self.make_segment(
                self.l1, title="Segment l1s1", order=1, slug="segment-1"
            )
            self.l1s3 = self.make_segment(
                self.l1, title="Segment l1s2", order=2, slug="segment-2"
            )
            self.session.add(self.l1s1)
            self.session.add(self.l1s2)
            self.session.add(self.l1s3)

            self.l2 = self.make_standard_course_lesson(
                title="lesson 2", course=self.course, order=2
            )
            self.session.add(self.l2)
            self.l2s1 = self.make_segment(
                self.l2,
                title="Intro segment l2",
                order=0,
                slug="intro-segment-l2",
                seg_type="text",
            )
            self.l2s2 = self.make_segment(
                self.l2, title="Segment l2s1", order=1, slug="segment-1"
            )
            self.l2s3 = self.make_segment(
                self.l2, title="Segment l2s2", order=2, slug="segment-2"
            )
            self.session.add(self.l2s1)
            self.session.add(self.l2s2)
            self.session.add(self.l2s3)
Example #27
0
def add_teacher(user, course, course_slug, lesson_id, institute=""):
    lesson = datamodels.Course.find_lesson_by_course_slug_and_id(
        course.slug, lesson_id)

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

    if not lesson:
        return jsonify({
            "success": False,
            "message": "Wrong lesson or course"
        }), 400

    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,
        )
    elif not new_teacher.teaches(course):
        return (
            jsonify({
                "success": False,
                "message": "This user is not a teacher."
            }),
            400,
        )

    if new_teacher.id in [teacher.id for teacher in lesson.teachers]:
        return jsonify({
            "success": False,
            "message": "Teacher already added"
        }), 400

    enrolment = datamodels.CourseEnrollment.find_by_course_and_student(
        course.id, new_teacher.id)

    if enrolment.access_level not in [
            CourseAccess.admin, CourseAccess.teacher
    ]:
        return jsonify({
            "success": False,
            "message": "User must be a teacher"
        }), 400

    lesson.teachers.append(enrolment)
    db = datamodels.get_session()
    db.add(lesson)
    db.commit()

    return jsonify({
        "success": True,
        "message": "Successfully added!",
        "teacher": render_teacher(new_teacher, course, lesson),
    })