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" |