viddl-rb 0.73 → 0.74

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
@@ -10,7 +10,7 @@ gem install viddl-rb
10
10
  __Usage:__
11
11
 
12
12
  Download a video:
13
- viddl-rb http://www.youtube.com/watch?v=QH2-TGUlwu4
13
+ ```viddl-rb http://www.youtube.com/watch?v=QH2-TGUlwu4```
14
14
 
15
15
  Viddl-rb supports the following command line options:
16
16
  ```
@@ -19,16 +19,17 @@ Viddl-rb supports the following command line options:
19
19
  -t, --title-only Prints title without downloading
20
20
  -f, --filter REGEX Filters a video playlist according to the regex (Youtube only right now)
21
21
  -s, --save-dir DIRECTORY Specifies the directory where videos should be saved
22
+ -d, --downloader TOOL Specifies the tool to download with. Supports 'wget', 'curl' and 'net-http'
22
23
  -h, --help Displays the help screen
23
24
  ```
24
25
 
25
26
  Download a video and extract the audio:
26
- viddl-rb http://www.youtube.com/watch?v=QH2-TGUlwu4 --extract-audio
27
+ ```viddl-rb http://www.youtube.com/watch?v=QH2-TGUlwu4 --extract-audio```
27
28
 
28
29
  In both cases we'll name the output file according to the video title.
29
30
 
30
31
  Setting the video save directory:
31
- viddl-rb http://vimeo.com/38372260 --save-dir C:/myvideos
32
+ ```viddl-rb http://vimeo.com/38372260 --save-dir C:/myvideos```
32
33
 
33
34
  The --save-dir option works with both absolute and relative paths (relative based on the directory viddl-rb is run from).
34
35
  If you want to save to a folder with spaces in it, you have to quote the path like this: --save-dir "C:/my videos"
@@ -36,13 +37,13 @@ If you want to save to a folder with spaces in it, you have to quote the path li
36
37
  __Youtube plugin specifics:__
37
38
 
38
39
  Download all videos on a playlist:
39
- viddl-rb http://www.youtube.com/playlist?list=PL7E8DA0A515924126
40
+ ```viddl-rb http://www.youtube.com/playlist?list=PL7E8DA0A515924126```
40
41
 
41
42
  Download all videos from a user:
42
- viddl-rb http://www.youtube.com/user/tedtalksdirector
43
+ ```viddl-rb http://www.youtube.com/user/tedtalksdirector```
43
44
 
44
45
  Filter videos to download from a user/playlist:
45
- viddl-rb http://www.youtube.com/user/tedtalksdirector --filter /internet/i
46
+ ```viddl-rb http://www.youtube.com/user/tedtalksdirector --filter /internet/i```
46
47
 
47
48
  The --filter argument accepts a regular expression and will only download videos where the title matches the regex.
48
49
  It uses the same syntax as Ruby regular expression literals do.
@@ -8,7 +8,7 @@ class Downloader
8
8
  url = url_name[:url]
9
9
  name = url_name[:name]
10
10
 
11
- result = save_file(url, name, params[:save_dir])
11
+ result = ViddlRb::DownloadHelper.save_file(url, name, :save_dir => params[:save_dir], :tool => params[:tool])
12
12
  unless result
13
13
  raise DownloadFailedError, "Download for #{name} failed."
14
14
  else
@@ -17,9 +17,4 @@ class Downloader
17
17
  end
18
18
  end
19
19
  end
20
-
21
- # TODO save_dir is not used yet
22
- def save_file(url, name, save_dir)
23
- ViddlRb::DownloadHelper.save_file(url, name, save_dir)
24
- end
25
20
  end
@@ -22,7 +22,8 @@ class ParameterParser
22
22
  :url_only => false,
23
23
  :title_only => false,
24
24
  :playlist_filter => nil,
25
- :save_dir => DEFAULT_SAVE_DIR
25
+ :save_dir => DEFAULT_SAVE_DIR,
26
+ :tool => nil
26
27
  }
27
28
 
28
29
  optparse = OptionParser.new do |opts|
@@ -56,6 +57,14 @@ class ParameterParser
56
57
  end
57
58
  end
58
59
 
60
+ opts.on("-d", "--downloader TOOL", "Specifies the tool to download with. Supports 'wget', 'curl' and 'net-http'") do |tool|
61
+ if tool =~ /(^wget$)|(^curl$)|(^net-http$)/
62
+ options[:tool] = tool
63
+ else
64
+ raise OptionParser::InvalidArgument.new("'#{tool}' is not a valid tool.")
65
+ end
66
+ end
67
+
59
68
  opts.on_tail('-h', '--help', 'Display this screen') do
60
69
  print_help_and_exit(opts)
61
70
  end
@@ -63,7 +72,8 @@ class ParameterParser
63
72
 
64
73
  optparse.parse!(args) # removes all options from args
65
74
  print_help_and_exit(optparse) if args.empty? # exit if no video url
66
- url = validate_url(args.first) # the url is the only element left
75
+ url = args.first # the url is the only element left
76
+ validate_url!(url) # raise exception if invalid url
67
77
  options[:url] = url
68
78
  options
69
79
  end
@@ -73,10 +83,8 @@ class ParameterParser
73
83
  exit(0)
74
84
  end
75
85
 
76
- def self.validate_url(url)
77
- if url =~ /^http/
78
- url
79
- else
86
+ def self.validate_url!(url)
87
+ unless url =~ /^http/
80
88
  raise OptionParser::InvalidArgument.new(
81
89
  "please include 'http' with your URL e.g. http://www.youtube.com/watch?v=QH2-TGUlwu4")
82
90
  end
@@ -25,7 +25,7 @@ begin
25
25
 
26
26
  puts "Loading Plugins"
27
27
  ViddlRb::UtilityHelper.load_plugins
28
- "Plugins loaded: #{ViddlRb::PluginBase.registered_plugins.inspect}"
28
+ puts "Plugins loaded: #{ViddlRb::PluginBase.registered_plugins.inspect}"
29
29
 
30
30
  puts "Will try to extract audio: #{params[:extract_audio] == true}."
31
31
  puts "Analyzing URL: #{params[:url]}"
@@ -33,7 +33,7 @@ begin
33
33
  app = Driver.new(params)
34
34
  app.start # starts the download process
35
35
 
36
- rescue OptionParser::ParseError => e
36
+ rescue OptionParser::ParseError, ViddlRb::RequirementError => e
37
37
  puts "Error: #{e.message}"
38
38
  exit(1)
39
39
 
@@ -1,57 +1,94 @@
1
1
  module ViddlRb
2
2
 
3
+ class RequirementError < StandardError; end
4
+
3
5
  class DownloadHelper
4
- #usually not called directly
5
- def self.fetch_file(uri)
6
- begin
7
- require "progressbar" #http://github.com/nex3/ruby-progressbar
8
- rescue LoadError
9
- puts "ERROR: You don't seem to have curl or wget on your system. In this case you'll need to install the 'progressbar' gem."
10
- exit
11
- end
12
- progress_bar = nil
13
- open(uri, :proxy => nil,
14
- :content_length_proc => lambda { |length|
15
- if length && 0 < length
16
- progress_bar = ProgressBar.new(uri.to_s, length)
17
- progress_bar.file_transfer_mode #to show download speed and file size
18
- end
19
- },
20
- :progress_proc => lambda { |progress|
21
- progress_bar.set(progress) if progress_bar
22
- }) {|file| return file.read}
23
- end
6
+
7
+ #viddl will use the first of these tools it finds on the system to download the video.
8
+ #if the system does not have any of these tools, net/http is used instead.
9
+ TOOLS_PRIORITY_LIST = [:wget, :curl]
24
10
 
25
11
  #simple helper that will save a file from the web and save it with a progress bar
26
- def self.save_file(file_uri, file_name, save_dir = ".", amount_of_retries = 6)
12
+ def self.save_file(file_url, file_name, opts = {})
27
13
  trap("SIGINT") { puts "goodbye"; exit }
28
14
 
29
- file_path = File.expand_path(File.join(save_dir, file_name))
15
+ #default options
16
+ options = {:save_dir => ".",
17
+ :amount_of_retries => 6,
18
+ :tool => get_tool}
19
+
20
+ opts[:tool] = options[:tool] if opts[:tool].nil?
21
+ options.merge!(opts)
22
+
23
+ file_path = File.expand_path(File.join(options[:save_dir], file_name))
24
+ success = false
25
+
30
26
  #Some providers seem to flake out every now end then
31
- amount_of_retries.times do |i|
32
- if UtilityHelper.os_has?("wget")
33
- puts "using wget"
34
- `wget \"#{file_uri}\" -O #{file_path.inspect}`
35
- elsif UtilityHelper.os_has?("curl")
36
- puts "using curl"
27
+ options[:amount_of_retries].times do |i|
28
+ case options[:tool].to_sym
29
+ when :wget
30
+ puts "Using wget"
31
+ success = system "wget \"#{file_url}\" -O #{file_path.inspect}"
32
+ when :curl
33
+ puts "Using curl"
37
34
  #-L means: follow redirects, We set an agent because Vimeo seems to want one
38
- `curl -A 'Wget/1.8.1' --retry 10 --retry-delay 5 --retry-max-time 4 -L \"#{file_uri}\" -o #{file_path.inspect}`
35
+ success = system "curl -A 'Wget/1.8.1' --retry 10 --retry-delay 5 --retry-max-time 4 -L \"#{file_url}\" -o #{file_path.inspect}"
39
36
  else
40
- puts "using net/http"
41
- open(file_path, 'wb') { |file|
42
- file.write(fetch_file(file_uri)); puts
43
- }
37
+ require_progressbar
38
+ puts "Using net/http"
39
+ success = download_and_save_file(file_url, file_path)
44
40
  end
45
41
  #we were successful, we're outta here
46
- if $? == 0
42
+ if success
47
43
  break
48
44
  else
49
45
  puts "Download seems to have failed (retrying, attempt #{i+1}/#{amount_of_retries})"
50
46
  sleep 2
51
47
  end
52
48
  end
53
- $? == 0
49
+ success
50
+ end
51
+
52
+ def self.get_tool
53
+ tool = TOOLS_PRIORITY_LIST.find { |tool| ViddlRb::UtilityHelper.os_has?(tool) }
54
+ tool || :net_http
54
55
  end
55
56
 
57
+ def self.require_progressbar
58
+ begin
59
+ require "progressbar"
60
+ rescue LoadError
61
+ raise RequirementError,
62
+ "you don't seem to have curl or wget on your system. In this case you'll need to install the 'progressbar' gem."
63
+ end
64
+ end
65
+
66
+ # downloads and saves a file using the net/http streaming api
67
+ # return true if the download was successful, else returns false
68
+ def self.download_and_save_file(download_url, full_path)
69
+ final_url = UtilityHelper.get_final_location(download_url) # follow all redirects
70
+ uri = URI(final_url)
71
+ file = File.new(full_path, "wb")
72
+ file_size = 0
73
+
74
+ Net::HTTP.start(uri.host, uri.port) do |http|
75
+ http.request_get(uri.request_uri) do |res|
76
+ file_size = res.read_header["content-length"].to_i
77
+ bar = ProgressBar.new(File.basename(full_path), file_size)
78
+ bar.file_transfer_mode
79
+ res.read_body do |segment|
80
+ bar.inc(segment.size)
81
+ file.write(segment)
82
+ end
83
+ end
84
+ end
85
+ file.close
86
+ print "\n"
87
+ download_successful?(full_path, file_size) #because Net::HTTP.start does not throw Net exceptions
88
+ end
89
+
90
+ def self.download_successful?(full_file_path, file_size)
91
+ File.exist?(full_file_path) && File.size(full_file_path) == file_size
92
+ end
56
93
  end
57
94
  end
@@ -18,7 +18,7 @@ module ViddlRb
18
18
  windows = ENV['OS'] =~ /windows/i
19
19
 
20
20
  unless windows
21
- `which #{utility}`.include?(utility)
21
+ `which #{utility}`.include?(utility.to_s)
22
22
  else
23
23
  if !system("where /q where").nil? #if Windows has the where utility
24
24
  system("where /q #{utility}") #/q is the quiet mode flag
@@ -31,6 +31,15 @@ module ViddlRb
31
31
  end
32
32
  end
33
33
  end
34
-
34
+
35
+ #recursively get the final location (after following all redirects) for an url.
36
+ def self.get_final_location(url)
37
+ Net::HTTP.get_response(URI(url)) do |res|
38
+ location = res["location"]
39
+ return url if location.nil?
40
+ return get_final_location(location)
41
+ end
42
+ end
43
+
35
44
  end
36
45
  end
@@ -95,19 +95,9 @@ module ViddlRb
95
95
  def self.follow_all_redirects(urls_filenames)
96
96
  urls_filenames.map do |uf|
97
97
  url = uf[:url]
98
- final_location = get_final_location(url)
98
+ final_location = UtilityHelper.get_final_location(url)
99
99
  {:url => final_location, :name => uf[:name]}
100
100
  end
101
101
  end
102
102
  private_class_method :follow_all_redirects
103
-
104
- #recursively get the final location (after following all redirects) for an url.
105
- def self.get_final_location(url)
106
- Net::HTTP.get_response(URI(url)) do |res|
107
- location = res["location"]
108
- return url if location.nil?
109
- return get_final_location(location)
110
- end
111
- end
112
- private_class_method :get_final_location
113
103
  end
metadata CHANGED
@@ -1,12 +1,12 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: viddl-rb
3
3
  version: !ruby/object:Gem::Version
4
- hash: 153
4
+ hash: 159
5
5
  prerelease:
6
6
  segments:
7
7
  - 0
8
- - 73
9
- version: "0.73"
8
+ - 74
9
+ version: "0.74"
10
10
  platform: ruby
11
11
  authors:
12
12
  - Marc Seeger
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2012-10-05 00:00:00 +02:00
17
+ date: 2012-10-07 00:00:00 +02:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency
@@ -87,7 +87,21 @@ dependencies:
87
87
  version: "0"
88
88
  type: :development
89
89
  version_requirements: *id005
90
- description: An extendable commandline video downloader for flash video sites. Includes plugins for vimeo, youtube and megavideo
90
+ - !ruby/object:Gem::Dependency
91
+ name: progressbar
92
+ prerelease: false
93
+ requirement: &id006 !ruby/object:Gem::Requirement
94
+ none: false
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ hash: 3
99
+ segments:
100
+ - 0
101
+ version: "0"
102
+ type: :development
103
+ version_requirements: *id006
104
+ description: An extendable commandline video downloader for flash video sites. Includes plugins for vimeo, youtube, dailymotion and more
91
105
  email: mail@marc-seeger.de
92
106
  executables:
93
107
  - viddl-rb