From 9a5310260a276a57c084d07de2bb97d78ce2a8ff Mon Sep 17 00:00:00 2001 From: Michael Orlitzky Date: Thu, 29 Oct 2009 10:47:47 -0400 Subject: [PATCH] Added GetOpt option parsing. Take a '--continue' option, passed on to the downloader, which determines whether or not we attempt to continue a previous download. Modified the downloaders to throw an IOError if the output file already exists and we're not continuing a previous download. Print the external command used to execute Wget. --- bin/whatever-dl | 56 ++++++++++++++++++++++++++++++++------ src/downloader.rb | 2 +- src/open_uri_downloader.rb | 6 +++- src/wget_downloader.rb | 16 +++++++++-- 4 files changed, 68 insertions(+), 12 deletions(-) diff --git a/bin/whatever-dl b/bin/whatever-dl index fbc84e9..448db85 100755 --- a/bin/whatever-dl +++ b/bin/whatever-dl @@ -24,6 +24,9 @@ # a symlink which points to it. require 'pathname' +# And getoptlong to check for our one option, --continue. +require 'getoptlong' + # This bit of magic adds the parent directory (the # project root) to the list of ruby load paths. # Thus, our require statements will work regardless of @@ -53,19 +56,56 @@ EXIT_SUCCESS = 0 EXIT_NO_URL = 1 EXIT_INVALID_URL = 2 EXIT_COULDNT_GET_VIDEO_URL = 3 -EXIT_OUTPUT_FILE_ALREADY_EXISTS = 4 +EXIT_IO_ERROR = 4 EXIT_ERROR_READING_FROM_VIDEO_URL = 5 EXIT_CONNECTION_REFUSED = 6 EXIT_HTTP_ERROR = 7 EXIT_ACCESS_DENIED = 8 +def usage() + puts < + +Options: + -c, --continue Continue downloading a previously-attempted file. + +EOF + +end + # Only actually do something if this script was called # directly (i.e. not from the tests). if (__FILE__ == $0) then + # Default options. + options = { :continue => false } + + # Parse the command-line options into the options hash. + opts = GetoptLong.new(["--continue", "-c", GetoptLong::NO_ARGUMENT], + ["--help", "-h", GetoptLong::NO_ARGUMENT]) + + opts.each do |opt, arg| + case opt + when '--help' + usage() + Kernel.exit(EXIT_SUCCESS) + when '--continue' + options[:continue] = true + end + end + + # Warn about nonsensical options. + if options[:continue] and not (Configuration::DOWNLOAD_METHOD == :wget) + puts 'WARNING: The --continue flag does nothing unless DOWNLOAD_METHOD is :wget.' + end + + # Note that GetoptLong steals its arguments from ARGV, so we don't need + # to take optional arguments into account when figuring out whether or not + # we were passed a URL. if (ARGV.length < 1) then # If the user didn't give us a URL, yell # at him or her. - puts 'Usage: whatever-dl ' + usage() Kernel.exit(EXIT_NO_URL) end @@ -83,11 +123,6 @@ if (__FILE__ == $0) then puts 'Error retrieving video URL.' exit(EXIT_COULDNT_GET_VIDEO_URL) end - - if File.exists?(site.get_video_filename()) - puts "Error: output file already exists. Please remove #{site.get_video_filename()}, and try again." - Kernel.exit(EXIT_OUTPUT_FILE_ALREADY_EXISTS) - end # The Downloader class is a factory; it should decide # which subclass we get. @@ -98,7 +133,9 @@ if (__FILE__ == $0) then # naturally not report any of these, since it will die in # its own process. begin - downloader.download(video_url, site.get_video_filename()) + downloader.download(video_url, + site.get_video_filename(), + continue=options[:continue]) rescue Errno::ECONNREFUSED => e puts 'The connection to the server (to download the video file) was refused. Check your connection, and try again later.' Kernel.exit(EXIT_CONNECTION_REFUSED) @@ -107,6 +144,9 @@ if (__FILE__ == $0) then rescue OpenURI::HTTPError => e puts "An HTTP error occurred while downloading the video file: #{e.message}." Kernel.exit(EXIT_HTTP_ERROR) + rescue IOError => e + puts "Input/Output Error: #{e.message}" + Kernel.exit(EXIT_IO_ERROR) end # Write an empty line at the end for aesthetic reasons. diff --git a/src/downloader.rb b/src/downloader.rb index eac7c18..742e792 100644 --- a/src/downloader.rb +++ b/src/downloader.rb @@ -30,7 +30,7 @@ class Downloader # Abstract - def download(url, outfile) + def download(url, outfile, continue=false) raise NotImplementedError end diff --git a/src/open_uri_downloader.rb b/src/open_uri_downloader.rb index 44ea037..06c9b3d 100644 --- a/src/open_uri_downloader.rb +++ b/src/open_uri_downloader.rb @@ -20,7 +20,11 @@ require 'src/uri_utilities' class OpenUriDownloader < Downloader - def download(url, outfile) + def download(url, outfile, continue=false) + if File.exists?(outfile) + raise IOError.new("Output file already exists. Please remove #{outfile}, and try again.") + end + uri = URI.parse(url) uu = UriUtilities.new() diff --git a/src/wget_downloader.rb b/src/wget_downloader.rb index 2cbdd45..825ee12 100644 --- a/src/wget_downloader.rb +++ b/src/wget_downloader.rb @@ -18,9 +18,21 @@ class WgetDownloader < Downloader - def download(url, outfile) + def download(url, outfile, continue=false) + if (continue == false and File.exists?(outfile)) + raise IOError.new("Output file already exists. Please remove #{outfile}, and try again. If this is a partially-downloaded file, you can use the --continue flag to pick up where it left off.") + end + + options = '' + + if continue == true + options += '--continue' + end + # This one's easy. - Kernel.exec("wget -O \"#{outfile}\" \"#{url}\"") + cmd = "wget #{options} -O \"#{outfile}\" \"#{url}\"" + puts "\nExecuting external command: #{cmd}\n\n" + Kernel.exec(cmd) end end -- 2.44.2