tap-server 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- 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>
|