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)
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)
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)
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)
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.")
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)
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)
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)
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)
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
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)