Setup:
gem install httparty parallel
Usage: (get the ID from the topic page's URL; can be any level)
ruby khan_duration.rb solving-linear-equations-and-inequalities
| require 'ostruct' | |
| require 'httparty' | |
| require 'parallel' | |
| class Khan | |
| include HTTParty | |
| base_uri 'www.khanacademy.org/api/v1' | |
| format :json | |
| def topic(topic_id) | |
| puts "Loading topic #{topic_id}" | |
| Topic.new(self.class.get("/topic/#{topic_id}"), self) | |
| end | |
| def video(video_id) | |
| puts "Loading video #{video_id}" | |
| Video.new(self.class.get("/videos/#{video_id}")) | |
| end | |
| class Video | |
| attr_reader :duration | |
| def initialize(api_data) | |
| @duration = api_data['duration'] | |
| end | |
| end | |
| class Topic | |
| def initialize(api_data, khan) | |
| children_data_by_kind = api_data['children'].group_by { |c| c['kind'] } | |
| @topic_datas = children_data_by_kind['Topic'] || [] | |
| @video_datas = children_data_by_kind['Video'] || [] | |
| @khan = khan | |
| end | |
| def duration | |
| durables = subtopics + videos | |
| durables.map(&:duration).reduce(&:+) | |
| end | |
| def subtopics | |
| Parallel.map(@topic_datas, in_threads: 8) { |td| @khan.topic(td['id']) } | |
| end | |
| def videos | |
| Parallel.map(@video_datas, in_threads: 8) { |vd| @khan.video(vd['id']) } | |
| end | |
| end | |
| end | |
| topic_id = ARGV[0] || 'basic_addition' | |
| khan = Khan.new | |
| duration = khan.topic(topic_id).duration | |
| puts "#{topic_id} lasts #{duration} seconds" |