tap-server 0.3.0 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History +5 -0
- data/cmd/server.rb +36 -8
- data/lib/tap/controller/rest_routes.rb +77 -0
- data/lib/tap/controller/utils.rb +29 -0
- data/lib/tap/controller.rb +244 -145
- data/lib/tap/controllers/app.rb +97 -55
- data/lib/tap/controllers/data.rb +132 -0
- data/lib/tap/controllers/schema.rb +137 -223
- data/lib/tap/controllers/server.rb +70 -27
- data/lib/tap/server/data.rb +178 -0
- data/lib/tap/server/runner.rb +71 -0
- data/lib/tap/server/server_error.rb +35 -0
- data/lib/tap/server.rb +60 -275
- data/lib/tap/tasks/echo.rb +39 -6
- data/lib/tap/tasks/render.rb +65 -0
- data/public/stylesheets/tap.css +15 -2
- data/views/configurable/_config.erb +1 -0
- data/views/configurable/_configs.erb +28 -0
- data/views/configurable/_flag.erb +2 -0
- data/views/configurable/_list_select.erb +8 -0
- data/views/configurable/_select.erb +6 -0
- data/views/configurable/_switch.erb +2 -0
- data/views/layout.erb +1 -1
- data/views/object/obj.erb +1 -0
- data/views/tap/controllers/app/_action.erb +3 -0
- data/views/tap/controllers/app/build.erb +18 -0
- data/views/tap/controllers/app/enque.erb +13 -0
- data/views/tap/controllers/app/info.erb +20 -7
- data/views/tap/controllers/data/_controls.erb +21 -0
- data/views/tap/controllers/data/_index_entry.erb +1 -0
- data/views/tap/controllers/data/_upload.erb +8 -0
- data/views/tap/controllers/data/entry.erb +8 -0
- data/views/tap/controllers/data/index.erb +14 -0
- data/views/tap/controllers/schema/_build.erb +6 -0
- data/views/tap/controllers/schema/_index_entry.erb +6 -0
- data/views/tap/controllers/schema/entry.erb +135 -0
- data/views/tap/controllers/schema/join.erb +6 -4
- data/views/tap/controllers/schema/task.erb +6 -0
- data/views/tap/controllers/server/access.erb +4 -0
- data/views/tap/controllers/server/admin.erb +21 -0
- data/views/tap/controllers/server/help.erb +23 -0
- data/views/tap/controllers/server/index.erb +43 -3
- data/views/tap/task/input.erb +17 -0
- data/views/tap/tasks/load/input.erb +11 -0
- metadata +35 -17
- data/lib/tap/server_error.rb +0 -34
- data/lib/tap/support/persistence.rb +0 -71
- data/lib/tap/tasks/server.rb +0 -30
- data/views/tap/controllers/app/index.erb +0 -44
- data/views/tap/controllers/schema/config/default.erb +0 -4
- data/views/tap/controllers/schema/config/flag.erb +0 -3
- data/views/tap/controllers/schema/config/switch.erb +0 -6
- data/views/tap/controllers/schema/configurations.erb +0 -27
- data/views/tap/controllers/schema/node.erb +0 -47
- data/views/tap/controllers/schema/preview.erb +0 -3
- data/views/tap/controllers/schema/round.erb +0 -30
- data/views/tap/controllers/schema/schema.erb +0 -28
- data/views/tap/tasks/echo/result.html +0 -1
data/lib/tap/controllers/app.rb
CHANGED
@@ -1,59 +1,109 @@
|
|
1
1
|
require 'tap/controller'
|
2
|
-
require '
|
3
|
-
require 'time'
|
2
|
+
require 'tap/controllers/schema'
|
4
3
|
|
5
4
|
module Tap
|
6
5
|
module Controllers
|
7
6
|
|
8
|
-
# ::controller
|
7
|
+
# :startdoc::controller builds and runs workflows
|
9
8
|
class App < Tap::Controller
|
10
|
-
set :
|
11
|
-
|
12
|
-
def call(env)
|
13
|
-
# serve public files before actions
|
14
|
-
server = env['tap.server'] ||= Tap::Server.new
|
15
|
-
|
16
|
-
if path = server.search(:public, env['PATH_INFO'])
|
17
|
-
content = File.read(path)
|
18
|
-
headers = {
|
19
|
-
"Last-Modified" => [File.mtime(path).httpdate],
|
20
|
-
"Content-Type" => [Rack::Mime.mime_type(File.extname(path), 'text/plain')],
|
21
|
-
"Content-Length" => [content.size.to_s]
|
22
|
-
}
|
9
|
+
set :default_action, :info
|
23
10
|
|
24
|
-
|
25
|
-
|
26
|
-
|
11
|
+
nest :schema, Schema do
|
12
|
+
def dispatch(route)
|
13
|
+
route.unshift rest_action(route)
|
14
|
+
super(route)
|
27
15
|
end
|
28
16
|
end
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
env_names[environment] = name
|
34
|
-
end
|
35
|
-
|
36
|
-
render('index.erb', :locals => {:env => server.env, :env_names => env_names}, :layout => true)
|
17
|
+
|
18
|
+
# Returns the state of app.
|
19
|
+
def state
|
20
|
+
app.state.to_s
|
37
21
|
end
|
38
22
|
|
23
|
+
# Returns the controls and current application info.
|
39
24
|
def info
|
25
|
+
render 'info.erb', :locals => {
|
26
|
+
:actions => [:run, :stop, :terminate, :reset],
|
27
|
+
}, :layout => true
|
28
|
+
end
|
29
|
+
|
30
|
+
# Runs app on a separate thread (on post).
|
31
|
+
def run
|
40
32
|
if request.post?
|
41
|
-
app.
|
33
|
+
server.thread ||= Thread.new { app.run; server.thread = nil; }
|
34
|
+
end
|
35
|
+
|
36
|
+
redirect uri(:info)
|
37
|
+
end
|
38
|
+
|
39
|
+
def reset
|
40
|
+
app.reset if request.post?
|
41
|
+
redirect uri(:info)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Stops app (on post).
|
45
|
+
def stop
|
46
|
+
app.stop if request.post?
|
47
|
+
redirect uri(:info)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Teminates app (on post).
|
51
|
+
def terminate
|
52
|
+
app.terminate if request.post?
|
53
|
+
redirect uri(:info)
|
54
|
+
end
|
55
|
+
|
56
|
+
def build
|
57
|
+
schema = request[:schema] || server.data.read(:schema, request[:id])
|
58
|
+
|
59
|
+
unless request.post?
|
60
|
+
return render('build.erb', :schema => schema, :layout => true)
|
61
|
+
end
|
62
|
+
|
63
|
+
schema = Tap::Schema.load(schema).resolve! do |type, key, data|
|
64
|
+
server.env.manifest(type)[key]
|
65
|
+
end.validate!
|
66
|
+
|
67
|
+
if request[:reset] == "on"
|
68
|
+
app.reset
|
69
|
+
end
|
70
|
+
|
71
|
+
tasks.merge!(server.env.build(schema, app))
|
72
|
+
|
73
|
+
if request[:run] == "on"
|
74
|
+
run
|
42
75
|
else
|
43
|
-
|
76
|
+
redirect uri(:enque)
|
44
77
|
end
|
45
78
|
end
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
begin
|
51
|
-
path = root.subpath(:log, 'server.log')
|
52
|
-
raise unless File.exists?(path)
|
53
|
-
rescue
|
54
|
-
raise Tap::ServerError.new("invalid path", 404)
|
79
|
+
|
80
|
+
def enque
|
81
|
+
unless request.post?
|
82
|
+
return render('enque.erb', :layout => true)
|
55
83
|
end
|
56
|
-
|
84
|
+
|
85
|
+
queue = if request[:load]
|
86
|
+
YAML.load(request[:queue] || "{}")
|
87
|
+
else
|
88
|
+
request[:queue] || {}
|
89
|
+
end
|
90
|
+
|
91
|
+
queue.each do |(key, inputs)|
|
92
|
+
unless task = tasks[key]
|
93
|
+
raise "no task for: #{key}"
|
94
|
+
end
|
95
|
+
app.enq(task, *inputs)
|
96
|
+
end
|
97
|
+
|
98
|
+
redirect uri(:info)
|
99
|
+
end
|
100
|
+
|
101
|
+
def tail(id)
|
102
|
+
unless data.has?("#{id}.log")
|
103
|
+
raise Tap::ServerError.new("invalid id: #{id}", 404)
|
104
|
+
end
|
105
|
+
|
106
|
+
path = data.path("#{id}.log")
|
57
107
|
pos = request['pos'].to_i
|
58
108
|
if pos > File.size(path)
|
59
109
|
raise Tap::ServerError.new("tail position out of range (try update)", 500)
|
@@ -75,23 +125,15 @@ module Tap
|
|
75
125
|
}, :layout => true)
|
76
126
|
end
|
77
127
|
end
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
def stop
|
85
|
-
app.stop
|
86
|
-
redirect("/app/info")
|
87
|
-
end
|
88
|
-
|
89
|
-
def terminate
|
90
|
-
app.terminate
|
91
|
-
redirect("/app/info")
|
128
|
+
|
129
|
+
protected
|
130
|
+
|
131
|
+
def tasks
|
132
|
+
app.cache[:tasks] ||= {}
|
92
133
|
end
|
93
|
-
|
94
|
-
def
|
134
|
+
|
135
|
+
def app
|
136
|
+
server.app
|
95
137
|
end
|
96
138
|
end
|
97
139
|
end
|
@@ -0,0 +1,132 @@
|
|
1
|
+
require 'tap/controller'
|
2
|
+
|
3
|
+
module Tap
|
4
|
+
module Controllers
|
5
|
+
# ::controller
|
6
|
+
class Data < Tap::Controller
|
7
|
+
include RestRoutes
|
8
|
+
include Utils
|
9
|
+
|
10
|
+
set :default_layout, 'layout.erb'
|
11
|
+
|
12
|
+
# GET /projects
|
13
|
+
def index
|
14
|
+
render 'index.erb', :layout => true
|
15
|
+
end
|
16
|
+
|
17
|
+
# GET /projects/id
|
18
|
+
# GET /projects?id=id&as=
|
19
|
+
def show(id)
|
20
|
+
case request['as']
|
21
|
+
when 'preview'
|
22
|
+
response.headers['Content-Type'] = 'text/plain'
|
23
|
+
data.read(type, id)
|
24
|
+
|
25
|
+
when 'download'
|
26
|
+
unless path = data.find(type, id)
|
27
|
+
raise "unknown #{type}: #{id.inspect}"
|
28
|
+
end
|
29
|
+
|
30
|
+
download(path)
|
31
|
+
else
|
32
|
+
display(id)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# POST /projects/id
|
37
|
+
# POST /projects?id=id
|
38
|
+
# POST /projects?type=
|
39
|
+
def create(id)
|
40
|
+
if id == "new"
|
41
|
+
id = data.next_id(type).to_s
|
42
|
+
end
|
43
|
+
|
44
|
+
data.create(type, id) {|io| io << parse_entry }
|
45
|
+
redirect uri(id)
|
46
|
+
end
|
47
|
+
|
48
|
+
# PUT /projects/id
|
49
|
+
# POST /projects/id?_method=put
|
50
|
+
# POST /projects?_method=put&_action=select&id=id
|
51
|
+
def update(id)
|
52
|
+
data.update(type, id) {|io| io << parse_entry }
|
53
|
+
redirect uri(id)
|
54
|
+
end
|
55
|
+
|
56
|
+
# DELETE /projects/id
|
57
|
+
# POST /projects/id?_method=delete
|
58
|
+
# POST /projects?_method=put&id=id
|
59
|
+
def destroy(id)
|
60
|
+
data.destroy(type, id)
|
61
|
+
redirect uri
|
62
|
+
end
|
63
|
+
|
64
|
+
def upload(id=nil)
|
65
|
+
check_id(id)
|
66
|
+
data.import(type, request[type], id)
|
67
|
+
redirect uri
|
68
|
+
end
|
69
|
+
|
70
|
+
def select(ids=[])
|
71
|
+
data.cache[type] = ids
|
72
|
+
redirect uri
|
73
|
+
end
|
74
|
+
|
75
|
+
# Renames id to request['name'] in the schema data.
|
76
|
+
def rename(id)
|
77
|
+
redirect data.move(type, id, request['new_id'])
|
78
|
+
end
|
79
|
+
|
80
|
+
def duplicate(id)
|
81
|
+
redirect data.copy(type, id, request['new_id'] || "#{id}_copy")
|
82
|
+
end
|
83
|
+
|
84
|
+
# Helper methods
|
85
|
+
protected
|
86
|
+
|
87
|
+
def type
|
88
|
+
:data
|
89
|
+
end
|
90
|
+
|
91
|
+
def data
|
92
|
+
server.data
|
93
|
+
end
|
94
|
+
|
95
|
+
#--
|
96
|
+
# args remains an array, ie methods can take one or no inputs (but note
|
97
|
+
# that if id is specified as an array, methods can receive and array of
|
98
|
+
# ids.)
|
99
|
+
def dispatch(route)
|
100
|
+
action, *args = route
|
101
|
+
|
102
|
+
if args.empty?
|
103
|
+
if id = request['id']
|
104
|
+
args << id
|
105
|
+
end
|
106
|
+
else
|
107
|
+
args = [File.join(*args)]
|
108
|
+
end
|
109
|
+
|
110
|
+
args.unshift(action)
|
111
|
+
super(args)
|
112
|
+
end
|
113
|
+
|
114
|
+
def display(id)
|
115
|
+
render "entry.erb", :locals => {
|
116
|
+
:id => id,
|
117
|
+
:content => data.read(type, id)
|
118
|
+
}, :layout => true
|
119
|
+
end
|
120
|
+
|
121
|
+
def parse_entry
|
122
|
+
request[type]
|
123
|
+
end
|
124
|
+
|
125
|
+
def check_id(id)
|
126
|
+
if id == "new"
|
127
|
+
raise "reserved id: #{id.inspect}"
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|