Exemple #1
0
    def post(self):
        user_data = models.UserData.current()

        if not user_data:
            self.redirect(util.create_login_url(self.request.uri))
            return

        if not util_discussion.is_honeypot_empty(self.request):
            # Honeypot caught a spammer (in case this is ever public or spammers
            # have google accounts)!
            return

        comment_text = self.request.get("comment_text")
        comments_hidden = self.request.get("comments_hidden")
        video_key = self.request.get("video_key")
        playlist_key = self.request.get("playlist_key")
        video = db.get(video_key)

        if comment_text and video:
            if len(comment_text) > 300:
                comment_text = comment_text[
                    0:300]  # max comment length, also limited by client

            comment = models_discussion.Feedback(parent=user_data)
            comment.set_author(user_data)
            comment.content = comment_text
            comment.targets = [video.key()]
            comment.types = [models_discussion.FeedbackType.Comment]
            comment.put()

        self.redirect(
            "/discussion/pagecomments?video_key=%s&playlist_key=%s&page=0&comments_hidden=%s&sort_order=%s"
            % (video_key, playlist_key, comments_hidden,
               voting.VotingSortOrder.NewestFirst))
Exemple #2
0
    def get(self):
        user = util.get_current_user()

        # This if/then clause just makes sure that the user is logged in

        if user:
            question_key = self.request.get('question_key')
            if question_key:
                question = db.get(question_key)
                bc = breadcrumb(question.subject)
                root = Subject.gql('WHERE parent_subject=:1', None).get()
                subjects = Subject.gql('WHERE parent_subject = :1', root)
                greeting = 'user: %s [<a href="%s">sign out</a>]' % (user.nickname(), users.create_logout_url('/'))

                template_values = {
                    'question': question,
                    'subjects': subjects,
                    'greeting': greeting,
                    'current_url': self.request.uri,
                    'breadcrumb': bc,
                    }
                path = os.path.join(os.path.dirname(__file__), 'viewquestion.html')
                self.response.out.write(template.render(path, template_values))
        else:
            self.redirect(util.create_login_url(self.request.uri))
Exemple #3
0
    def post(self):

        user = util.get_current_user()

        if not user:
            self.redirect(util.create_login_url(self.request.uri))
            return

        if not is_honeypot_empty(self.request):
            # Honeypot caught a spammer (in case this is ever public or spammers
            # have google accounts)!
            return

        comment_text = self.request.get("comment_text")
        comments_hidden = self.request.get("comments_hidden")
        video_key = self.request.get("video_key")
        playlist_key = self.request.get("playlist_key")
        video = db.get(video_key)

        if comment_text and video:
            if len(comment_text) > 300:
                comment_text = comment_text[0:300] # max comment length, also limited by client

            comment = models_discussion.Feedback()
            comment.author = user
            comment.content = comment_text
            comment.targets = [video.key()]
            comment.types = [models_discussion.FeedbackType.Comment]
            db.put(comment)

        self.redirect("/discussion/pagecomments?video_key=%s&playlist_key=%s&page=0&comments_hidden=%s" % (video_key, playlist_key, comments_hidden))
Exemple #4
0
    def get(self):
        user_data = UserData.current()

        if not user_data:
            self.redirect(util.create_login_url(self.request.uri))
            return

        accept_coach = self.request_bool("accept", default = False)
        user_data_coach = self.request_user_data("coach_email")
        user_data_student = self.request_user_data('student_email')

        if bool(user_data_coach) == bool(user_data_student):
            raise Exception('must provide coach_email xor student_email')

        if user_data_coach:
            user_data_student = user_data
        elif 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")
Exemple #5
0
    def post(self):

        user_data = models.UserData.current()

        if not user_data:
            self.redirect(util.create_login_url(self.request.uri))
            return

        if not util_discussion.is_honeypot_empty(self.request):
            # Honeypot caught a spammer (in case this is ever public or spammers
            # have google accounts)!
            return

        question_text = self.request.get("question_text")
        video_key = self.request.get("video_key")
        playlist_key = self.request.get("playlist_key")
        video = db.get(video_key)
        question_key = ""

        if question_text and video:
            if len(question_text) > 500:
                question_text = question_text[
                    0:500]  # max question length, also limited by client

            question = models_discussion.Feedback(parent=user_data)
            question.set_author(user_data)
            question.content = question_text
            question.targets = [video.key()]
            question.types = [models_discussion.FeedbackType.Question]
            question.put()
            question_key = question.key()

        self.redirect(
            "/discussion/pagequestions?video_key=%s&playlist_key=%s&qa_expand_key=%s"
            % (video_key, playlist_key, question_key))
Exemple #6
0
    def post(self):
        user = util.get_current_user()

        if user is None:
            self.redirect(util.create_login_url(self.request.uri))
            return

        user_data = UserData.get_or_insert_for(user)

        coach_email = self.request_string("coach", default="")
        if coach_email:
            coach_user = users.User(coach_email)
            coach_user_data = UserData.get_for(coach_user)

            if coach_user_data:

                if coach_email not in user_data.coaches and coach_email.lower(
                ) not in user_data.coaches:
                    user_data.coaches.append(coach_email)
                    user_data.put()

                self.redirect("/coaches")
                return

        self.redirect("/coaches?invalid_coach=1")
Exemple #7
0
    def post(self):
        user_data = models.UserData.current()

        if not user_data:
            self.redirect(util.create_login_url(self.request.uri))
            return

        if not util_discussion.is_honeypot_empty(self.request):
            # Honeypot caught a spammer (in case this is ever public or spammers
            # have google accounts)!
            return

        comment_text = self.request.get("comment_text")
        comments_hidden = self.request.get("comments_hidden")
        video_key = self.request.get("video_key")
        playlist_key = self.request.get("playlist_key")
        video = db.get(video_key)

        if comment_text and video:
            if len(comment_text) > 300:
                comment_text = comment_text[0:300]  # max comment length, also limited by client

            comment = models_discussion.Feedback(parent=user_data)
            comment.set_author(user_data)
            comment.content = comment_text
            comment.targets = [video.key()]
            comment.types = [models_discussion.FeedbackType.Comment]
            comment.put()

        self.redirect(
            "/discussion/pagecomments?video_key=%s&playlist_key=%s&page=0&comments_hidden=%s&sort_order=%s"
            % (video_key, playlist_key, comments_hidden, voting.VotingSortOrder.NewestFirst)
        )
Exemple #8
0
    def render_template(self, template_name, template_values):
        template_values['App'] = App
        template_values['None'] = None
        template_values['points'] = None
        template_values['username'] = ""

        user = util.get_current_user()
        if user is not None:
            template_values['username'] = user.nickname()

        user_data = UserData.get_for(user)

        template_values['user_data'] = user_data
        template_values['points'] = user_data.points if user_data else 0

        if not template_values.has_key('continue'):
            template_values['continue'] = self.request.uri

        # Always insert a post-login request before our continue url
        template_values['continue'] = util.create_post_login_url(template_values['continue'])

        template_values['login_url'] = ('%s&direct=1' % util.create_login_url(template_values['continue']))
        template_values['logout_url'] = util.create_logout_url(self.request.uri)

        template_values['is_mobile'] = self.is_mobile()

        path = os.path.join(os.path.dirname(__file__), template_name)
        self.response.out.write(template.render(path, template_values))
Exemple #9
0
    def post(self):

        user_data = models.UserData.current()

        if not user_data:
            self.redirect(util.create_login_url(self.request.uri))
            return

        if not util_discussion.is_honeypot_empty(self.request):
            # Honeypot caught a spammer (in case this is ever public or spammers
            # have google accounts)!
            return

        question_text = self.request.get("question_text")
        video_key = self.request.get("video_key")
        playlist_key = self.request.get("playlist_key")
        video = db.get(video_key)
        question_key = ""

        if question_text and video:
            if len(question_text) > 500:
                question_text = question_text[0:500] # max question length, also limited by client

            question = models_discussion.Feedback(parent=user_data)
            question.set_author(user_data)
            question.content = question_text
            question.targets = [video.key()]
            question.types = [models_discussion.FeedbackType.Question]
            question.put()
            question_key = question.key()

        self.redirect("/discussion/pagequestions?video_key=%s&playlist_key=%s&qa_expand_key=%s" % 
                (video_key, playlist_key, question_key))
Exemple #10
0
def video_comments_context(video, playlist, page=0, comments_hidden=True):

    if page > 0:
        comments_hidden = False # Never hide questions if specifying specific page
    else:
        page = 1

    limit_per_page = 10
    limit_initially_visible = 3 if comments_hidden else limit_per_page

    comments_query = models_discussion.Feedback.gql("WHERE types = :1 AND targets = :2 AND deleted = :3 ORDER BY date DESC", models_discussion.FeedbackType.Comment, video.key(), False)
    count_total = comments_query.count()
    comments = comments_query.fetch(limit_per_page, (page - 1) * limit_per_page)

    count_page = len(comments)
    pages_total = max(1, ((count_total - 1) / limit_per_page) + 1)
    return {
            "user": util.get_current_user(),
            "is_mod": is_current_user_moderator(),
            "video": video,
            "playlist": playlist,
            "comments": comments,
            "count_total": count_total,
            "comments_hidden": count_page > limit_initially_visible,
            "limit_initially_visible": limit_initially_visible,
            "pages": range(1, pages_total + 1),
            "pages_total": pages_total,
            "prev_page_1_based": page - 1,
            "current_page_1_based": page,
            "next_page_1_based": page + 1,
            "show_page_controls": pages_total > 1,
            "login_url": util.create_login_url("/video?v=%s" % video.youtube_id)
           }
Exemple #11
0
    def get(self):
        user_data = UserData.current()

        if user_data:

            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,
                    'student_lists': [
                        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'
            }
            self.render_jinja2_template('viewstudentlists.html',
                                        template_values)
        else:
            self.redirect(util.create_login_url(self.request.uri))
Exemple #12
0
    def get(self):
        user_data = UserData.current()

        if not user_data:
            self.redirect(util.create_login_url(self.request.uri))
            return

        accept_coach = self.request_bool("accept", default=False)
        user_data_coach = self.request_user_data("coach_email")
        user_data_student = self.request_user_data('student_email')

        if bool(user_data_coach) == bool(user_data_student):
            raise Exception('must provide coach_email xor student_email')

        if user_data_coach:
            user_data_student = user_data
        elif 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")
Exemple #13
0
 def get(self):
     user = util.get_current_user()
     if user:
         question_key = self.request.get('question_key')
         self.redirect('/answerquestion?question_key=' + question_key + '&preview_mode=True')
     else:
         self.redirect(util.create_login_url(self.request.uri))
Exemple #14
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))
Exemple #15
0
    def get(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

            student_lists = StudentList.get_for_coach(coach.key())

            student_lists_list = [{
                'key': 'allstudents',
                'name': 'כל התלמידים'.decode("utf8"),
            }];
            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
            
            exercises = models.Exercise.get_all_use_cache()
            exercises.sort(key=lambda ex: ex.display_name)

            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': exercises,
                    '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)
        else:
            self.redirect(util.create_login_url(self.request.uri))
Exemple #16
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)
Exemple #17
0
    def get(self):
        user = util.get_current_user()
        if user:
            user_data = UserData.get_or_insert_for(user)
            invalid_coach = self.request_bool("invalid_coach", default = False)

            self.render_template('viewcoaches.html', { 'coaches': user_data.coaches, 'invalid_coach': invalid_coach })
        else:
            self.redirect(util.create_login_url(self.request.uri))
Exemple #18
0
    def get(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

            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
            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': simplejson.dumps(student_lists_list),
                'coach_nickname': coach.nickname,
                'selected_graph_type': selected_graph_type,
                'initial_graph_url': initial_graph_url,
                'exercises': models.Exercise.get_all_use_cache(),
                'is_profile_empty': not coach.has_students(),
                'selected_nav_link': 'coach',
                "view": self.request_string("view", default=""),
            }
            self.render_jinja2_template('viewclassprofile.html',
                                        template_values)
        else:
            self.redirect(util.create_login_url(self.request.uri))
Exemple #19
0
    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)
Exemple #20
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)
Exemple #21
0
    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)
Exemple #22
0
    def post(self):
        user = util.get_current_user()
        if user is None:
            self.redirect(util.create_login_url(self.request.uri))
            return

        user_data = UserData.get_or_insert_for(user)
        coach_email = self.request.get('coach').lower()            
        user_data.coaches.append(coach_email)
        user_data.put()
        self.redirect("/coaches")
Exemple #23
0
def video_qa_context(video, playlist=None, page=0, qa_expand_id=None):

    limit_per_page = 5

    if qa_expand_id:
        # If we're showing an initially expanded question,
        # make sure we're on the correct page
        question = models_discussion.Feedback.get_by_id(qa_expand_id)
        if question:
            question_preceding_query = models_discussion.Feedback.gql("WHERE types = :1 AND targets = :2 AND deleted = :3 AND date > :4 ORDER BY date DESC", models_discussion.FeedbackType.Question, video.key(), False, question.date)
            count_preceding = question_preceding_query.count()
            page = 1 + (count_preceding / limit_per_page)

    if page <= 0:
        page = 1

    question_query = models_discussion.Feedback.gql("WHERE types = :1 AND targets = :2 AND deleted = :3 ORDER BY date DESC", models_discussion.FeedbackType.Question, video.key(), False)
    answer_query = models_discussion.Feedback.gql("WHERE types = :1 AND targets = :2 AND deleted = :3 ORDER BY date", models_discussion.FeedbackType.Answer, video.key(), False)

    count_total = question_query.count()
    questions = question_query.fetch(limit_per_page, (page - 1) * limit_per_page)

    dict_questions = {}
    # Store each question in this page in a dict for answer population
    for question in questions:
        dict_questions[question.key()] = question

    # Just grab all answers for this video and cache in page's questions
    for answer in answer_query:
        # Grab the key only for each answer, don't run a full gql query on the ReferenceProperty
        question_key = answer.parent_key()
        if (dict_questions.has_key(question_key)):
            question = dict_questions[question_key]
            question.children_cache.append(answer)

    count_page = len(questions)
    pages_total = max(1, ((count_total - 1) / limit_per_page) + 1)
    return {
            "user": util.get_current_user(),
            "is_mod": is_current_user_moderator(),
            "video": video,
            "playlist": playlist,
            "questions": questions,
            "count_total": count_total,
            "pages": range(1, pages_total + 1),
            "pages_total": pages_total,
            "prev_page_1_based": page - 1,
            "current_page_1_based": page,
            "next_page_1_based": page + 1,
            "show_page_controls": pages_total > 1,
            "qa_expand_id": qa_expand_id,
            "issue_labels": ('Component-Videos,Video-%s' % video.youtube_id),
            "login_url": util.create_login_url("/video?v=%s" % video.youtube_id)
           }
Exemple #24
0
 def get(self):
     user = util.get_current_user()
     question_key = self.request.get('question_key')
     question = db.get(question_key)
     redirect_url = self.request.get('redirect')
     if user:
         if user == question.author:
             question.delete()
         self.redirect(redirect_url)
     else:
         self.redirect(util.create_login_url(self.request.uri))
Exemple #25
0
    def post(self):
        user = util.get_current_user()
        if user is None:
            self.redirect(util.create_login_url(self.request.uri))
            return

        user_data = UserData.get_or_insert_for(user)
        coach_email = self.request.get('coach').lower()
        user_data.coaches.append(coach_email)
        user_data.put()
        self.redirect("/coaches")
Exemple #26
0
    def get(self):
        user = util.get_current_user()
        if user:
            user_data = UserData.get_or_insert_for(user)
            invalid_coach = self.request_bool("invalid_coach", default=False)

            self.render_template('viewcoaches.html', {
                'coaches': user_data.coaches,
                'invalid_coach': invalid_coach
            })
        else:
            self.redirect(util.create_login_url(self.request.uri))
Exemple #27
0
    def get(self):  
        user = util.get_current_user()
        user_data = UserData.get_for_current_user()
        template_values = qa.add_template_values({'App': App,
                                                  'points': user_data.points,
                                                  'username': user and user.nickname() or "",
                                                  'login_url': util.create_login_url(self.request.uri),
                                                  'student_email' : self.request.get('student_email'),
                                                  }, 
                                                  self.request)

        self.render_template('import.html', template_values)
Exemple #28
0
 def get(self):
     user = util.get_current_user()
     if user:
         subject_key = self.request.get('subject_key')
         if subject_key:
             subject = db.get(subject_key)
             html_tree = htmlChildren(subject)
             template_values = {'subject': subject, 'tree': html_tree}
             path = os.path.join(os.path.dirname(__file__), 'viewsubject.html')
             self.response.out.write(template.render(path, template_values))
     else:
         self.redirect(util.create_login_url(self.request.uri))
Exemple #29
0
    def get(self):
        user = util.get_current_user()
        user_data = UserData.get_for_current_user()
        template_values = qa.add_template_values(
            {
                'App': App,
                'points': user_data.points,
                'username': user and user.nickname() or "",
                'login_url': util.create_login_url(self.request.uri),
                'student_email': self.request.get('student_email'),
            }, self.request)

        self.render_template('import.html', template_values)
Exemple #30
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 #31
0
    def get(self):  
        user = util.get_current_user()
        user_data = UserData.get_for_current_user()
        logout_url = users.create_logout_url(self.request.uri)
        template_values = qa.add_template_values({'App': App,
                                                  'points': user_data.points,
                                                  'username': user and user.nickname() or "",
                                                  'login_url': util.create_login_url(self.request.uri),
                                                  'student_email' : self.request.get('student_email'),
                                                  'logout_url': logout_url}, 
                                                  self.request)

        path = os.path.join(os.path.dirname(__file__), 'import.html')
        self.response.out.write(template.render(path, template_values)) 
Exemple #32
0
    def get(self):

        user_data = models.UserData.current()

        if not user_data:
            self.redirect(util.create_login_url(self.request.uri))
            return

        answers = feedback_answers_for_user_data(user_data)

        # Whenever looking at this page, make sure the feedback count is recalculated
        # in case the user was notified about deleted or flagged posts.
        user_data.count_feedback_notification = -1
        user_data.put()

        dict_videos = {}
        dict_answers = {}

        for answer in answers:

            video = answer.video()

            dict_votes = models_discussion.FeedbackVote.get_dict_for_user_data_and_video(
                user_data, video)
            voting.add_vote_expando_properties(answer, dict_votes)

            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.first_topic().title + video.title)

        context = {
            "email": user_data.email,
            "videos": videos,
            "dict_answers": dict_answers
        }

        self.render_jinja2_template(
            'discussion/video_feedback_notification_list.html', context)
Exemple #33
0
    def get(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

            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
            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": simplejson.dumps(student_lists_list),
                "coach_nickname": coach.nickname,
                "selected_graph_type": selected_graph_type,
                "initial_graph_url": initial_graph_url,
                "exercises": models.Exercise.get_all_use_cache(),
                "is_profile_empty": not coach.has_students(),
                "selected_nav_link": "coach",
                "view": self.request_string("view", default=""),
            }
            self.render_jinja2_template("viewclassprofile.html", template_values)
        else:
            self.redirect(util.create_login_url(self.request.uri))
Exemple #34
0
    def get(self):
        user = util.get_current_user()
        subject_key = self.request.get('subject_key')
        subject = db.get(subject_key)
        redirect_url = self.request.get('redirect')
        logging.error("current user = " + str(user))

        if user:
            if user == subject.author:
                subject = db.get(subject_key)
                self.delete_subject(subject)

            self.redirect(redirect_url)
        else:
            self.redirect(util.create_login_url(self.request.uri))
Exemple #35
0
 def get(self):
     user = util.get_current_user()
     if user is None:
         self.redirect(util.create_login_url(self.request.uri))
         return
     user_data = UserData.get_or_insert_for(user)
     coach_email = self.request.get('coach')
     if coach_email:
         if coach_email in user_data.coaches:
             user_data.coaches.remove(coach_email)
             user_data.put()
         elif coach_email.lower() in user_data.coaches:
             user_data.coaches.remove(coach_email.lower())
             user_data.put()          
     self.redirect("/coaches") 
Exemple #36
0
 def get(self):
     user = util.get_current_user()
     if user is None:
         self.redirect(util.create_login_url(self.request.uri))
         return
     user_data = UserData.get_or_insert_for(user)
     coach_email = self.request.get('coach')
     if coach_email:
         if coach_email in user_data.coaches:
             user_data.coaches.remove(coach_email)
             user_data.put()
         elif coach_email.lower() in user_data.coaches:
             user_data.coaches.remove(coach_email.lower())
             user_data.put()
     self.redirect("/coaches")
Exemple #37
0
    def get(self):
        user = util.get_current_user()
        question_key = self.request.get('question_key')
        question = db.get(question_key)
        redirect_url = self.request.get('redirect')
        if user:
            if user == question.author:
                if question.published:
                    question.published = None
                else:
                    question.published = True
                question.put()
#            self.redirect(redirect_url)
            self.redirect('/qbrary')
        else:
            self.redirect(util.create_login_url(self.request.uri))
Exemple #38
0
 def render_template(self, template_name, template_values):
     template_values["App"] = App
     template_values["None"] = None
     template_values["points"] = None
     template_values["username"] = ""
     user = util.get_current_user()
     if user is not None:
         template_values["username"] = user.nickname()
     user_data = UserData.get_for(user)
     if user_data is not None:
         template_values["user_data"] = user_data
         template_values["points"] = user_data.points
     template_values["login_url"] = util.create_login_url(self.request.uri)
     template_values["logout_url"] = users.create_logout_url(self.request.uri)
     path = os.path.join(os.path.dirname(__file__), template_name)
     self.response.out.write(template.render(path, template_values))
Exemple #39
0
    def get(self):
        user = util.get_current_user()
        user_data = UserData.get_for_current_user()
        logout_url = users.create_logout_url(self.request.uri)
        template_values = qa.add_template_values(
            {
                'App': App,
                'points': user_data.points,
                'username': user and user.nickname() or "",
                'login_url': util.create_login_url(self.request.uri),
                'student_email': self.request.get('student_email'),
                'logout_url': logout_url
            }, self.request)

        path = os.path.join(os.path.dirname(__file__), 'import.html')
        self.response.out.write(template.render(path, template_values))
Exemple #40
0
    def get(self):
        user = util.get_current_user()
        if user:
            user_data = UserData.get_or_insert_for(user)
            logout_url = users.create_logout_url(self.request.uri)

            template_values = {
                'App': App,
                'username': user.nickname(),
                'logout_url': logout_url,
                'coaches': user_data.coaches
            }

            self.render_template('viewcoaches.html', template_values)
        else:
            self.redirect(util.create_login_url(self.request.uri))
Exemple #41
0
    def get(self):
        user = util.get_current_user()
        if user:
            user_data = UserData.get_or_insert_for(user)
            logout_url = users.create_logout_url(self.request.uri)

            template_values = {
                'App' : App,
                'username': user.nickname(),
                'logout_url': logout_url,
                'coaches': user_data.coaches
                }

            self.render_template('viewcoaches.html', template_values)
        else:
            self.redirect(util.create_login_url(self.request.uri))
Exemple #42
0
    def render_template(self, template_name, template_values):
        template_values['App'] = App
        template_values['None'] = None
        template_values['points'] = None
        template_values['username'] = ""
        user = util.get_current_user()
        if user is not None:
            template_values['username'] = user.nickname()            
        user_data = UserData.get_for(user)

        template_values['user_data'] = user_data
        template_values['points'] = user_data.points if user_data else 0

        template_values['login_url'] = util.create_login_url(self.request.uri)
        template_values['logout_url'] = users.create_logout_url(self.request.uri)
        path = os.path.join(os.path.dirname(__file__), template_name)
        self.response.out.write(template.render(path, template_values))
Exemple #43
0
 def render_template(self, template_name, template_values):
     template_values['App'] = App
     template_values['None'] = None
     template_values['points'] = None
     template_values['username'] = ""
     user = util.get_current_user()
     if user is not None:
         template_values['username'] = user.nickname()
     user_data = UserData.get_for(user)
     if user_data is not None:
         template_values['user_data'] = user_data
         template_values['points'] = user_data.points
     template_values['login_url'] = util.create_login_url(self.request.uri)
     template_values['logout_url'] = users.create_logout_url(
         self.request.uri)
     path = os.path.join(os.path.dirname(__file__), template_name)
     self.response.out.write(template.render(path, template_values))
Exemple #44
0
    def get(self):

        user_data = models.UserData.current()

        if not user_data:
            self.redirect(util.create_login_url(self.request.uri))
            return

        answers = feedback_answers_for_user_data(user_data)

        # Whenever looking at this page, make sure the feedback count is recalculated
        # in case the user was notified about deleted or flagged posts.
        user_data.count_feedback_notification = -1
        user_data.put()

        dict_videos = {}
        dict_answers = {}

        for answer in answers:

            video = answer.video()

            dict_votes = models_discussion.FeedbackVote.get_dict_for_user_data_and_video(user_data, video)
            voting.add_vote_expando_properties(answer, dict_votes)

            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.first_topic().title + video.title)

        context = {
                    "email": user_data.email,
                    "videos": videos,
                    "dict_answers": dict_answers
                  }

        self.render_jinja2_template('discussion/video_feedback_notification_list.html', context)
Exemple #45
0
    def get(self):
        user_data = UserData.current()

        if user_data:

            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'
            }
            self.render_jinja2_template('viewstudentlists.html', template_values)
        else:
            self.redirect(util.create_login_url(self.request.uri))
Exemple #46
0
    def post(self):

        user_data = models.UserData.current()

        if not user_data:
            self.redirect(util.create_login_url(self.request.uri))
            return

        if not util_discussion.is_honeypot_empty(self.request):
            # Honeypot caught a spammer (in case this is ever public or spammers
            # have google accounts)!
            return

        answer_text = self.request.get("answer_text")
        video_key = self.request.get("video_key")
        question_key = self.request.get("question_key")

        video = db.get(video_key)
        question = db.get(question_key)

        if answer_text and video and question:

            answer = models_discussion.Feedback(parent=user_data)
            answer.set_author(user_data)
            answer.content = answer_text
            answer.targets = [video.key(), question.key()]
            answer.types = [models_discussion.FeedbackType.Answer]

            if user_data.discussion_banned:
                # Hellbanned users' posts are automatically hidden
                answer.deleted = True

            # We don't limit answer.content length, which means we're vulnerable to
            # RequestTooLargeErrors being thrown if somebody submits a POST over the GAE
            # limit of 1MB per entity.  This is *highly* unlikely for a legitimate piece of feedback,
            # and we're choosing to crash in this case until someone legitimately runs into this.
            # See Issue 841.
            answer.put()

            if not answer.deleted:
                notification.new_answer_for_video_question(
                    video, question, answer)

        self.redirect("/discussion/answers?question_key=%s" % question_key)
Exemple #47
0
    def get(self):

        user_data = models.UserData.current()

        if not user_data:
            self.redirect(util.create_login_url(self.request.uri))
            return

        answers = feedback_answers_for_user_data(user_data)

        dict_videos = {}
        dict_answers = {}

        for answer in answers:

            video = answer.video()

            dict_votes = models_discussion.FeedbackVote.get_dict_for_user_data_and_video(
                user_data, video)
            voting.add_vote_expando_properties(answer, dict_votes)

            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)

        context = {
            "email": user_data.email,
            "videos": videos,
            "dict_answers": dict_answers
        }

        self.render_jinja2_template(
            'discussion/video_feedback_notification_list.html', context)
Exemple #48
0
    def get(self):
        user_data = UserData.current()

        if user_data:
            invalid_coach = self.request_bool("invalid_coach", default = False)

            coach_requests = CoachRequest.get_for_student(user_data).fetch(1000)

            template_values = {
                        "coach_emails": user_data.coach_emails(),
                        "invalid_coach": invalid_coach,
                        "coach_requests": coach_requests,
                        "student_id": user_data.email,
                        'selected_nav_link': 'coach'
                    }

            self.render_jinja2_template('viewcoaches.html', template_values)
        else:
            self.redirect(util.create_login_url(self.request.uri))
Exemple #49
0
    def post(self):
        user_data = UserData.current()

        if not user_data:
            self.redirect(util.create_login_url(self.request.uri))
            return
        user_data_student = self.request_user_data("student_email")
        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")
Exemple #50
0
    def post(self):

        user_data = models.UserData.current()

        if not user_data:
            self.redirect(util.create_login_url(self.request.uri))
            return

        if not util_discussion.is_honeypot_empty(self.request):
            # Honeypot caught a spammer (in case this is ever public or spammers
            # have google accounts)!
            return

        answer_text = self.request.get("answer_text")
        video_key = self.request.get("video_key")
        question_key = self.request.get("question_key")

        video = db.get(video_key)
        question = db.get(question_key)

        if answer_text and video and question:

            answer = models_discussion.Feedback(parent=user_data)
            answer.set_author(user_data)
            answer.content = answer_text
            answer.targets = [video.key(), question.key()]
            answer.types = [models_discussion.FeedbackType.Answer]

            if user_data.discussion_banned:
                # Hellbanned users' posts are automatically hidden
                answer.deleted = True

            # We don't limit answer.content length, which means we're vulnerable to
            # RequestTooLargeErrors being thrown if somebody submits a POST over the GAE
            # limit of 1MB per entity.  This is *highly* unlikely for a legitimate piece of feedback,
            # and we're choosing to crash in this case until someone legitimately runs into this.
            # See Issue 841.
            answer.put()

            if not answer.deleted:
                notification.new_answer_for_video_question(video, question, answer)

        self.redirect("/discussion/answers?question_key=%s" % question_key)
Exemple #51
0
    def get(self):

        user = util.get_current_user()
        if user:

            # Do a SQL query to select the root subject (it has no parent)

            subs = Subject.gql('WHERE parent_subject=:1', None)

            # We need at least the root subject

            if subs.count() < 1:
                root = Subject()
                root.author = user
                root.name = 'root'
                root.put()
            else:
                root = subs[0]

            # select all of the children of the root subject to

            subjects = Subject.gql('WHERE parent_subject = :1', root)

            # select all of the questions that the user has created

            published = Question.gql('WHERE author = :1 and published = :2 and not_completed = :3', user, True, False)
            notpublished = Question.gql('WHERE author = :1 and published = :2 and not_completed = :3', user, None, False)
            greeting = 'user: %s [<a href="%s">sign out</a>]' % (user.nickname(), users.create_logout_url('/'))

            template_values = {
                'subjects': subjects,
                'greeting': greeting,
                'published': published,
                'notpublished': notpublished,
                'current_url': self.request.uri,
                'user': user,
                }

            path = os.path.join(os.path.dirname(__file__), 'myprofile.html')
            self.response.out.write(template.render(path, template_values))
        else:

            self.redirect(util.create_login_url(self.request.uri))
Exemple #52
0
    def get(self):
        user = util.get_current_user()
        if user:
            questions = Question.gql('')
            author_questions_dict = dict()
            for question in questions:
                if question.author.nickname() in author_questions_dict:
                    author_questions_dict[question.author.nickname()].append(question.question_text)
                else:
                    author_questions_dict[question.author.nickname()] = [question.question_text]

            template_values = {
                'author_questions_dict': author_questions_dict,
                'greeting': "boo",
                'current_url': self.request.uri
                }
            path = os.path.join(os.path.dirname(__file__), 'viewauthors.html')
            self.response.out.write(template.render(path, template_values))
        else:
            self.redirect(util.create_login_url(self.request.uri))
Exemple #53
0
    def get(self):
        user = util.get_current_user()

        # This if/then clause just makes sure that the user is logged in

        if user:
            subs = Subject.gql('WHERE parent_subject=:1', None)

            # We need at least the root subject

            if subs.count() < 1:
                root = Subject()
                root.author = user
                root.name = 'root'
                root.put()
            else:
                root = subs[0]

            self.redirect('/editsubject?subject_key=' + root.key().__str__())
        else:
            self.redirect(util.create_login_url(self.request.uri))
Exemple #54
0
    def get(self):
        user = util.get_current_user()
        if user:
            subject_key = self.request.get('subject_key')
            if subject_key:
                subject = db.get(subject_key)
                root = Subject.gql('WHERE parent_subject=:1', None).get()
                subjects = Subject.gql('WHERE parent_subject = :1', root)
                greeting = 'user: %s [<a href="%s">sign out</a>]' % (user.nickname(), users.create_logout_url('/'))

                html_tree = pickQuizTopicHTML(subject)
                template_values = {
                    'subject': subject,
                    'subjects': subjects,
                    'greeting': greeting,
                    'tree': html_tree,
                    }
                path = os.path.join(os.path.dirname(__file__), 'pickquiztopic.html')
                self.response.out.write(template.render(path, template_values))
        else:
            self.redirect(util.create_login_url(self.request.uri))
Exemple #55
0
    def post(self):
        user_data = UserData.current()

        if not user_data:
            self.redirect(util.create_login_url(self.request.uri))
            return

        user_data_coach = self.request_user_data("coach")
        if user_data_coach:
            if not user_data.is_coached_by(user_data_coach):
                user_data.coaches.append(user_data_coach.key_email)
                user_data.put()

            if not self.is_ajax_request():
                self.redirect("/coaches")
            return

        if self.is_ajax_request():
            self.response.set_status(400)
        else:
            self.redirect("/coaches?invalid_coach=1")