Beispiel #1
0
    def get(self):
        coach = UserData.current()

        user_override = self.request_user_data("coach_email")
        if user_override and user_override.are_students_visible_to(coach):
            # Only allow looking at a student list other than your own
            # if you are a dev, admin, or coworker.
            coach = user_override

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

        student_lists_list = [{
            'key': 'allstudents',
            'name': 'All students',
        }]
        for student_list in student_lists:
            student_lists_list.append({
                'key': str(student_list.key()),
                'name': student_list.name,
            })

        list_id, _ = get_last_student_list(self, student_lists,
                                           coach == UserData.current())
        current_list = None
        for student_list in student_lists_list:
            if student_list['key'] == list_id:
                current_list = student_list

        selected_graph_type = self.request_string(
            "selected_graph_type") or ClassProgressReportGraph.GRAPH_TYPE
        if selected_graph_type == 'progressreport' or selected_graph_type == 'goals':  # TomY This is temporary until all the graphs are API calls
            initial_graph_url = "/api/v1/user/students/%s?coach_email=%s&%s" % (
                selected_graph_type, urllib.quote(coach.email),
                urllib.unquote(
                    self.request_string("graph_query_params", default="")))
        else:
            initial_graph_url = "/profile/graph/%s?coach_email=%s&%s" % (
                selected_graph_type, urllib.quote(coach.email),
                urllib.unquote(
                    self.request_string("graph_query_params", default="")))
        initial_graph_url += 'list_id=%s' % list_id

        template_values = {
            'user_data_coach': coach,
            'coach_email': coach.email,
            'list_id': list_id,
            'student_list': current_list,
            'student_lists': student_lists_list,
            'student_lists_json': json.dumps(student_lists_list),
            'coach_nickname': coach.nickname,
            'selected_graph_type': selected_graph_type,
            'initial_graph_url': initial_graph_url,
            'exercises': exercise_models.Exercise.get_all_use_cache(),
            'is_profile_empty': not coach.has_students(),
            'selected_nav_link': 'coach',
            "view": self.request_string("view", default=""),
            'stats_charts_class': 'coach-view',
        }
        self.render_jinja2_template('viewclassprofile.html', template_values)
    def get(self):
        coach = UserData.current()

        user_override = self.request_user_data("coach_email")
        if user_override and user_override.are_students_visible_to(coach):
            # Only allow looking at a student list other than your own
            # if you are a dev, admin, or coworker.
            coach = user_override

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

        student_lists_list = [{
            'key': 'allstudents',
            'name': 'All students',
        }];
        for student_list in student_lists:
            student_lists_list.append({
                'key': str(student_list.key()),
                'name': student_list.name,
            })

        list_id, _ = get_last_student_list(self, student_lists, coach==UserData.current())
        current_list = None
        for student_list in student_lists_list:
            if student_list['key'] == list_id:
                current_list = student_list

        selected_graph_type = self.request_string("selected_graph_type") or ClassProgressReportGraph.GRAPH_TYPE
        if selected_graph_type == 'progressreport' or selected_graph_type == 'goals': # TomY This is temporary until all the graphs are API calls
            initial_graph_url = "/api/v1/user/students/%s?coach_email=%s&%s" % (selected_graph_type, urllib.quote(coach.email), urllib.unquote(self.request_string("graph_query_params", default="")))
        else:
            initial_graph_url = "/profile/graph/%s?coach_email=%s&%s" % (selected_graph_type, urllib.quote(coach.email), urllib.unquote(self.request_string("graph_query_params", default="")))
        initial_graph_url += 'list_id=%s' % list_id

        template_values = {
                'user_data_coach': coach,
                'coach_email': coach.email,
                'list_id': list_id,
                'student_list': current_list,
                'student_lists': student_lists_list,
                'student_lists_json': json.dumps(student_lists_list),
                'coach_nickname': coach.nickname,
                'selected_graph_type': selected_graph_type,
                'initial_graph_url': initial_graph_url,
                'exercises': exercise_models.Exercise.get_all_use_cache(),
                'is_profile_empty': not coach.has_students(),
                'selected_nav_link': 'coach',
                "view": self.request_string("view", default=""),
                'stats_charts_class': 'coach-view',
                }
        self.render_jinja2_template('viewclassprofile.html', template_values)
Beispiel #3
0
def delete_scratchpad(scratchpad_id):
    """Mark a pre-existing Scratchpad as deleted.

    An empty request body is expected."""

    if not gandalf.bridge.gandalf("scratchpads"):
        return api_forbidden_response(
            "Forbidden: You don't have permission to do this")

    user = UserData.current()
    scratchpad = scratchpad_models.Scratchpad.get_by_id(scratchpad_id)

    if not scratchpad or scratchpad.deleted:
        return api_not_found_response("No scratchpad with id %s" %
                                      scratchpad_id)

    # Users can only delete scratchpad they created
    # EXCEPTION: Developres can delete any scratchpad
    if not user.developer and scratchpad.user_id != user.user_id:
        return api_forbidden_response(
            "Forbidden: Scratchpad owned by different user")

    scratchpad.deleted = True
    scratchpad.put()

    return api_success_no_content_response()
Beispiel #4
0
def create_scratchpad():
    """Create a new Scratchpad and associated ScratchpadRevision.

    The POST data should be a JSON-encoded dict, which is passed verbatim to
    Scratchpad.create as keyword arguments.
    """
    if not gandalf.bridge.gandalf("scratchpads"):
        return api_forbidden_response(
            "Forbidden: You don't have permission to do this")

    if not request.json:
        return api_invalid_param_response("Bad data supplied: Not JSON")

    # TODO(jlfwong): Support phantom users
    user = UserData.current()

    if not (user and user.developer):
        # Certain fields are only modifiable by developers
        for field in scratchpad_models.Scratchpad._developer_only_fields:
            if request.json.get(field):
                return api_forbidden_response(
                    "Forbidden: Only developers can change the %s" % field)

    try:
        # Convert unicode encoded JSON keys to strings
        create_args = dict_keys_to_strings(request.json)
        if user:
            create_args['user_id'] = user.user_id
        return scratchpad_models.Scratchpad.create(**create_args)
    except (db.BadValueError, db.BadKeyError), e:
        return api_invalid_param_response("Bad data supplied: " + e.message)
 def test_request_video(self):
     exs = exercise_models.Exercise.all().fetch(1000)
     user = UserData.current()
     self.assertFalse(exs[0].video_requested)
     exs[0].request_video()
     self.assertTrue(exs[0].video_requested)
     self.assertEqual(exs[0].video_requests_count, 1)
Beispiel #6
0
def delete_scratchpad(scratchpad_id):
    """Mark a pre-existing Scratchpad as deleted.

    An empty request body is expected."""

    if not gandalf.bridge.gandalf("scratchpads"):
        return api_forbidden_response(
            "Forbidden: You don't have permission to do this")

    user = UserData.current()
    scratchpad = scratchpad_models.Scratchpad.get_by_id(scratchpad_id)

    if not scratchpad or scratchpad.deleted:
        return api_not_found_response(
            "No scratchpad with id %s" % scratchpad_id)

    # Users can only delete scratchpad they created
    # EXCEPTION: Developres can delete any scratchpad
    if not user.developer and scratchpad.user_id != user.user_id:
        return api_forbidden_response(
            "Forbidden: Scratchpad owned by different user")

    scratchpad.deleted = True
    scratchpad.put()

    return api_success_no_content_response()
Beispiel #7
0
    def post(self):
        template_values = {}
        user_data = UserData.current()

        status_file = StringIO.StringIO(self.request_string('status_file'))
        reader = csv.reader(status_file)
        student_list = []
        for line in reader:
            student_email = line[0]
            student_status = line[1]
            student_comment = line[2]

            student = SummerStudent.all().filter('email =', student_email).get()
            if student is None:
                logging.error("Student %s not found" % student_email)
                continue

            student.application_status = student_status
            student.comment = student_comment
            if student_status == "Accepted":
                student.accepted = True

            student_list.append(student)

        db.put(student_list)

        self.response.out.write("OK")
        self.response.set_status(200)
Beispiel #8
0
    def post(self):
        user_data = UserData.current()
        if not user_data:
            return

        if user_data.is_child_account():
            self.render_json({"error": "You cannot vote yet."})
            return

        vote_type = self.request_int(
            "vote_type", default=discussion_models.FeedbackVote.ABSTAIN)

        if (vote_type == discussion_models.FeedbackVote.UP
                and not Privileges.can_up_vote(user_data)):
            self.render_json({
                "error":
                Privileges.need_points_desc(Privileges.UP_VOTE_THRESHOLD,
                                            "up vote")
            })
            return
        elif (vote_type == discussion_models.FeedbackVote.DOWN
              and not Privileges.can_down_vote(user_data)):
            self.render_json({
                "error":
                Privileges.need_points_desc(Privileges.DOWN_VOTE_THRESHOLD,
                                            "down vote")
            })
            return

        entity_key = self.request_string("entity_key", default="")
        if entity_key:
            entity = db.get(entity_key)
            if entity and entity.authored_by(user_data):
                self.render_json(
                    {"error": "You cannot vote for your own posts."})
                return

        if vote_type != discussion_models.FeedbackVote.ABSTAIN:
            limiter = VoteRateLimiter(user_data)
            if not limiter.increment():
                self.render_json({"error": limiter.denied_desc()})
                return

        # We kick off a taskqueue item to perform the actual vote insertion
        # so we don't have to worry about fast writes to the entity group
        # causing contention problems for the HR datastore, because
        # the taskqueue will just retry w/ exponential backoff.
        # TODO(marcia): user_data.email may change. user_id is preferred
        taskqueue.add(url='/admin/discussion/finishvoteentity',
                      queue_name='voting-queue',
                      params={
                          "email":
                          user_data.email,
                          "vote_type":
                          self.request_int(
                              "vote_type",
                              default=discussion_models.FeedbackVote.ABSTAIN),
                          "entity_key":
                          entity_key
                      })
Beispiel #9
0
def create_scratchpad():
    """Create a new Scratchpad and associated ScratchpadRevision.

    The POST data should be a JSON-encoded dict, which is passed verbatim to
    Scratchpad.create as keyword arguments.
    """
    if not gandalf.bridge.gandalf("scratchpads"):
        return api_forbidden_response(
            "Forbidden: You don't have permission to do this")

    if not request.json:
        return api_invalid_param_response("Bad data supplied: Not JSON")

    # TODO(jlfwong): Support phantom users
    user = UserData.current()

    if not (user and user.developer):
        # Certain fields are only modifiable by developers
        for field in scratchpad_models.Scratchpad._developer_only_fields:
            if request.json.get(field):
                return api_forbidden_response(
                    "Forbidden: Only developers can change the %s" % field)

    try:
        # Convert unicode encoded JSON keys to strings
        create_args = dict_keys_to_strings(request.json)
        if user:
            create_args['user_id'] = user.user_id
        return scratchpad_models.Scratchpad.create(**create_args)
    except (db.BadValueError, db.BadKeyError), e:
        return api_invalid_param_response("Bad data supplied: " + e.message)
Beispiel #10
0
    def post(self):
        user_data = UserData.current()
        if not user_data:
            return

        if user_data.is_child_account():
            self.render_json({"error": "Je kan nog niet stemmen."})
            return

        vote_type = self.request_int(
            "vote_type", default=discussion_models.FeedbackVote.ABSTAIN)

        if (vote_type == discussion_models.FeedbackVote.UP and
            not Privileges.can_up_vote(user_data)):
            self.render_json({
                "error": Privileges.need_points_desc(
                    Privileges.UP_VOTE_THRESHOLD, "up vote")
            })
            return
        elif (vote_type == discussion_models.FeedbackVote.DOWN and
              not Privileges.can_down_vote(user_data)):
            self.render_json({
                "error": Privileges.need_points_desc(
                    Privileges.DOWN_VOTE_THRESHOLD, "down vote")
            })
            return

        entity_key = self.request_string("entity_key", default="")
        if entity_key:
            entity = db.get(entity_key)
            if entity and entity.authored_by(user_data):
                self.render_json({
                    "error": "Je kan niet op je eigen opmerking stemmen."
                })
                return

        if vote_type != discussion_models.FeedbackVote.ABSTAIN:
            limiter = VoteRateLimiter(user_data)
            if not limiter.increment():
                self.render_json({"error": limiter.denied_desc()})
                return

        # We kick off a taskqueue item to perform the actual vote insertion
        # so we don't have to worry about fast writes to the entity group
        # causing contention problems for the HR datastore, because
        # the taskqueue will just retry w/ exponential backoff.
        # TODO(marcia): user_data.email may change. user_id is preferred
        taskqueue.add(
            url='/admin/discussion/finishvoteentity',
            queue_name='voting-queue',
            params={
                "email": user_data.email,
                "vote_type": self.request_int(
                    "vote_type",
                    default=discussion_models.FeedbackVote.ABSTAIN),
                "entity_key": entity_key
            }
        )
Beispiel #11
0
    def get(self):
        user_data = UserData.current()
        user_data_override = self.request_user_data("coach_email")
        if user_util.is_current_user_developer() and user_data_override:
            user_data = user_data_override

        invalid_student = self.request_bool("invalid_student", default=False)

        coach_requests = [req.student_requested_identifier
                          for req in CoachRequest.get_for_coach(user_data)
                          if req.student_requested_data]

        student_lists_models = StudentList.get_for_coach(user_data.key())
        student_lists_list = []
        for student_list in student_lists_models:
            student_lists_list.append({
                'key': str(student_list.key()),
                'name': student_list.name,
            })
        student_lists_dict = dict((g['key'], g) for g in student_lists_list)

        def student_to_dict(s):
            """Convert the UserData s to a dictionary for rendering."""
            return {
                'key': str(s.key()),
                'email': s.email,
                'username': s.username,
                # Note that child users don't have an email.
                'identifier': s.username or s.email,
                'nickname': s.nickname,
                'profile_root': s.profile_root,
                'can_modify_coaches': s.can_modify_coaches(),
                'studentLists':
                        [l for l in [student_lists_dict.get(str(list_id))
                           for list_id in s.student_lists] if l],
            }

        students_data = user_data.get_students_data()
        students = map(student_to_dict, students_data)
        students.sort(key=lambda s: s['nickname'])

        child_accounts = map(student_to_dict, user_data.get_child_users())
        template_values = {
            'students': students,
            'child_accounts': child_accounts,
            'child_account_keyset': set([c['key'] for c in child_accounts]),
            'students_json': json.dumps(students),
            'student_lists': student_lists_list,
            'student_lists_json': json.dumps(student_lists_list),
            'invalid_student': invalid_student,
            'coach_requests': coach_requests,
            'coach_requests_json': json.dumps(coach_requests),
            'selected_nav_link': 'coach',
            'email': user_data.email,
        }
        self.render_jinja2_template('viewstudentlists.html', template_values)
Beispiel #12
0
    def get(self):
        user_data = UserData.current()
        user_video_css = video_models.UserVideoCss.get_for_user_data(user_data)
        self.response.headers['Content-Type'] = 'text/css'

        if user_video_css.version == user_data.uservideocss_version:
            # Don't cache if there's a version mismatch and update isn't finished
            self.response.headers['Cache-Control'] = 'public,max-age=1000000'

        self.response.out.write(user_video_css.video_css)
Beispiel #13
0
    def get(self):
        user_data = UserData.current()
        user_video_css = video_models.UserVideoCss.get_for_user_data(user_data)
        self.response.headers['Content-Type'] = 'text/css'

        if user_video_css.version == user_data.uservideocss_version:
            # Don't cache if there's a version mismatch and update isn't finished
            self.response.headers['Cache-Control'] = 'public,max-age=1000000'

        self.response.out.write(user_video_css.video_css)
Beispiel #14
0
    def get(self):
        coach = UserData.current()

        self.render_jinja2_template('coach_resources/view_demo.html', {
            "selected_id": "demo",
            "base_url": "/toolkit",
            "not_in_toolkit_format": 1,
            "is_logged_in": json.dumps(not coach.is_phantom if coach
                                       else False),
        })
Beispiel #15
0
    def do_request(self, student, coach, redirect_to):
        if not UserData.current():
            self.redirect(url_util.create_login_url(self.request.uri))
            return

        if student and coach:
            self.remove_student_from_coach(student, coach)

        if not self.is_ajax_request():
            self.redirect(redirect_to)
Beispiel #16
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)
Beispiel #17
0
    def get_profile_target_user_data(self):
        coach = UserData.current()

        if coach:
            user_override = self.request_user_data("coach_email")
            if user_override and user_override.are_students_visible_to(coach):
                # Only allow looking at a student list other than your own
                # if you are a dev, admin, or coworker.
                coach = user_override

        return coach
    def get_profile_target_user_data(self):
        coach = UserData.current()

        if coach:
            user_override = self.request_user_data("coach_email")
            if user_override and user_override.are_students_visible_to(coach):
                # Only allow looking at a student list other than your own
                # if you are a dev, admin, or coworker.
                coach = user_override

        return coach
Beispiel #19
0
    def get(self):
        template_values = {}
        user_data = UserData.current()

        if user_data is not None:
            return self.authenticated_response()

        else:
            template_values = {
                "authenticated" : False,
            }

        self.add_global_template_values(template_values)
        self.render_jinja2_template('summer/summer_process.html', template_values)
Beispiel #20
0
    def get(self):
        coach = UserData.current()

        self.render_jinja2_template(
            'coach_resources/view_demo.html', {
                "selected_id":
                "demo",
                "base_url":
                "/toolkit",
                "not_in_toolkit_format":
                1,
                "is_logged_in":
                json.dumps(not coach.is_phantom if coach else False),
            })
Beispiel #21
0
    def get(self):
        coach = UserData.current()

        if coach is not None:
            coach_email = coach.email
            is_profile_empty = not coach.has_students()
        else:
            coach_email = None
            is_profile_empty = True

        self.render_jinja2_template('coach_resources/view_resources.html', {
            'selected_id': 'coach-resources',
            'coach_email': coach_email,
            'is_profile_empty': is_profile_empty,
        })
Beispiel #22
0
    def get(self):
        user_data = UserData.current()

        from exercises.exercise_util import exercise_graph_dict_json

        context = {
            'graph_dict_data': exercise_graph_dict_json(user_data),
            'user_data': user_data,
            'map_coords':
            json.dumps(deserializeMapCoords(user_data.map_coords)),

            # Get pregenerated library content from our in-memory/memcache
            # two-layer cache
            'library_content': library_content_html(),
        }
        self.render_jinja2_template("goals/creategoal.html", context)
Beispiel #23
0
    def get(self):
        coach = UserData.current()

        if coach is not None:
            coach_email = coach.email
            is_profile_empty = not coach.has_students()
        else:
            coach_email = None
            is_profile_empty = True

        self.render_jinja2_template(
            'coach_resources/view_resources.html', {
                'selected_id': 'coach-resources',
                'coach_email': coach_email,
                'is_profile_empty': is_profile_empty,
            })
Beispiel #24
0
    def post(self):
        user_data = UserData.current()

        user_data_student = self.request_student_user_data()
        if user_data_student:
            if not user_data_student.is_coached_by(user_data):
                coach_request = CoachRequest.get_or_insert_for(user_data, user_data_student)
                if coach_request:
                    if not self.is_ajax_request():
                        self.redirect("/students")
                    return

        if self.is_ajax_request():
            self.response.set_status(404)
        else:
            self.redirect("/students?invalid_student=1")
Beispiel #25
0
def update_scratchpad(scratchpad_id):
    """Update a pre-existing Scratchpad and create a new ScratchpadRevision.

    The POST data should be a JSON-encoded dict, which is passsed verbatim to
    Scratchpad.update as keyword arguments.
    """
    if not gandalf.bridge.gandalf("scratchpads"):
        return api_forbidden_response(
            "Forbidden: You don't have permission to do this")

    if not request.json:
        return api_invalid_param_response("Bad data supplied: Not JSON")

    user = UserData.current()
    scratchpad = scratchpad_models.Scratchpad.get_by_id(scratchpad_id)

    if not scratchpad or scratchpad.deleted:
        return api_not_found_response(
            "No scratchpad with id %s" % scratchpad_id)

    if not user.developer:
        # Certain fields are only modifiable by developers
        for field in scratchpad_models.Scratchpad._developer_only_fields:
            if request.json.get(field):
                return api_forbidden_response(
                    "Forbidden: Only developers can change the %s" % field)

    # The user can update the scratchpad if any of the following are true:
    #  1. The scratchpad is tutorial/official and the user is a developer
    #  2. The scratchpad was created by the user
    if scratchpad.category in ("tutorial", "official") and user.developer:
        pass
    elif scratchpad.user_id != user.user_id:
        # Only the creator of a scratchpad can update it
        return api_forbidden_response(
            "Forbidden: Scratchpad owned by different user")

    try:
        # Convert unicode encoded JSON keys to strings
        update_args = dict_keys_to_strings(request.json)
        if 'id' in update_args:
            # Backbone passes the id in update calls - ignore it
            del update_args['id']
        return scratchpad.update(**update_args)
    except (db.BadValueError, db.BadKeyError), e:
        return api_invalid_param_response("Bad data supplied: " + e.message)
Beispiel #26
0
    def get(self):
        user_data = UserData.current()
        sort = self.request_int("sort",
                                default=VotingSortOrder.HighestPointsFirst)

        if user_data:
            user_data.question_sort_order = sort
            user_data.put()

        readable_id = self.request_string("readable_id", default="")
        topic_title = self.request_string("topic_title", default="")

        if readable_id and topic_title:
            self.redirect("/video/%s?topic=%s&sort=%s" % (
                urllib.quote(readable_id), urllib.quote(topic_title), sort))
        else:
            self.redirect("/")
Beispiel #27
0
def update_scratchpad(scratchpad_id):
    """Update a pre-existing Scratchpad and create a new ScratchpadRevision.

    The POST data should be a JSON-encoded dict, which is passsed verbatim to
    Scratchpad.update as keyword arguments.
    """
    if not gandalf.bridge.gandalf("scratchpads"):
        return api_forbidden_response(
            "Forbidden: You don't have permission to do this")

    if not request.json:
        return api_invalid_param_response("Bad data supplied: Not JSON")

    user = UserData.current()
    scratchpad = scratchpad_models.Scratchpad.get_by_id(scratchpad_id)

    if not scratchpad or scratchpad.deleted:
        return api_not_found_response("No scratchpad with id %s" %
                                      scratchpad_id)

    if not user.developer:
        # Certain fields are only modifiable by developers
        for field in scratchpad_models.Scratchpad._developer_only_fields:
            if request.json.get(field):
                return api_forbidden_response(
                    "Forbidden: Only developers can change the %s" % field)

    # The user can update the scratchpad if any of the following are true:
    #  1. The scratchpad is tutorial/official and the user is a developer
    #  2. The scratchpad was created by the user
    if scratchpad.category in ("tutorial", "official") and user.developer:
        pass
    elif scratchpad.user_id != user.user_id:
        # Only the creator of a scratchpad can update it
        return api_forbidden_response(
            "Forbidden: Scratchpad owned by different user")

    try:
        # Convert unicode encoded JSON keys to strings
        update_args = dict_keys_to_strings(request.json)
        if 'id' in update_args:
            # Backbone passes the id in update calls - ignore it
            del update_args['id']
        return scratchpad.update(**update_args)
    except (db.BadValueError, db.BadKeyError), e:
        return api_invalid_param_response("Bad data supplied: " + e.message)
Beispiel #28
0
    def get(self):
        template_values = {}
        user_data = UserData.current()

        if user_data is not None:
            template_values = self.authenticated_response()
            if template_values is None:
                self.redirect("/summer/application")
                return

        else:
            template_values = {
                "authenticated" : False,
            }

        self.add_global_template_values(template_values)
        self.render_jinja2_template('summer/summer_status.html', template_values)
Beispiel #29
0
    def get(self):
        user_data = UserData.current()
        sort = self.request_int("sort",
                                default=VotingSortOrder.HighestPointsFirst)

        if user_data:
            user_data.question_sort_order = sort
            user_data.put()

        readable_id = self.request_string("readable_id", default="")
        topic_title = self.request_string("topic_title", default="")

        if readable_id and topic_title:
            self.redirect("/video/%s?topic=%s&sort=%s" % (
                urllib.quote(readable_id), urllib.quote(topic_title), sort))
        else:
            self.redirect("/")
Beispiel #30
0
    def get(self):
        user_data = UserData.current()
        user_exercise_graph = UserExerciseGraph.get(user_data)

        from exercises.exercise_util import exercise_graph_dict_json

        context = {
            'graph_dict_data': exercise_graph_dict_json(
                user_data, user_exercise_graph),
            'user_data': user_data,
            'map_coords': json.dumps(
                deserializeMapCoords(user_data.map_coords)),

            # Get pregenerated library content from our in-memory/memcache
            # two-layer cache
            'library_content': library_content_html(),
        }
        self.render_jinja2_template("goals/creategoal.html", context)
Beispiel #31
0
    def authenticated_response(self):
        user_data = UserData.current()
        user_email = user_data.user_email
        nickname = ""
        if facebook_util.is_facebook_user_id(user_email):
            nickname = facebook_util.get_facebook_nickname(user_email)

        query = SummerStudent.all()
        query.filter('email = ', user_email)
        student = query.get()

        students = []
        is_parent = False

        if student is None:
            query = SummerParentData.all()
            query.filter('email = ', user_email)
            parent = query.get()
            if parent is None:
                return None

            is_parent = True
            number_of_students = 0
            for student_key in parent.students:
                student = SummerStudent.get(student_key)
                students.append(student)
                if student.accepted and not student.tuition_paid:
                    number_of_students += 1

        else:
            number_of_students = 1
            students.append(student)

        template_values = {
            "authenticated" : True,
            "is_parent" : is_parent,
            "students" : students,
            "number_of_students": json.dumps(number_of_students),
            "student" : students[0],
            "user_email" : user_email,
            "nickname" : nickname,
        }

        return template_values
Beispiel #32
0
    def get(self):
        user_data = UserData.current()
        user_data_override = self.request_user_data("coach_email")
        if user_util.is_current_user_developer() and user_data_override:
            user_data = user_data_override

        invalid_student = self.request_bool("invalid_student", default = False)

        coach_requests = [x.student_requested_data.email for x in CoachRequest.get_for_coach(user_data) if x.student_requested_data]

        student_lists_models = StudentList.get_for_coach(user_data.key())
        student_lists_list = [];
        for student_list in student_lists_models:
            student_lists_list.append({
                'key': str(student_list.key()),
                'name': student_list.name,
            })
        student_lists_dict = dict((g['key'], g) for g in student_lists_list)

        students_data = user_data.get_students_data()
        students = map(lambda s: {
            'key': str(s.key()),
            'email': s.email,
            'nickname': s.nickname,
            'profile_root': s.profile_root,
            'studentLists': [l for l in [student_lists_dict.get(str(list_id)) for list_id in s.student_lists] if l],
        }, students_data)
        students.sort(key=lambda s: s['nickname'])

        template_values = {
            'students': students,
            'students_json': json.dumps(students),
            'student_lists': student_lists_list,
            'student_lists_json': json.dumps(student_lists_list),
            'invalid_student': invalid_student,
            'coach_requests': coach_requests,
            'coach_requests_json': json.dumps(coach_requests),
            'selected_nav_link': 'coach',
            'email': user_data.email,
        }
        self.render_jinja2_template('viewstudentlists.html', template_values)
Beispiel #33
0
    def get(self):
        """ Only used when a coach deletes a request in studentlists.js.
        """
        user_data = UserData.current()

        accept_coach = self.request_bool("accept", default = False)
        user_data_student = self.request_student_user_data()

        if user_data_student:
            user_data_coach = user_data

        if (user_data_coach and
                not user_data_student.is_coached_by(user_data_coach)):
            coach_request = CoachRequest.get_for(user_data_coach, user_data_student)
            if coach_request:
                coach_request.delete()

                if user_data.key_email == user_data_student.key_email and accept_coach:
                    user_data_student.coaches.append(user_data_coach.key_email)
                    user_data_student.put()

        if not self.is_ajax_request():
            self.redirect("/coaches")
Beispiel #34
0
    def authenticated_response(self):
        user_data = UserData.current()
        user_email = user_data.user_email
        nickname = ""
        if facebook_util.is_facebook_user_id(user_email):
            nickname = facebook_util.get_facebook_nickname(user_email)

        query = SummerStudent.all()
        query.filter('email = ', user_email)
        student = query.get()

        students = []
        is_parent = False

        if student is None:
            query = SummerParentData.all()
            query.filter('email = ', user_email)
            parent = query.get()
            if parent is None:
                return None

            is_parent = True
            for student_key in parent.students:
                students.append(SummerStudent.get(student_key))

        else:
            students.append(student)

        template_values = {
            "authenticated" : True,
            "is_parent" : is_parent,
            "students" : students,
            "user_email" : user_email,
            "nickname" : nickname,
        }

        return template_values
Beispiel #35
0
    def authenticated_response(self):
        user_data = UserData.current()
        user_email = user_data.user_email

        template_values = {
                "authenticated" : True,
                "user_email" : user_email,
        }

        sio = StringIO.StringIO()
        sw = csv.writer(sio)
        properties = [p for p in SummerStudent().properties()]
        sw.writerow(properties)
        for student in SummerStudent.all().fetch(5000):
            try:
                row = []
                for p in properties:
                    v = getattr(student, p)
                    if isinstance(v, basestring):
                        v = v.encode("utf-8")
                    row.append(v)
                sw.writerow(row)
            except Exception, e:
                logging.error("Unable to write row for student %s" % student.email)
Beispiel #36
0
    def get(self):
        from exercises import attempt_problem

        login_user = UserData.current()
        exercises_list = [exercise for exercise in Exercise.all()]
        videos_list = [video for video in Video.all()]

        user_count = self.request_int('users', 5)
        for user_id in xrange(0, user_count):
            # Create a new user
            first_name = random.choice(CreateRandomGoalData.first_names)
            last_name = random.choice(CreateRandomGoalData.last_names)
            nickname = "%s %s" % (first_name, last_name)
            email = 'test_%i@automatedrandomdata' % user_id
            user = users.User(email)

            logging.info("Creating user %s: (%i/%i)" %
                         (nickname, user_id + 1, user_count))

            user_data = UserData.get_or_insert(
                key_name="test_user_%i" % user_id,
                user=user,
                current_user=user,
                user_id=str(user_id),
                moderator=False,
                last_login=datetime.now(),
                proficient_exercises=[],
                suggested_exercises=[],
                need_to_reassess=True,
                points=0,
                coaches=[login_user.user_email],
                user_email=email,
                user_nickname=nickname,
            )
            user_data.put()

            # Delete user exercise & video progress
            query = UserExercise.all()
            query.filter('user = '******'user = '******'type':
                        'GoalObjectiveExerciseProficiency',
                        'exercise':
                        random.choice(exercises_list)
                    })

                for objective in xrange(1, random.randint(2, 4)):
                    obj_descriptors.append({
                        'type': 'GoalObjectiveWatchVideo',
                        'video': random.choice(videos_list)
                    })

                title = first_name + "'s Goal #" + str(goal_idx)
                logging.info("Creating goal " + title)

                objectives = GoalObjective.from_descriptors(
                    obj_descriptors, user_data)
                goal = Goal(parent=user_data,
                            title=title,
                            objectives=objectives)
                user_data.save_goal(goal)

                for objective in obj_descriptors:
                    if objective['type'] == 'GoalObjectiveExerciseProficiency':
                        user_exercise = user_data.get_or_insert_exercise(
                            objective['exercise'])
                        chooser = random.randint(1, 120)
                        if chooser >= 60:
                            continue
                        elif chooser > 15:
                            count = 1
                            hints = 0
                        elif chooser < 7:
                            count = 20
                            hints = 0
                        else:
                            count = 25
                            hints = 1
                        logging.info(
                            "Starting exercise: %s (%i problems, %i hints)" %
                            (objective['exercise'].name, count, hints * count))
                        for i in xrange(1, count):
                            attempt_problem(user_data, user_exercise, i, 1,
                                            'TEST', 'TEST', 'TEST', True,
                                            hints, 0, False, False, "TEST",
                                            '0.0.0.0')

                    elif objective['type'] == 'GoalObjectiveWatchVideo':
                        seconds = random.randint(1, 1200)
                        logging.info("Watching %i seconds of video %s" %
                                     (seconds, objective['video'].title))
                        VideoLog.add_entry(user_data,
                                           objective['video'],
                                           seconds,
                                           0,
                                           detect_cheat=False)

        self.response.out.write('OK')
def get_coach_student_and_student_list(request_handler):
    coach = UserData.current()
    student_list = get_student_list(coach,
        request_handler.request_string("list_id"))
    student = get_student(coach, request_handler)
    return (coach, student, student_list)
Beispiel #38
0
def get_coach_student_and_student_list(request_handler):
    coach = UserData.current()
    student_list = get_student_list(coach,
                                    request_handler.request_string("list_id"))
    student = get_student(coach, request_handler)
    return (coach, student, student_list)
Beispiel #39
0
    def get(self, email_or_username=None, subpath=None):
        """Render a student profile.

        Keyword arguments:
        email_or_username -- matches the first grouping in /profile/(.+?)/(.*)
        subpath -- matches the second grouping, and is ignored server-side,
        but is used to route client-side

        """
        current_user_data = UserData.current() or UserData.pre_phantom()

        if current_user_data.is_pre_phantom and email_or_username is None:
            # Pre-phantom users don't have any profiles - just redirect them
            # to the homepage if they try to view their own.
            self.redirect(util.create_login_url(self.request.uri))
            return

        if not email_or_username:
            user_data = current_user_data
        elif email_or_username == 'nouser' and current_user_data.is_phantom:
            user_data = current_user_data
        else:
            user_data = UserData.get_from_url_segment(email_or_username)
            if (user_models.UniqueUsername.is_valid_username(email_or_username)
                    and user_data and user_data.username
                    and user_data.username != email_or_username):
                # The path segment is a username and resolved to the user,
                # but is not actually their canonical name. Redirect to the
                # canonical version.
                if subpath:
                    self.redirect("/profile/%s/%s" %
                                  (user_data.username, subpath))
                else:
                    self.redirect("/profile/%s" % user_data.username)
                return

        profile = UserProfile.from_user(user_data, current_user_data)

        if profile is None:
            self.render_jinja2_template('noprofile.html', {})
            return

        is_self = user_data.user_id == current_user_data.user_id
        show_intro = False

        if is_self:
            promo_record = promo_record_model.PromoRecord.get_for_values(
                "New Profile Promo", user_data.user_id)

            if promo_record is None:
                # The user has never seen the new profile page! Show a tour.
                if subpath:
                    # But if they're not on the root profile page, force them.
                    self.redirect("/profile")
                    return

                show_intro = True
                promo_record_model.PromoRecord.record_promo(
                    "New Profile Promo", user_data.user_id, skip_check=True)

        has_full_access = is_self or user_data.is_visible_to(current_user_data)
        tz_offset = self.request_int("tz_offset", default=0)

        template_values = {
            'show_intro': show_intro,
            'profile': profile,
            'tz_offset': tz_offset,
            'count_videos': setting_model.Setting.count_videos(),
            'count_exercises': exercise_models.Exercise.get_count(),
            'user_data_student': user_data if has_full_access else None,
            'profile_root': user_data.profile_root,
            "view": self.request_string("view", default=""),
        }
        self.render_jinja2_template('viewprofile.html', template_values)
    def get(self, username=None, subpath=None):

        """Render a student profile.

        Keyword arguments:
        email_or_username -- matches the first grouping in /profile/(.+?)/(.*)
        subpath -- matches the second grouping, and is ignored server-side,
        but is used to route client-side

        """
        current_user_data = UserData.current() or UserData.pre_phantom()

        if current_user_data.is_pre_phantom and username is None:
            # Pre-phantom users don't have any profiles - just redirect them
            # to the homepage if they try to view their own.
            self.redirect(url_util.create_login_url(self.request.uri))
            return

        if not current_user_data.is_phantom and username == 'nouser':
            # If anybody has bookmarked, or gets redirected to, or otherwise
            # finds their way to /profile/nouser while they're logged in, just
            # redirect them to their actual profile.
            #
            # /profile/nouser is only sensible for phantom users and is never
            # used to look at another user's profile.
            self.redirect(current_user_data.profile_root)
            return

        if not username:
            user_data = current_user_data
        elif username == 'nouser' and current_user_data.is_phantom:
            user_data = current_user_data
        else:
            user_data = UserData.get_from_url_segment(username)
            if (user_models.UniqueUsername.is_valid_username(username)
                    and user_data
                    and user_data.username
                    and user_data.username != username):
                # The path segment is a username and resolved to the user,
                # but is not actually their canonical name. Redirect to the
                # canonical version.
                if subpath:
                    self.redirect("/profile/%s/%s" % (user_data.username,
                                                      subpath))
                else:
                    self.redirect("/profile/%s" % user_data.username)
                return

        profile = util_profile.UserProfile.from_user(user_data,
                current_user_data)

        if profile is None:
            self.render_jinja2_template('noprofile.html', {})
            return

        is_self = user_data.user_id == current_user_data.user_id
        show_intro = False
        show_discussion_intro = False

        if is_self:
            promo_record = promo_record_model.PromoRecord.get_for_values(
                    "New Profile Promo", user_data.user_id)

            if promo_record is None:
                # The user has never seen the new profile page! Show a tour.
                if subpath:
                    # But if they're not on the root profile page, force them.
                    self.redirect("/profile")
                    return

                show_intro = True
                promo_record_model.PromoRecord.record_promo(
                    "New Profile Promo", user_data.user_id, skip_check=True)
                # We also mark the "new discussion promo" as having been seen,
                # because it is a sub-set of the full tour, and new users don't
                # need to see it twice.
                promo_record_model.PromoRecord.record_promo(
                    "New Discussion Promo", user_data.user_id, skip_check=True)
            else:
                # The user has already seen the original profile page tour, but
                # not necessarily the "new discussion tab" tour.
                discussion_promo_record = (
                    promo_record_model.PromoRecord.get_for_values(
                        "New Discussion Promo", user_data.user_id))

                if discussion_promo_record is None:
                    # The user hasn't seen the new discussion promo.
                    show_discussion_intro = True
                    promo_record_model.PromoRecord.record_promo(
                        "New Discussion Promo", user_data.user_id,
                            skip_check=True)

        # This is the main capability bit - it indicates whether or not the
        # actor can view exercise, video, and goals data on the site for the
        # current profile.
        is_activity_visible = user_data.is_visible_to(current_user_data)

        # Resolve any other miscellaneous capabilities. This may need to be
        # changed if ACLing gets signicantly more complicated.
        if is_self:
            is_settings_available = not user_data.is_child_account()
            is_discussion_available = not user_data.is_child_account()
            is_coach_list_readable = True
            is_coach_list_writable = user_data.can_modify_coaches()
        else:
            is_actor_parent = ParentChildPair.is_pair(
                    parent_user_data=current_user_data,
                    child_user_data=user_data)
            is_settings_available = is_actor_parent
            is_discussion_available = (is_activity_visible and
                                       not user_data.is_child_account())
            is_coach_list_readable = is_actor_parent
            is_coach_list_writable = False

        tz_offset = self.request_int("tz_offset", default=0)

        # If profile is public and / or activity is visible,
        # include all the relevant data.
        if profile.is_public or is_activity_visible:
            template_values = {
                'show_intro': show_intro,
                'show_discussion_intro': show_discussion_intro,
                'profile': profile,
                'tz_offset': tz_offset,
                'count_videos': setting_model.Setting.count_videos(),
                'count_exercises': exercise_models.Exercise.get_count(),
                'user_data_student':
                    user_data if is_activity_visible else None,
                'profile_root': user_data.profile_root,
                'is_settings_available': is_settings_available,
                'is_coach_list_readable': is_coach_list_readable,
                'is_coach_list_writable': is_coach_list_writable,
                'is_discussion_available': is_discussion_available,
                'view': self.request_string("view", default=""),
            }

        # For private profiles
        else:
            template_values = {
                'profile': profile,
                'profile_root': profile.profile_root,
                'user_data_student': None,
                'count_videos': 0,
                'count_exercises': 0
            }
        self.render_jinja2_template('viewprofile.html', template_values)
Beispiel #41
0
    def get(self):
        user_data = UserData.current()
        user_data_override = self.request_user_data("coach_email")
        if user_util.is_current_user_developer() and user_data_override:
            user_data = user_data_override

        invalid_student = self.request_bool("invalid_student", default=False)

        coach_requests = [
            req.student_requested_identifier
            for req in CoachRequest.get_for_coach(user_data)
            if req.student_requested_data
        ]

        student_lists_models = StudentList.get_for_coach(user_data.key())
        student_lists_list = []
        for student_list in student_lists_models:
            student_lists_list.append({
                'key': str(student_list.key()),
                'name': student_list.name,
            })
        student_lists_dict = dict((g['key'], g) for g in student_lists_list)

        def student_to_dict(s):
            """Convert the UserData s to a dictionary for rendering."""
            return {
                'key':
                str(s.key()),
                'email':
                s.email,
                'username':
                s.username,
                # Note that child users don't have an email.
                'identifier':
                s.username or s.email,
                'nickname':
                s.nickname,
                'profile_root':
                s.profile_root,
                'can_modify_coaches':
                s.can_modify_coaches(),
                'studentLists': [
                    l for l in [
                        student_lists_dict.get(str(list_id))
                        for list_id in s.student_lists
                    ] if l
                ],
            }

        students_data = user_data.get_students_data()
        students = map(student_to_dict, students_data)
        students.sort(key=lambda s: s['nickname'])

        child_accounts = map(student_to_dict, user_data.get_child_users())
        template_values = {
            'students': students,
            'child_accounts': child_accounts,
            'child_account_keyset': set([c['key'] for c in child_accounts]),
            'students_json': json.dumps(students),
            'student_lists': student_lists_list,
            'student_lists_json': json.dumps(student_lists_list),
            'invalid_student': invalid_student,
            'coach_requests': coach_requests,
            'coach_requests_json': json.dumps(coach_requests),
            'selected_nav_link': 'coach',
            'email': user_data.email,
        }
        self.render_jinja2_template('viewstudentlists.html', template_values)
Beispiel #42
0
 def get(self):
     """ Redirect legacy /coaches to profile page's coaches tab.
     """
     user_data = UserData.current()
     self.redirect(user_data.profile_root + "coaches")
Beispiel #43
0
 def get(self):
     return self.do_request(self.request_student_user_data(),
                            UserData.current(), "/students")
Beispiel #44
0
 def get_student_list(self, coach):
     student_lists = StudentList.get_for_coach(coach.key())
     _, actual_list = get_last_student_list(
         self, student_lists,
         coach.key() == UserData.current().key())
     return actual_list
 def get_student_list(self, coach):
     student_lists = StudentList.get_for_coach(coach.key())
     current_user_is_coach = (coach.key() == UserData.current().key())
     _, actual_list = util_profile.get_last_student_list(self,
             student_lists, current_user_is_coach)
     return actual_list
Beispiel #46
0
    def get(self):
        template_values = {}
        user_data = UserData.current()

        if user_data is not None:
            user_email = user_data.user_email
            nickname = ""
            if facebook_util.is_facebook_user_id(user_email):
                nickname = facebook_util.get_facebook_nickname(user_email)

            application_filled = self.request.get('application_filled')
            make_payment = self.request.get('make_payment')

            if make_payment:
                student_email = self.request.get('student_email')
                is_parent_str = self.request.get('is_parent')

                query = SummerStudent.all()
                query.filter('email = ', student_email)
                student = query.get()

                if student is None:
                    output_str = 'Please <a href="/summer/application">apply</a> first' % student_email
                    self.response.out.write(output_str)
                    return

                if student.processing_fee_paid:
                    self.redirect("/summer/application-status")
                    return

                query = SummerParentData.all()
                query.filter('email = ', student.parent_email)
                parent = query.get()

                if parent is None:
                    logging.error("Unexpected NULL parent for student <%s> with parent <%s>" %
                                   (student_email, student.parent_email))

                if is_parent_str == "True":
                    is_parent = True
                else:
                    is_parent = False

                payee_phone_a = ""
                payee_phone_b = ""
                payee_phone_c = ""
                phone_parts = parent.phone.split("-")
                if phone_parts is not None:
                    payee_phone_a = phone_parts[0]
                    payee_phone_b = phone_parts[1]
                    payee_phone_c = phone_parts[2]

                template_values = {
                    "authenticated" : True,
                    "make_payment" : True,
                    "is_parent" : is_parent,
                    "is_parent_js" : json.dumps(is_parent),
                    "student" : student,
                    "student_js" : json.dumps(student.to_dict()),
                    "payee" : parent,
                    "payee_phone_a" : payee_phone_a,
                    "payee_phone_b" : payee_phone_b,
                    "payee_phone_c" : payee_phone_c,
                    "user_email" : user_email,
                    "nickname" : nickname,
                }

            elif not application_filled:
                template_values = self.authenticated_response()

            else:
                first_name = self.request.get('first_name')
                student_email = self.request.get('student_email')

                query = SummerStudent.all()
                query.filter('email = ', student_email)
                student = query.get()
                if student is None:
                    student = SummerStudent()
                    student.email = student_email
                    student.applier_email = user_email
                    student.processing_fee_paid = False
                    student.tuition_paid = False

                student.first_name = first_name
                student.last_name = self.request.get('last_name')

                student.date_of_birth = self.request.get('date_of_birth')

                if self.request.get('gender') == "Female":
                    student.is_female = True
                else:
                    student.is_female = False

                student.grade = self.request.get('grade')
                student.school = self.request.get('school')
                student.school_zipcode = self.request.get('school_zip')

                student.session_1 = self.request.get('session_1')
                student.session_2 = self.request.get('session_2')
                student.session_3 = self.request.get('session_3')

                session_choices = { "0":[], "1":[], "2":[], "3":[] }
                session_choices[student.session_1].append("Session 1")
                session_choices[student.session_2].append("Session 2")
                session_choices[student.session_3].append("Session 3")

                student.no_choice = session_choices["0"]
                student.first_choice = session_choices["1"]
                student.second_choice = session_choices["2"]
                student.third_choice = session_choices["3"]

                student.answer_why = self.request.get('answer_why')
                student.answer_how = self.request.get('answer_how')

                student.processing_fee = self.request.get('fee')

                student.tuition = 'TBD'

                student.application_year = '2012'
                student.application_status = 'Processing'

                if user_email == student_email:
                    is_parent = False
                    student.self_applied = True
                else:
                    is_parent = True
                    student.self_applied = False

                student.parent_relation = self.request.get('relation')
                student.parent_email = self.request.get('parent_email')

                student.put()

                query = SummerParentData.all()
                query.filter('email = ', student.parent_email)
                parent = query.get()
                if parent is None:
                    parent = SummerParentData()
                    parent.email = student.parent_email

                parent.first_name = self.request.get('parent_first_name')
                parent.last_name = self.request.get('parent_last_name')
                parent.address_1 = self.request.get('parent_address_1')
                parent.address_2 = self.request.get('parent_address_2')
                parent.city = self.request.get('parent_city')
                parent.state = self.request.get('parent_state')
                parent.zipcode = self.request.get('parent_zip')
                parent.country = self.request.get('parent_country')
                parent.phone = self.request.get('parent_phone')
                parent.comments = self.request.get('parent_comments')

                if student.key() not in parent.students:
                    parent.students.append(student.key())

                parent.put()

                if student.processing_fee_paid:
                    self.redirect("/summer/application-status")
                    return

                payee_phone_a = ""
                payee_phone_b = ""
                payee_phone_c = ""
                phone_parts = parent.phone.split("-")
                if phone_parts is not None:
                    payee_phone_a = phone_parts[0]
                    payee_phone_b = phone_parts[1]
                    payee_phone_c = phone_parts[2]

                # Only send email if the user's email is a valid one
                if not facebook_util.is_facebook_user_id(parent.email):
                    mail.send_mail( \
                        sender = FROM_EMAIL, \
                        to = parent.email, \
                        subject = "Khan Academy Discovery Lab Application", \
                        body = """Dear %s,
                
We have received your application for %s %s for the Khan Academy Discovery Lab 2012. Please ensure you have paid the $5.00 processing fee for the application.

We will notify you about the status of the application as soon as possible, no later than March 1st, 2012. You can always check the status of the application any time at http://www.khanacademy.org/summer/application-status.

Thank you!
Khan Academy Discovery Lab""" % (parent.first_name, student.first_name, student.last_name))

                template_values = {
                    "authenticated" : True,
                    "make_payment" : True,
                    "is_parent" : is_parent,
                    "is_parent_js" : json.dumps(is_parent),
                    "student" : student,
                    "student_js" : json.dumps(student.to_dict()),
                    "parent" : parent,
                    "parent_js" : json.dumps(parent.to_dict()),
                    "payee" : parent,
                    "payee_phone_a" : payee_phone_a,
                    "payee_phone_b" : payee_phone_b,
                    "payee_phone_c" : payee_phone_c,
                    "user_email" : user_email,
                    "nickname" : nickname,
                }

        else:
            template_values = {
                "authenticated" : False,
                "applied" : False
            }

        self.add_global_template_values(template_values)
        self.render_jinja2_template('summer/summer.html', template_values)
Beispiel #47
0
    def get_template(self, template_file, additional_dirs=None):
        """Computes location of template files for the current namespace."""
        self.template_value[COURSE_INFO_KEY] = self.app_context.get_environ()
        self.template_value['is_course_admin'] = Roles.is_course_admin(
            self.app_context)
        self.template_value[
            'is_read_write_course'] = self.app_context.fs.is_read_write()
        self.template_value['is_super_admin'] = Roles.is_super_admin()
        self.template_value[COURSE_BASE_KEY] = self.get_base_href(self)
        template_environ = self.app_context.get_template_environ(
            self.template_value[COURSE_INFO_KEY]['course']['locale'],
            additional_dirs)
        import khan.util as util
        import khan.templatefilters as templatefilters
        import badges.templatetags
        import avatars.templatetags
        import js_css_packages.templatetags
        import app
        import templatetags
        import user_models
        template_environ.filters['gcb_tags'] = jinja_utils.get_gcb_tags_filter(
            self)
        template_environ.filters[
            'thousands_separated'] = util.thousands_separated_number
        template_environ.filters['pluralize'] = templatefilters.pluralize
        template_environ.filters["escapejs"] = templatefilters.escapejs
        template_environ.globals["badges"] = badges.templatetags
        template_environ.globals["avatars"] = avatars.templatetags
        template_environ.globals[
            "js_css_packages"] = js_css_packages.templatetags
        template_environ.globals["App"] = app.App
        template_environ.globals["templatetags"] = templatetags
        from user_models import StudentList, UserData, ParentChildPair
        import logging
        current_user_data = UserData.current(True)
        #logging.error("Current user: %s" % current_user_data)
        #logging.error("Nickname: %s" % current_user_data.nickname)
        #logging.error("Username: %s" % current_user_data.username)
        #logging.error("UserNickname: %s" % current_user_data.user_nickname)
        #logging.error("UserEmail: %s" % current_user_data.user_email)
        if current_user_data:
            template_environ.globals[
                "username"] = current_user_data.nickname or current_user_data.username or current_user_data.user_nickname or current_user_data.user_email
        else:
            template_environ.globals["username"] = ""

        #template_environ['environment_args'] = {'autoescape' : False}


#        template_environ["filters"] = {
#            'gcb_tags': jinja_utils.get_gcb_tags_filter(self),
#            #"thousands_separated": util.thousands_separated_number,
#        }
#        template_environ["globals"] = {
#            "templatetags": templatetags,
#            "profiles": profiles.templatetags,
#            "avatars": avatars.templatetags,
#            "badges": badges.templatetags,
#            "phantom_users": phantom_users.templatetags,
##            "gae_mini_profiler": gae_mini_profiler.templatetags,
##            "xsrf": api.auth.xsrf,
##            "UserData": UserData,
##            "json": json,
##            "App": App,
##            "handlebars_template": handlebars.render.render_from_jinja,
##            "gandalf": gandalf.bridge.gandalf,
#        }
        return template_environ.get_template(template_file)
Beispiel #48
0
 def get(self):
     return self.do_request(
         self.request_student_user_data(),
         UserData.current(),
         "/students"
     )
    def get(self, email_or_username=None, subpath=None):

        """Render a student profile.

        Keyword arguments:
        email_or_username -- matches the first grouping in /profile/(.+?)/(.*)
        subpath -- matches the second grouping, and is ignored server-side,
        but is used to route client-side

        """
        current_user_data = UserData.current() or UserData.pre_phantom()

        if current_user_data.is_pre_phantom and email_or_username is None:
            # Pre-phantom users don't have any profiles - just redirect them
            # to the homepage if they try to view their own.
            self.redirect(util.create_login_url(self.request.uri))
            return

        if not email_or_username:
            user_data = current_user_data
        elif email_or_username == 'nouser' and current_user_data.is_phantom:
            user_data = current_user_data
        else:
            user_data = UserData.get_from_url_segment(email_or_username)
            if (user_models.UniqueUsername.is_valid_username(email_or_username)
                    and user_data
                    and user_data.username
                    and user_data.username != email_or_username):
                # The path segment is a username and resolved to the user,
                # but is not actually their canonical name. Redirect to the
                # canonical version.
                if subpath:
                    self.redirect("/profile/%s/%s" % (user_data.username,
                                                      subpath))
                else:
                    self.redirect("/profile/%s" % user_data.username)
                return


        profile = UserProfile.from_user(user_data, current_user_data)

        if profile is None:
            self.render_jinja2_template('noprofile.html', {})
            return

        is_self = user_data.user_id == current_user_data.user_id
        show_intro = False

        if is_self:
            promo_record = promo_record_model.PromoRecord.get_for_values(
                    "New Profile Promo", user_data.user_id)

            if promo_record is None:
                # The user has never seen the new profile page! Show a tour.
                if subpath:
                    # But if they're not on the root profile page, force them.
                    self.redirect("/profile")
                    return

                show_intro = True
                promo_record_model.PromoRecord.record_promo("New Profile Promo",
                                                user_data.user_id,
                                                skip_check=True)

        has_full_access = is_self or user_data.is_visible_to(current_user_data)
        tz_offset = self.request_int("tz_offset", default=0)

        template_values = {
            'show_intro': show_intro,
            'profile': profile,
            'tz_offset': tz_offset,
            'count_videos': setting_model.Setting.count_videos(),
            'count_exercises': exercise_models.Exercise.get_count(),
            'user_data_student': user_data if has_full_access else None,
            'profile_root': user_data.profile_root,
            "view": self.request_string("view", default=""),
        }
        self.render_jinja2_template('viewprofile.html', template_values)
Beispiel #50
0
 def get(self):
     """ Redirect legacy /coaches to profile page's coaches tab.
     """
     user_data = UserData.current()
     self.redirect(user_data.profile_root + "coaches")
Beispiel #51
-1
 def get_student_list(self, coach):
     student_lists = StudentList.get_for_coach(coach.key())
     _, actual_list = get_last_student_list(self, student_lists, coach.key()==UserData.current().key())
     return actual_list