def get(self): coach = UserData.current() user_override = self.request_user_data("coach_email") if user_override and user_override.are_students_visible_to(coach): # Only allow looking at a student list other than your own # if you are a dev, admin, or coworker. coach = user_override student_lists = StudentList.get_for_coach(coach.key()) student_lists_list = [{ 'key': 'allstudents', 'name': 'All students', }] for student_list in student_lists: student_lists_list.append({ 'key': str(student_list.key()), 'name': student_list.name, }) list_id, _ = get_last_student_list(self, student_lists, coach == UserData.current()) current_list = None for student_list in student_lists_list: if student_list['key'] == list_id: current_list = student_list selected_graph_type = self.request_string( "selected_graph_type") or ClassProgressReportGraph.GRAPH_TYPE if selected_graph_type == 'progressreport' or selected_graph_type == 'goals': # TomY This is temporary until all the graphs are API calls initial_graph_url = "/api/v1/user/students/%s?coach_email=%s&%s" % ( selected_graph_type, urllib.quote(coach.email), urllib.unquote( self.request_string("graph_query_params", default=""))) else: initial_graph_url = "/profile/graph/%s?coach_email=%s&%s" % ( selected_graph_type, urllib.quote(coach.email), urllib.unquote( self.request_string("graph_query_params", default=""))) initial_graph_url += 'list_id=%s' % list_id template_values = { 'user_data_coach': coach, 'coach_email': coach.email, 'list_id': list_id, 'student_list': current_list, 'student_lists': student_lists_list, 'student_lists_json': json.dumps(student_lists_list), 'coach_nickname': coach.nickname, 'selected_graph_type': selected_graph_type, 'initial_graph_url': initial_graph_url, 'exercises': exercise_models.Exercise.get_all_use_cache(), 'is_profile_empty': not coach.has_students(), 'selected_nav_link': 'coach', "view": self.request_string("view", default=""), 'stats_charts_class': 'coach-view', } self.render_jinja2_template('viewclassprofile.html', template_values)
def get(self): coach = UserData.current() user_override = self.request_user_data("coach_email") if user_override and user_override.are_students_visible_to(coach): # Only allow looking at a student list other than your own # if you are a dev, admin, or coworker. coach = user_override student_lists = StudentList.get_for_coach(coach.key()) student_lists_list = [{ 'key': 'allstudents', 'name': 'All students', }]; for student_list in student_lists: student_lists_list.append({ 'key': str(student_list.key()), 'name': student_list.name, }) list_id, _ = get_last_student_list(self, student_lists, coach==UserData.current()) current_list = None for student_list in student_lists_list: if student_list['key'] == list_id: current_list = student_list selected_graph_type = self.request_string("selected_graph_type") or ClassProgressReportGraph.GRAPH_TYPE if selected_graph_type == 'progressreport' or selected_graph_type == 'goals': # TomY This is temporary until all the graphs are API calls initial_graph_url = "/api/v1/user/students/%s?coach_email=%s&%s" % (selected_graph_type, urllib.quote(coach.email), urllib.unquote(self.request_string("graph_query_params", default=""))) else: initial_graph_url = "/profile/graph/%s?coach_email=%s&%s" % (selected_graph_type, urllib.quote(coach.email), urllib.unquote(self.request_string("graph_query_params", default=""))) initial_graph_url += 'list_id=%s' % list_id template_values = { 'user_data_coach': coach, 'coach_email': coach.email, 'list_id': list_id, 'student_list': current_list, 'student_lists': student_lists_list, 'student_lists_json': json.dumps(student_lists_list), 'coach_nickname': coach.nickname, 'selected_graph_type': selected_graph_type, 'initial_graph_url': initial_graph_url, 'exercises': exercise_models.Exercise.get_all_use_cache(), 'is_profile_empty': not coach.has_students(), 'selected_nav_link': 'coach', "view": self.request_string("view", default=""), 'stats_charts_class': 'coach-view', } self.render_jinja2_template('viewclassprofile.html', template_values)
def delete_scratchpad(scratchpad_id): """Mark a pre-existing Scratchpad as deleted. An empty request body is expected.""" if not gandalf.bridge.gandalf("scratchpads"): return api_forbidden_response( "Forbidden: You don't have permission to do this") 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) # Users can only delete scratchpad they created # EXCEPTION: Developres can delete any scratchpad if not user.developer and scratchpad.user_id != user.user_id: return api_forbidden_response( "Forbidden: Scratchpad owned by different user") scratchpad.deleted = True scratchpad.put() return api_success_no_content_response()
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 test_request_video(self): exs = exercise_models.Exercise.all().fetch(1000) user = UserData.current() self.assertFalse(exs[0].video_requested) exs[0].request_video() self.assertTrue(exs[0].video_requested) self.assertEqual(exs[0].video_requests_count, 1)
def delete_scratchpad(scratchpad_id): """Mark a pre-existing Scratchpad as deleted. An empty request body is expected.""" if not gandalf.bridge.gandalf("scratchpads"): return api_forbidden_response( "Forbidden: You don't have permission to do this") 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) # Users can only delete scratchpad they created # EXCEPTION: Developres can delete any scratchpad if not user.developer and scratchpad.user_id != user.user_id: return api_forbidden_response( "Forbidden: Scratchpad owned by different user") scratchpad.deleted = True scratchpad.put() return api_success_no_content_response()
def post(self): template_values = {} user_data = UserData.current() status_file = StringIO.StringIO(self.request_string('status_file')) reader = csv.reader(status_file) student_list = [] for line in reader: student_email = line[0] student_status = line[1] student_comment = line[2] student = SummerStudent.all().filter('email =', student_email).get() if student is None: logging.error("Student %s not found" % student_email) continue student.application_status = student_status student.comment = student_comment if student_status == "Accepted": student.accepted = True student_list.append(student) db.put(student_list) self.response.out.write("OK") self.response.set_status(200)
def post(self): user_data = UserData.current() if not user_data: return if user_data.is_child_account(): self.render_json({"error": "You cannot vote yet."}) return vote_type = self.request_int( "vote_type", default=discussion_models.FeedbackVote.ABSTAIN) if (vote_type == discussion_models.FeedbackVote.UP and not Privileges.can_up_vote(user_data)): self.render_json({ "error": Privileges.need_points_desc(Privileges.UP_VOTE_THRESHOLD, "up vote") }) return elif (vote_type == discussion_models.FeedbackVote.DOWN and not Privileges.can_down_vote(user_data)): self.render_json({ "error": Privileges.need_points_desc(Privileges.DOWN_VOTE_THRESHOLD, "down vote") }) return entity_key = self.request_string("entity_key", default="") if entity_key: entity = db.get(entity_key) if entity and entity.authored_by(user_data): self.render_json( {"error": "You cannot vote for your own posts."}) return if vote_type != discussion_models.FeedbackVote.ABSTAIN: limiter = VoteRateLimiter(user_data) if not limiter.increment(): self.render_json({"error": limiter.denied_desc()}) return # We kick off a taskqueue item to perform the actual vote insertion # so we don't have to worry about fast writes to the entity group # causing contention problems for the HR datastore, because # the taskqueue will just retry w/ exponential backoff. # TODO(marcia): user_data.email may change. user_id is preferred taskqueue.add(url='/admin/discussion/finishvoteentity', queue_name='voting-queue', params={ "email": user_data.email, "vote_type": self.request_int( "vote_type", default=discussion_models.FeedbackVote.ABSTAIN), "entity_key": entity_key })
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 post(self): user_data = UserData.current() if not user_data: return if user_data.is_child_account(): self.render_json({"error": "Je kan nog niet stemmen."}) return vote_type = self.request_int( "vote_type", default=discussion_models.FeedbackVote.ABSTAIN) if (vote_type == discussion_models.FeedbackVote.UP and not Privileges.can_up_vote(user_data)): self.render_json({ "error": Privileges.need_points_desc( Privileges.UP_VOTE_THRESHOLD, "up vote") }) return elif (vote_type == discussion_models.FeedbackVote.DOWN and not Privileges.can_down_vote(user_data)): self.render_json({ "error": Privileges.need_points_desc( Privileges.DOWN_VOTE_THRESHOLD, "down vote") }) return entity_key = self.request_string("entity_key", default="") if entity_key: entity = db.get(entity_key) if entity and entity.authored_by(user_data): self.render_json({ "error": "Je kan niet op je eigen opmerking stemmen." }) return if vote_type != discussion_models.FeedbackVote.ABSTAIN: limiter = VoteRateLimiter(user_data) if not limiter.increment(): self.render_json({"error": limiter.denied_desc()}) return # We kick off a taskqueue item to perform the actual vote insertion # so we don't have to worry about fast writes to the entity group # causing contention problems for the HR datastore, because # the taskqueue will just retry w/ exponential backoff. # TODO(marcia): user_data.email may change. user_id is preferred taskqueue.add( url='/admin/discussion/finishvoteentity', queue_name='voting-queue', params={ "email": user_data.email, "vote_type": self.request_int( "vote_type", default=discussion_models.FeedbackVote.ABSTAIN), "entity_key": entity_key } )
def get(self): user_data = UserData.current() user_data_override = self.request_user_data("coach_email") if user_util.is_current_user_developer() and user_data_override: user_data = user_data_override invalid_student = self.request_bool("invalid_student", default=False) coach_requests = [req.student_requested_identifier for req in CoachRequest.get_for_coach(user_data) if req.student_requested_data] student_lists_models = StudentList.get_for_coach(user_data.key()) student_lists_list = [] for student_list in student_lists_models: student_lists_list.append({ 'key': str(student_list.key()), 'name': student_list.name, }) student_lists_dict = dict((g['key'], g) for g in student_lists_list) def student_to_dict(s): """Convert the UserData s to a dictionary for rendering.""" return { 'key': str(s.key()), 'email': s.email, 'username': s.username, # Note that child users don't have an email. 'identifier': s.username or s.email, 'nickname': s.nickname, 'profile_root': s.profile_root, 'can_modify_coaches': s.can_modify_coaches(), 'studentLists': [l for l in [student_lists_dict.get(str(list_id)) for list_id in s.student_lists] if l], } students_data = user_data.get_students_data() students = map(student_to_dict, students_data) students.sort(key=lambda s: s['nickname']) child_accounts = map(student_to_dict, user_data.get_child_users()) template_values = { 'students': students, 'child_accounts': child_accounts, 'child_account_keyset': set([c['key'] for c in child_accounts]), 'students_json': json.dumps(students), 'student_lists': student_lists_list, 'student_lists_json': json.dumps(student_lists_list), 'invalid_student': invalid_student, 'coach_requests': coach_requests, 'coach_requests_json': json.dumps(coach_requests), 'selected_nav_link': 'coach', 'email': user_data.email, } self.render_jinja2_template('viewstudentlists.html', template_values)
def get(self): user_data = UserData.current() user_video_css = video_models.UserVideoCss.get_for_user_data(user_data) self.response.headers['Content-Type'] = 'text/css' if user_video_css.version == user_data.uservideocss_version: # Don't cache if there's a version mismatch and update isn't finished self.response.headers['Cache-Control'] = 'public,max-age=1000000' self.response.out.write(user_video_css.video_css)
def get(self): user_data = UserData.current() user_video_css = video_models.UserVideoCss.get_for_user_data(user_data) self.response.headers['Content-Type'] = 'text/css' if user_video_css.version == user_data.uservideocss_version: # Don't cache if there's a version mismatch and update isn't finished self.response.headers['Cache-Control'] = 'public,max-age=1000000' self.response.out.write(user_video_css.video_css)
def get(self): coach = UserData.current() self.render_jinja2_template('coach_resources/view_demo.html', { "selected_id": "demo", "base_url": "/toolkit", "not_in_toolkit_format": 1, "is_logged_in": json.dumps(not coach.is_phantom if coach else False), })
def do_request(self, student, coach, redirect_to): if not UserData.current(): self.redirect(url_util.create_login_url(self.request.uri)) return if student and coach: self.remove_student_from_coach(student, coach) if not self.is_ajax_request(): self.redirect(redirect_to)
def do_request(self, student, coach, redirect_to): if not UserData.current(): self.redirect(util.create_login_url(self.request.uri)) return if student and coach: self.remove_student_from_coach(student, coach) if not self.is_ajax_request(): self.redirect(redirect_to)
def get_profile_target_user_data(self): coach = UserData.current() if coach: user_override = self.request_user_data("coach_email") if user_override and user_override.are_students_visible_to(coach): # Only allow looking at a student list other than your own # if you are a dev, admin, or coworker. coach = user_override return coach
def get_profile_target_user_data(self): coach = UserData.current() if coach: user_override = self.request_user_data("coach_email") if user_override and user_override.are_students_visible_to(coach): # Only allow looking at a student list other than your own # if you are a dev, admin, or coworker. coach = user_override return coach
def get(self): template_values = {} user_data = UserData.current() if user_data is not None: return self.authenticated_response() else: template_values = { "authenticated" : False, } self.add_global_template_values(template_values) self.render_jinja2_template('summer/summer_process.html', template_values)
def get(self): coach = UserData.current() self.render_jinja2_template( 'coach_resources/view_demo.html', { "selected_id": "demo", "base_url": "/toolkit", "not_in_toolkit_format": 1, "is_logged_in": json.dumps(not coach.is_phantom if coach else False), })
def get(self): coach = UserData.current() if coach is not None: coach_email = coach.email is_profile_empty = not coach.has_students() else: coach_email = None is_profile_empty = True self.render_jinja2_template('coach_resources/view_resources.html', { 'selected_id': 'coach-resources', 'coach_email': coach_email, 'is_profile_empty': is_profile_empty, })
def get(self): user_data = UserData.current() from exercises.exercise_util import exercise_graph_dict_json context = { 'graph_dict_data': exercise_graph_dict_json(user_data), 'user_data': user_data, 'map_coords': json.dumps(deserializeMapCoords(user_data.map_coords)), # Get pregenerated library content from our in-memory/memcache # two-layer cache 'library_content': library_content_html(), } self.render_jinja2_template("goals/creategoal.html", context)
def get(self): coach = UserData.current() if coach is not None: coach_email = coach.email is_profile_empty = not coach.has_students() else: coach_email = None is_profile_empty = True self.render_jinja2_template( 'coach_resources/view_resources.html', { 'selected_id': 'coach-resources', 'coach_email': coach_email, 'is_profile_empty': is_profile_empty, })
def post(self): user_data = UserData.current() user_data_student = self.request_student_user_data() if user_data_student: if not user_data_student.is_coached_by(user_data): coach_request = CoachRequest.get_or_insert_for(user_data, user_data_student) if coach_request: if not self.is_ajax_request(): self.redirect("/students") return if self.is_ajax_request(): self.response.set_status(404) else: self.redirect("/students?invalid_student=1")
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 get(self): user_data = UserData.current() sort = self.request_int("sort", default=VotingSortOrder.HighestPointsFirst) if user_data: user_data.question_sort_order = sort user_data.put() readable_id = self.request_string("readable_id", default="") topic_title = self.request_string("topic_title", default="") if readable_id and topic_title: self.redirect("/video/%s?topic=%s&sort=%s" % ( urllib.quote(readable_id), urllib.quote(topic_title), sort)) else: self.redirect("/")
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 get(self): template_values = {} user_data = UserData.current() if user_data is not None: template_values = self.authenticated_response() if template_values is None: self.redirect("/summer/application") return else: template_values = { "authenticated" : False, } self.add_global_template_values(template_values) self.render_jinja2_template('summer/summer_status.html', template_values)
def get(self): user_data = UserData.current() sort = self.request_int("sort", default=VotingSortOrder.HighestPointsFirst) if user_data: user_data.question_sort_order = sort user_data.put() readable_id = self.request_string("readable_id", default="") topic_title = self.request_string("topic_title", default="") if readable_id and topic_title: self.redirect("/video/%s?topic=%s&sort=%s" % ( urllib.quote(readable_id), urllib.quote(topic_title), sort)) else: self.redirect("/")
def get(self): user_data = UserData.current() user_exercise_graph = UserExerciseGraph.get(user_data) from exercises.exercise_util import exercise_graph_dict_json context = { 'graph_dict_data': exercise_graph_dict_json( user_data, user_exercise_graph), 'user_data': user_data, 'map_coords': json.dumps( deserializeMapCoords(user_data.map_coords)), # Get pregenerated library content from our in-memory/memcache # two-layer cache 'library_content': library_content_html(), } self.render_jinja2_template("goals/creategoal.html", context)
def authenticated_response(self): user_data = UserData.current() user_email = user_data.user_email nickname = "" if facebook_util.is_facebook_user_id(user_email): nickname = facebook_util.get_facebook_nickname(user_email) query = SummerStudent.all() query.filter('email = ', user_email) student = query.get() students = [] is_parent = False if student is None: query = SummerParentData.all() query.filter('email = ', user_email) parent = query.get() if parent is None: return None is_parent = True number_of_students = 0 for student_key in parent.students: student = SummerStudent.get(student_key) students.append(student) if student.accepted and not student.tuition_paid: number_of_students += 1 else: number_of_students = 1 students.append(student) template_values = { "authenticated" : True, "is_parent" : is_parent, "students" : students, "number_of_students": json.dumps(number_of_students), "student" : students[0], "user_email" : user_email, "nickname" : nickname, } return template_values
def get(self): user_data = UserData.current() user_data_override = self.request_user_data("coach_email") if user_util.is_current_user_developer() and user_data_override: user_data = user_data_override invalid_student = self.request_bool("invalid_student", default = False) coach_requests = [x.student_requested_data.email for x in CoachRequest.get_for_coach(user_data) if x.student_requested_data] student_lists_models = StudentList.get_for_coach(user_data.key()) student_lists_list = []; for student_list in student_lists_models: student_lists_list.append({ 'key': str(student_list.key()), 'name': student_list.name, }) student_lists_dict = dict((g['key'], g) for g in student_lists_list) students_data = user_data.get_students_data() students = map(lambda s: { 'key': str(s.key()), 'email': s.email, 'nickname': s.nickname, 'profile_root': s.profile_root, 'studentLists': [l for l in [student_lists_dict.get(str(list_id)) for list_id in s.student_lists] if l], }, students_data) students.sort(key=lambda s: s['nickname']) template_values = { 'students': students, 'students_json': json.dumps(students), 'student_lists': student_lists_list, 'student_lists_json': json.dumps(student_lists_list), 'invalid_student': invalid_student, 'coach_requests': coach_requests, 'coach_requests_json': json.dumps(coach_requests), 'selected_nav_link': 'coach', 'email': user_data.email, } self.render_jinja2_template('viewstudentlists.html', template_values)
def get(self): """ Only used when a coach deletes a request in studentlists.js. """ user_data = UserData.current() accept_coach = self.request_bool("accept", default = False) user_data_student = self.request_student_user_data() if user_data_student: user_data_coach = user_data if (user_data_coach and not user_data_student.is_coached_by(user_data_coach)): coach_request = CoachRequest.get_for(user_data_coach, user_data_student) if coach_request: coach_request.delete() if user_data.key_email == user_data_student.key_email and accept_coach: user_data_student.coaches.append(user_data_coach.key_email) user_data_student.put() if not self.is_ajax_request(): self.redirect("/coaches")
def authenticated_response(self): user_data = UserData.current() user_email = user_data.user_email nickname = "" if facebook_util.is_facebook_user_id(user_email): nickname = facebook_util.get_facebook_nickname(user_email) query = SummerStudent.all() query.filter('email = ', user_email) student = query.get() students = [] is_parent = False if student is None: query = SummerParentData.all() query.filter('email = ', user_email) parent = query.get() if parent is None: return None is_parent = True for student_key in parent.students: students.append(SummerStudent.get(student_key)) else: students.append(student) template_values = { "authenticated" : True, "is_parent" : is_parent, "students" : students, "user_email" : user_email, "nickname" : nickname, } return template_values
def authenticated_response(self): user_data = UserData.current() user_email = user_data.user_email template_values = { "authenticated" : True, "user_email" : user_email, } sio = StringIO.StringIO() sw = csv.writer(sio) properties = [p for p in SummerStudent().properties()] sw.writerow(properties) for student in SummerStudent.all().fetch(5000): try: row = [] for p in properties: v = getattr(student, p) if isinstance(v, basestring): v = v.encode("utf-8") row.append(v) sw.writerow(row) except Exception, e: logging.error("Unable to write row for student %s" % student.email)
def get(self): from exercises import attempt_problem login_user = UserData.current() exercises_list = [exercise for exercise in Exercise.all()] videos_list = [video for video in Video.all()] user_count = self.request_int('users', 5) for user_id in xrange(0, user_count): # Create a new user first_name = random.choice(CreateRandomGoalData.first_names) last_name = random.choice(CreateRandomGoalData.last_names) nickname = "%s %s" % (first_name, last_name) email = 'test_%i@automatedrandomdata' % user_id user = users.User(email) logging.info("Creating user %s: (%i/%i)" % (nickname, user_id + 1, user_count)) user_data = UserData.get_or_insert( key_name="test_user_%i" % user_id, user=user, current_user=user, user_id=str(user_id), moderator=False, last_login=datetime.now(), proficient_exercises=[], suggested_exercises=[], need_to_reassess=True, points=0, coaches=[login_user.user_email], user_email=email, user_nickname=nickname, ) user_data.put() # Delete user exercise & video progress query = UserExercise.all() query.filter('user = '******'user = '******'type': 'GoalObjectiveExerciseProficiency', 'exercise': random.choice(exercises_list) }) for objective in xrange(1, random.randint(2, 4)): obj_descriptors.append({ 'type': 'GoalObjectiveWatchVideo', 'video': random.choice(videos_list) }) title = first_name + "'s Goal #" + str(goal_idx) logging.info("Creating goal " + title) objectives = GoalObjective.from_descriptors( obj_descriptors, user_data) goal = Goal(parent=user_data, title=title, objectives=objectives) user_data.save_goal(goal) for objective in obj_descriptors: if objective['type'] == 'GoalObjectiveExerciseProficiency': user_exercise = user_data.get_or_insert_exercise( objective['exercise']) chooser = random.randint(1, 120) if chooser >= 60: continue elif chooser > 15: count = 1 hints = 0 elif chooser < 7: count = 20 hints = 0 else: count = 25 hints = 1 logging.info( "Starting exercise: %s (%i problems, %i hints)" % (objective['exercise'].name, count, hints * count)) for i in xrange(1, count): attempt_problem(user_data, user_exercise, i, 1, 'TEST', 'TEST', 'TEST', True, hints, 0, False, False, "TEST", '0.0.0.0') elif objective['type'] == 'GoalObjectiveWatchVideo': seconds = random.randint(1, 1200) logging.info("Watching %i seconds of video %s" % (seconds, objective['video'].title)) VideoLog.add_entry(user_data, objective['video'], seconds, 0, detect_cheat=False) self.response.out.write('OK')
def get_coach_student_and_student_list(request_handler): coach = UserData.current() student_list = get_student_list(coach, request_handler.request_string("list_id")) student = get_student(coach, request_handler) return (coach, student, student_list)
def get_coach_student_and_student_list(request_handler): coach = UserData.current() student_list = get_student_list(coach, request_handler.request_string("list_id")) student = get_student(coach, request_handler) return (coach, student, student_list)
def get(self, email_or_username=None, subpath=None): """Render a student profile. Keyword arguments: email_or_username -- matches the first grouping in /profile/(.+?)/(.*) subpath -- matches the second grouping, and is ignored server-side, but is used to route client-side """ current_user_data = UserData.current() or UserData.pre_phantom() if current_user_data.is_pre_phantom and email_or_username is None: # Pre-phantom users don't have any profiles - just redirect them # to the homepage if they try to view their own. self.redirect(util.create_login_url(self.request.uri)) return if not email_or_username: user_data = current_user_data elif email_or_username == 'nouser' and current_user_data.is_phantom: user_data = current_user_data else: user_data = UserData.get_from_url_segment(email_or_username) if (user_models.UniqueUsername.is_valid_username(email_or_username) and user_data and user_data.username and user_data.username != email_or_username): # The path segment is a username and resolved to the user, # but is not actually their canonical name. Redirect to the # canonical version. if subpath: self.redirect("/profile/%s/%s" % (user_data.username, subpath)) else: self.redirect("/profile/%s" % user_data.username) return profile = UserProfile.from_user(user_data, current_user_data) if profile is None: self.render_jinja2_template('noprofile.html', {}) return is_self = user_data.user_id == current_user_data.user_id show_intro = False if is_self: promo_record = promo_record_model.PromoRecord.get_for_values( "New Profile Promo", user_data.user_id) if promo_record is None: # The user has never seen the new profile page! Show a tour. if subpath: # But if they're not on the root profile page, force them. self.redirect("/profile") return show_intro = True promo_record_model.PromoRecord.record_promo( "New Profile Promo", user_data.user_id, skip_check=True) has_full_access = is_self or user_data.is_visible_to(current_user_data) tz_offset = self.request_int("tz_offset", default=0) template_values = { 'show_intro': show_intro, 'profile': profile, 'tz_offset': tz_offset, 'count_videos': setting_model.Setting.count_videos(), 'count_exercises': exercise_models.Exercise.get_count(), 'user_data_student': user_data if has_full_access else None, 'profile_root': user_data.profile_root, "view": self.request_string("view", default=""), } self.render_jinja2_template('viewprofile.html', template_values)
def get(self, username=None, subpath=None): """Render a student profile. Keyword arguments: email_or_username -- matches the first grouping in /profile/(.+?)/(.*) subpath -- matches the second grouping, and is ignored server-side, but is used to route client-side """ current_user_data = UserData.current() or UserData.pre_phantom() if current_user_data.is_pre_phantom and username is None: # Pre-phantom users don't have any profiles - just redirect them # to the homepage if they try to view their own. self.redirect(url_util.create_login_url(self.request.uri)) return if not current_user_data.is_phantom and username == 'nouser': # If anybody has bookmarked, or gets redirected to, or otherwise # finds their way to /profile/nouser while they're logged in, just # redirect them to their actual profile. # # /profile/nouser is only sensible for phantom users and is never # used to look at another user's profile. self.redirect(current_user_data.profile_root) return if not username: user_data = current_user_data elif username == 'nouser' and current_user_data.is_phantom: user_data = current_user_data else: user_data = UserData.get_from_url_segment(username) if (user_models.UniqueUsername.is_valid_username(username) and user_data and user_data.username and user_data.username != username): # The path segment is a username and resolved to the user, # but is not actually their canonical name. Redirect to the # canonical version. if subpath: self.redirect("/profile/%s/%s" % (user_data.username, subpath)) else: self.redirect("/profile/%s" % user_data.username) return profile = util_profile.UserProfile.from_user(user_data, current_user_data) if profile is None: self.render_jinja2_template('noprofile.html', {}) return is_self = user_data.user_id == current_user_data.user_id show_intro = False show_discussion_intro = False if is_self: promo_record = promo_record_model.PromoRecord.get_for_values( "New Profile Promo", user_data.user_id) if promo_record is None: # The user has never seen the new profile page! Show a tour. if subpath: # But if they're not on the root profile page, force them. self.redirect("/profile") return show_intro = True promo_record_model.PromoRecord.record_promo( "New Profile Promo", user_data.user_id, skip_check=True) # We also mark the "new discussion promo" as having been seen, # because it is a sub-set of the full tour, and new users don't # need to see it twice. promo_record_model.PromoRecord.record_promo( "New Discussion Promo", user_data.user_id, skip_check=True) else: # The user has already seen the original profile page tour, but # not necessarily the "new discussion tab" tour. discussion_promo_record = ( promo_record_model.PromoRecord.get_for_values( "New Discussion Promo", user_data.user_id)) if discussion_promo_record is None: # The user hasn't seen the new discussion promo. show_discussion_intro = True promo_record_model.PromoRecord.record_promo( "New Discussion Promo", user_data.user_id, skip_check=True) # This is the main capability bit - it indicates whether or not the # actor can view exercise, video, and goals data on the site for the # current profile. is_activity_visible = user_data.is_visible_to(current_user_data) # Resolve any other miscellaneous capabilities. This may need to be # changed if ACLing gets signicantly more complicated. if is_self: is_settings_available = not user_data.is_child_account() is_discussion_available = not user_data.is_child_account() is_coach_list_readable = True is_coach_list_writable = user_data.can_modify_coaches() else: is_actor_parent = ParentChildPair.is_pair( parent_user_data=current_user_data, child_user_data=user_data) is_settings_available = is_actor_parent is_discussion_available = (is_activity_visible and not user_data.is_child_account()) is_coach_list_readable = is_actor_parent is_coach_list_writable = False tz_offset = self.request_int("tz_offset", default=0) # If profile is public and / or activity is visible, # include all the relevant data. if profile.is_public or is_activity_visible: template_values = { 'show_intro': show_intro, 'show_discussion_intro': show_discussion_intro, 'profile': profile, 'tz_offset': tz_offset, 'count_videos': setting_model.Setting.count_videos(), 'count_exercises': exercise_models.Exercise.get_count(), 'user_data_student': user_data if is_activity_visible else None, 'profile_root': user_data.profile_root, 'is_settings_available': is_settings_available, 'is_coach_list_readable': is_coach_list_readable, 'is_coach_list_writable': is_coach_list_writable, 'is_discussion_available': is_discussion_available, 'view': self.request_string("view", default=""), } # For private profiles else: template_values = { 'profile': profile, 'profile_root': profile.profile_root, 'user_data_student': None, 'count_videos': 0, 'count_exercises': 0 } self.render_jinja2_template('viewprofile.html', template_values)
def get(self): user_data = UserData.current() user_data_override = self.request_user_data("coach_email") if user_util.is_current_user_developer() and user_data_override: user_data = user_data_override invalid_student = self.request_bool("invalid_student", default=False) coach_requests = [ req.student_requested_identifier for req in CoachRequest.get_for_coach(user_data) if req.student_requested_data ] student_lists_models = StudentList.get_for_coach(user_data.key()) student_lists_list = [] for student_list in student_lists_models: student_lists_list.append({ 'key': str(student_list.key()), 'name': student_list.name, }) student_lists_dict = dict((g['key'], g) for g in student_lists_list) def student_to_dict(s): """Convert the UserData s to a dictionary for rendering.""" return { 'key': str(s.key()), 'email': s.email, 'username': s.username, # Note that child users don't have an email. 'identifier': s.username or s.email, 'nickname': s.nickname, 'profile_root': s.profile_root, 'can_modify_coaches': s.can_modify_coaches(), 'studentLists': [ l for l in [ student_lists_dict.get(str(list_id)) for list_id in s.student_lists ] if l ], } students_data = user_data.get_students_data() students = map(student_to_dict, students_data) students.sort(key=lambda s: s['nickname']) child_accounts = map(student_to_dict, user_data.get_child_users()) template_values = { 'students': students, 'child_accounts': child_accounts, 'child_account_keyset': set([c['key'] for c in child_accounts]), 'students_json': json.dumps(students), 'student_lists': student_lists_list, 'student_lists_json': json.dumps(student_lists_list), 'invalid_student': invalid_student, 'coach_requests': coach_requests, 'coach_requests_json': json.dumps(coach_requests), 'selected_nav_link': 'coach', 'email': user_data.email, } self.render_jinja2_template('viewstudentlists.html', template_values)
def get(self): """ Redirect legacy /coaches to profile page's coaches tab. """ user_data = UserData.current() self.redirect(user_data.profile_root + "coaches")
def get(self): return self.do_request(self.request_student_user_data(), UserData.current(), "/students")
def get_student_list(self, coach): student_lists = StudentList.get_for_coach(coach.key()) _, actual_list = get_last_student_list( self, student_lists, coach.key() == UserData.current().key()) return actual_list
def get_student_list(self, coach): student_lists = StudentList.get_for_coach(coach.key()) current_user_is_coach = (coach.key() == UserData.current().key()) _, actual_list = util_profile.get_last_student_list(self, student_lists, current_user_is_coach) return actual_list
def get(self): template_values = {} user_data = UserData.current() if user_data is not None: user_email = user_data.user_email nickname = "" if facebook_util.is_facebook_user_id(user_email): nickname = facebook_util.get_facebook_nickname(user_email) application_filled = self.request.get('application_filled') make_payment = self.request.get('make_payment') if make_payment: student_email = self.request.get('student_email') is_parent_str = self.request.get('is_parent') query = SummerStudent.all() query.filter('email = ', student_email) student = query.get() if student is None: output_str = 'Please <a href="/summer/application">apply</a> first' % student_email self.response.out.write(output_str) return if student.processing_fee_paid: self.redirect("/summer/application-status") return query = SummerParentData.all() query.filter('email = ', student.parent_email) parent = query.get() if parent is None: logging.error("Unexpected NULL parent for student <%s> with parent <%s>" % (student_email, student.parent_email)) if is_parent_str == "True": is_parent = True else: is_parent = False payee_phone_a = "" payee_phone_b = "" payee_phone_c = "" phone_parts = parent.phone.split("-") if phone_parts is not None: payee_phone_a = phone_parts[0] payee_phone_b = phone_parts[1] payee_phone_c = phone_parts[2] template_values = { "authenticated" : True, "make_payment" : True, "is_parent" : is_parent, "is_parent_js" : json.dumps(is_parent), "student" : student, "student_js" : json.dumps(student.to_dict()), "payee" : parent, "payee_phone_a" : payee_phone_a, "payee_phone_b" : payee_phone_b, "payee_phone_c" : payee_phone_c, "user_email" : user_email, "nickname" : nickname, } elif not application_filled: template_values = self.authenticated_response() else: first_name = self.request.get('first_name') student_email = self.request.get('student_email') query = SummerStudent.all() query.filter('email = ', student_email) student = query.get() if student is None: student = SummerStudent() student.email = student_email student.applier_email = user_email student.processing_fee_paid = False student.tuition_paid = False student.first_name = first_name student.last_name = self.request.get('last_name') student.date_of_birth = self.request.get('date_of_birth') if self.request.get('gender') == "Female": student.is_female = True else: student.is_female = False student.grade = self.request.get('grade') student.school = self.request.get('school') student.school_zipcode = self.request.get('school_zip') student.session_1 = self.request.get('session_1') student.session_2 = self.request.get('session_2') student.session_3 = self.request.get('session_3') session_choices = { "0":[], "1":[], "2":[], "3":[] } session_choices[student.session_1].append("Session 1") session_choices[student.session_2].append("Session 2") session_choices[student.session_3].append("Session 3") student.no_choice = session_choices["0"] student.first_choice = session_choices["1"] student.second_choice = session_choices["2"] student.third_choice = session_choices["3"] student.answer_why = self.request.get('answer_why') student.answer_how = self.request.get('answer_how') student.processing_fee = self.request.get('fee') student.tuition = 'TBD' student.application_year = '2012' student.application_status = 'Processing' if user_email == student_email: is_parent = False student.self_applied = True else: is_parent = True student.self_applied = False student.parent_relation = self.request.get('relation') student.parent_email = self.request.get('parent_email') student.put() query = SummerParentData.all() query.filter('email = ', student.parent_email) parent = query.get() if parent is None: parent = SummerParentData() parent.email = student.parent_email parent.first_name = self.request.get('parent_first_name') parent.last_name = self.request.get('parent_last_name') parent.address_1 = self.request.get('parent_address_1') parent.address_2 = self.request.get('parent_address_2') parent.city = self.request.get('parent_city') parent.state = self.request.get('parent_state') parent.zipcode = self.request.get('parent_zip') parent.country = self.request.get('parent_country') parent.phone = self.request.get('parent_phone') parent.comments = self.request.get('parent_comments') if student.key() not in parent.students: parent.students.append(student.key()) parent.put() if student.processing_fee_paid: self.redirect("/summer/application-status") return payee_phone_a = "" payee_phone_b = "" payee_phone_c = "" phone_parts = parent.phone.split("-") if phone_parts is not None: payee_phone_a = phone_parts[0] payee_phone_b = phone_parts[1] payee_phone_c = phone_parts[2] # Only send email if the user's email is a valid one if not facebook_util.is_facebook_user_id(parent.email): mail.send_mail( \ sender = FROM_EMAIL, \ to = parent.email, \ subject = "Khan Academy Discovery Lab Application", \ body = """Dear %s, We have received your application for %s %s for the Khan Academy Discovery Lab 2012. Please ensure you have paid the $5.00 processing fee for the application. We will notify you about the status of the application as soon as possible, no later than March 1st, 2012. You can always check the status of the application any time at http://www.khanacademy.org/summer/application-status. Thank you! Khan Academy Discovery Lab""" % (parent.first_name, student.first_name, student.last_name)) template_values = { "authenticated" : True, "make_payment" : True, "is_parent" : is_parent, "is_parent_js" : json.dumps(is_parent), "student" : student, "student_js" : json.dumps(student.to_dict()), "parent" : parent, "parent_js" : json.dumps(parent.to_dict()), "payee" : parent, "payee_phone_a" : payee_phone_a, "payee_phone_b" : payee_phone_b, "payee_phone_c" : payee_phone_c, "user_email" : user_email, "nickname" : nickname, } else: template_values = { "authenticated" : False, "applied" : False } self.add_global_template_values(template_values) self.render_jinja2_template('summer/summer.html', template_values)
def get_template(self, template_file, additional_dirs=None): """Computes location of template files for the current namespace.""" self.template_value[COURSE_INFO_KEY] = self.app_context.get_environ() self.template_value['is_course_admin'] = Roles.is_course_admin( self.app_context) self.template_value[ 'is_read_write_course'] = self.app_context.fs.is_read_write() self.template_value['is_super_admin'] = Roles.is_super_admin() self.template_value[COURSE_BASE_KEY] = self.get_base_href(self) template_environ = self.app_context.get_template_environ( self.template_value[COURSE_INFO_KEY]['course']['locale'], additional_dirs) import khan.util as util import khan.templatefilters as templatefilters import badges.templatetags import avatars.templatetags import js_css_packages.templatetags import app import templatetags import user_models template_environ.filters['gcb_tags'] = jinja_utils.get_gcb_tags_filter( self) template_environ.filters[ 'thousands_separated'] = util.thousands_separated_number template_environ.filters['pluralize'] = templatefilters.pluralize template_environ.filters["escapejs"] = templatefilters.escapejs template_environ.globals["badges"] = badges.templatetags template_environ.globals["avatars"] = avatars.templatetags template_environ.globals[ "js_css_packages"] = js_css_packages.templatetags template_environ.globals["App"] = app.App template_environ.globals["templatetags"] = templatetags from user_models import StudentList, UserData, ParentChildPair import logging current_user_data = UserData.current(True) #logging.error("Current user: %s" % current_user_data) #logging.error("Nickname: %s" % current_user_data.nickname) #logging.error("Username: %s" % current_user_data.username) #logging.error("UserNickname: %s" % current_user_data.user_nickname) #logging.error("UserEmail: %s" % current_user_data.user_email) if current_user_data: template_environ.globals[ "username"] = current_user_data.nickname or current_user_data.username or current_user_data.user_nickname or current_user_data.user_email else: template_environ.globals["username"] = "" #template_environ['environment_args'] = {'autoescape' : False} # template_environ["filters"] = { # 'gcb_tags': jinja_utils.get_gcb_tags_filter(self), # #"thousands_separated": util.thousands_separated_number, # } # template_environ["globals"] = { # "templatetags": templatetags, # "profiles": profiles.templatetags, # "avatars": avatars.templatetags, # "badges": badges.templatetags, # "phantom_users": phantom_users.templatetags, ## "gae_mini_profiler": gae_mini_profiler.templatetags, ## "xsrf": api.auth.xsrf, ## "UserData": UserData, ## "json": json, ## "App": App, ## "handlebars_template": handlebars.render.render_from_jinja, ## "gandalf": gandalf.bridge.gandalf, # } return template_environ.get_template(template_file)
def get(self): return self.do_request( self.request_student_user_data(), UserData.current(), "/students" )
def get(self, email_or_username=None, subpath=None): """Render a student profile. Keyword arguments: email_or_username -- matches the first grouping in /profile/(.+?)/(.*) subpath -- matches the second grouping, and is ignored server-side, but is used to route client-side """ current_user_data = UserData.current() or UserData.pre_phantom() if current_user_data.is_pre_phantom and email_or_username is None: # Pre-phantom users don't have any profiles - just redirect them # to the homepage if they try to view their own. self.redirect(util.create_login_url(self.request.uri)) return if not email_or_username: user_data = current_user_data elif email_or_username == 'nouser' and current_user_data.is_phantom: user_data = current_user_data else: user_data = UserData.get_from_url_segment(email_or_username) if (user_models.UniqueUsername.is_valid_username(email_or_username) and user_data and user_data.username and user_data.username != email_or_username): # The path segment is a username and resolved to the user, # but is not actually their canonical name. Redirect to the # canonical version. if subpath: self.redirect("/profile/%s/%s" % (user_data.username, subpath)) else: self.redirect("/profile/%s" % user_data.username) return profile = UserProfile.from_user(user_data, current_user_data) if profile is None: self.render_jinja2_template('noprofile.html', {}) return is_self = user_data.user_id == current_user_data.user_id show_intro = False if is_self: promo_record = promo_record_model.PromoRecord.get_for_values( "New Profile Promo", user_data.user_id) if promo_record is None: # The user has never seen the new profile page! Show a tour. if subpath: # But if they're not on the root profile page, force them. self.redirect("/profile") return show_intro = True promo_record_model.PromoRecord.record_promo("New Profile Promo", user_data.user_id, skip_check=True) has_full_access = is_self or user_data.is_visible_to(current_user_data) tz_offset = self.request_int("tz_offset", default=0) template_values = { 'show_intro': show_intro, 'profile': profile, 'tz_offset': tz_offset, 'count_videos': setting_model.Setting.count_videos(), 'count_exercises': exercise_models.Exercise.get_count(), 'user_data_student': user_data if has_full_access else None, 'profile_root': user_data.profile_root, "view": self.request_string("view", default=""), } self.render_jinja2_template('viewprofile.html', template_values)
def get(self): """ Redirect legacy /coaches to profile page's coaches tab. """ user_data = UserData.current() self.redirect(user_data.profile_root + "coaches")
def get_student_list(self, coach): student_lists = StudentList.get_for_coach(coach.key()) _, actual_list = get_last_student_list(self, student_lists, coach.key()==UserData.current().key()) return actual_list