def exercise_message(exercise, user_exercise_graph, sees_graph=False,
        review_mode=False):
    """Render UserExercise html for APIActionResults["exercise_message_html"] listener in khan-exercise.js.

    This is called **each time** a problem is either attempted or a hint is called (via /api/v1.py)
    returns nothing unless a user is struggling, proficient, etc. then it returns the appropriat template

    See Also: APIActionResults

    sees_graph is part of an ab_test to see if a small graph will help
    """

    # TODO(david): Should we show a message if the user gets a problem wrong
    #     after proficiency, to explain that this exercise needs to be reviewed?

    exercise_states = user_exercise_graph.states(exercise.name)

    if review_mode and user_exercise_graph.has_completed_review():
        filename = 'exercise_message_review_finished.html'

    elif (exercise_states['proficient'] and not exercise_states['reviewing'] and
            not review_mode):
        if sees_graph:
            filename = 'exercise_message_proficient_withgraph.html'
        else:
            filename = 'exercise_message_proficient.html'

    elif exercise_states['struggling']:
        filename = 'exercise_message_struggling.html'
        exercise_states['exercise_videos'] = exercise.related_videos_fetch()

    else:
        return None

    return shared_jinja.get().render_template(filename, **exercise_states)
示例#2
0
def badge_info(user_data):
    from badges import badges, util_badges

    counts_dict = {}
    if user_data:
        counts_dict = util_badges.get_badge_counts(user_data)
    else:
        counts_dict = badges.BadgeCategory.empty_count_dict()

    sum_counts = 0
    for key in counts_dict:
        sum_counts += counts_dict[key]

    context = {
        "sum": sum_counts,
        "bronze": counts_dict[badges.BadgeCategory.BRONZE],
        "silver": counts_dict[badges.BadgeCategory.SILVER],
        "gold": counts_dict[badges.BadgeCategory.GOLD],
        "platinum": counts_dict[badges.BadgeCategory.PLATINUM],
        "diamond": counts_dict[badges.BadgeCategory.DIAMOND],
        "master": counts_dict[badges.BadgeCategory.MASTER],
        "user": user_data,
    }
    return shared_jinja.get().render_template(
        "phantom_users/badge_counts.html", **context)
示例#3
0
def login_notifications_html(text, user_data, continue_url="/"):
    context = {"login_notification": text,
               "continue": continue_url,
               "user_data": user_data}

    return shared_jinja.get().render_template(
        "phantom_users/notifications.html", **context)
示例#4
0
def point_info(user_data):
    if user_data:
        points = user_data.points
    else:
        points = 0
    context = {"points": points}
    return shared_jinja.get().render_template("phantom_users/user_points.html", **context)
def badge_block(badge, user_badge=None, show_frequency=False,
                user_data_student=None):

    if user_badge:
        badge.is_owned = True

    if badge.is_hidden():
        return ""  # Don't render anything for this hidden badge

    frequency = None
    if show_frequency:
        frequency = badge.frequency()

    can_become_goal = (user_data_student and
                       not user_data_student.is_phantom and
                       not badge.is_owned and
                       badge.is_goal)

    template_values = {"badge": badge,
                       "user_badge": user_badge,
                       "extended_description": badge.safe_extended_description,
                       "frequency": frequency,
                       "can_become_goal": can_become_goal}

    return shared_jinja.get().render_template("badges/badge_block.html",
                                              **template_values)
示例#6
0
def topic_browser(browser_id, version_number=None):
    if version_number:
        version = topic_models.TopicVersion.get_by_number(version_number)
    else:
        version = None

    root = topic_models.Topic.get_root(version)
    if not root:
        return ""

    tree = root.make_tree(types = ["Topics"])

    # TODO(tomyedwab): Remove this once the confusion over the old Developmental Math playlists settles down
    if not version:
        version = topic_models.TopicVersion.get_default_version()
    developmental_math = topic_models.Topic(
        id="developmental-math",
        version=version,
        title="Developmental Math",
        standalone_title="Developmental Math"
    )
    developmental_math.children = []
    #[topic for topic in tree.children if topic.id == "math"][0].children.append(developmental_math)

    template_values = {
       'browser_id': browser_id, 'topic_tree': tree 
    }

    return shared_jinja.get().render_template("topic_browser.html", **template_values)
示例#7
0
文件: library.py 项目: di445/server
def library_content_html(mobile=False, version_number=None):

    if version_number:
        version = TopicVersion.get_by_number(version_number)
    else:
        version = TopicVersion.get_default_version()

    tree = Topic.get_root(version).make_tree(types = ["Topics", "Video", "Exercise", "Url"])

    videos = [item for item in walk_children(tree) if item.kind()=="Video"]

    root, = prepare(tree)
    topics = root.subtopics

    timestamp = time.time()

    template_values = {
        'topics': topics,
        'is_mobile': mobile,
        # convert timestamp to a nice integer for the JS
        'timestamp': int(round(timestamp * 1000)),
        'version_date': str(version.made_default_on),
        'version_id': version.number,
        'approx_vid_count': Video.approx_count(),
        'exercise_count': Exercise.get_count(),
    }

    html = shared_jinja.get().render_template("library_content_template.html", **template_values)

    return html
示例#8
0
def badge_counts(user_data):

    counts_dict = {}
    # TODO: awkward turtle, decide what happens with phantom users
    link_to_profile = "/profile"
    if user_data:
        counts_dict = util_badges.get_badge_counts(user_data)
        link_to_profile = user_data.profile_root + "/achievements"
    else:
        counts_dict = badges.BadgeCategory.empty_count_dict()

    sum_counts = 0
    for key in counts_dict:
        sum_counts += counts_dict[key]

    template_context = {
            "link_to_profile": link_to_profile,
            "sum": sum_counts,
            "bronze": counts_dict[badges.BadgeCategory.BRONZE],
            "silver": counts_dict[badges.BadgeCategory.SILVER],
            "gold": counts_dict[badges.BadgeCategory.GOLD],
            "platinum": counts_dict[badges.BadgeCategory.PLATINUM],
            "diamond": counts_dict[badges.BadgeCategory.DIAMOND],
            "master": counts_dict[badges.BadgeCategory.MASTER],
    }

    return shared_jinja.get().render_template("badges/badge_counts.html", **template_context)
示例#9
0
def column_major_sorted_videos(topic,
                               num_cols=3,
                               column_width=300,
                               gutter=20,
                               font_size=12):
    content = topic.content
    items_in_column = len(content) / num_cols
    remainder = len(content) % num_cols
    link_height = font_size * 1.5
    # Calculate the column indexes (tops of columns). Since video lists won't divide evenly, distribute
    # the remainder to the left-most columns first, and correctly increment the indices for remaining columns
    column_indices = [(items_in_column * multiplier +
                       (multiplier if multiplier <= remainder else remainder))
                      for multiplier in range(1, num_cols + 1)]

    template_values = {
        "topic": topic,
        "content": content,
        "column_width": column_width,
        "column_indices": column_indices,
        "link_height": link_height,
        "list_height": column_indices[0] * link_height,
    }

    return shared_jinja.get().render_template("column_major_order_videos.html",
                                              **template_values)
示例#10
0
def topic_browser(browser_id, version_number=None):
    if version_number:
        version = topic_models.TopicVersion.get_by_number(version_number)
    else:
        version = None

    root = topic_models.Topic.get_root(version)
    if not root:
        return ""

    tree = root.make_tree(types=["Topics"])

    # TODO(tomyedwab): Remove this once the confusion over the old Developmental Math playlists settles down
    if not version:
        version = topic_models.TopicVersion.get_default_version()
    developmental_math = topic_models.Topic(
        id="developmental-math",
        version=version,
        title="Developmental Math",
        standalone_title="Developmental Math")
    developmental_math.children = []
    #[topic for topic in tree.children if topic.id == "math"][0].children.append(developmental_math)

    template_values = {'browser_id': browser_id, 'topic_tree': tree}

    return shared_jinja.get().render_template("topic_browser.html",
                                              **template_values)
示例#11
0
def streak_bar(user_exercise_dict):
    progress = user_exercise_dict["progress"]

    bar_max_width = 228
    bar_width = min(1.0, progress) * bar_max_width

    levels = []
    if user_exercise_dict["summative"]:
        c_levels = user_exercise_dict["num_milestones"]
        level_offset = bar_max_width / float(c_levels)
        for ix in range(c_levels - 1):
            levels.append(math.ceil((ix + 1) * level_offset) + 1)

    template_values = {
        "is_suggested": user_exercise_dict["suggested"],
        "is_proficient": user_exercise_dict["proficient"],
        "float_progress": progress,
        "progress": models.UserExercise.to_progress_display(progress),
        "bar_width": bar_width,
        "bar_max_width": bar_max_width,
        "levels": levels
    }

    return shared_jinja.get().render_template("streak_bar.html",
                                              **template_values)
示例#12
0
def playlist_browser(browser_id):
    template_values = {
        'browser_id': browser_id,
        'playlist_structure': topics_list.PLAYLIST_STRUCTURE
    }

    return shared_jinja.get().render_template("playlist_browser.html",
                                              **template_values)
示例#13
0
def point_info(user_data):
    if user_data:
        points = user_data.points
    else:
        points = 0
    context = {"points": points}
    return shared_jinja.get().render_template("phantom_users/user_points.html",
                                              **context)
示例#14
0
def email_share_badge(desc, activity, event_description=None):
    contex = {}
    if desc:
        subject = "I just earned the %s %s on Khan Academy" % (desc, ("" if not activity else "in " + activity))
        body = "You should check it out %s" % BASE_BADGE_URL
        context = {"subject": subject, "body": body, "event_description": event_description}

    return shared_jinja.get().render_template("social/email_share.html", **context)
示例#15
0
def email_share_video(title, youtube_id, event_description=None):
    contex = {}
    if title and youtube_id:
        subject = "I just learned about %s on Khan Academy" % title
        body = "You can learn about it too. Check out %s" % (BASE_VIDEO_URL % youtube_id)
        context = {"subject": subject, "body": body, "event_description": event_description}

    return shared_jinja.get().render_template("social/email_share.html", **context)
示例#16
0
def login_notifications_html(text, user_data, continue_url="/"):
    context = {
        "login_notification": text,
        "continue": continue_url,
        "user_data": user_data
    }

    return shared_jinja.get().render_template(
        "phantom_users/notifications.html", **context)
示例#17
0
def library_content_html(ajax=False, version_number=None):
    """" Returns the HTML for the structure of the topics as they will be
    populated on the homepage. Does not actually contain the list of video
    names as those are filled in later asynchronously via the cache.
    """
    if version_number:
        version = topic_models.TopicVersion.get_by_number(version_number)
    else:
        version = topic_models.TopicVersion.get_default_version()

    tree = topic_models.Topic.get_root(version).make_tree(
        types=["Topics", "Video", "Url"])
    topics = flatten_tree(tree)

    # TODO(tomyedwab): Remove this once the confusion over the old
    # Developmental Math playlists settles down
    developmental_math = topic_models.Topic(
        id="developmental-math",
        version=version,
        title="Developmental Math",
        standalone_title="Developmental Math",
        description="The Developmental Math playlist has been reorganized. "
        "The videos which used to be in the Developmental Math "
        "playlist can now be found under "
        "<a href=\"#algebra\">Algebra</a>.")
    developmental_math.is_super = True
    developmental_math.subtopics = []
    developmental_math.homepage_title = "Developmental Math"
    topics.append(developmental_math)

    topics.sort(key=lambda topic: topic.standalone_title)

    # special case the duplicate topics for now, eventually we need to
    # either make use of multiple parent functionality (with a hack
    # for a different title), or just wait until we rework homepage
    topics = [
        topic for topic in topics
        if not topic.id == "new-and-noteworthy" and not (
            topic.standalone_title == "California Standards Test: Geometry"
            and not topic.id == "geometry-2")
    ]

    # print_topics(topics)

    add_next_topic(topics)

    template_values = {
        'topics': topics,
        'ajax': ajax,
        'version_date': str(version.made_default_on),
        'version_id': version.number
    }

    html = shared_jinja.get().render_template("library_content_template.html",
                                              **template_values)

    return html
示例#18
0
def playlist_content_html():
    """" Returns the HTML for the structure of the playlists as they will be
    populated ont he homepage. Does not actually contain the list of video
    names as those are filled in later asynchronously via the cache.
    
    """

    # No cache found -- regenerate HTML
    smart_history = getSmartHistoryContent()

    dict_playlists_by_title = {}
    all_playlists = []

    for playlist in Playlist.all():
        if playlist.title in topics_list:
            dict_playlists_by_title[playlist.title] = playlist

    for topic in topics_list:
        if topic in dict_playlists_by_title:
            playlist = dict_playlists_by_title[topic]
            video_count = playlist.get_video_count()
            # 3 columns, 18px per row. This must be updated in conjunction
            # with code in homepage.js
            height = math.ceil(video_count / 3) * 18

            playlist_data = {
                'title': topic,
                'topic': topic,
                'playlist': playlist,
                'list_height': height,
                'next': None,
            }

            all_playlists.append(playlist_data)

    playlist_data_prev = None
    for playlist_data in all_playlists:
        if playlist_data_prev:
            playlist_data_prev['next'] = playlist_data
        playlist_data_prev = playlist_data

    timestamp = time.time()
    template_values = {
        'App': App,
        'all_playlists': all_playlists,
        'smart_history': smart_history,

        # convert timestamp to a nice integer for the JS
        'timestamp': int(round(timestamp * 1000)),
    }

    html = shared_jinja.get().render_template("library_playlist_template.html",
                                              **template_values)
    Setting.cached_playlist_content_date(
        str(datetime.datetime.fromtimestamp(timestamp)))
    return html
示例#19
0
def library_content_html(ajax=False, version_number=None):
    """" Returns the HTML for the structure of the topics as they will be
    populated on the homepage. Does not actually contain the list of video
    names as those are filled in later asynchronously via the cache.
    """
    if version_number:
        version = topic_models.TopicVersion.get_by_number(version_number)
    else:
        version = topic_models.TopicVersion.get_default_version()

    tree = topic_models.Topic.get_root(version).make_tree(
        types=["Topics", "Video", "Url"])
    topics = flatten_tree(tree)

    # TODO(tomyedwab): Remove this once the confusion over the old
    # Developmental Math playlists settles down
    developmental_math = topic_models.Topic(
        id="developmental-math",
        version=version,
        title="Developmental Math",
        standalone_title="Developmental Math",
        description="The Developmental Math playlist has been reorganized. "
                    "The videos which used to be in the Developmental Math "
                    "playlist can now be found under "
                    "<a href=\"#algebra\">Algebra</a>."
    )
    developmental_math.is_super = True
    developmental_math.subtopics = []
    developmental_math.homepage_title = "Developmental Math"
    topics.append(developmental_math)

    topics.sort(key=lambda topic: topic.standalone_title)

    # special case the duplicate topics for now, eventually we need to
    # either make use of multiple parent functionality (with a hack
    # for a different title), or just wait until we rework homepage
    topics = [topic for topic in topics 
              if not topic.id == "new-and-noteworthy" and not
              (topic.standalone_title == "California Standards Test: Geometry" 
              and not topic.id == "geometry-2")] 

    # print_topics(topics)

    add_next_topic(topics)

    template_values = {
        'topics': topics,
        'ajax': ajax,
        'version_date': str(version.made_default_on),
        'version_id': version.number
    }

    html = shared_jinja.get().render_template("library_content_template.html",
                                              **template_values)

    return html
示例#20
0
def playlist_content_html():
    """" Returns the HTML for the structure of the playlists as they will be
    populated ont he homepage. Does not actually contain the list of video
    names as those are filled in later asynchronously via the cache.
    
    """
    
    # No cache found -- regenerate HTML
    smart_history = getSmartHistoryContent()

    dict_playlists_by_title = {}
    all_playlists = []

    for playlist in Playlist.all():
        if playlist.title in topics_list:
            dict_playlists_by_title[playlist.title] = playlist

    for topic in topics_list:
        if topic in dict_playlists_by_title:
            playlist = dict_playlists_by_title[topic]
            video_count = playlist.get_video_count() 
            # 3 columns, 18px per row. This must be updated in conjunction
            # with code in homepage.js
            height = math.ceil(video_count / 3) * 18

            playlist_data = {
                             'title': topic,
                             'topic': topic,
                             'playlist': playlist,
                             'list_height': height,
                             'next': None,
                             }

            all_playlists.append(playlist_data)

    playlist_data_prev = None
    for playlist_data in all_playlists:
        if playlist_data_prev:
            playlist_data_prev['next'] = playlist_data
        playlist_data_prev = playlist_data

    timestamp = time.time()
    template_values = {
        'App' : App,
        'all_playlists': all_playlists,
        'smart_history': smart_history,
        
        # convert timestamp to a nice integer for the JS
        'timestamp': int(round(timestamp * 1000)),
        }

    html = shared_jinja.get().render_template("library_playlist_template.html",
                                              **template_values)
    Setting.cached_playlist_content_date(
            str(datetime.datetime.fromtimestamp(timestamp)))
    return html
示例#21
0
def email_share_exercise(name, problems, proficiency, event_description=None):
    contex = {}
    if name and problems:
        subject = "I was just working on about %s on Khan Academy" % name
        body = "And I answered %s question%s right %s You can try it too: %s" % (problems, "" if problems == 1 else "s", ( "to earn proficiency!" if proficiency else "." ), BASE_EXERCISE_URL)
        context = { 'subject': subject,
                    'body': body,
                    'event_description': event_description }

    return shared_jinja.get().render_template("social/email_share.html", **context)
示例#22
0
def share_video_button(video_title, description, youtube_id, event_description=None):
    context = {}
    if video_title and description and youtube_id:
        context = { 'type': 'video',
                    'video_title': video_title,
                    'description': description,
                    'youtube_id': youtube_id,
                    'event_description': event_description }

    return shared_jinja.get().render_template("social/share_button.html", **context)
示例#23
0
def facebook_share_video(name, desc, youtube_id, event_description=None):
    context = {}
    if name and desc and id:
        context = { 'type': 'video',
                    'name': name,
                    'desc': desc,
                    'id': youtube_id,
                    'event_description': event_description }

    return shared_jinja.get().render_template("social/facebook_share.html", **context)
示例#24
0
def share_exercise_button(problem_count, proficiency, name, event_description=None):
    context = {}
    if problem_count and name:
        context = { 'type': 'exercise',
                    'problem_count': problem_count,
                    'proficiency': proficiency,
                    'name': name,
                    'event_description': event_description }

    return shared_jinja.get().render_template("social/share_button.html", **context)
示例#25
0
def twitter_share_exercise(name, problems, proficiency, event_description=None):
    context = {}
    if name and problems:
        url = BASE_EXERCISE_URL
        text = "just answered %s question%s right %s %s" % (problems, "" if problems == 1 else "s", ( "to achieve proficiency in" if proficiency else "in" ), name)
        context = { 'url': url, 
                    'text': text,
                    'tagline': SITE_TAGLINE,
                    'event_description': event_description }

    return shared_jinja.get().render_template("social/twitter_share.html", **context)
示例#26
0
def login_notifications_html(login_notifications, user_data, continue_url="/"):
    login_notification = None if len(
        login_notifications) == 0 else login_notifications[0]

    context = {
        "login_notification": login_notification,
        "continue": continue_url,
        "user_data": user_data
    }
    return shared_jinja.get().render_template(
        "phantom_users/notifications.html", **context)
示例#27
0
def facebook_share_exercise(problem_count, proficiency, name, event_description=None):
    context = {}
    if problem_count and name:
        context = { 'type': 'exercise',
                    'problem_count': problem_count, 
                    'plural': "" if problem_count == 1 else "s",
                    'proficiency': ("to achieve proficiency in" if proficiency else "in"),
                    'name': name,
                    'event_description': event_description }

    return shared_jinja.get().render_template("social/facebook_share.html", **context)
示例#28
0
def share_badge_button(description, icon_src, extended_description, context_name, event_description=None):
    context = {}
    if description and icon_src and extended_description:
        context = { 'type': 'badge',
                    'description': description,
                    'icon_src': icon_src,
                    'extended_description': extended_description,
                    'target_context_name': context_name,
                    'event_description': event_description }

    return shared_jinja.get().render_template("social/share_button.html", **context)
示例#29
0
def facebook_share_badge(desc, icon, extended_desc, activity, event_description=None):
    context = {}
    if desc and icon and extended_desc:
        context = { 'type': 'badge', 
                    'desc': desc, 
                    'icon': icon, 
                    'extended_desc': extended_desc,
                    'activity': activity, 
                    'event_description': event_description }

    return shared_jinja.get().render_template("social/facebook_share.html", **context)
示例#30
0
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)
示例#31
0
def share_video_button(video_title, description, youtube_id, event_description=None):
    context = {}
    if video_title and description and youtube_id:
        context = {
            "type": "video",
            "video_title": video_title,
            "description": description,
            "youtube_id": youtube_id,
            "event_description": event_description,
        }

    return shared_jinja.get().render_template("social/share_button.html", **context)
示例#32
0
def share_exercise_button(problem_count, proficiency, name, event_description=None):
    context = {}
    if problem_count and name:
        context = {
            "type": "exercise",
            "problem_count": problem_count,
            "proficiency": proficiency,
            "name": name,
            "event_description": event_description,
        }

    return shared_jinja.get().render_template("social/share_button.html", **context)
示例#33
0
def facebook_share_video(name, desc, youtube_id, event_description=None):
    context = {}
    if name and desc and id:
        context = {
            "type": "video",
            "name": name,
            "desc": desc,
            "id": youtube_id,
            "event_description": event_description,
        }

    return shared_jinja.get().render_template("social/facebook_share.html", **context)
示例#34
0
def twitter_share_video(title, youtube_id, event_description=None):
    context = {}
    if title and youtube_id :
        url = BASE_VIDEO_URL % youtube_id
        text = "just learned about %s" % title 
        context = { 'type': 'video',
                    'url': url,
                    'text': text,
                    'tagline': SITE_TAGLINE, 
                    'event_description': event_description } 

    return shared_jinja.get().render_template("social/twitter_share.html", **context)
示例#35
0
def twitter_share_badge(desc, activity, event_description=None):
    context= {}
    if desc:
        url = BASE_BADGE_URL
        text = "just earned the %s%s on" % (desc, ( "" if not activity else " in " + activity ))
        context = { 'type': 'badge',
                    'url': url,
                    'text': text,
                    'tagline': SITE_TAGLINE,
                    'event_description': event_description }

    return shared_jinja.get().render_template("social/twitter_share.html", **context)
示例#36
0
def login_notifications_html(login_notifications, user_data, continue_url="/"):
    if len(login_notifications):
        login_notification = login_notifications[0]
    else:
        login_notification = None

    context = {"login_notification": login_notification,
               "continue": continue_url,
               "user_data": user_data}

    return shared_jinja.get().render_template(
        "phantom_users/notifications.html", **context)
示例#37
0
def facebook_share_badge(desc, icon, extended_desc, activity, event_description=None):
    context = {}
    if desc and icon and extended_desc:
        context = {
            "type": "badge",
            "desc": desc,
            "icon": icon,
            "extended_desc": extended_desc,
            "activity": activity,
            "event_description": event_description,
        }

    return shared_jinja.get().render_template("social/facebook_share.html", **context)
示例#38
0
def share_badge_button(description, icon_src, extended_description, context_name, event_description=None):
    context = {}
    if description and icon_src and extended_description:
        context = {
            "type": "badge",
            "description": description,
            "icon_src": icon_src,
            "extended_description": extended_description,
            "target_context_name": context_name,
            "event_description": event_description,
        }

    return shared_jinja.get().render_template("social/share_button.html", **context)
示例#39
0
def facebook_share_exercise(problem_count, proficiency, name, event_description=None):
    context = {}
    if problem_count and name:
        context = {
            "type": "oefening",
            "problem_count": problem_count,
            "plural": "" if problem_count == 1 else "en",
            "proficiency": ("to achieve proficiency in" if proficiency else "in"),
            "name": name,
            "event_description": event_description,
        }

    return shared_jinja.get().render_template("social/facebook_share.html", **context)
示例#40
0
def facebook_share_video(name, desc, youtube_id, event_description=None):
    context = {}
    if name and desc and id:
        context = {
            'type': 'video',
            'name': name,
            'desc': desc,
            'id': youtube_id,
            'event_description': event_description
        }

    return shared_jinja.get().render_template("social/facebook_share.html",
                                              **context)
示例#41
0
def exercise_message(exercise,
                     user_exercise_graph,
                     sees_graph=False,
                     review_mode=False):
    """Render UserExercise html for APIActionResults["exercise_message_html"] listener in khan-exercise.js.

    This is called **each time** a problem is either attempted or a hint is called (via /api/v1.py)
    returns nothing unless a user is struggling, proficient, etc. then it returns the appropriat template

    See Also: APIActionResults

    sees_graph is part of an ab_test to see if a small graph will help
    """

    # TODO(david): Should we show a message if the user gets a problem wrong
    #     after proficiency, to explain that this exercise needs to be reviewed?

    exercise_states = user_exercise_graph.states(exercise.name)

    if review_mode and user_exercise_graph.has_completed_review():
        filename = 'exercise_message_review_finished.html'

    elif (exercise_states['proficient'] and not exercise_states['reviewing']
          and not review_mode):
        if sees_graph:
            filename = 'exercise_message_proficient_withgraph.html'
        else:
            filename = 'exercise_message_proficient.html'

    elif exercise_states['struggling']:
        filename = 'exercise_message_struggling.html'
        suggested_prereqs = []
        if exercise.prerequisites:
            proficient_exercises = user_exercise_graph.proficient_exercise_names(
            )
            for prereq in exercise.prerequisites:
                if prereq not in proficient_exercises:
                    suggested_prereqs.append({
                        'ka_url':
                        exercise_models.Exercise.get_relative_url(prereq),
                        'display_name':
                        exercise_models.Exercise.to_display_name(prereq),
                    })
        exercise_states['suggested_prereqs'] = apijsonify.jsonify(
            suggested_prereqs)

    else:
        return None

    return shared_jinja.get().render_template(filename, **exercise_states)
示例#42
0
def twitter_share_badge(desc, activity, event_description=None):
    context = {}
    if desc:
        url = BASE_BADGE_URL
        text = "just earned the %s%s on" % (desc, ("" if not activity else " in " + activity))
        context = {
            "type": "badge",
            "url": url,
            "text": text,
            "tagline": SITE_TAGLINE,
            "event_description": event_description,
        }

    return shared_jinja.get().render_template("social/twitter_share.html", **context)
示例#43
0
def email_share_badge(desc, activity, event_description=None):
    contex = {}
    if desc:
        subject = "I just earned the %s %s on Khan Academy" % (desc, (
            "" if not activity else "in " + activity))
        body = "You should check it out %s" % BASE_BADGE_URL
        context = {
            'subject': subject,
            'body': body,
            'event_description': event_description
        }

    return shared_jinja.get().render_template("social/email_share.html",
                                              **context)
示例#44
0
def email_share_video(title, youtube_id, event_description=None):
    contex = {}
    if title and youtube_id:
        subject = "I just learned about %s on Khan Academy" % title
        body = "You can learn about it too. Check out %s" % (BASE_VIDEO_URL %
                                                             youtube_id)
        context = {
            'subject': subject,
            'body': body,
            'event_description': event_description
        }

    return shared_jinja.get().render_template("social/email_share.html",
                                              **context)
示例#45
0
def badge_notifications_html(user_badges):
    all_badges_dict = util_badges.all_badges_dict()
    for user_badge in user_badges:
        user_badge.badge = all_badges_dict.get(user_badge.badge_name)
        if user_badge.badge:
            user_badge.badge.is_owned = True

    user_badges = filter(lambda user_badge: user_badge.badge is not None, user_badges)

    if len(user_badges) > 1:
        user_badges = sorted(user_badges, reverse=True, key=lambda user_badge: user_badge.badge.points)[:badges.UserNotifier.NOTIFICATION_LIMIT]

    context = {"user_badges": user_badges}

    return shared_jinja.get().render_template("badges/notifications.html", **context)
示例#46
0
def twitter_share_video(title, youtube_id, event_description=None):
    context = {}
    if title and youtube_id:
        url = BASE_VIDEO_URL % youtube_id
        text = "just learned about %s" % title
        context = {
            'type': 'video',
            'url': url,
            'text': text,
            'tagline': SITE_TAGLINE,
            'event_description': event_description
        }

    return shared_jinja.get().render_template("social/twitter_share.html",
                                              **context)
示例#47
0
def share_video_button(video_title,
                       description,
                       youtube_id,
                       event_description=None):
    context = {}
    if video_title and description and youtube_id:
        context = {
            'type': 'video',
            'video_title': video_title,
            'description': description,
            'youtube_id': youtube_id,
            'event_description': event_description
        }

    return shared_jinja.get().render_template("social/share_button.html",
                                              **context)
示例#48
0
def email_share_exercise(name, problems, proficiency, event_description=None):
    contex = {}
    if name and problems:
        subject = "I was just working on about %s on Khan Academy" % name
        body = "And I answered %s question%s right %s You can try it too: %s" % (
            problems, "" if problems == 1 else "s",
            ("to earn proficiency!" if proficiency else "."),
            BASE_EXERCISE_URL)
        context = {
            'subject': subject,
            'body': body,
            'event_description': event_description
        }

    return shared_jinja.get().render_template("social/email_share.html",
                                              **context)
示例#49
0
def share_exercise_button(problem_count,
                          proficiency,
                          name,
                          event_description=None):
    context = {}
    if problem_count and name:
        context = {
            'type': 'exercise',
            'problem_count': problem_count,
            'proficiency': proficiency,
            'name': name,
            'event_description': event_description
        }

    return shared_jinja.get().render_template("social/share_button.html",
                                              **context)
示例#50
0
def twitter_share_badge(desc, activity, event_description=None):
    context = {}
    if desc:
        url = BASE_BADGE_URL
        text = "just earned the %s%s on" % (desc,
                                            ("" if not activity else " in " +
                                             activity))
        context = {
            'type': 'badge',
            'url': url,
            'text': text,
            'tagline': SITE_TAGLINE,
            'event_description': event_description
        }

    return shared_jinja.get().render_template("social/twitter_share.html",
                                              **context)
示例#51
0
def topic_browser(browser_id, version_number=None):
    if version_number:
        version = models.TopicVersion.get_by_number(version_number)
    else:
        version = None

    root = models.Topic.get_root(version)
    if not root:
        return ""

    tree = root.make_tree(types = ["Topics"])

    template_values = {
       'browser_id': browser_id, 'topic_tree': tree 
    }

    return shared_jinja.get().render_template("topic_browser.html", **template_values)
示例#52
0
def facebook_share_badge(desc,
                         icon,
                         extended_desc,
                         activity,
                         event_description=None):
    context = {}
    if desc and icon and extended_desc:
        context = {
            'type': 'badge',
            'desc': desc,
            'icon': icon,
            'extended_desc': extended_desc,
            'activity': activity,
            'event_description': event_description
        }

    return shared_jinja.get().render_template("social/facebook_share.html",
                                              **context)
示例#53
0
def share_badge_button(description,
                       icon_src,
                       extended_description,
                       context_name,
                       event_description=None):
    context = {}
    if description and icon_src and extended_description:
        context = {
            'type': 'badge',
            'description': description,
            'icon_src': icon_src,
            'extended_description': extended_description,
            'target_context_name': context_name,
            'event_description': event_description
        }

    return shared_jinja.get().render_template("social/share_button.html",
                                              **context)
示例#54
0
def facebook_share_exercise(problem_count,
                            proficiency,
                            name,
                            event_description=None):
    context = {}
    if problem_count and name:
        context = {
            'type': 'exercise',
            'problem_count': problem_count,
            'plural': "" if problem_count == 1 else "s",
            'proficiency':
            ("to achieve proficiency in" if proficiency else "in"),
            'name': name,
            'event_description': event_description
        }

    return shared_jinja.get().render_template("social/facebook_share.html",
                                              **context)
示例#55
0
def library_content_html(ajax=False, version_number=None):
    """" Returns the HTML for the structure of the topics as they will be
    populated ont he homepage. Does not actually contain the list of video
    names as those are filled in later asynchronously via the cache.
    """
    if version_number:
        version = TopicVersion.get_by_number(version_number)
    else:
        version = TopicVersion.get_default_version()

    tree = Topic.get_root(version).make_tree(
        types=["Topics", "Video", "Exercise", "Url"])

    videos = [item for item in walk_children(tree) if item.kind() == "Video"]
    add_related_exercises(videos)

    topics = flatten_tree(tree)

    #topics.sort(key = lambda topic: topic.standalone_title)

    # special case the duplicate topics for now, eventually we need to either make use of multiple parent functionality (with a hack for a different title), or just wait until we rework homepage
    topics = [
        topic for topic in topics if (not topic.id == "new-and-noteworthy")
    ]

    # print_topics(topics)

    add_next_topic(topics)

    timestamp = time.time()

    template_values = {
        'topics': topics,
        'ajax': ajax,
        # convert timestamp to a nice integer for the JS
        'timestamp': int(round(timestamp * 1000)),
        'version_date': str(version.made_default_on),
        'version_id': version.number
    }

    html = shared_jinja.get().render_template("library_content_template.html",
                                              **template_values)

    return html
示例#56
0
def twitter_share_exercise(name,
                           problems,
                           proficiency,
                           event_description=None):
    context = {}
    if name and problems:
        url = BASE_EXERCISE_URL
        text = "just answered %s question%s right %s %s" % (
            problems, "" if problems == 1 else "s",
            ("to achieve proficiency in" if proficiency else "in"), name)
        context = {
            'url': url,
            'text': text,
            'tagline': SITE_TAGLINE,
            'event_description': event_description
        }

    return shared_jinja.get().render_template("social/twitter_share.html",
                                              **context)
示例#57
0
def badge_block(badge, user_badge=None, show_frequency=False):

    if user_badge:
        badge.is_owned = True

    if badge.is_hidden():
        return ""  # Don't render anything for this hidden badge

    frequency = None
    if show_frequency:
        frequency = badge.frequency()

    template_values = {
        "badge": badge,
        "user_badge": user_badge,
        "extended_description": badge.safe_extended_description,
        "frequency": frequency
    }

    return shared_jinja.get().render_template("badges/badge_block.html",
                                              **template_values)