railscasts_download 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,16 +1,19 @@
1
- # Railscasts Downloader
1
+ # Railscasts Download
2
2
 
3
3
  Download all revised and pro railscasts with one-line command!
4
4
 
5
- Downloader use Railscasts rss feed to get list of all videos. At the time for downloading pro videos, rss content must be provide
6
- explicitly by user (see examples).
5
+ Downloader use Railscasts rss feed to get list of all videos. Automatic downloads for pro accounts added in V 0.2.0.
7
6
 
8
7
  ## Example
9
8
 
10
- login first to get access to railscasts pro rss feed, copy and save it as file named pro_railscasts.rss
11
- (automatically download pro rss coming soon)
9
+ All railscasts including revised and pro (pro account required):
12
10
 
13
- railscasts_download --rss_uri /home/yourname/pro_railscasts.rss #create rss file first!
11
+ railscasts_download --revised -l my_login@railscasts.com
12
+ > Enter your password: *********
13
+
14
+ custom railscasts list:
15
+
16
+ railscasts_download --rss_uri /home/yourname/custom_railscasts_list.rss
14
17
 
15
18
  or simply put:
16
19
 
@@ -26,6 +29,7 @@ to get only free railscasts.
26
29
 
27
30
  * Ruby >= 1.9.2
28
31
  * Bundler
32
+ * GNU wget
29
33
 
30
34
  ## Running tests
31
35
 
@@ -33,4 +37,4 @@ to get only free railscasts.
33
37
 
34
38
  ## License
35
39
 
36
- Released under the MIT license. Copyright (C) 2012 Karol Nowicki
40
+ Released under the MIT license. Copyright (C) 2012 Karol Nowicki
@@ -2,17 +2,33 @@
2
2
 
3
3
  require 'railscasts_download'
4
4
  require 'optparse'
5
+ require 'highline/import'
5
6
 
6
7
  options = {}
7
8
 
8
9
  optparse = OptionParser.new do|opts|
9
- opts.banner = "Usage: railscasts_download [options]"
10
+ opts.banner = "Usage: railscasts_download [options][--revised --login LOGIN --password PASSWORD]"
10
11
 
11
12
  options[:rss_uri] = false
12
- opts.on( '-r', '--rss_uri RSS_URI', 'Get file specified by URI as videos list source.' ) do |rss_uri|
13
+ opts.on( '-rss', '--rss_uri RSS_URI', 'Get file specified by URI as videos list source.' ) do |rss_uri|
13
14
  options[:rss_uri] = rss_uri
14
15
  end
15
16
 
17
+ options[:revised] = false
18
+ opts.on( '-r', '--revised', 'Get all railscasts with revised and pro (login required).' ) do
19
+ options[:revised] = true
20
+ end
21
+
22
+ options[:login_uri] = false
23
+ opts.on( '-luri', '--login_uri LOGIN_URI', 'Specify Login URI (required if it`s has been changed`).' ) do |login_uri|
24
+ options[:login_uri] = login_uri
25
+ end
26
+
27
+ options[:login] = false
28
+ opts.on( '-l', '--login YOUR_MAIL', 'Specify your login (email) which you are using to login to railscasts.' ) do |login|
29
+ options[:login] = login
30
+ end
31
+
16
32
  opts.on( '-h', '--help', 'Display this screen' ) do
17
33
  puts opts
18
34
  puts "RSS_URI could be a remote url or local file system path"
@@ -22,5 +38,7 @@ end
22
38
 
23
39
  optparse.parse!
24
40
 
41
+ options[:password] = ask("Enter your password: ") { |q| q.echo = "*" } if options[:revised]
42
+
25
43
  saver = RailscastsDownload::Saver.new( options )
26
44
  saver.get_all
@@ -0,0 +1,46 @@
1
+ module RailscastsDownload
2
+ class PageExplorer
3
+ require 'mechanize'
4
+
5
+ def initialize( options = {} )
6
+ if options[:revised]
7
+ @login_uri = options[:login_uri]
8
+ @login = options[:login]
9
+ @password = options[:password]
10
+ else
11
+ @free_uri = options[:rss_uri]
12
+ end
13
+ end
14
+
15
+ def get_rss_body
16
+ if @login
17
+ login_to_pro( @login_uri, @login, @password )
18
+ link = get_rss_link
19
+ @body = link.click.body
20
+ else
21
+ @body = open( @free_uri ).read
22
+ end
23
+ @body
24
+ end
25
+
26
+ private
27
+ def get_rss_link
28
+ @agent.links.map{|link| link if link.text == "Rss"}.compact.first
29
+ end
30
+
31
+ def valid_signed_in!
32
+ unless get_rss_link
33
+ puts '!!! Bad login/password combination !!!'
34
+ exit
35
+ end
36
+ end
37
+
38
+ def login_to_pro( login_uri, login, password )
39
+ @agent = Mechanize.new.get( login_uri )
40
+ @agent.form.login = login
41
+ @agent.form.password = password
42
+ @agent = @agent.form.submit
43
+ valid_signed_in!
44
+ end
45
+ end
46
+ end
@@ -1,9 +1,10 @@
1
1
  module RailscastsDownload
2
- class Rss
2
+ class RssExplorer
3
3
  require 'rss'
4
4
 
5
- def initialize( uri )
6
- get_rss( uri )
5
+ def initialize( rss_body )
6
+ @body = rss_body
7
+ get_rss
7
8
  end
8
9
 
9
10
  def get_uris
@@ -12,8 +13,8 @@ module RailscastsDownload
12
13
 
13
14
  private
14
15
 
15
- def get_rss( uri )
16
- @rss = RSS::Parser.parse( open( uri ).read, false )
16
+ def get_rss
17
+ @rss = RSS::Parser.parse( @body, false )
17
18
  end
18
19
  end
19
20
  end
@@ -1,12 +1,15 @@
1
- require_relative './rss'
1
+ require_relative './rss_explorer'
2
2
  require_relative './downloader'
3
+ require_relative './page_explorer'
3
4
 
4
5
  module RailscastsDownload
5
6
  class Saver
6
- def initialize( params={} )
7
- @saver = params[:downloader] || Downloader.new
8
- uri = params[:rss_uri] || "http://feeds.feedburner.com/railscasts"
9
- @rss = Rss.new( uri )
7
+ def initialize( options={} )
8
+ @downloader = options[:downloader] || Downloader.new
9
+ options[:rss_uri] ||= "http://feeds.feedburner.com/railscasts" unless options[:revised]
10
+ options[:login_uri] ||= "http://railscasts.com/login" if options[:revised]
11
+ @page = options[:page_explorer] || PageExplorer.new( options )
12
+ @rss = options[:rss_explorer] || RssExplorer.new( @page.get_rss_body )
10
13
  end
11
14
 
12
15
  def get_all
@@ -14,13 +17,14 @@ module RailscastsDownload
14
17
  end
15
18
 
16
19
  def get_file( uri )
17
- @saver.get( uri )
20
+ @downloader.get( uri )
18
21
  end
19
22
 
20
23
  def videos_uris
21
24
  @rss.get_uris
22
25
  end
23
26
 
27
+
24
28
  def missing_videos_uris
25
29
  videos_filenames = videos_uris.map { |url| url.split( '/' ).last }
26
30
  missing_files = videos_filenames - Dir.glob( '*.mp4' )
@@ -1,3 +1,3 @@
1
1
  module RailscastsDownload
2
- VERSION = "0.1.0"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -1,4 +1,5 @@
1
1
  require "railscasts_download/version"
2
- require "railscasts_download/rss"
2
+ require "railscasts_download/rss_explorer"
3
+ require "railscasts_download/page_explorer"
3
4
  require "railscasts_download/downloader"
4
5
  require "railscasts_download/saver"
@@ -20,5 +20,6 @@ Gem::Specification.new do |s|
20
20
 
21
21
  # specify any dependencies here; for example:
22
22
  # s.add_development_dependency "rspec"
23
- # s.add_runtime_dependency "rest-client"
23
+ s.add_runtime_dependency "mechanize"
24
+ s.add_runtime_dependency "highline"
24
25
  end
@@ -1,13 +1,16 @@
1
1
  #Setup env here to speedup (true) or reality (false)
2
- MOCKED_RSS = true
3
- STUBBED_DOWNLOADER = true
2
+ STUBBED = true
4
3
  #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
5
4
 
6
5
  class RailscastDownloadTest < Test::Unit::TestCase
7
6
  def setup
8
- source_file = File.dirname( __FILE__ ) + '/../fixtures/rss.txt' if MOCKED_RSS
9
- downloader = StubDownloader.new if STUBBED_DOWNLOADER
10
- @saver = RailscastsDownload::Saver.new( downloader: downloader, rss_uri: source_file )
7
+ options ={
8
+ source_file: File.dirname( __FILE__ ) + '/../fixtures/rss.txt',
9
+ downloader: StubDownloader.new,
10
+ rss_explorer: StubRssExplorer.new,
11
+ page_explorer: StubPageExplorer.new
12
+ } if STUBBED
13
+ @saver = RailscastsDownload::Saver.new( options )
11
14
  end
12
15
 
13
16
  def teardown
@@ -0,0 +1,6 @@
1
+ http://media.railscasts.com/assets/episodes/videos/001-caching-with-instance-variables.mp4
2
+ http://media.railscasts.com/assets/episodes/videos/002-dynamic-find-by-methods.mp4
3
+ http://media.railscasts.com/assets/episodes/videos/332-refinery-cms-basics.mp4
4
+ http://media.railscasts.com/assets/episodes/videos/330-better-sass-with-bourbon.mp4
5
+ http://media.railscasts.com/assets/episodes/videos/328-twitter-bootstrap-basics.mp4
6
+ http://media.railscasts.com/assets/episodes/videos/326-activeattr.mp4
@@ -0,0 +1,12 @@
1
+ class PageExplorerTest < Test::Unit::TestCase
2
+ def setup
3
+ @source_file = File.dirname( __FILE__ ) + '/../fixtures/rss.txt'
4
+ @page_explorer = RailscastsDownload::PageExplorer.new( rss_uri: @source_file)
5
+ end
6
+ #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
7
+
8
+ def test_rss_body_returns_correct_body
9
+ assert_equal( open( @source_file ).read, @page_explorer.get_rss_body )
10
+ end
11
+
12
+ end
@@ -1,8 +1,14 @@
1
1
  class RailscastsDownloadInEmptyEnvTestClear < Test::Unit::TestCase
2
+
2
3
  def setup
3
4
  source_file = File.dirname( __FILE__ ) + '/../fixtures/rss.txt'
4
5
  downloader = StubDownloader.new
5
- @saver = RailscastsDownload::Saver.new( downloader: downloader, rss_uri: source_file )
6
+ rss_explorer = StubRssExplorer.new
7
+ page_explorer = StubPageExplorer.new
8
+ @saver = RailscastsDownload::Saver.new( downloader: downloader,
9
+ rss_explorer: rss_explorer,
10
+ page_explorer: page_explorer,
11
+ rss_uri: source_file )
6
12
  end
7
13
  #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
8
14
 
@@ -25,18 +31,24 @@ class RailscastsDownloadInEmptyEnvTestClear < Test::Unit::TestCase
25
31
  end
26
32
 
27
33
  def test_videos_uris_returns_all_uris
28
- assert_equal( 311, @saver.videos_uris.count )
34
+ assert_equal( 6, @saver.videos_uris.count )
29
35
  end
30
36
 
31
37
  def test_missing_videos_uris_returns_all_uris
32
- assert_equal( 311, @saver.missing_videos_uris.count )
38
+ assert_equal( 6, @saver.missing_videos_uris.count )
33
39
  end
34
40
  end
35
41
 
36
42
  class RailscastsDownloadWithSomeVideoesTest < Test::Unit::TestCase
37
43
  def setup
38
44
  source_file = File.dirname( __FILE__ ) + '/../fixtures/rss.txt'
39
- @saver = RailscastsDownload::Saver.new( rss_uri: source_file )
45
+ downloader = StubDownloader.new
46
+ rss_explorer = StubRssExplorer.new
47
+ page_explorer = StubPageExplorer.new
48
+ @saver = RailscastsDownload::Saver.new( downloader: downloader,
49
+ rss_explorer: rss_explorer,
50
+ page_explorer: page_explorer,
51
+ rss_uri: source_file )
40
52
  File.new( "001-caching-with-instance-variables.mp4", "w+" ).close
41
53
  end
42
54
 
@@ -51,10 +63,10 @@ class RailscastsDownloadWithSomeVideoesTest < Test::Unit::TestCase
51
63
  end
52
64
 
53
65
  def test_videos_uris_returns_all_uris
54
- assert_equal( 311, @saver.videos_uris.count )
66
+ assert_equal( 6, @saver.videos_uris.count )
55
67
  end
56
68
 
57
69
  def test_missing_videos_uris_returns_only_missing_uris
58
- assert_equal( 310, @saver.missing_videos_uris.count )
70
+ assert_equal( 5, @saver.missing_videos_uris.count )
59
71
  end
60
72
  end
@@ -1,8 +1,7 @@
1
-
2
- class RssTest < Test::Unit::TestCase
1
+ class RssExplorerbTest < Test::Unit::TestCase
3
2
  def setup
4
3
  source_file = File.dirname( __FILE__ ) + '/../fixtures/rss.txt'
5
- @rss = RailscastsDownload::Rss.new( source_file )
4
+ @rss = RailscastsDownload::RssExplorer.new( open( source_file ).read )
6
5
  end
7
6
  #- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
8
7
 
@@ -0,0 +1,9 @@
1
+ class StubPageExplorer
2
+ def initialize( options = {} )
3
+ end
4
+
5
+ def get_rss_body
6
+ source_file = File.dirname( __FILE__ ) + '/../fixtures/rss.txt'
7
+ open( source_file ).read
8
+ end
9
+ end
@@ -0,0 +1,9 @@
1
+ class StubRssExplorer
2
+ def initialize
3
+ end
4
+
5
+ def get_uris
6
+ source_file = File.dirname( __FILE__ ) + '/../fixtures/uris.txt'
7
+ open( source_file ).read.each_line.map{ |l| l[0, (l.length-1)] }
8
+ end
9
+ end
data/test/test_helper.rb CHANGED
@@ -1,4 +1,6 @@
1
1
  require File.expand_path( "../../lib/railscasts_download", __FILE__ )
2
2
  require File.expand_path( "../stubs/downloader", __FILE__ )
3
+ require File.expand_path( "../stubs/page_explorer", __FILE__ )
4
+ require File.expand_path( "../stubs/rss_explorer", __FILE__ )
3
5
  require 'test/unit'
4
6
  require "turn"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: railscasts_download
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,8 +9,30 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-03-29 00:00:00.000000000 Z
13
- dependencies: []
12
+ date: 2012-03-30 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: mechanize
16
+ requirement: &12329620 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *12329620
25
+ - !ruby/object:Gem::Dependency
26
+ name: highline
27
+ requirement: &12329000 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
33
+ type: :runtime
34
+ prerelease: false
35
+ version_requirements: *12329000
14
36
  description: Download all revised and pro railscasts with oneline command.
15
37
  email:
16
38
  - karol@knowicki.pl
@@ -26,16 +48,21 @@ files:
26
48
  - bin/railscasts_download
27
49
  - lib/railscasts_download.rb
28
50
  - lib/railscasts_download/downloader.rb
29
- - lib/railscasts_download/rss.rb
51
+ - lib/railscasts_download/page_explorer.rb
52
+ - lib/railscasts_download/rss_explorer.rb
30
53
  - lib/railscasts_download/saver.rb
31
54
  - lib/railscasts_download/version.rb
32
55
  - railscasts_download.gemspec
33
56
  - test/acceptance/railscasts_download_test.rb
34
57
  - test/fixtures/rss.txt
58
+ - test/fixtures/uris.txt
59
+ - test/functional/page_explorer_test.rb
35
60
  - test/functional/railscasts_download_test.rb
36
- - test/functional/rss_test.rb
61
+ - test/functional/rss_explorer_test.rb
37
62
  - test/railscasts_download_test.rb
38
63
  - test/stubs/downloader.rb
64
+ - test/stubs/page_explorer.rb
65
+ - test/stubs/rss_explorer.rb
39
66
  - test/test_helper.rb
40
67
  homepage: ''
41
68
  licenses: []
@@ -51,7 +78,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
51
78
  version: '0'
52
79
  segments:
53
80
  - 0
54
- hash: 4319710688046479509
81
+ hash: 891208736094293957
55
82
  required_rubygems_version: !ruby/object:Gem::Requirement
56
83
  none: false
57
84
  requirements:
@@ -60,7 +87,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
60
87
  version: '0'
61
88
  segments:
62
89
  - 0
63
- hash: 4319710688046479509
90
+ hash: 891208736094293957
64
91
  requirements: []
65
92
  rubyforge_project: railscasts_download
66
93
  rubygems_version: 1.8.17
@@ -70,8 +97,12 @@ summary: Download all revised and pro railscasts with oneline command!
70
97
  test_files:
71
98
  - test/acceptance/railscasts_download_test.rb
72
99
  - test/fixtures/rss.txt
100
+ - test/fixtures/uris.txt
101
+ - test/functional/page_explorer_test.rb
73
102
  - test/functional/railscasts_download_test.rb
74
- - test/functional/rss_test.rb
103
+ - test/functional/rss_explorer_test.rb
75
104
  - test/railscasts_download_test.rb
76
105
  - test/stubs/downloader.rb
106
+ - test/stubs/page_explorer.rb
107
+ - test/stubs/rss_explorer.rb
77
108
  - test/test_helper.rb