tap-server 0.5.0 → 0.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.
- data/History +4 -0
- data/MIT-LICENSE +17 -15
- data/README +2 -11
- data/cmd/server.rb +27 -41
- data/lib/tap/controller.rb +22 -31
- data/lib/tap/controllers/app.rb +20 -116
- data/lib/tap/controllers/data.rb +16 -1
- data/lib/tap/controllers/server.rb +58 -15
- data/lib/tap/generator/generators/controller.rb +23 -0
- data/lib/tap/server.rb +75 -53
- data/lib/tap/tasks/echo.rb +1 -1
- data/templates/tap/generator/generators/controller/resource.erb +14 -0
- data/templates/tap/generator/generators/controller/test.erb +0 -0
- data/templates/tap/generator/generators/controller/view.erb +1 -0
- data/views/configurable/configurations.erb +57 -0
- data/views/configurable/default.erb +1 -0
- data/views/layout.erb +5 -2
- data/views/tap/{task → app/api}/help.erb +6 -4
- data/views/tap/controller/help.erb +4 -2
- data/views/tap/controllers/app/index.erb +47 -0
- data/views/tap/controllers/data/_upload.erb +1 -1
- data/views/tap/controllers/data/index.erb +16 -5
- data/views/tap/controllers/server/index.erb +10 -33
- data/views/tap/signals/signal/get.erb +1 -0
- data/views/tap/signals/signal/index.erb +4 -0
- data/views/tap/signals/signal/post.erb +1 -0
- metadata +18 -26
- data/lib/tap/controllers/schema.rb +0 -202
- data/lib/tap/server/runner.rb +0 -71
- data/public/javascripts/prototype.js +0 -4221
- data/public/javascripts/tap.js +0 -112
- data/views/configurable/_configs.erb +0 -33
- data/views/configurable/_flag.erb +0 -2
- data/views/configurable/_list_select.erb +0 -6
- data/views/configurable/_select.erb +0 -5
- data/views/configurable/_switch.erb +0 -2
- data/views/tap/controllers/app/_action.erb +0 -3
- data/views/tap/controllers/app/build.erb +0 -18
- data/views/tap/controllers/app/enque.erb +0 -13
- data/views/tap/controllers/app/info.erb +0 -21
- data/views/tap/controllers/app/tail.erb +0 -8
- data/views/tap/controllers/data/_index_entry.erb +0 -1
- data/views/tap/controllers/schema/_build.erb +0 -6
- data/views/tap/controllers/schema/_index_entry.erb +0 -6
- data/views/tap/controllers/schema/entry.erb +0 -144
- data/views/tap/task/input.erb +0 -17
- data/views/tap/tasks/load/input.erb +0 -11
data/lib/tap/controllers/data.rb
CHANGED
@@ -61,6 +61,7 @@ module Tap
|
|
61
61
|
# POST /projects?_method=put&id=id
|
62
62
|
def destroy(id)
|
63
63
|
data.destroy(type, id)
|
64
|
+
deselect([id])
|
64
65
|
redirect uri
|
65
66
|
end
|
66
67
|
|
@@ -72,7 +73,21 @@ module Tap
|
|
72
73
|
end
|
73
74
|
|
74
75
|
def select(ids=[])
|
75
|
-
data.cache[type]
|
76
|
+
current = data.cache[type] ||= []
|
77
|
+
data.cache[type] = current | ids
|
78
|
+
redirect uri
|
79
|
+
end
|
80
|
+
|
81
|
+
def deselect(ids=[])
|
82
|
+
if current = data.cache[type]
|
83
|
+
data.cache[type] = current - ids
|
84
|
+
end
|
85
|
+
redirect uri
|
86
|
+
end
|
87
|
+
|
88
|
+
def destroy_all(ids=[])
|
89
|
+
ids.each {|id| data.destroy(type, id) }
|
90
|
+
deselect(ids)
|
76
91
|
redirect uri
|
77
92
|
end
|
78
93
|
|
@@ -16,7 +16,24 @@ module Tap
|
|
16
16
|
include Utils
|
17
17
|
|
18
18
|
def index
|
19
|
-
|
19
|
+
env = server.env
|
20
|
+
env_keys = env.minihash(true)
|
21
|
+
constants = env.constants
|
22
|
+
manifests = env.collect do |current|
|
23
|
+
types = {}
|
24
|
+
constants.entries(current).minimap.each do |key, const|
|
25
|
+
const.types.keys.each do |type|
|
26
|
+
(types[type] ||= []) << [key, const]
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
types = types.to_a.sort_by {|type, minimap| type }
|
31
|
+
types.empty? ? nil : [env_keys[current], types]
|
32
|
+
end
|
33
|
+
|
34
|
+
render 'index.erb', :locals => {
|
35
|
+
:manifests => manifests.compact
|
36
|
+
}, :layout => true
|
20
37
|
end
|
21
38
|
|
22
39
|
# Returns pong
|
@@ -55,11 +72,12 @@ module Tap
|
|
55
72
|
end
|
56
73
|
end
|
57
74
|
|
58
|
-
def help(
|
59
|
-
if constant = server.env[
|
60
|
-
|
75
|
+
def help(*key)
|
76
|
+
if constant = server.env[key.join('/')]
|
77
|
+
path = server.module_path('help.erb', constant)
|
78
|
+
render :file => path, :locals => {:obj => constant}
|
61
79
|
else
|
62
|
-
"unknown
|
80
|
+
"unknown constant: #{key.join('/')}"
|
63
81
|
end
|
64
82
|
end
|
65
83
|
|
@@ -67,11 +85,31 @@ module Tap
|
|
67
85
|
set :define_action, false
|
68
86
|
|
69
87
|
def call(rack_env)
|
70
|
-
|
71
|
-
|
72
|
-
|
88
|
+
server = rack_env['tap.server']
|
89
|
+
env = server ? server.env : nil
|
90
|
+
path_info = rack_env['PATH_INFO']
|
91
|
+
|
92
|
+
# serve static files
|
93
|
+
path = env.path(:public, path_info) {|file| File.file?(file) }
|
94
|
+
return static_file(path) if path
|
95
|
+
|
96
|
+
# route to a controller
|
97
|
+
blank, path, path_info = path_info.split("/", 3)
|
98
|
+
constant = env ? env.constants.seek(unescape(path)) : nil
|
99
|
+
|
100
|
+
if constant
|
101
|
+
# adjust rack_env if route routes to a controller
|
102
|
+
rack_env['SCRIPT_NAME'] = "#{rack_env['SCRIPT_NAME'].chomp('/')}/#{path}"
|
103
|
+
rack_env['PATH_INFO'] = "/#{path_info}"
|
104
|
+
|
105
|
+
constant.unload if server.development
|
106
|
+
controller = constant.constantize
|
107
|
+
controller == Server ? super : controller.call(rack_env)
|
73
108
|
else
|
74
|
-
|
109
|
+
response = Rack::Response.new
|
110
|
+
response.status = 302
|
111
|
+
response['Location'] = ["/server#{rack_env['PATH_INFO']}".chomp("/")]
|
112
|
+
response.finish
|
75
113
|
end
|
76
114
|
end
|
77
115
|
|
@@ -87,15 +125,20 @@ module Tap
|
|
87
125
|
end
|
88
126
|
|
89
127
|
# Returns a help uri for the specified resource, currently only sketched out.
|
90
|
-
def help_uri(
|
91
|
-
uri("help/#{
|
128
|
+
def help_uri(key)
|
129
|
+
uri("help/#{key}")
|
92
130
|
end
|
93
131
|
|
94
|
-
|
95
|
-
|
96
|
-
|
132
|
+
def template
|
133
|
+
%Q{<% if !minimap.empty? && count > 1 %>
|
134
|
+
<h2><%= env_key %></h2>
|
135
|
+
<li>
|
136
|
+
<ul><% minimap.each do |key, entry| %>
|
137
|
+
<li><%= key %> (<a href="help/<%= key %>">?</a>)</li><% end %>
|
138
|
+
</ul>
|
139
|
+
</li>
|
140
|
+
<% end %>}
|
97
141
|
end
|
98
|
-
|
99
142
|
end
|
100
143
|
end
|
101
144
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'tap/generator/generators/resource'
|
2
|
+
|
3
|
+
module Tap
|
4
|
+
module Generator
|
5
|
+
module Generators
|
6
|
+
# :startdoc::generator generates a controller
|
7
|
+
#
|
8
|
+
# Generates a new Tap::Controller and an associated test file.
|
9
|
+
class Controller < Resource
|
10
|
+
|
11
|
+
def manifest(m, const_name)
|
12
|
+
const = super
|
13
|
+
|
14
|
+
views_dir = path('views', "#{const.path}")
|
15
|
+
m.directory File.dirname(views_dir)
|
16
|
+
m.template path(views_dir, "index.erb"), "view.erb"
|
17
|
+
|
18
|
+
const
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/tap/server.rb
CHANGED
@@ -1,12 +1,20 @@
|
|
1
|
+
require 'rack'
|
1
2
|
require 'tap'
|
2
3
|
require 'tap/server/data'
|
3
|
-
require 'tap/server/runner'
|
4
4
|
require 'tap/server/server_error'
|
5
5
|
|
6
6
|
module Tap
|
7
7
|
# ::configurable
|
8
8
|
class Server
|
9
|
-
include
|
9
|
+
include Rack::Utils
|
10
|
+
include Configurable
|
11
|
+
|
12
|
+
config :servers, %w[thin mongrel webrick], # the server handlers
|
13
|
+
:long => :server,
|
14
|
+
&c.list
|
15
|
+
|
16
|
+
config :host, '127.0.0.1', &c.string # the server host
|
17
|
+
config :port, 8080, &c.integer_or_nil # the server port
|
10
18
|
|
11
19
|
# Server implements a secret for HTTP administration of the server (ex
|
12
20
|
# remote shutdown). Under many circumstances this functionality is
|
@@ -16,22 +24,34 @@ module Tap
|
|
16
24
|
|
17
25
|
config :development, false, &c.flag
|
18
26
|
|
19
|
-
config :router, true, &c.switch
|
20
|
-
|
21
|
-
nest :env, Tap::Env, :type => :hidden
|
22
|
-
|
23
|
-
nest :app, Tap::App, :type => :hidden
|
24
|
-
|
25
27
|
nest :data, Data, :type => :hidden
|
26
28
|
|
27
|
-
|
29
|
+
attr_reader :app
|
30
|
+
attr_reader :controller
|
28
31
|
|
29
|
-
|
32
|
+
def initialize(config={}, app=Tap::App.instance, &block)
|
33
|
+
@handler = nil
|
34
|
+
@controller = block
|
35
|
+
|
36
|
+
@app = app
|
37
|
+
initialize_config(config)
|
38
|
+
end
|
39
|
+
|
40
|
+
def env
|
41
|
+
app.env
|
42
|
+
end
|
30
43
|
|
31
|
-
def
|
44
|
+
def bind(controller)
|
45
|
+
if controller.kind_of?(String)
|
46
|
+
controller = app.resolve(controller)
|
47
|
+
end
|
48
|
+
|
49
|
+
unless controller.respond_to?(:call)
|
50
|
+
raise "invalid controller: #{controller.inspect}"
|
51
|
+
end
|
52
|
+
|
32
53
|
@controller = controller
|
33
|
-
|
34
|
-
super(config)
|
54
|
+
self
|
35
55
|
end
|
36
56
|
|
37
57
|
# Returns true if input is equal to the secret, if a secret is set. Used
|
@@ -41,36 +61,18 @@ module Tap
|
|
41
61
|
secret != nil && input == secret
|
42
62
|
end
|
43
63
|
|
44
|
-
def
|
45
|
-
|
46
|
-
|
47
|
-
# route to a controller
|
48
|
-
blank, path, path_info = rack_env['PATH_INFO'].split("/", 3)
|
49
|
-
controller = lookup_controller(unescape(path))
|
50
|
-
|
51
|
-
if controller
|
52
|
-
# adjust rack_env if route routes to a controller
|
53
|
-
rack_env['SCRIPT_NAME'] = ["#{rack_env['SCRIPT_NAME'].chomp('/')}/#{path}"]
|
54
|
-
rack_env['PATH_INFO'] = ["/#{path_info}"]
|
55
|
-
else
|
56
|
-
# use default controller
|
57
|
-
controller = self.controller
|
58
|
-
path = nil
|
59
|
-
end
|
60
|
-
|
61
|
-
rack_env['tap.controller_path'] = path
|
62
|
-
controller
|
64
|
+
def template_path(path)
|
65
|
+
app.env.path(:views, path) {|file| File.file?(file) }
|
63
66
|
end
|
64
|
-
|
67
|
+
|
68
|
+
def module_path(path, klass)
|
69
|
+
app.env.module_path(:views, klass.ancestors, path) {|file| File.file?(file) }
|
70
|
+
end
|
71
|
+
|
65
72
|
# The {Rack}[http://rack.rubyforge.org/doc/] interface method.
|
66
73
|
def call(rack_env)
|
67
74
|
# handle the request
|
68
75
|
rack_env['tap.server'] = self
|
69
|
-
|
70
|
-
unless controller = route(rack_env)
|
71
|
-
raise ServerError.new("404 Error: could not route to controller", 404)
|
72
|
-
end
|
73
|
-
|
74
76
|
controller.call(rack_env)
|
75
77
|
rescue ServerError
|
76
78
|
$!.response
|
@@ -78,27 +80,47 @@ module Tap
|
|
78
80
|
ServerError.response($!)
|
79
81
|
end
|
80
82
|
|
81
|
-
|
82
|
-
|
83
|
+
# Runs self as configured, on the specified server, host, and port. Use an
|
84
|
+
# INT signal to interrupt.
|
85
|
+
def run!(handler=rack_handler)
|
86
|
+
return self if @handler
|
87
|
+
|
88
|
+
handler.run(self, :Host => host, :Port => port) do |handler|
|
89
|
+
@handler = handler
|
90
|
+
trap(:INT) { stop! }
|
91
|
+
yield if block_given?
|
92
|
+
end
|
93
|
+
|
94
|
+
self
|
95
|
+
end
|
96
|
+
|
97
|
+
# Stops the server if running (ie a handler is set).
|
98
|
+
def stop!
|
99
|
+
if @handler
|
100
|
+
# Use thins' hard #stop! if available, otherwise just #stop
|
101
|
+
@handler.respond_to?(:stop!) ? @handler.stop! : @handler.stop
|
102
|
+
@handler = nil
|
103
|
+
|
104
|
+
yield if block_given?
|
105
|
+
end
|
106
|
+
|
107
|
+
self
|
83
108
|
end
|
84
109
|
|
85
110
|
protected
|
86
111
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
else
|
97
|
-
nil
|
112
|
+
# Looks up and returns the first available Rack::Handler as listed in the
|
113
|
+
# servers configuration. (Note rack_handler returns a handler class, not
|
114
|
+
# an instance). Adapted from Sinatra.detect_rack_handler
|
115
|
+
def rack_handler # :nodoc:
|
116
|
+
servers.each do |server_name|
|
117
|
+
begin
|
118
|
+
return Rack::Handler.get(server_name)
|
119
|
+
rescue LoadError
|
120
|
+
rescue NameError
|
98
121
|
end
|
99
|
-
else
|
100
|
-
env[:controller][key]
|
101
122
|
end
|
123
|
+
raise "Server handler (#{servers.join(',')}) not found."
|
102
124
|
end
|
103
125
|
end
|
104
126
|
end
|
data/lib/tap/tasks/echo.rb
CHANGED
@@ -15,7 +15,7 @@ module Tap
|
|
15
15
|
#config :sym, :sym, &c.symbol # sym
|
16
16
|
config :integer, 10, &c.integer # integer
|
17
17
|
config :numeric, 10, &c.numeric # numeric
|
18
|
-
config :float, 10, &c.float # float
|
18
|
+
config :float, 10.0, &c.float # float
|
19
19
|
|
20
20
|
config :string_or_nil, nil, &c.string_or_nil # string_or_nil (nil)
|
21
21
|
#config :sym_or_nil, nil, &c.symbol_or_nil # symbol_or_nil (nil)
|
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'tap/controller'
|
2
|
+
|
3
|
+
<% redirect do |target| %># :startdoc::controller <replace with summary>
|
4
|
+
# <replace with description>
|
5
|
+
|
6
|
+
# <%= const.name %> Documentation
|
7
|
+
class <%= const.name %> < Tap::Controller
|
8
|
+
|
9
|
+
# Methods define actions on the controller
|
10
|
+
def index
|
11
|
+
render 'index.erb', :locals => {:obj => 'moon'}, :layout => true
|
12
|
+
end
|
13
|
+
|
14
|
+
end <% module_nest(const.nesting, ' ') { target } end %>
|
File without changes
|
@@ -0,0 +1 @@
|
|
1
|
+
Goodnight <%%= obj %>!
|
@@ -0,0 +1,57 @@
|
|
1
|
+
<dl>
|
2
|
+
<% configurations.each_pair do |key, config| %>
|
3
|
+
<% next if config[:type] == :hidden %>
|
4
|
+
<% name = "#{name_base}[#{key.inspect}]" %>
|
5
|
+
<% value = values[key] %>
|
6
|
+
|
7
|
+
<% if config.is_nest? %>
|
8
|
+
<dt class="name"><%= key %></dt>
|
9
|
+
<dd class="nested-configs">
|
10
|
+
<%= module_render("configurations.erb", obj, :locals => {
|
11
|
+
:name_base => name,
|
12
|
+
:configurations => config.default(false).delegates,
|
13
|
+
:values => value
|
14
|
+
}) %>
|
15
|
+
</dd>
|
16
|
+
<% next %>
|
17
|
+
<% end %>
|
18
|
+
|
19
|
+
<dt><%= key %></dt>
|
20
|
+
<dd>
|
21
|
+
<% case config[:type] %>
|
22
|
+
<% when :flag %>
|
23
|
+
<input name="<%= name %>" type="hidden" value="false" />
|
24
|
+
<input name="<%= name %>" type="checkbox" value="true" <%= value ? 'checked="true"' : '' %> />
|
25
|
+
|
26
|
+
<% when :switch %>
|
27
|
+
<input name="<%= name %>" type="radio" value="true" <%= value ? 'checked="true" ' : '' %>>on</input>
|
28
|
+
<input name="<%= name %>" type="radio" value="false" <%= !value ? 'checked="true" ' : '' %>>off</input>
|
29
|
+
|
30
|
+
<% when :select %>
|
31
|
+
<select name="<%= name %>">
|
32
|
+
<% (config[:options] || []).each do |option| %>
|
33
|
+
<option value="<%= option %>" <%= value == option ? "selected='true' " : ""%>><%= option %></option>
|
34
|
+
<% end %>
|
35
|
+
</select>
|
36
|
+
|
37
|
+
<% when :list_select %>
|
38
|
+
<input type="hidden" name="<%= name %>[]" value="#" />
|
39
|
+
<select name="<%= name %>[]" multiple="true">
|
40
|
+
<% (config[:options] || []).each do |option| %>
|
41
|
+
<option value="<%= option %>" <%= value && value.include?(option) ? "selected='true' " : ""%>><%= option %></option>
|
42
|
+
<% end %>
|
43
|
+
</select>
|
44
|
+
|
45
|
+
<% when :hidden %>
|
46
|
+
<% next %>
|
47
|
+
<% else %>
|
48
|
+
<%= render(
|
49
|
+
:file => module_path("#{config[:type]}.erb", obj.class) || template_path("configurable/default.erb"),
|
50
|
+
:locals => {
|
51
|
+
:name => name,
|
52
|
+
:config => config,
|
53
|
+
:value => value}) %>
|
54
|
+
<% end %>
|
55
|
+
</dd>
|
56
|
+
<% end %>
|
57
|
+
</dl>
|
@@ -0,0 +1 @@
|
|
1
|
+
<input name="<%= name %>" type="text" value="<%= value %>" />
|
data/views/layout.erb
CHANGED
@@ -2,10 +2,13 @@
|
|
2
2
|
<head>
|
3
3
|
<title>Tap (Server)</title>
|
4
4
|
<link rel="stylesheet" type="text/css" href="/stylesheets/tap.css" />
|
5
|
-
<script src="/javascripts/
|
6
|
-
<script src="/javascripts/tap.js"></script>
|
5
|
+
<!-- <script src="/javascripts/tap.js"></script> -->
|
7
6
|
</head>
|
8
7
|
<body>
|
9
8
|
<%= content %>
|
9
|
+
|
10
|
+
<ul>
|
11
|
+
<li><a href="/">Home</a></li>
|
12
|
+
</ul>
|
10
13
|
</body>
|
11
14
|
</html>
|
@@ -2,16 +2,18 @@
|
|
2
2
|
|
3
3
|
<ul>
|
4
4
|
<li class="source_file">
|
5
|
-
<h2>
|
6
|
-
<
|
5
|
+
<h2>Registered As</h2>
|
6
|
+
<ul><% Lazydoc::Document[obj.to_s].each_pair do |type, comment| %>
|
7
|
+
<li><%= type %> (<%= comment.document.source_file %>)</li><% end %>
|
8
|
+
</ul>
|
7
9
|
</li>
|
8
10
|
<li>
|
9
11
|
<h2>Summary</h2>
|
10
|
-
<%= obj.desc.subject %>
|
12
|
+
<%= obj.desc ? obj.desc.subject : nil %>
|
11
13
|
</li>
|
12
14
|
<li>
|
13
15
|
<h2>Documentation</h2>
|
14
|
-
<pre class="desc"><%= obj.desc.wrap %></pre>
|
16
|
+
<pre class="desc"><%= obj.desc ? obj.desc.wrap : nil %></pre>
|
15
17
|
</li>
|
16
18
|
<li>
|
17
19
|
<h2>Signature</h2>
|