Exemplo n.º 1
0
def create_scratchpad():
    """Create a new Scratchpad and associated ScratchpadRevision.

    The POST data should be a JSON-encoded dict, which is passed verbatim to
    Scratchpad.create as keyword arguments.
    """
    if not gandalf.bridge.gandalf("scratchpads"):
        return api_forbidden_response(
            "Forbidden: You don't have permission to do this")

    if not request.json:
        return api_invalid_param_response("Bad data supplied: Not JSON")

    # TODO(jlfwong): Support phantom users
    user = UserData.current()

    if not (user and user.developer):
        # Certain fields are only modifiable by developers
        for field in scratchpad_models.Scratchpad._developer_only_fields:
            if request.json.get(field):
                return api_forbidden_response(
                    "Forbidden: Only developers can change the %s" % field)

    try:
        # Convert unicode encoded JSON keys to strings
        create_args = dict_keys_to_strings(request.json)
        if user:
            create_args['user_id'] = user.user_id
        return scratchpad_models.Scratchpad.create(**create_args)
    except (db.BadValueError, db.BadKeyError), e:
        return api_invalid_param_response("Bad data supplied: " + e.message)
Exemplo n.º 2
0
def create_scratchpad():
    """Create a new Scratchpad and associated ScratchpadRevision.

    The POST data should be a JSON-encoded dict, which is passed verbatim to
    Scratchpad.create as keyword arguments.
    """
    if not gandalf.bridge.gandalf("scratchpads"):
        return api_forbidden_response(
            "Forbidden: You don't have permission to do this")

    if not request.json:
        return api_invalid_param_response("Bad data supplied: Not JSON")

    # TODO(jlfwong): Support phantom users
    user = UserData.current()

    if not (user and user.developer):
        # Certain fields are only modifiable by developers
        for field in scratchpad_models.Scratchpad._developer_only_fields:
            if request.json.get(field):
                return api_forbidden_response(
                    "Forbidden: Only developers can change the %s" % field)

    try:
        # Convert unicode encoded JSON keys to strings
        create_args = dict_keys_to_strings(request.json)
        if user:
            create_args['user_id'] = user.user_id
        return scratchpad_models.Scratchpad.create(**create_args)
    except (db.BadValueError, db.BadKeyError), e:
        return api_invalid_param_response("Bad data supplied: " + e.message)
Exemplo n.º 3
0
def get_student_progress_report():
    user_data_coach = get_user_data_coach_from_request()

    if not user_data_coach:
        return api_invalid_param_response("User is not logged in.")

    try:
        students = get_students_data_from_request(user_data_coach)
    except Exception, e:
        return api_invalid_param_response(e.message)
Exemplo n.º 4
0
def get_user_goal(id):
    user_data = models.UserData.current()
    if not user_data:
        return api_invalid_param_response("User not logged in")

    goal = Goal.get_by_id(id, parent=user_data)

    if not goal:
        return api_invalid_param_response("Could not find goal with ID " + str(id))

    return goal.get_visible_data(None)
Exemplo n.º 5
0
def create_user_goal():
    user_data = models.UserData.current()
    if not user_data:
        return api_invalid_param_response("User is not logged in.")

    user_override = request.request_user_data("email")
    if user_data.developer and user_override and user_override.key_email != user_data.key_email:
        user_data = user_override

    json = request.json
    title = json.get('title')
    if not title:
        return api_invalid_param_response('Title is invalid.')

    objective_descriptors = []

    goal_exercises = GoalList.exercises_in_current_goals(user_data)
    goal_videos = GoalList.videos_in_current_goals(user_data)

    if json:
        for obj in json['objectives']:
            if obj['type'] == 'GoalObjectiveAnyExerciseProficiency':
                objective_descriptors.append(obj)

            if obj['type'] == 'GoalObjectiveAnyVideo':
                objective_descriptors.append(obj)

            if obj['type'] == 'GoalObjectiveExerciseProficiency':
                obj['exercise'] = models.Exercise.get_by_name(obj['internal_id'])
                if not obj['exercise'] or not obj['exercise'].is_visible_to_current_user():
                    return api_invalid_param_response("Internal error: Could not find exercise.")
                if user_data.is_proficient_at(obj['exercise'].name):
                    return api_invalid_param_response("Exercise has already been completed.")
                if obj['exercise'].name in goal_exercises:
                    return api_invalid_param_response("Exercise is already an objective in a current goal.")
                objective_descriptors.append(obj)

            if obj['type'] == 'GoalObjectiveWatchVideo':
                obj['video'] = models.Video.get_for_readable_id(obj['internal_id'])
                if not obj['video']:
                    return api_invalid_param_response("Internal error: Could not find video.")
                user_video = models.UserVideo.get_for_video_and_user_data(obj['video'], user_data)
                if user_video and user_video.completed:
                    return api_invalid_param_response("Video has already been watched.")
                if obj['video'].readable_id in goal_videos:
                    return api_invalid_param_response("Video is already an objective in a current goal.")
                objective_descriptors.append(obj)

    if objective_descriptors:
        objectives = GoalObjective.from_descriptors(objective_descriptors,
            user_data)

        goal = Goal(parent=user_data, title=title, objectives=objectives)
        user_data.save_goal(goal)

        return goal.get_visible_data(None)
    else:
        return api_invalid_param_response("No objectives specified.")
Exemplo n.º 6
0
def get_students_progress_summary():
    user_data_coach = get_user_data_coach_from_request()

    try:
        list_students = get_students_data_from_request(user_data_coach)
    except Exception, e:
        return api_invalid_param_response(e.message)
Exemplo n.º 7
0
def get_student_goals():
    user_data_coach = get_user_data_coach_from_request()

    try:
        students = get_students_data_from_request(user_data_coach)
    except Exception, e:
        return api_invalid_param_response(e.message)
Exemplo n.º 8
0
def update_scratchpad(scratchpad_id):
    """Update a pre-existing Scratchpad and create a new ScratchpadRevision.

    The POST data should be a JSON-encoded dict, which is passsed verbatim to
    Scratchpad.update as keyword arguments.
    """
    if not gandalf.bridge.gandalf("scratchpads"):
        return api_forbidden_response(
            "Forbidden: You don't have permission to do this")

    if not request.json:
        return api_invalid_param_response("Bad data supplied: Not JSON")

    user = UserData.current()
    scratchpad = scratchpad_models.Scratchpad.get_by_id(scratchpad_id)

    if not scratchpad or scratchpad.deleted:
        return api_not_found_response(
            "No scratchpad with id %s" % scratchpad_id)

    if not user.developer:
        # Certain fields are only modifiable by developers
        for field in scratchpad_models.Scratchpad._developer_only_fields:
            if request.json.get(field):
                return api_forbidden_response(
                    "Forbidden: Only developers can change the %s" % field)

    # The user can update the scratchpad if any of the following are true:
    #  1. The scratchpad is tutorial/official and the user is a developer
    #  2. The scratchpad was created by the user
    if scratchpad.category in ("tutorial", "official") and user.developer:
        pass
    elif scratchpad.user_id != user.user_id:
        # Only the creator of a scratchpad can update it
        return api_forbidden_response(
            "Forbidden: Scratchpad owned by different user")

    try:
        # Convert unicode encoded JSON keys to strings
        update_args = dict_keys_to_strings(request.json)
        if 'id' in update_args:
            # Backbone passes the id in update calls - ignore it
            del update_args['id']
        return scratchpad.update(**update_args)
    except (db.BadValueError, db.BadKeyError), e:
        return api_invalid_param_response("Bad data supplied: " + e.message)
Exemplo n.º 9
0
def update_scratchpad(scratchpad_id):
    """Update a pre-existing Scratchpad and create a new ScratchpadRevision.

    The POST data should be a JSON-encoded dict, which is passsed verbatim to
    Scratchpad.update as keyword arguments.
    """
    if not gandalf.bridge.gandalf("scratchpads"):
        return api_forbidden_response(
            "Forbidden: You don't have permission to do this")

    if not request.json:
        return api_invalid_param_response("Bad data supplied: Not JSON")

    user = UserData.current()
    scratchpad = scratchpad_models.Scratchpad.get_by_id(scratchpad_id)

    if not scratchpad or scratchpad.deleted:
        return api_not_found_response("No scratchpad with id %s" %
                                      scratchpad_id)

    if not user.developer:
        # Certain fields are only modifiable by developers
        for field in scratchpad_models.Scratchpad._developer_only_fields:
            if request.json.get(field):
                return api_forbidden_response(
                    "Forbidden: Only developers can change the %s" % field)

    # The user can update the scratchpad if any of the following are true:
    #  1. The scratchpad is tutorial/official and the user is a developer
    #  2. The scratchpad was created by the user
    if scratchpad.category in ("tutorial", "official") and user.developer:
        pass
    elif scratchpad.user_id != user.user_id:
        # Only the creator of a scratchpad can update it
        return api_forbidden_response(
            "Forbidden: Scratchpad owned by different user")

    try:
        # Convert unicode encoded JSON keys to strings
        update_args = dict_keys_to_strings(request.json)
        if 'id' in update_args:
            # Backbone passes the id in update calls - ignore it
            del update_args['id']
        return scratchpad.update(**update_args)
    except (db.BadValueError, db.BadKeyError), e:
        return api_invalid_param_response("Bad data supplied: " + e.message)
Exemplo n.º 10
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
Exemplo n.º 11
0
def put_user_goal(id):
    user_data = models.UserData.current()
    if not user_data:
        return api_invalid_param_response("User not logged in")

    goal = Goal.get_by_id(id, parent=user_data)

    if not goal:
        return api_invalid_param_response("Could not find goal with ID " + str(id))

    goal_json = request.json

    # currently all you can modify is the title
    if goal_json['title'] != goal.title:
        goal.title = goal_json['title']
        goal.put()

    # or abandon something
    if goal_json.get('abandoned') and not goal.abandoned:
        goal.abandon()
        goal.put()

    return goal.get_visible_data(None)