heel 0.6.0 → 1.0.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.
@@ -1,4 +1,7 @@
1
1
  = Changelog
2
+ == Version 1.0.0 - 2008-04-20
3
+
4
+ * Convert Heel to a Rack and Thin application
2
5
 
3
6
  == Version 0.6.0 - 2007-11-21
4
7
 
@@ -6,9 +9,6 @@
6
9
  * Changed change 'resources' directory to 'data'
7
10
  * Renamed internal constants
8
11
  * Changed operating URL's to avoid conflict with directories heel may be serving
9
- ** /css -> /heel_css
10
- ** /icons -> /heel_icons
11
- ** /status -> /heel_status
12
12
 
13
13
  == Version 0.5.0 - 2007-11-19
14
14
 
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2007, Jeremy Hinegardner
1
+ Copyright (c) 2007, 2008, Jeremy Hinegardner
2
2
 
3
3
  All rights reserved.
4
4
 
data/README CHANGED
@@ -6,44 +6,45 @@
6
6
 
7
7
  == DESCRIPTION:
8
8
 
9
- Heel is a small static file web server based on {mongrel}[http://mongrel.rubyforge.org]
10
- for use when you need a quick web server for a directory. Once the server is running heel will use
11
- {launchy}[http://copiousfreetime.rubyforge.org/launchy/] to open your browser at the URL of your document root.
12
-
13
- % heel
14
- ** Signals ready. TERM => stop. USR2 => restart. INT => stop (no restart).
15
- ** heel running at http://127.0.0.1:4331 with document root /Users/jeremy/Projects/heel
16
- ** Use Ctrl-C to stop.
17
- ** Launching your browser...
18
- 127.0.0.1 - - [19/Nov/2007:23:23:33 MST] "GET / HTTP/1.1" 200 8374
19
- 127.0.0.1 - - [19/Nov/2007:23:23:33 MST] "GET /css/listing.css HTTP/1.1" 200 984
20
- 127.0.0.1 - - [19/Nov/2007:23:23:33 MST] "GET /icons/application.png HTTP/1.1" 200 464
21
- 127.0.0.1 - - [19/Nov/2007:23:23:33 MST] "GET /icons/folder.png HTTP/1.1" 200 537
22
- 127.0.0.1 - - [19/Nov/2007:23:23:33 MST] "GET /favicon.ico HTTP/1.1" 404 0
9
+ Heel is a small static web server for use when you need a quick web server for a
10
+ directory. Once the server is running, heel will use
11
+ {launchy}[http://copiousfreetime.rubyforge.org/launchy/] to open your browser at
12
+ the URL of your document root.
13
+
14
+ Heel is built using {Rack}[http://rack.rubyforge.org] and
15
+ {Thin}[http://code.macournoyer.com/thin/]
16
+
17
+ % heel
18
+ >> Thin web server (v0.8.1 codename Rebel Porpoise)
19
+ >> Threaded mode OFF
20
+ >> Maximum connections set to 1024
21
+ >> Listening on 0.0.0.0:4331, CTRL+C to stop
22
+ Launching your browser...
23
23
 
24
24
  Or run it in the background
25
25
 
26
- % heel --daemonize
27
- Created /Users/jeremy/.heel
28
- heel's PID (/Users/jeremy/.heel/heel.pid) and log file (/Users/jeremy/.heel/heel.log) are stored here
26
+ % heel --daemonize
27
+ Created /Users/jeremy/.heel
28
+ heel's PID (/Users/jeremy/.heel/heel.pid) and log file (/Users/jeremy/.heel/heel.log) are stored here
29
+ Launching your browser at http://0.0.0.0:4331/
29
30
 
30
- % heel --kill
31
- Sending TERM to process 1086
32
- Done.
31
+ % heel --kill
32
+ Sending TERM to process 3304
33
+ Done.
33
34
 
34
35
  == FEATURES
35
36
 
36
37
  * Automatic launching of your browser to the URL it is serving with {launchy}[http://copiousfreetime.rubyforge.org/launchy/]
37
38
  * Automatic syntax highlighting of source code files with {coderay}[http://coderay.rubychan.de/]
38
39
  * Run in the foreground or daemonized
39
- * Bind to any address and port (default is 127.0.0.1:4331)
40
+ * Bind to any address and port (default is 0.0.0.0:4331)
40
41
 
41
42
  == SYNOPSIS:
42
43
 
43
44
  Usage: heel [options]
44
45
 
45
46
  -a, --address ADDRESS Address to bind to
46
- (default: 127.0.0.1)
47
+ (default: 0.0.0.0)
47
48
  -d, --daemonize Run daemonized in the background
48
49
  -h, --help Display this text
49
50
  -k, --kill Kill an existing daemonized heel process
@@ -65,13 +66,13 @@ Or run it in the background
65
66
  * {coderay}[http://coderay.rubychan.de/]
66
67
  * {launchy}[http://copiousfreetime.rubyforge.org/launchy/] >= 0.1.1
67
68
  * {mime-types}[http://mime-types.rubyforge.org/]
68
- * {mongrel}[http://mongrel.rubyforge.org/]
69
- * {rake}[http://rake.rubyforge.org/] >= 0.7.1
69
+ * {thin}[http://thin.rubyforge.org/]
70
70
 
71
71
  === For development:
72
72
 
73
73
  * {rcov}[http://eigenclass.org/hiki.rb?rcov] >= 0.7.0.1
74
74
  * {rspec}[http://rspec.rubyforge.org/] >= 0.7.3
75
+ * {rake}[http://rake.rubyforge.org/] >= 0.7.1
75
76
 
76
77
  == INSTALL:
77
78
 
@@ -79,12 +80,13 @@ Or run it in the background
79
80
 
80
81
  == CREDITS:
81
82
 
82
- * Zed Shaw for {mongrel}[http://mongrel.rubyforge.org]
83
+ * {Thin}[http://code.macournoyer.com/thin/]
84
+ * {Rack}[http://rack.rubyforge.org/]
83
85
  * http://www.famfamfam.com/ for amazing icons
84
86
 
85
87
  == BSD LICENSE:
86
88
 
87
- Copyright (c) 2007, Jeremy Hinegardner
89
+ Copyright (c) 2007, 2008, Jeremy Hinegardner
88
90
 
89
91
  All rights reserved.
90
92
 
data/bin/heel CHANGED
@@ -1,9 +1,13 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
+ #--
4
+ # Copyright (c) 2007, 2008 Jeremy Hinegardner
5
+ # All rights reserved. Licensed under the BSD license. See LICENSE for details
6
+ #++
7
+
3
8
  $: << File.expand_path(File.join(File.dirname(__FILE__),"..","lib"))
4
9
 
5
10
  require 'rubygems'
6
- require 'mongrel'
7
11
  require 'heel'
8
12
 
9
13
  Heel::Server.new(ARGV).run
data/data/error.rhtml CHANGED
@@ -22,7 +22,7 @@
22
22
  <b class="c4"></b><b class="c3"></b><b class="c2"></b><b class="c1"></b>
23
23
  </div>
24
24
  <div class="footer">
25
- <a href="<%= Heel::SPEC::homepage %>">heel</a>/v<%= Heel::VERSION %>
25
+ <a href="<%= homepage %>">heel</a>/v<%= ::Heel::VERSION %>
26
26
  </div>
27
27
  </div>
28
28
  </body>
data/data/listing.rhtml CHANGED
@@ -22,7 +22,7 @@
22
22
  <img src="<%= entry.icon_url %>" width="16" height="16" alt="icon for type <%= entry.content_type %>" />
23
23
  <% end %>
24
24
  <a href="<%= "#{base_uri.chomp('/')}/#{entry.link}" %>"><%= entry.name %></a>
25
- <% if highlighting and entry.content_type != 'Directory' then %>
25
+ <% if highlighting? and entry.content_type != 'Directory' then %>
26
26
  (<a href="<%= "#{base_uri.chomp('/')}/#{entry.link}?highlighting=false" %>">download</a>)
27
27
  <% end %>
28
28
  </td>
@@ -35,7 +35,7 @@
35
35
  </table>
36
36
  </div>
37
37
  <div class="footer">
38
- <a href="<%= Heel::SPEC::homepage %>">heel</a>/v<%= Heel::VERSION %>
38
+ <a href="http://copiousfreetime.rubyforge.org/heel/">heel</a>/v<%= Heel::VERSION %>
39
39
  </div>
40
40
  </body>
41
41
  </html>
data/gemspec.rb ADDED
@@ -0,0 +1,42 @@
1
+ require 'rubygems'
2
+ require 'heel/version'
3
+ require 'tasks/config'
4
+
5
+ Heel::GEM_SPEC = Gem::Specification.new do |spec|
6
+ proj = Configuration.for('project')
7
+ spec.name = proj.name
8
+ spec.version = Heel::VERSION
9
+
10
+ spec.author = proj.author
11
+ spec.email = proj.email
12
+ spec.homepage = proj.homepage
13
+ spec.summary = proj.summary
14
+ spec.description = proj.description
15
+ spec.platform = Gem::Platform::RUBY
16
+
17
+
18
+ pkg = Configuration.for('packaging')
19
+ spec.files = pkg.files.all
20
+ spec.executables = pkg.files.bin.collect { |b| File.basename(b) }
21
+ spec.add_dependency("thin", ">= 0.7.0")
22
+ spec.add_dependency("mime-types", ">= 1.15")
23
+ spec.add_dependency("launchy", ">= 0.3.1")
24
+ spec.add_dependency("coderay", ">= 0.7.4.215")
25
+
26
+ if rdoc = Configuration.for_if_exist?('rdoc') then
27
+ spec.has_rdoc = true
28
+ spec.extra_rdoc_files = pkg.files.rdoc
29
+ spec.rdoc_options = rdoc.options + [ "--main" , rdoc.main ]
30
+ else
31
+ spec.has_rdoc = false
32
+ end
33
+
34
+ if test = Configuration.for_if_exist?('testing') then
35
+ spec.test_files = test.files
36
+ end
37
+
38
+ if rf = Configuration.for_if_exist?('rubyforge') then
39
+ spec.rubyforge_project = rf.project
40
+ end
41
+
42
+ end
data/lib/heel.rb CHANGED
@@ -1,16 +1,21 @@
1
- module Heel
2
- APP_ROOT_DIR = File.dirname(File.expand_path(File.join(__FILE__,".."))).freeze
3
- APP_LIB_DIR = File.join(APP_ROOT_DIR,"lib")
4
- APP_DATA_DIR = File.join(APP_ROOT_DIR,"data")
5
- end
1
+ #--
2
+ # Copyright (c) 2007, 2008 Jeremy Hinegardner
3
+ # All rights reserved. Licensed under the BSD license. See LICENSE for details
4
+ #++
6
5
 
7
- require 'rubygems'
8
- require 'mongrel'
6
+ module Heel
7
+ # recursively descend the directory with the same name as this file and do a
8
+ # require 'heel/path/to/file'
9
+ #
10
+ def self.require_all_libs_relative_to_me
11
+ remove_parent = File.dirname(File.expand_path(__FILE__)) + File::SEPARATOR
12
+ descend_dir = File.join(remove_parent,File.basename(__FILE__, ".rb"))
9
13
 
10
- require 'heel/version'
11
- require 'heel/specification'
12
- require 'heel/gemspec'
13
- require 'heel/server'
14
- require 'heel/dir_handler'
15
- require 'heel/error_handler'
14
+ Dir.glob("#{descend_dir}/**/*.rb").each do |rb|
15
+ lib = rb.gsub(remove_parent,'')
16
+ require lib
17
+ end
18
+ end
19
+ end
16
20
 
21
+ Heel.require_all_libs_relative_to_me
@@ -0,0 +1,64 @@
1
+ #--
2
+ # Copyright (c) 2007, 2008 Jeremy Hinegardner
3
+ # All rights reserved. Licensed under BSD license. See LICENSE for details.
4
+ #++
5
+
6
+ module Heel
7
+
8
+ # Configuration module used by all the other modules and classes for
9
+ # determining paths and default values.
10
+ #
11
+ module Configuration
12
+
13
+ # The root directory of the project is considered to be the parent directory
14
+ # of the 'lib' directory.
15
+ #
16
+ # returns:: [String] The full expanded path of the parent directory of 'lib'
17
+ # going up the path from the current file. Trailing
18
+ # File::SEPARATOR is guaranteed.
19
+ #
20
+ def self.root_dir
21
+ unless @root_dir
22
+ path_parts = ::File.expand_path(__FILE__).split(::File::SEPARATOR)
23
+ lib_index = path_parts.rindex("lib")
24
+ @root_dir = path_parts[0...lib_index].join(::File::SEPARATOR) + ::File::SEPARATOR
25
+ end
26
+ return @root_dir
27
+ end
28
+
29
+ # returns:: [String] The full expanded path of the +config+ directory
30
+ # below _root_dir_. All parameters passed in are joined onto the
31
+ # result. Trailing File::SEPARATOR is guaranteed if _args_ are
32
+ # *not* present.
33
+ #
34
+ def self.config_path(*args)
35
+ self.sub_path("config", *args)
36
+ end
37
+
38
+ # returns:: [String] The full expanded path of the +data+ directory below
39
+ # _root_dir_. All parameters passed in are joined onto the
40
+ # result. Trailing File::SEPARATOR is guaranteed if
41
+ # _*args_ are *not* present.
42
+ #
43
+ def self.data_path(*args)
44
+ self.sub_path("data", *args)
45
+ end
46
+
47
+ # returns:: [String] The full expanded path of the +lib+ directory below
48
+ # _root_dir_. All parameters passed in are joined onto the
49
+ # result. Trailing File::SEPARATOR is guaranteed if
50
+ # _*args_ are *not* present.
51
+ #
52
+ def self.lib_path(*args)
53
+ self.sub_path("lib", *args)
54
+ end
55
+
56
+ HOMEPAGE = "http://copiousfreetime.rubyforge.org/heel/"
57
+
58
+ private
59
+ def self.sub_path(sub,*args)
60
+ sp = ::File.join(root_dir, sub) + File::SEPARATOR
61
+ sp = ::File.join(sp, *args) if args
62
+ end
63
+ end
64
+ end
@@ -0,0 +1,114 @@
1
+ #--
2
+ # Copyright (c) 2007, 2008 Jeremy Hinegardner
3
+ # All rights reserved. Licensed under the BSD license. See LICENSE for details
4
+ #++
5
+
6
+ require 'heel'
7
+ require 'erb'
8
+
9
+ module Heel
10
+ # generate html index pages of a directory
11
+ #
12
+ class DirectoryIndexer
13
+
14
+ attr_reader :options
15
+ attr_reader :template_file
16
+ attr_reader :template
17
+
18
+ def initialize( template_file, options )
19
+ @template_file = template_file
20
+ @options = options
21
+ reload_template
22
+ end
23
+
24
+ def should_ignore?(fname)
25
+ options[:ignore_globs].each do |glob|
26
+ return true if ::File.fnmatch(glob,fname)
27
+ end
28
+ false
29
+ end
30
+
31
+ def mime_map
32
+ @mime_map ||= Heel::MimeMap.new
33
+ end
34
+
35
+ def highlighting?
36
+ @options[:highlighting]
37
+ end
38
+
39
+ def reload_on_template_change?
40
+ @options[:reload_template_on_change]
41
+ end
42
+
43
+ def using_icons?
44
+ @options[:using_icons]
45
+ end
46
+
47
+ def reload_template
48
+ fstat = File.stat(@template_file)
49
+ @template_mtime ||= fstat.mtime
50
+ if @template.nil? or fstat.mtime > @template_mtime then
51
+ @template = ::ERB.new(File.read(@template_file))
52
+ end
53
+ end
54
+
55
+ # generate the directory index html page of a directory
56
+ #
57
+ def index_page_for(req)
58
+ reload_template if reload_on_template_change?
59
+ dir = req.request_path
60
+ base_uri = req.path_info
61
+ entries = []
62
+ Dir.entries(dir).each do |entry|
63
+ next if should_ignore?(entry)
64
+ next if dir == @options[:document_root] and entry == ".."
65
+
66
+ stat = File.stat(File.join(dir,entry))
67
+ entry_data = OpenStruct.new
68
+
69
+ entry_data.name = entry == ".." ? "Parent Directory" : entry
70
+ entry_data.link = entry
71
+ entry_data.size = num_to_bytes(stat.size)
72
+ entry_data.last_modified = stat.mtime.strftime("%Y-%m-%d %H:%M:%S")
73
+
74
+ if stat.directory? then
75
+ entry_data.content_type = "Directory"
76
+ entry_data.size = "-"
77
+ entry_data.name += "/"
78
+ if using_icons? then
79
+ entry_data.icon_url = File.join(options[:icon_url], MimeMap.icons_by_mime_type[:directory])
80
+ end
81
+ else
82
+ entry_data.mime_type = mime_map.mime_type_of(entry)
83
+ entry_data.content_type = entry_data.mime_type.content_type
84
+ if using_icons? then
85
+ entry_data.icon_url = File.join(options[:icon_url], mime_map.icon_for(entry_data.mime_type))
86
+ end
87
+ end
88
+ entries << entry_data
89
+ end
90
+
91
+ entries = entries.sort_by { |e| e.link }
92
+ return template.result(binding)
93
+ end
94
+
95
+ # essentially this is strfbytes from facets
96
+ #
97
+ def num_to_bytes(num,fmt="%.2f")
98
+ case
99
+ when num < 1024
100
+ "#{num} bytes"
101
+ when num < 1024**2
102
+ "#{fmt % (num.to_f / 1024)} KB"
103
+ when num < 1024**3
104
+ "#{fmt % (num.to_f / 1024**2)} MB"
105
+ when num < 1024**4
106
+ "#{fmt % (num.to_f / 1024**3)} GB"
107
+ when num < 1024**5
108
+ "#{fmt % (num.to_f / 1024**4)} TB"
109
+ else
110
+ "#{num} bytes"
111
+ end
112
+ end
113
+ end
114
+ end
@@ -0,0 +1,43 @@
1
+ #--
2
+ # Copyright (c) 2007, 2008 Jeremy Hinegardner
3
+ # All rights reserved. Licensed under the BSD license. See LICENSE for details
4
+ #++
5
+
6
+ require 'heel'
7
+ require 'rack'
8
+ require 'erb'
9
+
10
+ module Heel
11
+
12
+ class ErrorResponse < ::Rack::Response
13
+
14
+ attr_reader :base_uri
15
+
16
+ class << self
17
+ def template_file
18
+ @template_file ||= Heel::Configuration.data_path("error.rhtml")
19
+ end
20
+
21
+ def template
22
+ @template ||= ::ERB.new(File.read(template_file))
23
+ end
24
+
25
+ def homepage
26
+ @homepage ||= Heel::Configuration::HOMEPAGE
27
+ end
28
+ end
29
+
30
+ def initialize(base_uri, body, status = 404, header = {})
31
+ super(body, status, header)
32
+ self['Content-type'] = 'text/html'
33
+ @base_uri = base_uri
34
+ end
35
+
36
+ def finish
37
+ message = ::Rack::Utils::HTTP_STATUS_CODES[status]
38
+ homepage = ErrorResponse.homepage
39
+
40
+ return [ status, header.to_hash, ErrorResponse.template.result(binding) ]
41
+ end
42
+ end
43
+ end