Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 9ca12d0
Showing
23 changed files
with
568 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
*.gem | ||
.bundle | ||
Gemfile.lock | ||
pkg/* | ||
.rvmrc |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
source "http://rubygems.org" | ||
|
||
# Specify your gem's dependencies in das_catalog.gemspec | ||
gemspec |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
Copyright (c) 2011 Brendon Murphy | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
Das Catalog | ||
=========== | ||
|
||
The Das Catalog gem - used for downloading screencasts from the [Destroy All Software screencasts catalog](https://www.destroyallsoftware.com/screencasts). Uses the rss feed plus Mechanize to log you in and then download unsaved movies to a local directory. | ||
|
||
This gem is in not linked to Destroy All Software or endorsed by Gary Bernhardt. I just like his stuff. | ||
|
||
Requirements | ||
------------ | ||
|
||
I've written and only run the gem on Ruby 1.9.2. YMMV, but 1.8.x will definitely blow up. | ||
|
||
The gem also expects that wget exists in your path, as it uses it for downloaded the movie file. | ||
|
||
Installation | ||
------------ | ||
|
||
Install the gem | ||
|
||
$ gem install das_catalog | ||
|
||
Usage | ||
----- | ||
|
||
Run from the command line: | ||
|
||
$ das_catalog_sync | ||
|
||
It will prompt your for some settings (username, password, storage directory) and then be off and running. | ||
|
||
Stored Configuration | ||
-------------------- | ||
|
||
If you don't provide configuration, `das_catalog_sync` will prompt you for configuration values when you run it. | ||
|
||
However, you can persist a full or partial config in ~/.das_catalog.yml as such: | ||
|
||
--- | ||
username: your_username | ||
password: your_password | ||
downloads_directory: /Users/programmer/Movies/DAS | ||
|
||
If you wish to exclude any config, leave it out and `das_catalog_sync` will prompt your for it at runtime. | ||
|
||
Basic Process | ||
------------- | ||
|
||
The steps by which the gem works are fairly simple: | ||
|
||
1. Fetch the rss feed to see what is in the catalog | ||
2. Use Mechanize to log in at the DAS sign in page | ||
3. Find links in the feed that have not been downloaded yet | ||
4. Construct a download link, and grab the location header from the redirect (the movie on S3) | ||
5. Offload the download to wget for efficient processing | ||
|
||
TODO | ||
---- | ||
* Finish missing spec coverage (mostly in DasCatalog toplevel namespace) | ||
* Hook up Aruba for bin testing | ||
* Switch bin to [GLI](https://github.com/davetron5000/gli)? | ||
* CLI interface for tracking if you've watched a specific screencast | ||
* Make missing directory automatically | ||
* better wget detection/warnings | ||
* Lighten some dependencies (feed fetching, highline, etc) | ||
* Better cli access to modify the underlying pstore |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
require 'bundler' | ||
Bundler::GemHelper.install_tasks | ||
|
||
require 'rake/testtask' | ||
|
||
Rake::TestTask.new do |t| | ||
t.pattern = "spec/*_spec.rb" | ||
end | ||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
#!/usr/bin/env ruby | ||
|
||
require 'yaml' | ||
require 'highline/import' | ||
|
||
$LOAD_PATH.unshift File.expand_path("../lib", File.dirname(__FILE__)) | ||
|
||
require 'das_catalog' | ||
|
||
config_file = File.expand_path("~/.das_catalog.yml") | ||
|
||
config = if File.exists?(config_file) | ||
YAML.load_file(config_file) | ||
else | ||
{} | ||
end | ||
|
||
DasCatalog.configure do |c| | ||
c.username = config["username"] || ask("Enter your DAS username: ") { |q| q.echo = true } | ||
c.password = config["password"] || ask("Enter your DAS password: ") { |q| q.echo = "*" } | ||
c.downloads_directory = config["downloads_directory"] || ask("Enter your DAS downloads directory: ") { |q| q.echo = "*" } | ||
end | ||
|
||
DasCatalog.sync |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
# -*- encoding: utf-8 -*- | ||
$LOAD_PATH.push File.expand_path("../lib", __FILE__) | ||
require "das_catalog/version" | ||
|
||
Gem::Specification.new do |s| | ||
s.name = 'das_downloader' | ||
s.version = '0.0.1' | ||
s.platform = Gem::Platform::RUBY | ||
s.author = 'Brendon Murphy' | ||
s.email = 'xternal1+github@gmail.com' | ||
s.summary = 'Download screencasts from Destroy All Software catalog' | ||
s.description = 'Download screencasts from Destroy All Software catalog. Uses the rss feed plus Mechanize to log you in and then download new movies to your local drive.' | ||
|
||
s.files = Dir['lib/**/*.rb'] + Dir['bin/*'] + %w(README.md LICENSE) | ||
s.test_files = Dir['spec/**/*.rb'] | ||
s.require_path = 'lib' | ||
|
||
s.executables = ["das_catalog_sync"] | ||
|
||
s.add_dependency('feedzirra') | ||
s.add_dependency('mechanize') | ||
s.add_dependency('highline') | ||
|
||
s.add_development_dependency('minitest') | ||
s.add_development_dependency('mocha') | ||
s.add_development_dependency('fakefs') | ||
end |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
require 'feedzirra' | ||
require 'mechanize' | ||
require 'shellwords' | ||
require 'uri' | ||
require 'pstore' | ||
require 'forwardable' | ||
|
||
module DasCatalog | ||
SIGN_IN_URL = "https://www.destroyallsoftware.com/screencasts/users/sign_in" | ||
|
||
# TODO spec this | ||
class << self | ||
attr_accessor :username | ||
attr_accessor :password | ||
attr_accessor :downloads_directory | ||
|
||
attr_writer :logger | ||
def logger | ||
@logger ||= StdLogger.new | ||
end | ||
|
||
attr_writer :tracker_file | ||
def tracker_file | ||
@tracker_file ||= File.expand_path("~/.das_tracker.pstore") | ||
end | ||
end | ||
|
||
def self.configure | ||
yield self | ||
end | ||
|
||
# TODO spec this | ||
def self.agent | ||
@agent ||= begin | ||
agent = Mechanize.new | ||
page = agent.get SIGN_IN_URL | ||
form = page.forms.first | ||
form['user[email]'] = username | ||
form['user[password]'] = password | ||
agent.submit form | ||
agent | ||
end | ||
end | ||
|
||
# TODO spec this | ||
def self.sync | ||
feed = Feed.get | ||
feed.entries.each do |entry| | ||
sc = Screencast.for_link(entry.url) | ||
sc.download | ||
end | ||
end | ||
end | ||
|
||
require_relative "das_catalog/downloader" | ||
require_relative "das_catalog/feed" | ||
require_relative "das_catalog/std_logger" | ||
require_relative "das_catalog/screencast" | ||
require_relative "das_catalog/screencast_data" | ||
require_relative "das_catalog/store" |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
module DasCatalog | ||
# TODO spec this | ||
class Downloader | ||
def self.process(screencast) | ||
# Mechanize was choking on large file downloads and keeps them in memory, | ||
# outsource to wget | ||
agent = DasCatalog.agent | ||
agent.redirect_ok = false | ||
result = agent.get screencast.download_link | ||
url = result.header["location"] | ||
url =~ /^http.+?([^\/]+\.mov)\?/ | ||
output_filename = $1 | ||
`wget --quiet #{Shellwords.escape url} -O #{DasCatalog.downloads_directory}/#{output_filename}` | ||
end | ||
end | ||
end |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
module DasCatalog | ||
class Feed | ||
FEED_URL = "https://www.destroyallsoftware.com/screencasts/feed" | ||
|
||
def self.get | ||
Feedzirra::Feed.fetch_and_parse(FEED_URL) | ||
end | ||
end | ||
end |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
module DasCatalog | ||
class Screencast | ||
extend Forwardable | ||
include LoggerAccess | ||
|
||
attr_reader :screencast_data | ||
def_delegators :@screencast_data, :watched?, :downloaded?, :download_link | ||
|
||
def initialize(screencast_data) | ||
@screencast_data = screencast_data | ||
end | ||
|
||
def self.for_link(link) | ||
new ScreencastData.for_link(link) | ||
end | ||
|
||
def to_s | ||
screencast_data.link | ||
end | ||
|
||
def download | ||
return false if screencast_data.downloaded? | ||
log.info "Starting download of #{self}" | ||
Downloader.process(self) | ||
screencast_data.downloaded | ||
log.info "Finished download of #{self}" | ||
screencast_data.save | ||
end | ||
end | ||
end |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
module DasCatalog | ||
class ScreencastData | ||
attr_reader :link, :watched, :downloaded | ||
|
||
def initialize(link) | ||
@link = link | ||
end | ||
|
||
def self.for_link(link) | ||
Store.find(link) or new(link) #Store.store(new(link)) | ||
end | ||
|
||
alias :id :link | ||
|
||
def download_link | ||
"#{link}/download" | ||
end | ||
|
||
def downloaded | ||
@downloaded = true | ||
end | ||
|
||
def downloaded? | ||
@downloaded | ||
end | ||
|
||
def watched | ||
@watched = true | ||
end | ||
|
||
def unwatched | ||
@watched = false | ||
end | ||
|
||
def watched? | ||
@watched | ||
end | ||
|
||
def save | ||
Store.store(self) | ||
end | ||
end | ||
end |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
require 'logger' | ||
require 'delegate' | ||
|
||
module DasCatalog | ||
class StdLogger < DelegateClass(::Logger) | ||
def initialize | ||
@logger = ::Logger.new(STDOUT) | ||
super(@logger) | ||
end | ||
end | ||
|
||
module LoggerAccess | ||
def self.included(klass) | ||
klass.extend(self) | ||
end | ||
|
||
def log | ||
DasCatalog.logger | ||
end | ||
end | ||
end |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
module DasCatalog | ||
class Store | ||
def self.find(id) | ||
store = PStore.new(DasCatalog.tracker_file) | ||
store.transaction(true) do | ||
store[id] | ||
end | ||
end | ||
|
||
def self.store(screencast_data) | ||
store = PStore.new(DasCatalog.tracker_file) | ||
store.transaction do | ||
store[screencast_data.id] = screencast_data | ||
end | ||
end | ||
end | ||
end |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module DasCatalog | ||
VERSION = "0.0.1" | ||
end |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
require_relative "spec_helper" | ||
|
||
describe DasCatalog do | ||
it "has a DasCatalog::StdLogger by default" do | ||
assert DasCatalog.logger | ||
end | ||
end |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
require_relative "spec_helper" | ||
|
||
describe DasCatalog::Downloader do | ||
# TODO | ||
end | ||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
require_relative "spec_helper" | ||
|
||
describe DasCatalog::Feed do | ||
it "grabs the feed with feedzirra" do | ||
Feedzirra::Feed.expects(:fetch_and_parse).with("https://www.destroyallsoftware.com/screencasts/feed") | ||
DasCatalog::Feed.get | ||
end | ||
end |
Oops, something went wrong.