-
-
Save brianpartridge/67c7c4fae1a682d63dad7996948f6e87 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#! /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