railscasts_download 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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