level_up 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.txt +4 -0
- data/app/assets/stylesheets/level_up/application.css.scss +1 -1
- data/app/controllers/level_up/flowcharts_controller.rb +38 -0
- data/app/controllers/level_up/jobs_controller.rb +7 -30
- data/app/models/level_up/graph_builder.rb +80 -0
- data/app/views/layouts/level_up/_header.html.erb +3 -2
- data/app/views/level_up/flowcharts/index.html.erb +36 -0
- data/app/views/level_up/flowcharts/show.html.erb +20 -0
- data/config/routes.rb +4 -0
- data/lib/level_up/version.rb +1 -1
- data/test/dummy/config/environments/development.rb +3 -3
- data/test/dummy/config/initializers/preload_sti_models.rb +5 -0
- data/test/dummy/db/development.sqlite3 +0 -0
- data/test/dummy/log/development.log +845 -3294
- data/test/dummy/log/test.log +6557 -14587
- data/test/dummy/tmp/{job_1.svg → account_banish.svg} +0 -0
- data/test/dummy/tmp/account_downgrade.svg +123 -0
- data/test/dummy/tmp/account_upgrade.svg +48 -0
- data/test/dummy/tmp/cache/assets/C2C/CE0/sprockets%2F33f519d653c9b4886c417440a0993824 +0 -0
- data/test/dummy/tmp/cache/assets/C6A/F00/sprockets%2F177385361781d5fe78d217f1f48b8566 +0 -0
- data/test/dummy/tmp/cache/assets/C6C/ED0/sprockets%2F320c25374f5ea136824c04c256e1605b +0 -0
- data/test/dummy/tmp/cache/assets/C87/110/sprockets%2Fc4428c04b8830f451f7636c2811f975d +0 -0
- data/test/dummy/tmp/cache/assets/CB9/E40/sprockets%2F43e6286ecc7751fc65d32b72c6158940 +0 -0
- data/test/dummy/tmp/cache/assets/CCE/7E0/sprockets%2F7d295633b50bfa8b04345d5e600b343a +0 -0
- data/test/dummy/tmp/cache/assets/CD5/450/sprockets%2F2ac0e7e07211a99107e0ba7e2680c885 +0 -0
- data/test/dummy/tmp/cache/assets/CE4/220/sprockets%2Ff1a78dd6750c553265fd3a242d76c277 +0 -0
- data/test/dummy/tmp/cache/assets/CF7/BA0/sprockets%2F8f9487ea6943415e46a5d895e0920ebe +0 -0
- data/test/dummy/tmp/cache/assets/D0E/2B0/sprockets%2F3e386ff8d231b92766061c4fad4ad504 +0 -0
- data/test/dummy/tmp/cache/assets/D19/660/sprockets%2F018d64588c824dd3e7e6c8d6d0d6510e +0 -0
- data/test/dummy/tmp/cache/assets/D25/E10/sprockets%2F989ec024c5db6ae875689b410f8e6d53 +0 -0
- data/test/dummy/tmp/cache/assets/D33/200/sprockets%2Fc291105cf21ca8e744c65f3d4f446aa1 +0 -0
- data/test/dummy/tmp/cache/assets/D34/610/sprockets%2Fcc081ecb5b32894151f16a144383befe +0 -0
- data/test/dummy/tmp/cache/assets/D4D/110/sprockets%2Fc16dfb491d9b98f482b4f0059dd355b8 +0 -0
- data/test/dummy/tmp/cache/assets/D4F/890/sprockets%2Fe3f96e9aa9b032c43788676c5ce066db +0 -0
- data/test/dummy/tmp/cache/assets/D53/370/sprockets%2F1cf0ca91840a1483edcac4d0c403b149 +0 -0
- data/test/dummy/tmp/cache/assets/D69/B90/sprockets%2Fdb0ee3e51128419c85616ceaca66ab58 +0 -0
- data/test/dummy/tmp/cache/assets/D75/B20/sprockets%2Fb659146edbe91be3b1b9d64cb9370c76 +0 -0
- data/test/dummy/tmp/cache/assets/D79/430/sprockets%2Fc030f9d26fab468c49dc494195d77eab +0 -0
- data/test/dummy/tmp/cache/assets/D9D/3C0/sprockets%2F3019d99c7bae1e55eb7c2bf4688b1b1a +0 -0
- data/test/dummy/tmp/cache/assets/DAA/1A0/sprockets%2Fba643993838fce8ddc1d42e6ce1fc346 +0 -0
- data/test/dummy/tmp/cache/assets/DD4/DA0/sprockets%2F17fadf3354a429c53acfe9fca6268d5d +0 -0
- data/test/dummy/tmp/cache/assets/DF8/880/sprockets%2F255d8bde2bf6681724e4ddedcc3cbc02 +0 -0
- data/test/dummy/tmp/job_2.svg +109 -64
- data/test/dummy/tmp/pids/server.pid +1 -0
- data/test/unit/level_up/graph_builder_test.rb +77 -0
- data/test/unit/level_up/job_test.rb +7 -7
- metadata +20 -8
- data/test/dummy/tmp/job_3.svg +0 -78
data/CHANGELOG.txt
CHANGED
@@ -1,3 +1,7 @@
|
|
1
|
+
== 0.3.0 Wave Race
|
2
|
+
* Flowcharts (svg representation of jobs) accessible from the mountable web app
|
3
|
+
* New GraphBuilder class to easily build and customize Graphviz graphs
|
4
|
+
|
1
5
|
== 0.2.0 Hungry Beast
|
2
6
|
* Configurable size of saved backtrace when rescuing from an error
|
3
7
|
* Renamed 'states' into 'tasks'
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require_dependency 'level_up/application_controller'
|
2
|
+
|
3
|
+
module LevelUp
|
4
|
+
class FlowchartsController < ApplicationController
|
5
|
+
if Configuration.http_authentication
|
6
|
+
http_basic_authenticate_with name: Configuration.http_login, password: Configuration.http_password
|
7
|
+
end
|
8
|
+
|
9
|
+
def index
|
10
|
+
@job_classes = LevelUp::Job.descendants.map { |klass| klass }
|
11
|
+
end
|
12
|
+
|
13
|
+
def show
|
14
|
+
@job_type = params[:id]
|
15
|
+
@job_class = @job_type.camelize.safe_constantize
|
16
|
+
if @job_class
|
17
|
+
|
18
|
+
else
|
19
|
+
flash.now[:alert] = "Job class not found"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
respond_to :svg
|
24
|
+
def graphviz
|
25
|
+
job_type = params[:id]
|
26
|
+
job_class = job_type.camelize.safe_constantize
|
27
|
+
|
28
|
+
if job_class
|
29
|
+
builder = GraphBuilder.new(job_class)
|
30
|
+
graph = builder.graph
|
31
|
+
graph.output(:svg => "#{Rails.root}/tmp/#{job_type}.svg")
|
32
|
+
send_data(File.open("#{Rails.root}/tmp/#{job_type}.svg").read, filename: "#{job_type}.svg", type: 'image/svg+xml', disposition: 'inline')
|
33
|
+
else
|
34
|
+
render text: "Job class not found", status: 404
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -79,38 +79,15 @@ module LevelUp
|
|
79
79
|
respond_to :svg
|
80
80
|
def graphviz
|
81
81
|
job = Job.find params[:id]
|
82
|
-
g = GraphViz.new(:G, type: :digraph)
|
83
|
-
g[:bgcolor]= '#fafbfb'
|
84
82
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
g.edge[:arrowhead] = 'open'
|
93
|
-
|
94
|
-
tasks = {}
|
95
|
-
job.tasks.each do |task|
|
96
|
-
tasks[task] = g.add_nodes(task.to_s.humanize.downcase)
|
97
|
-
if task == :start
|
98
|
-
tasks[task][:fillcolor] = '#5db1a4'
|
99
|
-
tasks[task][:color] = '#048282'
|
100
|
-
elsif task == :end
|
101
|
-
tasks[task][:fillcolor] = '#b40d28'
|
102
|
-
tasks[task][:color] = '#600615'
|
103
|
-
end
|
104
|
-
end
|
105
|
-
|
106
|
-
job.tasks.each do |task|
|
107
|
-
job.transitions(task).each do |transition|
|
108
|
-
g.add_edges(tasks[task], tasks[transition])
|
109
|
-
end
|
83
|
+
if job
|
84
|
+
builder = GraphBuilder.new(job)
|
85
|
+
graph = builder.graph
|
86
|
+
graph.output(:svg => "#{Rails.root}/tmp/job_#{job.id}.svg")
|
87
|
+
send_data(File.open("#{Rails.root}/tmp/job_#{job.id}.svg").read, filename: "job_#{job.id}.svg", type: 'image/svg+xml', disposition: 'inline')
|
88
|
+
else
|
89
|
+
render text: "Job not found", status: 404
|
110
90
|
end
|
111
|
-
|
112
|
-
g.output(:svg => "#{Rails.root}/tmp/job_#{job.id}.svg")
|
113
|
-
send_data(File.open("#{Rails.root}/tmp/job_#{job.id}.svg").read, filename: "job_#{job.id}.svg", type: 'image/svg+xml', disposition: 'inline')
|
114
91
|
end
|
115
92
|
end
|
116
93
|
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
module LevelUp
|
2
|
+
class GraphBuilder
|
3
|
+
attr_accessor :target
|
4
|
+
attr_reader :configuration
|
5
|
+
|
6
|
+
@default_configuration = {
|
7
|
+
bgcolor: '#fafbfb',
|
8
|
+
|
9
|
+
node: {
|
10
|
+
color: '#111111',
|
11
|
+
style: 'filled',
|
12
|
+
shape: 'box',
|
13
|
+
fillcolor: '#666666',
|
14
|
+
fontcolor: 'white',
|
15
|
+
fontname: 'Verdana',
|
16
|
+
|
17
|
+
start: {
|
18
|
+
fillcolor: '#5db1a4',
|
19
|
+
color: '#048282'
|
20
|
+
},
|
21
|
+
|
22
|
+
end: {
|
23
|
+
fillcolor: '#b40d28',
|
24
|
+
color: '#600615'
|
25
|
+
}
|
26
|
+
},
|
27
|
+
|
28
|
+
edge: {
|
29
|
+
color: '#000000',
|
30
|
+
arrowhead: 'open'
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
class << self
|
35
|
+
attr_reader :default_configuration
|
36
|
+
end
|
37
|
+
|
38
|
+
def initialize(target, options = {})
|
39
|
+
@target = target
|
40
|
+
@configuration = self.class.default_configuration.deep_merge(options)
|
41
|
+
end
|
42
|
+
|
43
|
+
def graph
|
44
|
+
graph = GraphViz.new(:G, type: :digraph)
|
45
|
+
|
46
|
+
graph[:bgcolor] = @configuration[:bgcolor]
|
47
|
+
|
48
|
+
@configuration[:node].each do |k, v|
|
49
|
+
graph.node[k] = v unless v.is_a? Hash
|
50
|
+
end
|
51
|
+
|
52
|
+
@configuration[:edge].each do |k, v|
|
53
|
+
graph.edge[k] = v unless v.is_a? Hash
|
54
|
+
end
|
55
|
+
|
56
|
+
tasks = {}
|
57
|
+
@target.tasks.each do |task|
|
58
|
+
tasks[task] = graph.add_nodes(task.to_s.humanize.downcase)
|
59
|
+
if @configuration[:node].has_key? task
|
60
|
+
@configuration[:node][task].each do |k, v|
|
61
|
+
tasks[task][k] = v
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
@target.tasks.each do |task|
|
67
|
+
@target.transitions(task).each do |transition|
|
68
|
+
edge = graph.add_edges(tasks[task], tasks[transition])
|
69
|
+
if @configuration[:edge].has_key? task
|
70
|
+
@configuration[:edge][task].each do |k, v|
|
71
|
+
edge[k] = v
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
graph
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -4,13 +4,14 @@
|
|
4
4
|
<div class="grid-2">
|
5
5
|
<h1>Level<span class="colored-part">Up</span></h1>
|
6
6
|
</div>
|
7
|
-
<div class="grid-
|
7
|
+
<div class="grid-4">
|
8
8
|
<ul>
|
9
9
|
<li><%= link_to "Dashboard", root_path, class: "app-link" %></li>
|
10
10
|
<li><%= link_to "Jobs", jobs_path, class: "app-link" %></li>
|
11
|
+
<li><%= link_to "Flowcharts", flowcharts_path, class: "app-link" %></li>
|
11
12
|
</ul>
|
12
13
|
</div>
|
13
|
-
<div class="grid-
|
14
|
+
<div class="grid-6">
|
14
15
|
<div class="search-bar">
|
15
16
|
<%= form_tag jobs_path, method: :get do %>
|
16
17
|
<%= text_field_tag 'search[key_contains]', nil, placeholder: "Search for jobs by key" %>
|
@@ -0,0 +1,36 @@
|
|
1
|
+
<div class="container-12">
|
2
|
+
<div class="grid-12">
|
3
|
+
<div class="breadcrumbs">
|
4
|
+
<ul>
|
5
|
+
<li><%= link_to "Dashboard", root_path %></li> /
|
6
|
+
<li>Flowcharts</li>
|
7
|
+
</ul>
|
8
|
+
</div>
|
9
|
+
</div>
|
10
|
+
|
11
|
+
<div class="grid-12">
|
12
|
+
<table class="table-bordered">
|
13
|
+
<thead>
|
14
|
+
<tr>
|
15
|
+
<th>Type</th>
|
16
|
+
<th>Number of tasks</th>
|
17
|
+
<th>Number of transitions</th>
|
18
|
+
</tr>
|
19
|
+
</thead>
|
20
|
+
<tbody>
|
21
|
+
<% @job_classes.each do |job_class| %>
|
22
|
+
<tr>
|
23
|
+
<td><%= link_to job_class.name.underscore, flowchart_path(id: job_class.name.underscore) %></td>
|
24
|
+
<td><%= job_class.tasks.size %></td>
|
25
|
+
<td><%= job_class.schema.values.flatten.size %></td>
|
26
|
+
</tr>
|
27
|
+
<% end %>
|
28
|
+
<% if @job_classes.empty? %>
|
29
|
+
<tr>
|
30
|
+
<td colspan="3">No classes found</td>
|
31
|
+
</tr>
|
32
|
+
<% end %>
|
33
|
+
</tbody>
|
34
|
+
</table>
|
35
|
+
</div>
|
36
|
+
</div>
|
@@ -0,0 +1,20 @@
|
|
1
|
+
<div class="container-12">
|
2
|
+
<div class="grid-12">
|
3
|
+
<div class="breadcrumbs">
|
4
|
+
<ul>
|
5
|
+
<li><%= link_to "Dashboard", root_path %></li> /
|
6
|
+
<li><%= link_to "Flowcharts", flowcharts_path %></li> /
|
7
|
+
<li><%= @job_type %></li>
|
8
|
+
</ul>
|
9
|
+
</div>
|
10
|
+
</div>
|
11
|
+
|
12
|
+
<div class="grid-12">
|
13
|
+
<div class="simple-panel">
|
14
|
+
<h2>Job Flow</h2>
|
15
|
+
<div class="svg-graph">
|
16
|
+
<object id="svg-object" data="<%= graphviz_flowchart_path(id: @job_type, format: :svg) %>" type="image/svg+xml"></object>
|
17
|
+
</div>
|
18
|
+
</div>
|
19
|
+
</div>
|
20
|
+
</div>
|
data/config/routes.rb
CHANGED
data/lib/level_up/version.rb
CHANGED
@@ -35,7 +35,7 @@ Dummy::Application.configure do
|
|
35
35
|
# Expands the lines which load the assets
|
36
36
|
config.assets.debug = true
|
37
37
|
|
38
|
-
config.level_up.http_authentication = true
|
39
|
-
config.level_up.http_login = "admin"
|
40
|
-
config.level_up.http_password = "
|
38
|
+
#config.level_up.http_authentication = true
|
39
|
+
#config.level_up.http_login = "admin"
|
40
|
+
#config.level_up.http_password = "password"
|
41
41
|
end
|
Binary file
|