]> gitweb.michael.orlitzky.com - dead/whatever-dl.git/blob - bin/whatever-dl
fbc84e909bde09dbfc14f525404300c56e00394a
[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 # We need Pathname to get the real filesystem path
23 # of this script (and not, for example, the path of
24 # a symlink which points to it.
25 require 'pathname'
26
27 # This bit of magic adds the parent directory (the
28 # project root) to the list of ruby load paths.
29 # Thus, our require statements will work regardless of
30 # how or from where the script was run.
31 executable = Pathname.new(__FILE__).realpath.to_s
32 $: << File.dirname(executable) + '/../'
33
34 # Load our config file.
35 require 'bin/configuration'
36
37 # And the downloaders...
38 require 'src/downloader'
39
40 # The Dir.glob that's coming up doesn't use the
41 # Ruby library path so we need to tell it where to
42 # look explicitly.
43 websites_pattern = File.dirname(executable) + '/../src/websites/*.rb'
44
45 # All of the website classes are located in one
46 # directory, so we can 'require' them automatically.
47 Dir.glob(websites_pattern).each do |r|
48 require r
49 end
50
51
52 EXIT_SUCCESS = 0
53 EXIT_NO_URL = 1
54 EXIT_INVALID_URL = 2
55 EXIT_COULDNT_GET_VIDEO_URL = 3
56 EXIT_OUTPUT_FILE_ALREADY_EXISTS = 4
57 EXIT_ERROR_READING_FROM_VIDEO_URL = 5
58 EXIT_CONNECTION_REFUSED = 6
59 EXIT_HTTP_ERROR = 7
60 EXIT_ACCESS_DENIED = 8
61
62 # Only actually do something if this script was called
63 # directly (i.e. not from the tests).
64 if (__FILE__ == $0) then
65 if (ARGV.length < 1) then
66 # If the user didn't give us a URL, yell
67 # at him or her.
68 puts 'Usage: whatever-dl <url>'
69 Kernel.exit(EXIT_NO_URL)
70 end
71
72 # Factory method.
73 site = Website.create(ARGV[0])
74
75 if site.nil?
76 puts 'Invalid URL.'
77 exit(EXIT_INVALID_URL)
78 end
79
80 video_url = site.get_video_url()
81
82 if video_url.nil?
83 puts 'Error retrieving video URL.'
84 exit(EXIT_COULDNT_GET_VIDEO_URL)
85 end
86
87 if File.exists?(site.get_video_filename())
88 puts "Error: output file already exists. Please remove #{site.get_video_filename()}, and try again."
89 Kernel.exit(EXIT_OUTPUT_FILE_ALREADY_EXISTS)
90 end
91
92 # The Downloader class is a factory; it should decide
93 # which subclass we get.
94 downloader = Downloader.create(Configuration::DOWNLOAD_METHOD)
95
96 # Attempt to download the file, and rescue and report
97 # any (predictable) exceptions. The wget downloader will
98 # naturally not report any of these, since it will die in
99 # its own process.
100 begin
101 downloader.download(video_url, site.get_video_filename())
102 rescue Errno::ECONNREFUSED => e
103 puts 'The connection to the server (to download the video file) was refused. Check your connection, and try again later.'
104 Kernel.exit(EXIT_CONNECTION_REFUSED)
105 rescue Errno::EACCES => e
106 puts "Access denied. Check that you have write permission to the output file/directory. Details: #{e.message}."
107 rescue OpenURI::HTTPError => e
108 puts "An HTTP error occurred while downloading the video file: #{e.message}."
109 Kernel.exit(EXIT_HTTP_ERROR)
110 end
111
112 # Write an empty line at the end for aesthetic reasons.
113 puts ''
114
115 Kernel.exit(EXIT_SUCCESS)
116 end