def do_request(self, student, coach, redirect_to): if not UserData.current(): self.redirect(url_util.create_login_url(self.request.uri)) return if student and coach: self.remove_student_from_coach(student, coach) if not self.is_ajax_request(): self.redirect(redirect_to)
def user_info(user_data, continue_url=None): if not continue_url: continue_url = "/" context = { "user_data": user_data, "username": user_data.nickname or user_data.username, "login_url": url_util.create_login_url(continue_url), "logout_url": url_util.create_logout_url(continue_url), } return shared_jinja.get().render_template("user_info_only.html", **context)
def add_global_template_values(self, template_values): template_values['App'] = App template_values['None'] = None if not template_values.has_key('user_data'): user_data = user_models.UserData.current() template_values['user_data'] = user_data user_data = template_values['user_data'] display_name = "" if user_data: display_name = user_data.nickname or user_data.username template_values['server_time'] = time.time() # TODO(marcia): Remove username, points, logged_in template values # since they should be encapsulated in this UserProfile object logged_in_user_profile = util_profile.UserProfile.from_user(user_data, user_data) template_values['logged_in_user_profile'] = logged_in_user_profile # TODO(benkomalo): rename this global template property from "username" # as it's not really the user's username, but just a display name. template_values['username'] = display_name template_values['points'] = user_data.points if user_data else 0 template_values['logged_in'] = not user_data.is_phantom if user_data else False template_values['http_host'] = os.environ["HTTP_HOST"] # Always insert a post-login request before our continue url template_values['continue'] = url_util.create_post_login_url( template_values.get('continue') or self.request.uri) template_values['login_url'] = ('%s&direct=1' % url_util.create_login_url( template_values['continue'])) template_values['logout_url'] = url_util.create_logout_url( self.request.uri) # TODO(stephanie): these settings are temporary; for FB testing purposes only template_values['site_base_url'] = 'http://%s' % os.environ["HTTP_HOST"] template_values['is_mobile'] = False template_values['is_mobile_capable'] = False template_values['is_ipad'] = False if self.is_mobile_capable(): template_values['is_mobile_capable'] = True template_values['is_ipad'] = self.is_ipad() if 'is_mobile_allowed' in template_values and template_values['is_mobile_allowed']: template_values['is_mobile'] = self.is_mobile() # overridable hide_analytics querystring that defaults to true in dev # mode but false for prod. hide_analytics = self.request_bool("hide_analytics", App.is_dev_server) template_values['hide_analytics'] = hide_analytics # client-side error logging template_values['include_errorception'] = gandalf('errorception') # Analytics template_values['mixpanel_enabled'] = gandalf('mixpanel_enabled') # Enable for Mixpanel testing only # You will need to ask Tom, Kitt, or Marcia to add you to the "Khan # Academy Test" project on Mixpanel so that you can see the results. if False: template_values['mixpanel_test'] = "70acc4fce4511b89477ac005639cfee1" template_values['mixpanel_enabled'] = True template_values['hide_analytics'] = False if template_values['mixpanel_enabled']: template_values['mixpanel_id'] = gae_bingo.identity.identity() if not template_values['hide_analytics']: superprops_list = user_models.UserData.get_analytics_properties(user_data) # Create a superprops dict for MixPanel with a version number # Bump the version number if changes are made to the client-side # analytics code and we want to be able to filter by version. template_values['mixpanel_superprops'] = dict(superprops_list) # Copy over first 4 per-user properties for GA # (The 5th is reserved for Bingo) template_values['ga_custom_vars'] = superprops_list[0:4] if user_data: user_goals = goals.models.GoalList.get_current_goals(user_data) goals_data = [g.get_visible_data() for g in user_goals] if goals_data: template_values['global_goals'] = jsonify(goals_data) badges_earned = badges.util_badges.get_badge_notifications_json() template_values['badges_earned'] = badges_earned # Disable topic browser in the header on mobile devices template_values['watch_topic_browser_enabled'] = not self.is_mobile_capable() template_values['show_topic_pages'] = True return 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)