Exemple #1
0
    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 }
Exemple #3
0
    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))
Exemple #4
0
    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
        }
Exemple #6
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)
Exemple #10
0
 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,
    }
Exemple #12
0
    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))
Exemple #13
0
    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))