def get(self): user = util.get_current_user() if user: coach = user coach_email = self.request_string("coach_email") if users.is_current_user_admin() and coach_email: # Site administrators can look at any class profile coach = users.User(email=coach_email) user_data_coach = models.UserData.get_or_insert_for(coach) students_data = user_data_coach.get_students_data() class_points = 0 if students_data: class_points = reduce(lambda a,b: a + b, map(lambda student_data: student_data.points, students_data)) dict_students = map(lambda student_data: { "email": student_data.user.email(), "nickname": util.get_nickname_for(student_data.user), }, students_data) selected_graph_type = self.request_string("selected_graph_type") or ClassProgressReportGraph.GRAPH_TYPE 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=""))) # Sort students alphabetically and sort into 4 chunked up columns for easy table html dict_students_sorted = sorted(dict_students, key=lambda dict_student:dict_student["nickname"]) students_per_row = 4 students_per_col = max(1, len(dict_students_sorted) / students_per_row) list_cols = [[], [], [], []] list_students_columnized = [] for ix in range(0, len(dict_students_sorted)): dict_student = dict_students_sorted[ix] list_cols[(ix / students_per_col) % students_per_row].append(dict_student) for ix in range(0, len(dict_students_sorted)): dict_student = list_cols[ix % students_per_row][(ix / students_per_row) % students_per_col] list_students_columnized.append(dict_student) template_values = { 'coach': coach, 'coach_email': coach.email(), 'coach_nickname': util.get_nickname_for(coach), 'dict_students': dict_students, 'students_per_row': students_per_row, 'list_students_columnized': list_students_columnized, 'count_students': len(dict_students), 'class_points': class_points, 'selected_graph_type': selected_graph_type, 'initial_graph_url': initial_graph_url, 'exercises': models.Exercise.get_all_use_cache(), 'is_profile_empty': len(dict_students) <= 0, 'selected_nav_link': 'coach', } self.render_template('viewclassprofile.html', template_values) else: self.redirect(util.create_login_url(self.request.uri))
def class_exercises_over_time_graph_context(user_data): if not user_data: return {} user = user_data.user end_date = None student_emails = user_data.get_students() dict_student_exercises = {} dict_exercises = {} for student_email in student_emails: student = users.User(student_email) student_nickname = util.get_nickname_for(student) dict_student_exercises[student_nickname] = { "nickname": student_nickname, "email": student.email(), "exercises": [] } query = models.UserExercise.all() query.filter('user ='******'proficient_date >', None) query.order('proficient_date') for user_exercise in query: days_until_proficient = (user_exercise.proficient_date - user_data.joined).days proficient_date = user_exercise.proficient_date.strftime('%m/%d/%Y') data = ExerciseData(student_nickname, user_exercise.exercise, user_exercise.exercise, days_until_proficient, proficient_date) dict_student_exercises[student_nickname]["exercises"].append(data) end_date = user_exercise.proficient_date return { 'dict_student_exercises': dict_student_exercises }
def get(self): user = util.get_current_user() if user: student = user user_data_student = None student_email = self.request_string("student_email") if student_email and student_email != student.email(): student_override = users.User(email=student_email) user_data_student = models.UserData.get_or_insert_for(student_override) if (not users.is_current_user_admin()) and user.email() not in user_data_student.coaches and user.email().lower() not in user_data_student.coaches: # If current user isn't an admin or student's coach, they can't look at anything other than their own profile. self.redirect("/profile") else: # Allow access to this student's profile student = student_override if not user_data_student: user_data_student = models.UserData.get_or_insert_for(student) user_badges = util_badges.get_user_badges(student) selected_graph_type = self.request_string("selected_graph_type") or ActivityGraph.GRAPH_TYPE initial_graph_url = "/profile/graph/%s?student_email=%s&%s" % (selected_graph_type, urllib.quote(student.email()), urllib.unquote(self.request_string("graph_query_params", default=""))) tz_offset = self.request_int("tz_offset", default=0) template_values = { 'student': student, 'student_nickname': util.get_nickname_for(student), 'selected_graph_type': selected_graph_type, 'initial_graph_url': initial_graph_url, 'tz_offset': tz_offset, 'student_points': user_data_student.points, 'count_videos': models.Setting.count_videos(), 'count_videos_completed': user_data_student.get_videos_completed(), 'count_exercises': models.Exercise.get_count(), 'count_exercises_proficient': len(user_data_student.all_proficient_exercises), 'badge_collections': user_badges['badge_collections'], 'user_badges_bronze': user_badges['bronze_badges'], 'user_badges_silver': user_badges['silver_badges'], 'user_badges_gold': user_badges['gold_badges'], 'user_badges_platinum': user_badges['platinum_badges'], 'user_badges_diamond': user_badges['diamond_badges'], 'user_badges_master': user_badges['user_badges_master'], 'user_badges': [user_badges['bronze_badges'], user_badges['silver_badges'], user_badges['gold_badges'], user_badges['platinum_badges'], user_badges['diamond_badges'],user_badges['user_badges_master']], "show_badge_frequencies": self.request_bool("show_badge_frequencies", default=False), } self.render_template('viewprofile.html', template_values) else: self.redirect(util.create_login_url(self.request.uri))
def get(self): user = util.get_current_user() if not user: self.redirect(util.create_login_url(self.request.uri)) return answers = feedback_answers_for_user(user) dict_videos = {} dict_answers = {} for answer in answers: video = answer.first_target() if video == None or type(video).__name__ != "Video": continue video_key = video.key() dict_videos[video_key] = video if dict_answers.has_key(video_key): dict_answers[video_key].append(answer) else: dict_answers[video_key] = [answer] videos = sorted(dict_videos.values(), key=lambda video: video.playlists[0] + video.title) user_data = models.UserData.get_for_current_user() context = { "App": App, "points": user_data.points, "username": get_nickname_for(user), "email": user.email(), "login_url": util.create_login_url(self.request.uri), "logout_url": users.create_logout_url(self.request.uri), "videos": videos, "dict_answers": dict_answers } self.render_template('discussion/video_feedback_notification_list.html', context)
def class_time_graph_context(user_data, dt_utc, tz_offset): if not user_data: return {} user = user_data.user student_emails = user_data.get_students() classtime_table = None classtime_analyzer = classtime.ClassTimeAnalyzer(tz_offset) student_data = [] if classtime_analyzer.timezone_offset != -1: # If no timezone offset is specified, don't bother grabbing all the data # because we'll be redirecting back to here w/ timezone information. classtime_table = classtime_analyzer.get_classtime_table(student_emails, dt_utc) for student_email in student_emails: short_name = util.get_nickname_for(users.User(email=student_email)) if len(short_name) > 18: short_name = short_name[0:18] + "..." total_student_minutes = 0 if classtime_table is not None: total_student_minutes = classtime_table.get_student_total(student_email) student_data.append({ "name": short_name, "total_minutes": "~%.0f" % total_student_minutes }) return { "classtime_table": classtime_table, "coach_email": user.email(), "width": (60 * len(student_data)) + 120, "student_data": student_data, "is_graph_empty": len(classtime_table.rows) <= 0 }
def class_progress_report_graph_context(user_data): if not user_data: return {} user = user_data.user list_student_data = user_data.get_students_data() student_emails = map(lambda student_data: student_data.user.email(), list_student_data) class_exercises = get_class_exercises(list_student_data) exercises_all = models.Exercise.get_all_use_cache() exercises_found = [] for exercise in exercises_all: for student_email in student_emails: if class_exercises[student_email].has_key(exercise.name): exercises_found.append(exercise) break exercises_found_names = map(lambda exercise: exercise.name, exercises_found) exercise_data = {} for student_email in student_emails: student_data = class_exercises[student_email]["student_data"] if not student_data: continue name = util.get_nickname_for(student_data.user) i = 0 for exercise in exercises_found: exercise_name = exercise.name user_exercise = models.UserExercise() if class_exercises[student_email].has_key(exercise_name): user_exercise = class_exercises[student_email][exercise_name] if not exercise_data.has_key(exercise_name): exercise_data[exercise_name] = {} link = "/profile/graph/exerciseproblems?student_email=" + student_email + "&exercise_name=" + exercise_name status = "" hover = "" color = "transparent" if student_data.is_proficient_at(exercise_name): status = "Proficient" color = "proficient" if not student_data.is_explicitly_proficient_at(exercise_name): status = "Proficient (due to proficiency in a more advanced module)" elif user_exercise.exercise is not None and models.UserExercise.is_struggling_with( user_exercise, exercise): status = "Struggling" color = "struggling" elif user_exercise.exercise is not None and user_exercise.total_done > 0: status = "Started" color = "started" exercise_display = models.Exercise.to_display_name(exercise_name) short_name = name if len(short_name) > 18: short_name = short_name[0:18] + "..." if len(status) > 0: hover = "<b>%s</b><br/><br/><b>%s</b><br/><em><nobr>Status: %s</nobr></em><br/><em>Streak: %s</em><br/><em>Problems attempted: %s</em>" % ( escape(name), exercise_display, status, user_exercise.streak, user_exercise.total_done) exercise_data[exercise_name][student_email] = { "name": name, "short_name": short_name, "exercise_display": exercise_display, "link": link, "hover": hover, "color": color } i += 1 return { 'student_emails': student_emails, 'exercise_names': exercises_found_names, 'exercise_data': exercise_data, 'coach_email': user.email(), }
def exercise_problems_graph_context(user_data_student, exid): if not user_data_student: return {} user = user_data_student.user if not exid: exid = "addition_1" exercise = models.Exercise.get_by_name(exid) if not exercise: return {} user_exercise = user_data_student.get_or_insert_exercise(exercise) related_videos = exercise.related_videos() video_list = [] for exercise_video in related_videos: video_logs = models.VideoLog.get_for_user_and_video(user, exercise_video.key_for_video()) for video_log in video_logs: video_list.append(VideoPoint(video_log)) problem_list = [] problem_logs = models.ProblemLog.all().filter('user ='******'exercise =', exid).order("time_done") for problem_log in problem_logs: problem_list.append(ProblemPoint(problem_log)) max_problems_in_graph = 35 x_offset = 0 if len(problem_list) > max_problems_in_graph: x_offset = len(problem_list) - max_problems_in_graph problem_list = problem_list[-1 * max_problems_in_graph:] video_and_problem_list = [point for sublist in [video_list, problem_list] for point in sublist] video_and_problem_list = sorted(video_and_problem_list, lambda a,b: cmp(a.dt, b.dt)) video_point_last = None for video_or_problem in video_and_problem_list: if ProblemPoint.__name__ == video_or_problem.__class__.__name__: if video_point_last: video_or_problem.video_point = video_point_last video_point_last = None else: if video_point_last: video_point_last.seconds_watched += video_or_problem.seconds_watched video_point_last.dict_titles[video_or_problem.first_video_title] = True else: video_point_last = video_or_problem list_last_ten = problem_list[-10:] c_last_ten = len(list_last_ten) percent_last_ten_correct = 0 if c_last_ten: c_last_ten_correct = reduce(lambda a, b: a + b, map(lambda problem_point: 1 if problem_point.correct else 0, list_last_ten)) percent_last_ten_correct = int((float(c_last_ten_correct) / float(c_last_ten)) * 100) # Purposefully not showing any videos dangling after the last problem is done. # If video_point_last exists here, doing another problem will place it on the graph. x_axis_label = "Problem #" if x_offset: x_axis_label += " (Last %d problems)" % max_problems_in_graph return { 'exercise_display_name': models.Exercise.to_display_name(exid), 'exid': exid, 'problem_list': problem_list, 'streak': user_exercise.streak, 'longest_streak': user_exercise.longest_streak, 'percent_last_ten_correct': percent_last_ten_correct, 'student_nickname': util.get_nickname_for(user), 'x_offset': x_offset, 'x_axis_label': x_axis_label, }
def class_progress_report_graph_context(user_data): if not user_data: return {} user = user_data.user list_student_data = user_data.get_students_data() student_emails = map(lambda student_data: student_data.user.email(), list_student_data) class_exercises = get_class_exercises(list_student_data) exercises_all = models.Exercise.get_all_use_cache() exercises_found = [] for exercise in exercises_all: for student_email in student_emails: if class_exercises[student_email].has_key(exercise.name): exercises_found.append(exercise) break exercises_found_names = map(lambda exercise: exercise.name, exercises_found) exercise_data = {} for student_email in student_emails: student_data = class_exercises[student_email]["student_data"] if not student_data: continue name = util.get_nickname_for(student_data.user) i = 0 for exercise in exercises_found: exercise_name = exercise.name user_exercise = models.UserExercise() if class_exercises[student_email].has_key(exercise_name): user_exercise = class_exercises[student_email][exercise_name] if not exercise_data.has_key(exercise_name): exercise_data[exercise_name] = {} link = "/profile/graph/exerciseproblems?student_email="+student_email+"&exercise_name="+exercise_name status = "" hover = "" color = "transparent" if student_data.is_proficient_at(exercise_name): status = "Proficient" color = "proficient" if not student_data.is_explicitly_proficient_at(exercise_name): status = "Proficient (due to proficiency in a more advanced module)" elif user_exercise.exercise is not None and models.UserExercise.is_struggling_with(user_exercise, exercise): status = "Struggling" color = "struggling" elif user_exercise.exercise is not None and user_exercise.total_done > 0: status = "Started" color = "started" exercise_display = models.Exercise.to_display_name(exercise_name) short_name = name if len(short_name) > 18: short_name = short_name[0:18] + "..." if len(status) > 0: hover = "<b>%s</b><br/><br/><b>%s</b><br/><em><nobr>Status: %s</nobr></em><br/><em>Streak: %s</em><br/><em>Problems attempted: %s</em>" % (escape(name), exercise_display, status, user_exercise.streak, user_exercise.total_done) exercise_data[exercise_name][student_email] = { "name": name, "short_name": short_name, "exercise_display": exercise_display, "link": link, "hover": hover, "color": color } i += 1 return { 'student_emails': student_emails, 'exercise_names': exercises_found_names, 'exercise_data': exercise_data, 'coach_email': user.email(), }
def author_nickname(self): return get_nickname_for(self.author)
def exercise_problems_graph_context(user_data_student, exid): if not user_data_student: return {} user = user_data_student.user if not exid: exid = "addition_1" exercise = models.Exercise.get_by_name(exid) if not exercise: return {} user_exercise = user_data_student.get_or_insert_exercise(exercise) related_videos = exercise.related_videos() video_list = [] for exercise_video in related_videos: video_logs = models.VideoLog.get_for_user_and_video( user, exercise_video.key_for_video()) for video_log in video_logs: video_list.append(VideoPoint(video_log)) problem_list = [] problem_logs = models.ProblemLog.all().filter('user ='******'exercise =', exid).order("time_done") for problem_log in problem_logs: problem_list.append(ProblemPoint(problem_log)) max_problems_in_graph = 35 x_offset = 0 if len(problem_list) > max_problems_in_graph: x_offset = len(problem_list) - max_problems_in_graph problem_list = problem_list[-1 * max_problems_in_graph:] video_and_problem_list = [ point for sublist in [video_list, problem_list] for point in sublist ] video_and_problem_list = sorted(video_and_problem_list, lambda a, b: cmp(a.dt, b.dt)) video_point_last = None for video_or_problem in video_and_problem_list: if ProblemPoint.__name__ == video_or_problem.__class__.__name__: if video_point_last: video_or_problem.video_point = video_point_last video_point_last = None else: if video_point_last: video_point_last.seconds_watched += video_or_problem.seconds_watched video_point_last.dict_titles[ video_or_problem.first_video_title] = True else: video_point_last = video_or_problem list_last_ten = problem_list[-10:] c_last_ten = len(list_last_ten) percent_last_ten_correct = 0 if c_last_ten: c_last_ten_correct = reduce( lambda a, b: a + b, map(lambda problem_point: 1 if problem_point.correct else 0, list_last_ten)) percent_last_ten_correct = int( (float(c_last_ten_correct) / float(c_last_ten)) * 100) # Purposefully not showing any videos dangling after the last problem is done. # If video_point_last exists here, doing another problem will place it on the graph. x_axis_label = "Problem #" if x_offset: x_axis_label += " (Last %d problems)" % max_problems_in_graph return { 'exercise_display_name': models.Exercise.to_display_name(exid), 'exid': exid, 'problem_list': problem_list, 'streak': user_exercise.streak, 'longest_streak': user_exercise.longest_streak, 'percent_last_ten_correct': percent_last_ten_correct, 'student_nickname': util.get_nickname_for(user), 'x_offset': x_offset, 'x_axis_label': x_axis_label, }
def get(self): user = util.get_current_user() if user: student = user user_data_student = None student_email = self.request_string("student_email") if student_email and student_email != student.email(): student_override = users.User(email=student_email) user_data_student = models.UserData.get_or_insert_for( student_override) if (not users.is_current_user_admin()) and user.email( ) not in user_data_student.coaches and user.email().lower( ) not in user_data_student.coaches: # If current user isn't an admin or student's coach, they can't look at anything other than their own profile. self.redirect("/profile") else: # Allow access to this student's profile student = student_override if not user_data_student: user_data_student = models.UserData.get_or_insert_for(student) user_badges = util_badges.get_user_badges(student) selected_graph_type = self.request_string( "selected_graph_type") or ActivityGraph.GRAPH_TYPE initial_graph_url = "/profile/graph/%s?student_email=%s&%s" % ( selected_graph_type, urllib.quote(student.email()), urllib.unquote( self.request_string("graph_query_params", default=""))) tz_offset = self.request_int("tz_offset", default=0) template_values = { 'student': student, 'student_nickname': util.get_nickname_for(student), 'selected_graph_type': selected_graph_type, 'initial_graph_url': initial_graph_url, 'tz_offset': tz_offset, 'student_points': user_data_student.points, 'count_videos': models.Setting.count_videos(), 'count_videos_completed': user_data_student.get_videos_completed(), 'count_exercises': models.Exercise.get_count(), 'count_exercises_proficient': len(user_data_student.all_proficient_exercises), 'badge_collections': user_badges['badge_collections'], 'user_badges_bronze': user_badges['bronze_badges'], 'user_badges_silver': user_badges['silver_badges'], 'user_badges_gold': user_badges['gold_badges'], 'user_badges_platinum': user_badges['platinum_badges'], 'user_badges_diamond': user_badges['diamond_badges'], 'user_badges_master': user_badges['user_badges_master'], 'user_badges': [ user_badges['bronze_badges'], user_badges['silver_badges'], user_badges['gold_badges'], user_badges['platinum_badges'], user_badges['diamond_badges'], user_badges['user_badges_master'] ], "show_badge_frequencies": self.request_bool("show_badge_frequencies", default=False), } self.render_template('viewprofile.html', template_values) else: self.redirect(util.create_login_url(self.request.uri))
def get(self): user = util.get_current_user() if user: coach = user coach_email = self.request_string("coach_email") if users.is_current_user_admin() and coach_email: # Site administrators can look at any class profile coach = users.User(email=coach_email) user_data_coach = models.UserData.get_or_insert_for(coach) students_data = user_data_coach.get_students_data() class_points = 0 if students_data: class_points = reduce( lambda a, b: a + b, map(lambda student_data: student_data.points, students_data)) dict_students = map( lambda student_data: { "email": student_data.user.email(), "nickname": util.get_nickname_for(student_data.user), }, students_data) selected_graph_type = self.request_string( "selected_graph_type") or ClassProgressReportGraph.GRAPH_TYPE 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=""))) # Sort students alphabetically and sort into 4 chunked up columns for easy table html dict_students_sorted = sorted( dict_students, key=lambda dict_student: dict_student["nickname"]) students_per_row = 4 students_per_col = max( 1, len(dict_students_sorted) / students_per_row) list_cols = [[], [], [], []] list_students_columnized = [] for ix in range(0, len(dict_students_sorted)): dict_student = dict_students_sorted[ix] list_cols[(ix / students_per_col) % students_per_row].append(dict_student) for ix in range(0, len(dict_students_sorted)): dict_student = list_cols[ix % students_per_row][(ix / students_per_row) % students_per_col] list_students_columnized.append(dict_student) template_values = { 'coach': coach, 'coach_email': coach.email(), 'coach_nickname': util.get_nickname_for(coach), 'dict_students': dict_students, 'students_per_row': students_per_row, 'list_students_columnized': list_students_columnized, 'count_students': len(dict_students), 'class_points': class_points, 'selected_graph_type': selected_graph_type, 'initial_graph_url': initial_graph_url, 'exercises': models.Exercise.get_all_use_cache(), 'is_profile_empty': len(dict_students) <= 0, 'selected_nav_link': 'coach', } self.render_template('viewclassprofile.html', template_values) else: self.redirect(util.create_login_url(self.request.uri))