Skip to content

Instantly share code, notes, and snippets.

@brianpartridge
Forked from jasondew/das_download.rb
Last active August 30, 2017 03:31
Show Gist options
  • Save brianpartridge/67c7c4fae1a682d63dad7996948f6e87 to your computer and use it in GitHub Desktop.
Save brianpartridge/67c7c4fae1a682d63dad7996948f6e87 to your computer and use it in GitHub Desktop.
#! /usr/bin/env ruby
# usage:
# $ das_download.rb email password [download_directory]
require "mechanize"
class DasDownloader
attr_reader :agent, :email, :password, :output_dir
def initialize(email, password, output_dir)
@agent = Mechanize.new
@email, @password, @output_dir = email, password, output_dir
end
def screencasts
seasons_html(catalog_html).each_with_index.map do |season_html,index|
season = index + 1
episodes_html(season_html).map do |episode_html|
url = episode_html.at("a").attr("href")
next unless (meta = episode_html.at(".row"))
episode = meta.at(".number").text
title = meta.at(".title").text
download_url = scrape_download_url(url)
Screencast.new season, episode, title, download_url
end
end.flatten
end
def scrape_download_url(url)
raise "Unable to load details" unless (html = agent.get(url))
# This is necessary because the video source url is set dynamically by javascript.
return /resolution == \"1080p\"\) {\s*source\.src = \"(.*)\";/.match(html.at(".main_content").text)[1]
end
def run
screencasts.each do |screencast|
download screencast
end
end
private
def login
agent.get "https://www.destroyallsoftware.com/screencasts/users/sign_in"
if (form = agent.page.forms.first)
form["user[email]"] = email
form["user[password]"] = password
form.submit
agent.pluggable_parser.default = Mechanize::Download
end
end
def download(screencast)
id = "S#{screencast.season.to_s.rjust(2, "0")}E#{screencast.episode.to_s.rjust(2, "0")}"
title = screencast.title.gsub("/", "_").gsub(":", "").gsub(" ", "_").downcase
filename = "Destroy.All.Software.#{id}.#{title}.mp4"
puts "Downloading #{id} as #{filename}"
Dir.chdir(output_dir)
return if File.exists? filename
login
agent.get(screencast.url).save(filename)
end
def catalog_html
login
agent.get "https://www.destroyallsoftware.com/screencasts/catalog"
agent.page.search(".main_content")
end
def seasons_html(catalog)
catalog.search(".season").reverse
end
def episodes_html(season)
season.search(".episode")
end
Screencast = Struct.new(:season, :episode, :title, :url)
end
email = ARGV[0] or raise("Please provide the email address for your account")
password = ARGV[1] or raise("Please provide the password for your account")
output_dir = ARGV[2] or raise("Please provide an output directory")
DasDownloader.new(email, password, output_dir).run
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment