oddjob 1.6.0

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 38b952a30ef59eab2aecda48c84c792a02daff9e
4
+ data.tar.gz: 6d0f3456c227c1bef0888db3971a80671054ba1d
5
+ SHA512:
6
+ metadata.gz: 71b6164c4462f00a4e7c6cb6385eec124b2d13aea477301ae205d4aac46ed288293ada192acc5499bfa106963ee2edca41e422da83bcd6f54dac620c55c09ef8
7
+ data.tar.gz: aab8882dd01c9585ec228f6a3ba481f9f746b0e906345bbef4fd7f3ae00817ce74fde44c3e9a38feffba4b58bcd8cc340934b26538165a138c3f4af582b8b68b
data/.gitignore ADDED
@@ -0,0 +1,7 @@
1
+ *.swp
2
+ .ruby-version
3
+ .bundle
4
+ vendor
5
+ Gemfile.lock
6
+ pkg
7
+ doc
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Dependencies specified in oddjob.gemspec
4
+ gemspec
data/MIT-LICENSE ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) Mike Fellows
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19
+ DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,147 @@
1
+ # oddjob #
2
+
3
+ oddjob is a lightweight, command line controlled web server. Built for
4
+ development and testing purposes, it can be used to serve static content for
5
+ local web development and has basic file upload capabilities. It was initially
6
+ created when web browsers become more restrictive about displaying local files
7
+ directly (*i.e.* file:// URLs).
8
+
9
+ oddjob's file upload endpoint can be used directly via forms or ajax request you
10
+ build yourself with a POST to the `/oj_upload` URL. A basic file upload form
11
+ is also available via a GET request to that same URL. Upon upload the default
12
+ behaviour is for the server to dump the entire upload POST request (header and
13
+ body), followed by the contents of each uploaded file to STDOUT. This is
14
+ useful for small tests uploading text files, but if you need to upload larger
15
+ or binary format files tell oddjob to save the files to a directory instead. If
16
+ you upload and save the same file twice oddjob will not overwrite existing
17
+ saved files, instead a unique name is generated by adding a number to the end
18
+ of the file's name.
19
+
20
+ It is easy to hack the oddjob script to build quick test jigs for web
21
+ development. Sometimes using a simple test web server is easier than working
22
+ with a full fledged development or production environment. To hack the code
23
+ download from the [github repo](https://github.com/MCF/oddjob) and run oddjob
24
+ out of the included `bin` directory.
25
+
26
+ ## Installation ##
27
+
28
+ oddjob is available as a ruby gem. To install it for general command line
29
+ use simply use gem like so:
30
+
31
+ ```sh
32
+ gem install oddjob
33
+ ```
34
+
35
+ In the unlikely event you would like it tied to a project add the following
36
+ line to the project's Gemfile:
37
+
38
+ ```ruby
39
+ gem 'oddjob'
40
+ ```
41
+
42
+ And then execute:
43
+
44
+ ```sh
45
+ bundle
46
+ ```
47
+
48
+ You can also run oddjob directly from the git repo. Clone the git repo and run
49
+ oddjob directly from the repo's bin directory.
50
+
51
+ ## Usage ##
52
+
53
+ Command line usage is:
54
+
55
+ ```
56
+ oddjob [OPTIONS] [server_root]
57
+ ```
58
+
59
+ Where the optional server_root argument will be the server's root directory.
60
+ The default server root is the current working directory.
61
+
62
+ The default file upload behaviour will print the contents of the HTTP POST
63
+ request, and the contents of any uploaded files, to the server's STDOUT. It is
64
+ recommended that you only upload text files in this case. If an output
65
+ directory is specified all uploaded files are saved under their own names in
66
+ this directory. Pre-existing files are not overwritten, instead a number is
67
+ added to the end of the new file names when saving.
68
+
69
+ If a simulated network delay is specified the server will pause that many
70
+ seconds before returning a response for file(s) uploaded to the file upload
71
+ path: `/oj_upload`.
72
+
73
+ The server will only respond to clients on localhost unless the `--allhosts`
74
+ option is specified. Be aware of the security implications of allowing any
75
+ other host on your network to connect to the server if you use this option.
76
+
77
+ An informational page is available at the `/oj_info` path that includes the
78
+ command line usage.
79
+
80
+ The default server port is 4400.
81
+
82
+ Command line options:
83
+
84
+ -d, --delay=value File upload simulated network delay
85
+ -a, --allhosts Allow connections from all hosts
86
+ -o, --output=value Directory to save uploaded files
87
+ -p, --port=value Web server port to use
88
+ --version Display the version number and exit
89
+
90
+ -h, --help Display the usage message
91
+
92
+ To stop oddjob use the normal interrupt key combination (usually Ctrl-C).
93
+
94
+ ## Examples ##
95
+
96
+ ```sh
97
+ oddjob
98
+ ```
99
+
100
+ Serves the files and directories in your current working directory at the
101
+ `http://localhost:4400/` URL. File upload is available at
102
+ `http://localhost:4400/oj_upload`
103
+
104
+ ```sh
105
+ oddjob -p 2222 -o ./uploads ./my-site
106
+ ```
107
+
108
+ Serves the contents of the `./my-site` directory at the
109
+ `http://localhost:2222/` URL, file upload is available at
110
+ `http://localhost:2222/oj_upload` files are saved to the
111
+ `./uploads` directory.
112
+
113
+ ## Environment ##
114
+
115
+ oddjob is written in ruby and its only required dependency is a standard ruby
116
+ install. oddjob makes use of the built in ruby's
117
+ [webrick](http://ruby-doc.org/stdlib-2.0.0/libdoc/webrick/rdoc/WEBrick.html)
118
+ web server library. No gems are required for running oddjob. oddjob has been
119
+ tested with ruby 1.8.7 and up.
120
+
121
+ ## Security ##
122
+
123
+ By default oddjob serves to clients on localhost only (that is: browsers
124
+ running on the same computer as oddjob). If the `-a` option is used connections
125
+ from any client on your network are allowed. If you do not trust the users on
126
+ your local network the `-a` option could be a security concern. Anyone who can
127
+ connect to your IP address can browse and download the files served by oddjob.
128
+
129
+ oddjob will serve the contents of the directory specified on the command line,
130
+ or the current working directory if no directory is specified. It does no
131
+ filtering on the contents of the directory served, and the entire directory
132
+ tree below the top level directory is available for browsing.
133
+
134
+ ## License ##
135
+
136
+ oddjob is released under an [MIT style license](MIT-LICENSE).
137
+
138
+ ## Development ##
139
+
140
+ After checking out the repo, run `bundle install` to install dependencies. Then, run
141
+ `rake spec` to run the tests. Oddjob can be run directly from the repo's bin
142
+ directory for easy testing.
143
+
144
+ ## Contributing ##
145
+
146
+ Bug reports and pull requests are welcome on GitHub at
147
+ https://github.com/MCF/oddjob.
data/Rakefile ADDED
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task :default => :spec
data/bin/oddjob ADDED
@@ -0,0 +1,151 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #--
4
+ # Copyright (c) Mike Fellows
5
+ #
6
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
7
+ # of this software and associated documentation files (the "Software"), to deal
8
+ # in the Software without restriction, including without limitation the rights
9
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
+ # copies of the Software, and to permit persons to whom the Software is
11
+ # furnished to do so, subject to the following conditions:
12
+ #
13
+ # The above copyright notice and this permission notice shall be included in
14
+ # all copies or substantial portions of the Software.
15
+ #
16
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
22
+ # DEALINGS IN THE SOFTWARE.
23
+ #++
24
+
25
+ begin
26
+ require 'rubygems' # Ruby 1.8.7 compatible.
27
+ gem 'rake'
28
+ rescue LoadError
29
+ end
30
+
31
+ begin
32
+ require 'oddjob' # Installed as a gem.
33
+ rescue LoadError
34
+ lib = File.expand_path('../lib', File.dirname( __FILE__))
35
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
36
+
37
+ require 'oddjob' # Simply run from the repo, no gems.
38
+ end
39
+
40
+ def show_version
41
+ STDOUT.puts("Version: #{OddJob::VERSION}")
42
+ exit
43
+ end
44
+
45
+ def error(msg, suggest_usage = false)
46
+ STDERR.puts("ERORR: #{msg}")
47
+ STDERR.puts(" try the -h option for the command usage") if suggest_usage
48
+ exit 1
49
+ end
50
+
51
+ require 'optparse'
52
+
53
+ opts = {}
54
+
55
+ optparser = OptionParser.new do |o|
56
+ o.banner = "Usage: #{File.basename($0)} [OPTIONS] [server_root]"
57
+ o.separator <<TXT
58
+
59
+ Where the optional server_root argument will be the server's root directory.
60
+ The default server root is the current working directory.
61
+
62
+ The default file upload behaviour will print the contents of the HTTP POST
63
+ request, and the contents of any uploaded files, to the server's STDOUT. It is
64
+ recommended that you only upload text files in this case. If an output
65
+ directory is specified all uploaded files are saved under their own names in
66
+ this directory. Pre-existing files are not overwritten, instead a number is
67
+ added to the end of the new file names when saving.
68
+
69
+ If a simulated network delay is specified the server will pause that many
70
+ seconds before returning a response for file(s) uploaded to the file upload
71
+ path: #{OddJob::UPLOAD_PATH}.
72
+
73
+ The server will only respond to clients on localhost unless the --allhosts
74
+ option is specified. Be aware of the security implications of allowing any
75
+ other host on your network to connect to the server if you use this option.
76
+
77
+ An informational page is available at the #{OddJob::INFO_PATH} path.
78
+
79
+ The default server port is #{OddJob::DEFAULT_PORT}.
80
+
81
+ To stop the server use the normal interrupt key combination (usually Ctrl-C).
82
+
83
+ TXT
84
+
85
+ o.on('-d', '--delay=value', Float,
86
+ 'File upload simulated network delay') { |x| opts[:networkdelay] = x }
87
+ o.on('-a', '--allhosts',
88
+ 'Allow connections from all hosts') { opts[:allowall] = true }
89
+ o.on('-o', '--output=value', String,
90
+ 'Directory to save uploaded files') { |x| opts[:savedirectory] = x }
91
+ o.on('-p', '--port=value', Integer,
92
+ "Web server port to use") { |x| opts[:port] = x }
93
+ o.on('--version',
94
+ 'Display the version number and exit') { show_version() }
95
+
96
+ o.separator("")
97
+
98
+ o.on('-h', '--help', 'Display this message') { puts(o); exit }
99
+ end
100
+
101
+ theRest = []
102
+ begin
103
+ theRest = optparser.parse(ARGV)
104
+ rescue
105
+ error($!.to_s, true)
106
+ end
107
+
108
+ error("too many arguments given", true) if theRest.size > 1
109
+
110
+ if theRest.size == 1
111
+ opts[:serverroot] = theRest.pop
112
+
113
+ unless File.directory?(opts[:serverroot])
114
+ error([
115
+ "directory to serve does not exist or is not ",
116
+ "a directory: #{opts[:serverroot]}"
117
+ ].join(''))
118
+ end
119
+
120
+ if opts[:savedirectory] and not File.directory?(opts[:savedirectory])
121
+ error([
122
+ "output directory does not exist or is not ",
123
+ "a directory: #{opts[:savedirectory]}"
124
+ ].join(''))
125
+ end
126
+ end
127
+
128
+ if opts.has_key?(:port) and (opts[:port] < 0 or opts[:port] > 65535)
129
+ error("port specified is invalid: #{opts[:port]}")
130
+ end
131
+
132
+ if opts.has_key?(:networkdelay) and opts[:networkdelay] < 0
133
+ error("simulated delay cannot be negative: #{opts[:networkdelay]}")
134
+ end
135
+
136
+ opts[:usagemessage] = optparser.to_s
137
+
138
+ begin
139
+ OddJob.server(opts)
140
+ rescue Errno::EADDRINUSE => e
141
+ error([
142
+ "Could not bind to the port because it is already in use, ",
143
+ "port: #{opts[:port].nil? ? OddJob::DEFAULT_PORT : opts[:port]}"
144
+ ].join("\n"))
145
+ rescue Errno::EACCES => e
146
+ error([
147
+ "Could not bind to the port due to insufficient permission, usually",
148
+ "this happens when a non root user attempts to use a privileged port",
149
+ "(between 1 and 1000). Port requested: #{opts[:port]}"
150
+ ].join("\n"))
151
+ end
@@ -0,0 +1,3 @@
1
+ module OddJob
2
+ VERSION = '1.6.0'
3
+ end
data/lib/oddjob.rb ADDED
@@ -0,0 +1,288 @@
1
+ #--
2
+ # Copyright (c) Mike Fellows
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ # of this software and associated documentation files (the "Software"), to deal
6
+ # in the Software without restriction, including without limitation the rights
7
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ # copies of the Software, and to permit persons to whom the Software is
9
+ # furnished to do so, subject to the following conditions:
10
+ #
11
+ # The above copyright notice and this permission notice shall be included in
12
+ # all copies or substantial portions of the Software.
13
+ #
14
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20
+ # DEALINGS IN THE SOFTWARE.
21
+ #++
22
+
23
+ require 'webrick'
24
+ require 'oddjob/version'
25
+
26
+ module OddJob
27
+
28
+ UPLOAD_PATH = '/oj_upload'
29
+ INFO_PATH = '/oj_info'
30
+ DEFAULT_PORT = 4400
31
+
32
+ ##
33
+ # Start the oddjob server.
34
+ #
35
+ # +opts+ is a hash. Allowed keys are:
36
+ #
37
+ # * +:serverroot+ - directory to serve (default CWD)
38
+ # * +:savedirectory+ - where to save uploads (default dump to STDOUT)
39
+ # * +:usagemessage+ - the command line usage message to dispaly on info page
40
+ # * +:allowall+ - serve to clients other than on localhost? (default false)
41
+ # * +:networkdelay+ - simulated network delay (default no delay).
42
+ # * +:port+ - port to use. (default is in DEFAULT_PORT module constant)
43
+ #
44
+ # Runs the server until a TERM or INT signal is received (e.g. ctrl-c from
45
+ # the command line).
46
+ def OddJob.server(opts)
47
+ defaults = {
48
+ :serverroot => ".",
49
+ :savedirectory => nil,
50
+ :usagemessage => nil,
51
+ :allowall => false,
52
+ :networkdelay => 0,
53
+ :port => DEFAULT_PORT
54
+ }
55
+
56
+ options = defaults.merge(opts)
57
+
58
+ # Add any missing MIME types (http://bugs.ruby-lang.org/issues/5365)
59
+ m_types = WEBrick::HTTPUtils::DefaultMimeTypes.dup
60
+ m_types['js'] = 'application/javascript' unless m_types.has_key?('js')
61
+ m_types['svg'] = 'image/svg+xml' unless m_types.has_key?('svg')
62
+
63
+ server = WEBrick::HTTPServer.new(
64
+ :Port => options[:port],
65
+ :BindAddress => options[:allowall] ? '0.0.0.0' : '127.0.0.1',
66
+ :MimeTypes => m_types,
67
+ :DocumentRoot => options[:serverroot]
68
+ )
69
+
70
+ server.mount(
71
+ INFO_PATH,
72
+ Info,
73
+ options[:usagemessage]
74
+ )
75
+
76
+ server.mount(
77
+ UPLOAD_PATH,
78
+ FileUpload,
79
+ options[:networkdelay],
80
+ options[:savedirectory]
81
+ )
82
+
83
+ ['TERM', 'INT'].each { |signal| trap(signal){ server.shutdown } }
84
+
85
+ server.start
86
+ end
87
+
88
+ ##
89
+ # A very basic utility for rendering OddJob specific pages.
90
+
91
+ module HtmlRender
92
+
93
+ ##
94
+ # Wrap +content+ in the standard page layout. +title+ is set as the HTML
95
+ # page's title.
96
+ def page(content, title)
97
+ [
98
+ "<!DOCTYPE html>",
99
+ "<head>",
100
+ " <title>OJ #{title}</title>",
101
+ " <style>",
102
+ " body {font:100% arial,sans-serif; margin:1.5em 5em 4em 5em;}",
103
+ " a {text-decoration:none; color:rgb(248,157,30)}",
104
+ " a:hover {color:rgb(239,131,0);}",
105
+ " .header {font-size:0.75em; float:right; margin-bottom: 2.0em;}",
106
+ " </style>",
107
+ "</head>",
108
+ "<html><body>",
109
+ " <div class=\"header\">",
110
+ " <a href=\"https://github.com/MCF/oddjob\">OddJob on github</a>",
111
+ " </div>",
112
+ " <div style=\"clear:both;\"></div>",
113
+ content.kind_of?(Array) ? content.join("\n") : content,
114
+ "</body></html>",
115
+ ].join("\n")
116
+ end
117
+ end
118
+
119
+ ##
120
+ # Webrick servlet for creating the information page.
121
+
122
+ class Info < WEBrick::HTTPServlet::AbstractServlet
123
+ include HtmlRender
124
+
125
+ ##
126
+ # Standard servlet initialization function with an additional
127
+ # +cmd_usage+ argument for specifying the command line usage
128
+ # of the OddJob module's calling entity.
129
+ def initialize(server, cmd_usage, *options)
130
+ @usage = cmd_usage
131
+ super(server, options)
132
+ end
133
+
134
+ ##
135
+ # Respond to get request, returns informational page.
136
+ def do_GET(request, response)
137
+ response.status = 200
138
+ response['Content-Type'] = "text/html"
139
+ response.body = info_page
140
+ end
141
+
142
+ protected
143
+
144
+ ##
145
+ # Render the HTML for the informational page.
146
+ def info_page
147
+ html = [
148
+ " <h1>#{File.basename($0)}</h1>",
149
+ " <p>Version: <strong>#{VERSION}</strong></p>"
150
+ ]
151
+ html << " <pre>#{@usage}</pre>" unless @usage.nil?
152
+ page(html, "Info")
153
+ end
154
+
155
+ end
156
+
157
+ ##
158
+ # Webrick servlet for upload pages.
159
+
160
+ class FileUpload < WEBrick::HTTPServlet::AbstractServlet
161
+ include HtmlRender
162
+
163
+ ##
164
+ # Standard servlet initialization function with additional arguments.
165
+ #
166
+ # +delay+ is the seconds of simulated network delay to wait before
167
+ # responding after an upload request.
168
+ #
169
+ # +save_directory+ is the the directory location to save uploaded files.
170
+ # If +save_directory+ is set to nil uploaded files are not save, instead
171
+ # the entire http request is printed on STDOUT, followed by the name and
172
+ # contents of each file. Generally only useful for small and non-binary
173
+ # files.
174
+ def initialize(server, delay, save_directory, *options)
175
+ @simulated_delay = delay
176
+ @save_directory = save_directory
177
+ super(server, options)
178
+ end
179
+
180
+ ##
181
+ # Handles webrick post request when uploading one or more files via a
182
+ # standard HTML form submission. The form should include an input of type
183
+ # 'file'. See the page produced by the do_GET method for an example form.
184
+ def do_POST(request, response)
185
+
186
+ if @save_directory.nil? # Request to server STDOUT.
187
+ puts "-- BEGIN File Upload POST Request --"
188
+ puts request
189
+ puts "-- END File Upload POST Request --"
190
+ end
191
+
192
+ all_files = Array.new
193
+ ['file', 'file[]'].each do |name|
194
+ if request.query[name]
195
+ request.query[name].each_data do |data|
196
+
197
+ all_files.push(data.filename)
198
+
199
+ if @save_directory.nil? # File contents to server STDOUT.
200
+ puts "== BEGIN #{data.filename} Contents =="
201
+ puts data.to_s
202
+ puts "== END #{data.filename} Contents =="
203
+ else
204
+ output_name = unique_name(data.filename, @save_directory)
205
+ File.open(output_name, "w"){|f| f.print(data.to_s)}
206
+ puts "#{data.filename} uploaded, saved to #{output_name}"
207
+ end
208
+ end
209
+ end
210
+ end
211
+
212
+ response.status = 200
213
+ response['Content-type'] = 'text/html'
214
+ response.body = uploaded_page(all_files)
215
+
216
+ sleep(@simulated_delay)
217
+ end
218
+
219
+ ##
220
+ # Serves a simple file upload form. Uploads submitted are handled by this
221
+ # class' +do_Post+ method.
222
+ def do_GET(request, response)
223
+ response.status = 200
224
+ response['Content-type'] = 'text/html'
225
+ response.body = uploader_page
226
+ end
227
+
228
+ protected
229
+
230
+ ##
231
+ # Finds a unique name in the same directory for the given file.
232
+ #
233
+ # The uploaded file will be renamed if a file by that name already exists.
234
+ # An index number is added to the file's base name to make it unique. For
235
+ # example if test.txt already existed then test_1.txt would be checked,
236
+ # followed by test_2.txt, and so on.
237
+ def unique_name(desired_name, save_directory)
238
+ ext = File.extname(desired_name)
239
+ base = File.basename(desired_name, ext)
240
+
241
+ final_base = full_base = File.join(save_directory, base)
242
+ i = 1
243
+ while(File.exist?(final_base + ext))
244
+ final_base = "#{full_base}_#{i}"
245
+ i += 1
246
+ end
247
+
248
+ final_base + ext
249
+ end
250
+
251
+ ##
252
+ # Returns a string holding the full HTML page with the file upload form.
253
+ def uploader_page
254
+ html = [
255
+ "<h1>Uploader</h1>",
256
+ "<form action='' method='POST' enctype='multipart/form-data'>",
257
+ " <p>",
258
+ " Select file(s) to upload:",
259
+ " <br><br>",
260
+ " <input type='file' name='file' multiple='true'>",
261
+ " <br><br>",
262
+ " <input type='submit'>",
263
+ " </p>",
264
+ "</form>",
265
+ ]
266
+
267
+ page(html, "Uploader")
268
+ end
269
+
270
+ ##
271
+ # Returns a string holding the result of the upload page submission.
272
+ #
273
+ # +names+ is an array of the uploaded file names. These are names
274
+ # as submitted. Saved names may be different to avoid overwritting.
275
+ def uploaded_page(names)
276
+ html = [
277
+ "<h1>Results</h1>",
278
+ "<p>Uploaded:",
279
+ " <strong>#{names.join("</strong>, <strong>")}</strong>",
280
+ "</p>",
281
+ "<p><a href=''>Return to upload page</a></p>",
282
+ ]
283
+
284
+ page(html, "Upload Results")
285
+ end
286
+ end
287
+
288
+ end
data/oddjob.gemspec ADDED
@@ -0,0 +1,40 @@
1
+ # coding: utf-8
2
+
3
+ lib = File.expand_path('./lib', File.dirname( __FILE__))
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'oddjob/version'
6
+
7
+ Gem::Specification.new do |spec|
8
+ spec.name = 'oddjob'
9
+ spec.version = OddJob::VERSION
10
+ spec.authors = ['Mike Fellows']
11
+ spec.email = ['Mike.Fellows@shaw.ca']
12
+
13
+ spec.summary = 'OddJob is simple command line driven web server'
14
+ spec.description = <<TXT
15
+ Oddjob is a simple command line driver web server, written in ruby and
16
+ utilizing ruby's built in web server webrick. It is meant to be a test and
17
+ development tool, suitable for static content from a local directory.
18
+
19
+ Oddjob also provides basic file upload capabilities (single or multi-file
20
+ upload). This includes the ability to save uploaded files locally.
21
+
22
+ As a stand alone application the server is quick and convenient application
23
+ for web developers working with static files. Or get a copy of the source and
24
+ add in new endpoints for simple tests as needed.
25
+ TXT
26
+
27
+ spec.homepage = 'https://github.com/MCF/oddjob'
28
+ spec.license = 'MIT'
29
+
30
+ spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
31
+ spec.bindir = 'bin'
32
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
33
+ spec.require_paths = ['lib']
34
+ spec.extra_rdoc_files = ['README.md', 'MIT-LICENSE']
35
+ spec.rdoc_options = ['--main', 'README.md']
36
+
37
+ spec.add_development_dependency('bundler', '~> 1.10')
38
+ spec.add_development_dependency('rake', '~> 10.0')
39
+ spec.add_development_dependency('rspec')
40
+ end
metadata ADDED
@@ -0,0 +1,110 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: oddjob
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.6.0
5
+ platform: ruby
6
+ authors:
7
+ - Mike Fellows
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2016-02-13 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.10'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.10'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: |
56
+ Oddjob is a simple command line driver web server, written in ruby and
57
+ utilizing ruby's built in web server webrick. It is meant to be a test and
58
+ development tool, suitable for static content from a local directory.
59
+
60
+ Oddjob also provides basic file upload capabilities (single or multi-file
61
+ upload). This includes the ability to save uploaded files locally.
62
+
63
+ As a stand alone application the server is quick and convenient application
64
+ for web developers working with static files. Or get a copy of the source and
65
+ add in new endpoints for simple tests as needed.
66
+ email:
67
+ - Mike.Fellows@shaw.ca
68
+ executables:
69
+ - oddjob
70
+ extensions: []
71
+ extra_rdoc_files:
72
+ - README.md
73
+ - MIT-LICENSE
74
+ files:
75
+ - ".gitignore"
76
+ - Gemfile
77
+ - MIT-LICENSE
78
+ - README.md
79
+ - Rakefile
80
+ - bin/oddjob
81
+ - lib/oddjob.rb
82
+ - lib/oddjob/version.rb
83
+ - oddjob.gemspec
84
+ homepage: https://github.com/MCF/oddjob
85
+ licenses:
86
+ - MIT
87
+ metadata: {}
88
+ post_install_message:
89
+ rdoc_options:
90
+ - "--main"
91
+ - README.md
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ requirements:
96
+ - - ">="
97
+ - !ruby/object:Gem::Version
98
+ version: '0'
99
+ required_rubygems_version: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubyforge_project:
106
+ rubygems_version: 2.4.5
107
+ signing_key:
108
+ specification_version: 4
109
+ summary: OddJob is simple command line driven web server
110
+ test_files: []