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.
Files changed (48) hide show
  1. data/CHANGELOG.txt +4 -0
  2. data/app/assets/stylesheets/level_up/application.css.scss +1 -1
  3. data/app/controllers/level_up/flowcharts_controller.rb +38 -0
  4. data/app/controllers/level_up/jobs_controller.rb +7 -30
  5. data/app/models/level_up/graph_builder.rb +80 -0
  6. data/app/views/layouts/level_up/_header.html.erb +3 -2
  7. data/app/views/level_up/flowcharts/index.html.erb +36 -0
  8. data/app/views/level_up/flowcharts/show.html.erb +20 -0
  9. data/config/routes.rb +4 -0
  10. data/lib/level_up/version.rb +1 -1
  11. data/test/dummy/config/environments/development.rb +3 -3
  12. data/test/dummy/config/initializers/preload_sti_models.rb +5 -0
  13. data/test/dummy/db/development.sqlite3 +0 -0
  14. data/test/dummy/log/development.log +845 -3294
  15. data/test/dummy/log/test.log +6557 -14587
  16. data/test/dummy/tmp/{job_1.svg → account_banish.svg} +0 -0
  17. data/test/dummy/tmp/account_downgrade.svg +123 -0
  18. data/test/dummy/tmp/account_upgrade.svg +48 -0
  19. data/test/dummy/tmp/cache/assets/C2C/CE0/sprockets%2F33f519d653c9b4886c417440a0993824 +0 -0
  20. data/test/dummy/tmp/cache/assets/C6A/F00/sprockets%2F177385361781d5fe78d217f1f48b8566 +0 -0
  21. data/test/dummy/tmp/cache/assets/C6C/ED0/sprockets%2F320c25374f5ea136824c04c256e1605b +0 -0
  22. data/test/dummy/tmp/cache/assets/C87/110/sprockets%2Fc4428c04b8830f451f7636c2811f975d +0 -0
  23. data/test/dummy/tmp/cache/assets/CB9/E40/sprockets%2F43e6286ecc7751fc65d32b72c6158940 +0 -0
  24. data/test/dummy/tmp/cache/assets/CCE/7E0/sprockets%2F7d295633b50bfa8b04345d5e600b343a +0 -0
  25. data/test/dummy/tmp/cache/assets/CD5/450/sprockets%2F2ac0e7e07211a99107e0ba7e2680c885 +0 -0
  26. data/test/dummy/tmp/cache/assets/CE4/220/sprockets%2Ff1a78dd6750c553265fd3a242d76c277 +0 -0
  27. data/test/dummy/tmp/cache/assets/CF7/BA0/sprockets%2F8f9487ea6943415e46a5d895e0920ebe +0 -0
  28. data/test/dummy/tmp/cache/assets/D0E/2B0/sprockets%2F3e386ff8d231b92766061c4fad4ad504 +0 -0
  29. data/test/dummy/tmp/cache/assets/D19/660/sprockets%2F018d64588c824dd3e7e6c8d6d0d6510e +0 -0
  30. data/test/dummy/tmp/cache/assets/D25/E10/sprockets%2F989ec024c5db6ae875689b410f8e6d53 +0 -0
  31. data/test/dummy/tmp/cache/assets/D33/200/sprockets%2Fc291105cf21ca8e744c65f3d4f446aa1 +0 -0
  32. data/test/dummy/tmp/cache/assets/D34/610/sprockets%2Fcc081ecb5b32894151f16a144383befe +0 -0
  33. data/test/dummy/tmp/cache/assets/D4D/110/sprockets%2Fc16dfb491d9b98f482b4f0059dd355b8 +0 -0
  34. data/test/dummy/tmp/cache/assets/D4F/890/sprockets%2Fe3f96e9aa9b032c43788676c5ce066db +0 -0
  35. data/test/dummy/tmp/cache/assets/D53/370/sprockets%2F1cf0ca91840a1483edcac4d0c403b149 +0 -0
  36. data/test/dummy/tmp/cache/assets/D69/B90/sprockets%2Fdb0ee3e51128419c85616ceaca66ab58 +0 -0
  37. data/test/dummy/tmp/cache/assets/D75/B20/sprockets%2Fb659146edbe91be3b1b9d64cb9370c76 +0 -0
  38. data/test/dummy/tmp/cache/assets/D79/430/sprockets%2Fc030f9d26fab468c49dc494195d77eab +0 -0
  39. data/test/dummy/tmp/cache/assets/D9D/3C0/sprockets%2F3019d99c7bae1e55eb7c2bf4688b1b1a +0 -0
  40. data/test/dummy/tmp/cache/assets/DAA/1A0/sprockets%2Fba643993838fce8ddc1d42e6ce1fc346 +0 -0
  41. data/test/dummy/tmp/cache/assets/DD4/DA0/sprockets%2F17fadf3354a429c53acfe9fca6268d5d +0 -0
  42. data/test/dummy/tmp/cache/assets/DF8/880/sprockets%2F255d8bde2bf6681724e4ddedcc3cbc02 +0 -0
  43. data/test/dummy/tmp/job_2.svg +109 -64
  44. data/test/dummy/tmp/pids/server.pid +1 -0
  45. data/test/unit/level_up/graph_builder_test.rb +77 -0
  46. data/test/unit/level_up/job_test.rb +7 -7
  47. metadata +20 -8
  48. 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'
@@ -62,7 +62,7 @@ header {
62
62
  -webkit-box-sizing: border-box;
63
63
  -moz-box-sizing: border-box;
64
64
  box-sizing: border-box;
65
- width: 50%;
65
+ width: 33.33%;
66
66
 
67
67
  &:first-child {
68
68
  a.app-link {
@@ -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
- g.node[:color] = '#111111'
86
- g.node[:style] = 'filled'
87
- g.node[:shape] = 'box'
88
- g.node[:fillcolor] = '#666666'
89
- g.node[:fontcolor] = 'white'
90
- g.node[:fontname] = 'Verdana'
91
- g.edge[:color] = '#000000'
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-3">
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-7">
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
@@ -10,4 +10,8 @@ LevelUp::Engine.routes.draw do
10
10
  get "graphviz"
11
11
  end
12
12
  end
13
+
14
+ resources :flowcharts, only: [:index, :show] do
15
+ get "graphviz", on: :member
16
+ end
13
17
  end
@@ -1,3 +1,3 @@
1
1
  module LevelUp
2
- VERSION = "0.2.0"
2
+ VERSION = "0.3.0"
3
3
  end
@@ -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 = "pwd"
38
+ #config.level_up.http_authentication = true
39
+ #config.level_up.http_login = "admin"
40
+ #config.level_up.http_password = "password"
41
41
  end
@@ -0,0 +1,5 @@
1
+ if Rails.env.development?
2
+ %w[account_banish account_downgrade account_upgrade].each do |job_type|
3
+ require_dependency File.join("app","models", "#{job_type}.rb")
4
+ end
5
+ end
Binary file