]> gitweb.michael.orlitzky.com - dead/whatever-dl.git/blob - bin/whatever-dl
47253f13d8bd00eace1ccca43e69592de5948411
[dead/whatever-dl.git] / bin / whatever-dl
1 #!/usr/bin/ruby -w
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 require the UriUtilities class to handle
23 # the download of the video URL.
24 require 'src/uri_utilities'
25
26
27 # All of the website classes are located in one
28 # directory, so we can 'require' them automatically.
29 Dir.glob('src/websites/*.rb').each do |r|
30 require r
31 end
32
33
34 EXIT_SUCCESS = 0
35 EXIT_NO_URL = 1
36 EXIT_INVALID_URL = 2
37 EXIT_COULDNT_GET_VIDEO_URL = 3
38 EXIT_OUTPUT_FILE_ALREADY_EXISTS = 4
39 EXIT_ERROR_READING_FROM_VIDEO_URL = 5
40 EXIT_CONNECTION_REFUSED = 6
41 EXIT_HTTP_ERROR = 7
42 EXIT_ACCESS_DENIED = 8
43
44 # Only actually do something if this script was called
45 # directly (i.e. not from the tests).
46 if (__FILE__ == $0) then
47 if (ARGV.length < 1) then
48 # If the user didn't give us a URL, yell
49 # at him or her.
50 puts 'Usage: whatever-dl <url>'
51 Kernel.exit(EXIT_NO_URL)
52 end
53
54 # Check the URL against each website's class.
55 # The class will know whether or not the URL
56 # "belongs" to its website.
57
58 site = nil
59
60 Website.subclasses.each do |w|
61 if w.owns_url?(ARGV[0])
62 site = w.new()
63 break
64 end
65 end
66
67 if site.nil?
68 puts 'Invalid URL.'
69 exit(EXIT_INVALID_URL)
70 end
71
72 video_url = site.get_video_url(ARGV[0])
73
74 if video_url.nil?
75 puts 'Error retrieving video URL.'
76 exit(EXIT_COULDNT_GET_VIDEO_URL)
77 end
78
79 video_uri = URI.parse(video_url)
80 uu = UriUtilities.new()
81
82
83 # Here, we start out with a default file name and
84 # extension. If UriUtilities can parse a sane filename
85 # out of the URL, we'll use that. Otherwise, we fall
86 # back to the default.
87 outfile_name = 'default.ext'
88
89 if not uu.get_filename(video_uri).nil?
90 outfile_name = uu.get_filename(video_uri)
91 else
92 puts "We couldn't determine the video's filename. Falling back to the default, #{outfile_name}."
93 end
94
95
96 if File.exists?(outfile_name)
97 puts "Error: output file already exists. Please remove #{outfile_name}, and try again."
98 Kernel.exit(EXIT_OUTPUT_FILE_ALREADY_EXISTS)
99 end
100
101
102 # Attempt to download the file, and rescue and report
103 # any (predictable) exceptions.
104 begin
105 puts "Fetching #{video_url}"
106 uu.download_with_progress_bar(video_uri, outfile_name)
107 rescue Errno::ECONNREFUSED => e
108 puts 'The connection to the server (to download the video file) was refused. Check your connection, and try again later.'
109 Kernel.exit(EXIT_CONNECTION_REFUSED)
110 rescue Errno::EACCES => e
111 puts "Access denied. Check that you have write permission to the output file/directory. Details: #{e.message}."
112 rescue OpenURI::HTTPError => e
113 puts "An HTTP error occurred while downloading the video file: #{e.message}."
114 Kernel.exit(EXIT_HTTP_ERROR)
115 end
116
117 Kernel.exit(EXIT_SUCCESS)
118 end