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', 'available')) for t in topics] exercises_path = os.path.join(settings.KHAN_EXERCISES_DIRPATH, "exercises") exercise_langs = dict([(exercise["id"], ["en"]) for exercise in exercises]) # Determine what exercises (and languages) are available exercise_all_lang_codes = os.listdir(exercises_path) if os.path.exists(exercises_path) else [] exercise_all_lang_codes = set(exercise_all_lang_codes) - set(["test"]) for lang_code in exercise_all_lang_codes: # hard-code out test loc_path = os.path.join(exercises_path, lang_code) if not os.path.isdir(loc_path): continue for exercise in exercises: ex_path = os.path.join(loc_path, "%s.html" % exercise["id"]) if not os.path.exists(ex_path): continue exercise_langs[exercise["id"]].append(lang_code) 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
def stamp_availability_on_topic(topic, videos_path=None, 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 """ videos_path = videos_path or settings.CONTENT_ROOT 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"]: # RECURSIVE CALL: # The children have children, let them figure things out themselves if "children" in child: if not force and "nvideos_local" in child: continue 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: # Got a topic node, get immediate video children and figure out what to do. 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 is available if it contains a downloaded video, or any other resource type (other resources assumed to be downloaded) topic["available"] = bool(nvideos_local) topic["available"] = topic["available"] or bool(settings.BACKUP_VIDEO_SOURCE) topic["available"] = topic["available"] or bool(set(topic.get("contains", [])) - set(["Topic", "Video"])) return (topic, nvideos_local, nvideos_known, nvideos_available, changed)
def stamp_availability_on_topic(topic, videos_path=None, 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 """ videos_path = videos_path or settings.CONTENT_ROOT 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"]: # RECURSIVE CALL: # The children have children, let them figure things out themselves if "children" in child: if not force and "nvideos_local" in child: continue 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: # Got a topic node, get immediate video children and figure out what to do. 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 is available if it contains a downloaded video, or any other resource type (other resources assumed to be downloaded) topic["available"] = bool(nvideos_local) topic["available"] = topic["available"] or bool( settings.BACKUP_VIDEO_SOURCE) topic["available"] = topic["available"] or bool( set(topic.get("contains", [])) - set(["Topic", "Video"])) return (topic, nvideos_local, nvideos_known, nvideos_available, changed)