Beispiel #1
def topic_context(topic):
    Given a topic node, create all context related to showing that topic
    in a template.
    videos    = topic_tools.get_videos(topic)
    exercises = topic_tools.get_exercises(topic)
    topics    = topic_tools.get_live_topics(topic)
    my_topics = [dict((k, t[k]) for k in ('title', 'path', 'nvideos_local', 'nvideos_known', 'nvideos_available')) for t in topics]

    exercises_path = os.path.join(settings.STATIC_ROOT, "js", "khan-exercises", "exercises")
    exercise_langs = dict([(exercise["id"], ["en"]) for exercise in exercises])

    for lang_code in (set(os.listdir(exercises_path)) - set(["test"])):  # hard-code out test
        loc_path = os.path.join(exercises_path, lang_code)
        if not os.path.isdir(loc_path):

        for exercise in exercises:
            ex_path = os.path.join(loc_path, "%s.html" % exercise["id"])
            if not os.path.exists(ex_path):

    context = {
        "topic": topic,
        "title": topic["title"],
        "description": re.sub(r'<[^>]*?>', '', topic["description"] or ""),
        "videos": videos,
        "exercises": exercises,
        "exercise_langs": exercise_langs,
        "topics": my_topics,
    return context
Beispiel #2
def stamp_availability_on_topic(topic, videos_path=settings.CONTENT_ROOT, force=True, stamp_urls=True, update_counts_question_mark= None):
    """ Uses the (json) topic tree to query the django database for which video files exist

    Returns the original topic dictionary, with two properties added to each NON-LEAF node:
      * nvideos_known: The # of videos in and under that node, that are known (i.e. in the Khan Academy library)
      * nvideos_local: The # of vidoes in and under that node, that were actually downloaded and available locally
    And the following property for leaf nodes:
      * on_disk

    Input Parameters:
    * videos_path: the path to video files
    if update_counts_question_mark is None:
        update_counts_question_mark = do_video_counts_need_update_question_mark()

    if not force and "nvideos_local" in topic:
        return (topic, topic["nvideos_local"], topic["nvideos_known"], False)

    nvideos_local = 0
    nvideos_known = 0

    # Can't deal with leaves
    assert topic["kind"] == "Topic", "Should not be calling this function on leaves; it's inefficient!"

    # Only look for videos if there are more branches
    if len(topic["children"]) == 0:
        logging.debug("no children: %s" % topic["path"])

    for child in topic["children"]:
        #  The children have children, let them figure things out themselves
        if "children" in child:
            if not force and "nvideos_local" in child:
            stamp_availability_on_topic(topic=child, videos_path=videos_path, force=force, stamp_urls=stamp_urls, update_counts_question_mark=update_counts_question_mark)
            nvideos_local += child["nvideos_local"]
            nvideos_known += child["nvideos_known"]

    # BASE CASE:
    # All my children are leaves, so we'll query here (a bit more efficient than 1 query per leaf)
    videos = get_videos(topic)
    for video in videos:
        if force or update_counts_question_mark or "availability" not in video:
            stamp_availability_on_video(video, force=force, stamp_urls=stamp_urls, videos_path=videos_path)
        nvideos_local += int(video["on_disk"])
    nvideos_known += len(videos)
    nvideos_available = nvideos_local if not settings.BACKUP_VIDEO_SOURCE else nvideos_known

    changed = "nvideos_local" in topic and topic["nvideos_local"] != nvideos_local
    changed = changed or ("nvideos_known" in topic and topic["nvideos_known"] != nvideos_known)
    topic["nvideos_local"] = nvideos_local
    topic["nvideos_known"] = nvideos_known
    topic["nvideos_available"] = nvideos_available
    topic["available"] = bool(nvideos_local) or bool(settings.BACKUP_VIDEO_SOURCE)

    return (topic, nvideos_local, nvideos_known, nvideos_available, changed)