]> gitweb.michael.orlitzky.com - dead/whatever-dl.git/blob - bin/whatever-dl
782624973dbb860b59313aff47e4f87bd7eb953e
[dead/whatever-dl.git] / bin / whatever-dl
1 #!/usr/bin/ruby -wKU
2 #
3 # whatever-dl, a script to download online (web-based) videos.
4 #
5 # Copyright Michael Orlitzky
6 #
7 # http://michael.orlitzky.com/
8 #
9 # This program is free software: you can redistribute it and/or modify
10 # it under the terms of the GNU General Public License as published by
11 # the Free Software Foundation, either version 3 of the License, or
12 # (at your option) any later version.
13 #
14 # This program is distributed in the hope that it will be useful,
15 # but WITHOUT ANY WARRANTY; without even the implied warranty of
16 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 # GNU General Public License for more details.
18 #
19 # http://www.fsf.org/licensing/licenses/gpl.html
20 #
21
22 # This should load everything we need for us.
23 require 'whatever-dl'
24
25 # And getoptlong to check for our one option, --continue.
26 require 'getoptlong'
27
28 EXIT_SUCCESS = 0
29 EXIT_NO_URL = 1
30 EXIT_INVALID_URL = 2
31 EXIT_COULDNT_GET_VIDEO_URL = 3
32 EXIT_IO_ERROR = 4
33 EXIT_ERROR_READING_FROM_VIDEO_URL = 5
34 EXIT_CONNECTION_REFUSED = 6
35 EXIT_HTTP_ERROR = 7
36 EXIT_ACCESS_DENIED = 8
37
38 def usage()
39 puts <<EOF
40
41 Usage: whatever-dl [options] <url>
42
43 Options:
44 -c, --continue Continue downloading a previously-attempted file.
45
46 EOF
47
48 end
49
50 # Only actually do something if this script was called
51 # directly (i.e. not from the tests).
52 if (__FILE__ == $0) then
53 # Default options.
54 options = { :continue => false }
55
56 # Parse the command-line options into the options hash.
57 opts = GetoptLong.new(["--continue", "-c", GetoptLong::NO_ARGUMENT],
58 ["--help", "-h", GetoptLong::NO_ARGUMENT])
59
60 opts.each do |opt, arg|
61 case opt
62 when '--help'
63 usage()
64 Kernel.exit(EXIT_SUCCESS)
65 when '--continue'
66 options[:continue] = true
67 end
68 end
69
70 # Warn about nonsensical options.
71 if options[:continue] and not Configuration::DOWNLOAD_METHOD == :wget
72 puts 'WARNING: The --continue flag does nothing unless DOWNLOAD_METHOD is :wget.'
73 end
74
75 # Note that GetoptLong steals its arguments from ARGV, so we don't need
76 # to take optional arguments into account when figuring out whether or not
77 # we were passed a URL.
78 if (ARGV.length < 1) then
79 # If the user didn't give us a URL, yell
80 # at him or her.
81 usage()
82 Kernel.exit(EXIT_NO_URL)
83 end
84
85 # Factory method.
86 site = Website.create(ARGV[0])
87
88 if site.nil?
89 puts 'Invalid URL.'
90 exit(EXIT_INVALID_URL)
91 end
92
93 video_url = site.get_video_url()
94
95 if video_url.nil?
96 puts 'Error retrieving video URL:'
97 puts "Site not supported, and the generic parser couldn't find any videos."
98 exit(EXIT_COULDNT_GET_VIDEO_URL) end
99
100 # The Downloader class is a factory; it should decide
101 # which subclass we get.
102 downloader = Downloader.create(Configuration::DOWNLOAD_METHOD)
103
104 # Attempt to download the file, and rescue and report
105 # any (predictable) exceptions. The wget downloader will
106 # naturally not report any of these, since it will die in
107 # its own process.
108 begin
109 downloader.download(video_url,
110 site.get_video_filename(),
111 site.headers(),
112 continue=options[:continue])
113
114 rescue Errno::ECONNREFUSED => e
115 msg = 'The connection to the server (to download the video file) '
116 msg += 'was refused. Check your connection, and try again later.'
117 puts msg
118 Kernel.exit(EXIT_CONNECTION_REFUSED)
119
120 rescue Errno::EACCES => e
121 msg = 'Access denied. Check that you have write permission '
122 msg += "to the output file/directory. Details: #{e.message}."
123 puts msg
124 Kernel.exit(EXIT_ACCESS_DENIED)
125
126 rescue OpenURI::HTTPError => e
127 msg = 'An HTTP error occurred while downloading '
128 msg += " the video file: #{e.message}."
129 puts msg
130 Kernel.exit(EXIT_HTTP_ERROR)
131
132 rescue IOError => e
133 puts "Input/Output Error: #{e.message}"
134 Kernel.exit(EXIT_IO_ERROR)
135
136 end
137
138 # Write an empty line at the end for aesthetic reasons.
139 puts ''
140
141 Kernel.exit(EXIT_SUCCESS)
142 end