Beispiel #1
0
def attempt_problem_number(exercise_name, problem_number):
    user_data = models.UserData.current()

    if user_data:
        exercise = models.Exercise.get_by_name(exercise_name)
        user_exercise = user_data.get_or_insert_exercise(exercise)

        if user_exercise and problem_number:

            user_exercise, user_exercise_graph = attempt_problem(
                user_data,
                user_exercise,
                problem_number,
                request.request_int("attempt_number"),
                request.request_string("attempt_content"),
                request.request_string("sha1"),
                request.request_string("seed"),
                request.request_bool("complete"),
                request.request_int("count_hints", default=0),
                int(request.request_float("time_taken")),
                request.request_string("non_summative"),
                request.request_string("problem_type"),
                request.remote_addr,
            )

            # this always returns a delta of points earned each attempt
            points_earned = user_data.points - user_data.original_points()
            if (user_exercise.streak == 0):
                # never award points for a zero streak
                points_earned = 0
            if (user_exercise.streak == 1):
                # award points for the first correct exercise done, even if no prior history exists
                # and the above pts-original points gives a wrong answer
                points_earned = user_data.points if (
                    user_data.points == points_earned) else points_earned

            add_action_results(
                user_exercise, {
                    "exercise_message_html":
                    templatetags.exercise_message(
                        exercise, user_data.coaches,
                        user_exercise_graph.states(exercise.name)),
                    "points_earned": {
                        "points": points_earned
                    },
                    "attempt_correct":
                    request.request_bool("complete")
                })

            return user_exercise

    logging.warning("Problem %d attempted with no user_data present",
                    problem_number)
    return unauthorized_response()
Beispiel #2
0
def hint_problem_number(exercise_name, problem_number):

    user_data = models.UserData.current()

    if user_data:
        exercise = models.Exercise.get_by_name(exercise_name)
        user_exercise = user_data.get_or_insert_exercise(exercise)

        if user_exercise and problem_number:

            prev_user_exercise_graph = models.UserExerciseGraph.get(user_data)

            attempt_number = request.request_int("attempt_number")
            count_hints = request.request_int("count_hints")

            user_exercise, user_exercise_graph, goals_updated = attempt_problem(
                    user_data,
                    user_exercise,
                    problem_number,
                    attempt_number,
                    request.request_string("attempt_content"),
                    request.request_string("sha1"),
                    request.request_string("seed"),
                    request.request_bool("complete"),
                    count_hints,
                    int(request.request_float("time_taken")),
                    request.request_string("non_summative"),
                    request.request_string("problem_type"),
                    request.remote_addr,
                    )

            user_states = user_exercise_graph.states(exercise.name)
            review_mode = request.request_bool("review_mode", default=False)
            exercise_message_html = templatetags.exercise_message(exercise,
                    user_exercise_graph, review_mode=review_mode)

            add_action_results(user_exercise, {
                "exercise_message_html": exercise_message_html,
                "exercise_state": {
                    "state": [state for state in user_states if user_states[state]],
                    "template" : exercise_message_html,
                }
            })

            # A hint will count against the user iff they haven't attempted the question yet and it's their first hint
            if attempt_number == 0 and count_hints == 1:
                bingo("hints_costly_hint")
                bingo("hints_costly_hint_binary")

            return user_exercise

    logging.warning("Problem %d attempted with no user_data present", problem_number)
    return unauthorized_response()
Beispiel #3
0
def filter_query_by_request_dates(query, property):

    if request.request_string("dt_start"):
        try:
            dt_start = request.request_date_iso("dt_start")
            query.filter("%s >=" % property, dt_start)
        except ValueError:
            raise ValueError("Invalid date format sent to dt_start, use ISO 8601 Combined.")

    if request.request_string("dt_end"):
        try:
            dt_end = request.request_date_iso("dt_end")
            query.filter("%s <" % property, dt_end)
        except ValueError:
            raise ValueError("Invalid date format sent to dt_end, use ISO 8601 Combined.")
Beispiel #4
0
def autocomplete():

    video_results = []
    playlist_results = []

    query = request.request_string("q", default="").strip().lower()
    if query:

        max_results_per_type = 10

        video_results = filter(
                lambda video_dict: query in video_dict["title"].lower(),
                video_title_dicts())
        playlist_results = filter(
                lambda playlist_dict: query in playlist_dict["title"].lower(),
                playlist_title_dicts())

        video_results = sorted(
                video_results,
                key=lambda v: v["title"].lower().index(query))[:max_results_per_type]
        playlist_results = sorted(
                playlist_results,
                key=lambda p: p["title"].lower().index(query))[:max_results_per_type]

    return {
            "query": query,
            "videos": video_results,
            "playlists": playlist_results
    }
Beispiel #5
0
def autocomplete():

    video_results = []
    playlist_results = []

    query = request.request_string("q", default="").strip().lower()

    if query:

        max_results_per_type = 10

        video_results = filter(
            lambda video_dict: query in video_dict["title"].lower(),
            video_title_dicts())
        playlist_results = filter(
            lambda playlist_dict: query in playlist_dict["title"].lower(),
            playlist_title_dicts())

        video_results = sorted(video_results,
                               key=lambda dict: dict["title"].lower().index(
                                   query))[:max_results_per_type]
        playlist_results = sorted(playlist_results,
                                  key=lambda dict: dict["title"].lower().index(
                                      query))[:max_results_per_type]

    return {
        "query": query,
        "videos": video_results,
        "playlists": playlist_results
    }
Beispiel #6
0
def hint_problem_number(exercise_name, problem_number):

    user_data = models.UserData.current()

    if user_data:
        exercise = models.Exercise.get_by_name(exercise_name)
        user_exercise = user_data.get_or_insert_exercise(exercise)

        if user_exercise and problem_number:

            attempt_number = request.request_int("attempt_number")
            count_hints = request.request_int("count_hints")

            user_exercise, user_exercise_graph = attempt_problem(
                user_data,
                user_exercise,
                problem_number,
                attempt_number,
                request.request_string("attempt_content"),
                request.request_string("sha1"),
                request.request_string("seed"),
                request.request_bool("complete"),
                count_hints,
                int(request.request_float("time_taken")),
                request.request_string("non_summative"),
                request.request_string("problem_type"),
                request.remote_addr,
            )

            add_action_results(
                user_exercise, {
                    "exercise_message_html":
                    templatetags.exercise_message(
                        exercise, user_data.coaches,
                        user_exercise_graph.states(exercise.name)),
                })

            # A hint will count against the user iff they haven't attempted the question yet and it's their first hint
            if attempt_number == 0 and count_hints == 1:
                bingo("hints_costly_hint")
                bingo("hints_costly_hint_binary")

            return user_exercise

    logging.warning("Problem %d attempted with no user_data present",
                    problem_number)
    return unauthorized_response()
Beispiel #7
0
def filter_query_by_request_dates(query, property):

    if request.request_string("dt_start"):
        try:
            dt_start = request.request_date_iso("dt_start")
            query.filter("%s >=" % property, dt_start)
        except ValueError:
            raise ValueError(
                "Invalid date format sent to dt_start, use ISO 8601 Combined.")

    if request.request_string("dt_end"):
        try:
            dt_end = request.request_date_iso("dt_end")
            query.filter("%s <=" % property, dt_end)
        except ValueError:
            raise ValueError(
                "Invalid date format sent to dt_end, use ISO 8601 Combined.")
Beispiel #8
0
def attempt_problem_number(exercise_name, problem_number):
    user_data = models.UserData.current()

    if user_data:
        exercise = models.Exercise.get_by_name(exercise_name)
        user_exercise = user_data.get_or_insert_exercise(exercise)

        if user_exercise and problem_number:

            user_exercise, user_exercise_graph = attempt_problem(
                    user_data,
                    user_exercise,
                    problem_number,
                    request.request_int("attempt_number"),
                    request.request_string("attempt_content"),
                    request.request_string("sha1"),
                    request.request_string("seed"),
                    request.request_bool("complete"),
                    request.request_int("count_hints", default=0),
                    int(request.request_float("time_taken")),
                    request.request_string("non_summative"),
                    request.request_string("problem_type"),
                    request.remote_addr,
                    )

            # this always returns a delta of points earned each attempt
            points_earned = user_data.points - user_data.original_points()
            if(user_exercise.streak == 0):
                # never award points for a zero streak
                points_earned = 0
            if(user_exercise.streak == 1):
                # award points for the first correct exercise done, even if no prior history exists
                # and the above pts-original points gives a wrong answer
                points_earned = user_data.points if (user_data.points == points_earned) else points_earned

            add_action_results(user_exercise, {
                "exercise_message_html": templatetags.exercise_message(exercise, user_data.coaches, user_exercise_graph.states(exercise.name)),
                "points_earned" : { "points" : points_earned },
                "attempt_correct" : request.request_bool("complete")
            })

            return user_exercise

    logging.warning("Problem %d attempted with no user_data present", problem_number)
    return unauthorized_response()
Beispiel #9
0
def log_user_video(youtube_id):
    if (not request.request_string("seconds_watched") or
        not request.request_string("last_second_watched")):
        logging.critical("Video log request with no parameters received.")
        return api_invalid_param_response("Must supply seconds_watched and" +
            "last_second_watched")

    user_data = models.UserData.current()
    if not user_data:
        logging.warning("Video watched with no user_data present")
        return unauthorized_response()

    video_key_str = request.request_string("video_key")

    if not youtube_id and not video_key_str:
        return api_invalid_param_response("Must supply youtube_id or video_key")

    video_log = None
    if video_key_str:
        key = db.Key(video_key_str)
        video = db.get(key)
    else:
        video = models.Video.all().filter("youtube_id =", youtube_id).get()

    if not video:
        return api_error_response("Could not find video")

    seconds_watched = int(request.request_float("seconds_watched", default=0))
    last_second = int(request.request_float("last_second_watched", default=0))

    user_video, video_log, _, goals_updated = models.VideoLog.add_entry(
        user_data, video, seconds_watched, last_second)

    if video_log:
        action_results = {}
        action_results['user_video'] = user_video
        if goals_updated:
            action_results['updateGoals'] = [g.get_visible_data(None)
                for g in goals_updated]

        add_action_results(video_log, action_results)

    return video_log
Beispiel #10
0
def get_ordered_review_problems():
    """Retrieves an ordered list of a subset of the upcoming review problems."""

    # TODO(david): This should probably be abstracted away in exercises.py or
    # models.py (if/when there's more logic here) with a nice interface.

    user_data = get_visible_user_data_from_request()

    if not user_data:
        return []

    user_exercise_graph = models.UserExerciseGraph.get(user_data)
    review_exercises = user_exercise_graph.review_exercise_names()

    queued_exercises = request.request_string('queued', '').split(',')

    # Only return those exercises that aren't already queued up
    return filter(lambda ex: ex not in queued_exercises, review_exercises)
Beispiel #11
0
def video_download_available(video_id):

    video = None
    formats = request.request_string("formats", default="")
    allowed_formats = ["mp4", "png"]

    # If for any crazy reason we happen to have multiple entities for a single youtube id,
    # make sure they all have the same downloadable_formats so we don't keep trying to export them.
    for video in models.Video.all().filter("youtube_id =", video_id):

        modified = False

        for downloadable_format in formats.split(","):
            if downloadable_format in allowed_formats and downloadable_format not in video.downloadable_formats:
                video.downloadable_formats.append(downloadable_format)
                modified = True

        if modified:
            video.put()

    return video
Beispiel #12
0
def get_visible_user_data_from_request(disable_coach_visibility = False):

    user_data = models.UserData.current()
    if not user_data:
        return None

    if request.request_string("email"):
        user_data_student = request.request_user_data("email")

        if user_data_student and user_data_student.user_email == user_data.user_email:
            # if email in request is that of the current user, simply return the
            # current user_data, no need to check permission to view
            return user_data

        if user_data_student and (user_data.developer or (not disable_coach_visibility and user_data_student.is_coached_by(user_data))):
            return user_data_student
        else:
            return None

    else:
        return user_data
Beispiel #13
0
def get_visible_user_data_from_request(disable_coach_visibility=False):

    user_data = models.UserData.current()
    if not user_data:
        return None

    if request.request_string("email"):
        user_data_student = request.request_user_data("email")

        if user_data_student and user_data_student.user_email == user_data.user_email:
            # if email in request is that of the current user, simply return the
            # current user_data, no need to check permission to view
            return user_data

        if user_data_student and (
                user_data.developer or
            (not disable_coach_visibility
             and user_data_student.is_coached_by(user_data))):
            return user_data_student
        else:
            return None

    else:
        return user_data
Beispiel #14
0
def attempt_problem_number(exercise_name, problem_number):
    user_data = models.UserData.current()

    if user_data:
        exercise = models.Exercise.get_by_name(exercise_name)
        user_exercise = user_data.get_or_insert_exercise(exercise)

        if user_exercise and problem_number:

            user_exercise, user_exercise_graph, goals_updated = attempt_problem(
                    user_data,
                    user_exercise,
                    problem_number,
                    request.request_int("attempt_number"),
                    request.request_string("attempt_content"),
                    request.request_string("sha1"),
                    request.request_string("seed"),
                    request.request_bool("complete"),
                    request.request_int("count_hints", default=0),
                    int(request.request_float("time_taken")),
                    request.request_string("non_summative"),
                    request.request_string("problem_type"),
                    request.remote_addr,
                    )

            # this always returns a delta of points earned each attempt
            points_earned = user_data.points - user_data.original_points()
            if(user_exercise.streak == 0):
                # never award points for a zero streak
                points_earned = 0
            if(user_exercise.streak == 1):
                # award points for the first correct exercise done, even if no prior history exists
                # and the above pts-original points gives a wrong answer
                points_earned = user_data.points if (user_data.points == points_earned) else points_earned

            user_states = user_exercise_graph.states(exercise.name)
            correct = request.request_bool("complete")
            review_mode = request.request_bool("review_mode", default=False)

            action_results = {
                "exercise_state": {
                    "state": [state for state in user_states if user_states[state]],
                    "template" : templatetags.exercise_message(exercise,
                        user_exercise_graph, review_mode=review_mode),
                },
                "points_earned": {"points": points_earned},
                "attempt_correct": correct,
            }

            if goals_updated:
                action_results['updateGoals'] = [g.get_visible_data(None) for g in goals_updated]

            if review_mode:
                action_results['reviews_left'] = (
                    user_exercise_graph.reviews_left_count() + (1 - correct))

            add_action_results(user_exercise, action_results)
            return user_exercise

    logging.warning("Problem %d attempted with no user_data present", problem_number)
    return unauthorized_response()
Beispiel #15
0
def get_students_data_from_request(user_data):
    return util_profile.get_students_data(user_data, request.request_string("list_id"))
Beispiel #16
0
def token_to_session():
    set_current_oauth_map_in_session()
    return redirect(request.request_string("continue", default="/"))