rocketjob_mission_control 6.0.0.beta → 6.0.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.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/app/assets/javascripts/rocket_job_mission_control/application.js +2 -2
  3. data/app/assets/stylesheets/rocket_job_mission_control/jobs.css +0 -1
  4. data/app/controllers/rocket_job_mission_control/application_controller.rb +2 -0
  5. data/app/controllers/rocket_job_mission_control/dirmon_entries_controller.rb +3 -3
  6. data/app/controllers/rocket_job_mission_control/jobs_controller.rb +6 -3
  7. data/app/controllers/rocket_job_mission_control/servers_controller.rb +7 -7
  8. data/app/datatables/rocket_job_mission_control/dirmon_entries_datatable.rb +1 -1
  9. data/app/helpers/rocket_job_mission_control/application_helper.rb +9 -1
  10. data/app/helpers/rocket_job_mission_control/dirmon_entries_helper.rb +4 -0
  11. data/app/helpers/rocket_job_mission_control/servers_helper.rb +4 -0
  12. data/app/models/rocket_job_mission_control/dirmon_sanitizer.rb +2 -2
  13. data/app/models/rocket_job_mission_control/job_sanitizer.rb +2 -0
  14. data/app/views/layouts/rocket_job_mission_control/partials/_flash.html.erb +4 -4
  15. data/app/views/rocket_job_mission_control/jobs/_attributes.html.erb +12 -73
  16. data/app/views/rocket_job_mission_control/jobs/_dates.html.erb +7 -11
  17. data/app/views/rocket_job_mission_control/jobs/_details.html.erb +42 -3
  18. data/app/views/rocket_job_mission_control/jobs/_exception.html.erb +5 -16
  19. data/app/views/rocket_job_mission_control/jobs/_input_categories.html.erb +14 -64
  20. data/app/views/rocket_job_mission_control/jobs/_output_categories.html.erb +6 -17
  21. data/app/views/rocket_job_mission_control/jobs/_retryable.html.erb +8 -19
  22. data/app/views/rocket_job_mission_control/jobs/_status.html.erb +7 -7
  23. data/app/views/rocket_job_mission_control/jobs/edit_slice.html.erb +2 -2
  24. data/app/views/rocket_job_mission_control/jobs/view_slice.html.erb +2 -0
  25. data/lib/rocket_job_mission_control/engine.rb +0 -1
  26. data/lib/rocket_job_mission_control/version.rb +1 -1
  27. data/test/controllers/rocket_job_mission_control/dirmon_entries_controller_test.rb +3 -3
  28. data/test/controllers/rocket_job_mission_control/jobs_controller_test.rb +5 -5
  29. data/test/controllers/rocket_job_mission_control/servers_controller_test.rb +3 -3
  30. data/vendor/assets/javascripts/bootstrap.min.js +3 -4
  31. data/vendor/assets/javascripts/jquery-3.5.1.min.js +2 -0
  32. data/vendor/assets/stylesheets/bootstrap.min.css.erb +3 -3
  33. data/vendor/assets/stylesheets/bootstrap.min.css.map +1 -1
  34. metadata +19 -18
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d421e76cdd7a629d0f28598e52f2d6321bcdb0f062d50cf99b0e3ac791c0c823
4
- data.tar.gz: fa9f46ebbb28043994c98d42efc368973b57cf243ff793447c3985e6f56f152e
3
+ metadata.gz: b0ec59a8f1d7a5fe9cc19b916680252c9305da5541c483fe7d1d330329a89fee
4
+ data.tar.gz: 62c0a4f49640e726eedeebd27436d6c6190e1327c60e6ab51cd7c805c5b0c290
5
5
  SHA512:
6
- metadata.gz: 4cd18b8160af0cfa244403d522f4aa98d3e18c945f2e2fcc03001adb29e27a47c5dbcab50384b8e89630aa9a0302320d779307376fcfa720deb7535ff2201020
7
- data.tar.gz: 42b3d18cfa224ea50b25fd5eaeab7f4409a8452e4791dd91edf49358359e02b1418cecaf132710abca86d2f32d6198fc8e2ff3497e9273648f7ea11f755b4442
6
+ metadata.gz: 02c715b0419264397e74d1c76c3d3020488e6e7616f786aa1d84cd5c887a5b037c82bb8d1d952b794e8f66756b09319d83ce48c83bf2cedd184aaa2019c70012
7
+ data.tar.gz: 7ed5080f3b4470a2796240364cb6669dc5a1f9b334c0c26a3ea704e7fce0cdf2f792ab0ed1f10ea06196089098ae6295e2d0116d26e2b2d020e1c13dc3df5630
@@ -10,8 +10,8 @@
10
10
  // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
11
11
  // about supported directives.
12
12
  //
13
- //= require jquery3
14
- //= require jquery_ujs
13
+ //= require jquery-3.5.1.min.js
14
+ //= require rails-ujs
15
15
  //= require datatables.min.js
16
16
  //= require bootstrap.min
17
17
  //
@@ -43,7 +43,6 @@
43
43
  line-height: 2;
44
44
  resize: none;
45
45
  width: 100%;
46
- height: 20em;
47
46
  padding-top: 5px;
48
47
  padding-bottom: 5px;
49
48
  margin-bottom: 4px;
@@ -25,6 +25,8 @@ module RocketJobMissionControl
25
25
  end
26
26
 
27
27
  def login
28
+ return unless Config.authorization_callback
29
+
28
30
  @login ||= begin
29
31
  args = instance_exec(&Config.authorization_callback)
30
32
  args[:login]
@@ -115,7 +115,7 @@ module RocketJobMissionControl
115
115
  @dirmon_entry.enable!
116
116
  redirect_to(rocket_job_mission_control.dirmon_entry_path(@dirmon_entry))
117
117
  else
118
- flash[:alert] = t(:failure, scope: %i[dirmon_entry enable])
118
+ flash[:danger] = t(:failure, scope: %i[dirmon_entry enable])
119
119
  render(:show)
120
120
  end
121
121
  end
@@ -127,7 +127,7 @@ module RocketJobMissionControl
127
127
  @dirmon_entry.disable!
128
128
  redirect_to(rocket_job_mission_control.dirmon_entry_path(@dirmon_entry))
129
129
  else
130
- flash[:alert] = t(:failure, scope: %i[dirmon_entry disable])
130
+ flash[:danger] = t(:failure, scope: %i[dirmon_entry disable])
131
131
  render(:show)
132
132
  end
133
133
  end
@@ -149,7 +149,7 @@ module RocketJobMissionControl
149
149
 
150
150
  def find_entry_or_redirect
151
151
  unless @dirmon_entry = RocketJob::DirmonEntry.where(id: params[:id]).first
152
- flash[:alert] = t(:failure, scope: %i[dirmon_entry find], id: params[:id])
152
+ flash[:danger] = t(:failure, scope: %i[dirmon_entry find], id: ActionController::Base.helpers.sanitize(params[:id]))
153
153
  redirect_to(dirmon_entries_path)
154
154
  end
155
155
  end
@@ -182,6 +182,9 @@ module RocketJobMissionControl
182
182
  # Finds specific slice [Array]
183
183
  slice = @job.input.failed.skip(offset).first
184
184
 
185
+ # Converts \r\n line breaks to \n
186
+ updated_records.each { |record| record.gsub(/\r\n/, "\n") }
187
+
185
188
  # Assings modified slice (from the form) back to slice
186
189
  slice.records = updated_records
187
190
 
@@ -228,14 +231,14 @@ module RocketJobMissionControl
228
231
  offset = params.fetch(:offset, 0).to_i
229
232
 
230
233
  unless error_type.present?
231
- flash[:notice] = t(:no_errors, scope: %i[job failures])
234
+ flash[:warning] = t(:no_errors, scope: %i[job failures])
232
235
  redirect_to(job_path(@job))
233
236
  end
234
237
 
235
238
  scope = @job.input.failed.where("exception.class_name" => error_type)
236
239
  count = scope.count
237
240
  unless count.positive?
238
- flash[:notice] = t(:no_errors, scope: %i[job failures])
241
+ flash[:warning] = t(:no_errors, scope: %i[job failures])
239
242
  redirect_to(job_path(@job))
240
243
  end
241
244
 
@@ -278,7 +281,7 @@ module RocketJobMissionControl
278
281
 
279
282
  def find_job_or_redirect
280
283
  unless @job = RocketJob::Job.where(id: params[:id]).first
281
- flash[:alert] = t(:failure, scope: %i[job find], id: params[:id])
284
+ flash[:danger] = t(:failure, scope: %i[job find], id: ActionController::Base.helpers.sanitize(params[:id]))
282
285
 
283
286
  redirect_to(jobs_path)
284
287
  end
@@ -62,9 +62,9 @@ module RocketJobMissionControl
62
62
  RocketJob::Server.destroy_zombies
63
63
  elsif VALID_ACTIONS.include?(server_action)
64
64
  RocketJob::Subscribers::Server.publish(server_action)
65
- flash[:notice] = t(:success, scope: %i[server update_all], action: server_action.to_s)
65
+ flash[:success] = t(:success, scope: %i[server update_all], action: server_action.to_s)
66
66
  else
67
- flash[:alert] = t(:invalid, scope: %i[server update_all])
67
+ flash[:danger] = t(:invalid, scope: %i[server update_all])
68
68
  end
69
69
 
70
70
  # TODO: Refresh the same page it was on
@@ -76,7 +76,7 @@ module RocketJobMissionControl
76
76
  def stop
77
77
  authorize! :stop, @server
78
78
  RocketJob::Subscribers::Server.publish(:stop, server_id: @server.id)
79
- flash[:notice] = t(:success, scope: %i[server update_one], action: "stop", name: @server.name)
79
+ flash[:success] = t(:success, scope: %i[server update_one], action: "stop", name: @server.name)
80
80
 
81
81
  respond_to do |format|
82
82
  format.html { redirect_to servers_path }
@@ -86,7 +86,7 @@ module RocketJobMissionControl
86
86
  def destroy
87
87
  authorize! :destroy, @server
88
88
  @server.destroy
89
- flash[:notice] = t(:success, scope: %i[server destroy])
89
+ flash[:success] = t(:success, scope: %i[server destroy])
90
90
 
91
91
  respond_to do |format|
92
92
  format.html { redirect_to servers_path }
@@ -96,7 +96,7 @@ module RocketJobMissionControl
96
96
  def pause
97
97
  authorize! :pause, @server
98
98
  RocketJob::Subscribers::Server.publish(:pause, server_id: @server.id)
99
- flash[:notice] = t(:success, scope: %i[server update_one], action: "pause", name: @server.name)
99
+ flash[:success] = t(:success, scope: %i[server update_one], action: "pause", name: @server.name)
100
100
 
101
101
  respond_to do |format|
102
102
  format.html { redirect_to servers_path }
@@ -106,7 +106,7 @@ module RocketJobMissionControl
106
106
  def resume
107
107
  authorize! :resume, @server
108
108
  RocketJob::Subscribers::Server.publish(:resume, server_id: @server.id)
109
- flash[:notice] = t(:success, scope: %i[server update_one], action: "resume", name: @server.name)
109
+ flash[:success] = t(:success, scope: %i[server update_one], action: "resume", name: @server.name)
110
110
 
111
111
  respond_to do |format|
112
112
  format.html { redirect_to servers_path }
@@ -140,7 +140,7 @@ module RocketJobMissionControl
140
140
 
141
141
  def find_server_or_redirect
142
142
  unless @server = RocketJob::Server.where(id: params[:id]).first
143
- flash[:alert] = t(:failure, scope: %i[server find], id: params[:id])
143
+ flash[:danger] = t(:failure, scope: %i[server find], id: params[:id])
144
144
 
145
145
  redirect_to(servers_path)
146
146
  end
@@ -17,7 +17,7 @@ module RocketJobMissionControl
17
17
  <<-EOS
18
18
  <a href="#{dirmon_entry_path(dirmon.id)}">
19
19
  <i class="#{state_icon(dirmon.state)}" style="font-size: 75%" title="#{dirmon.state}"></i>
20
- #{dirmon.name}
20
+ #{h(dirmon.name)}
21
21
  </a>
22
22
  EOS
23
23
  end
@@ -56,6 +56,14 @@ module RocketJobMissionControl
56
56
  values
57
57
  end
58
58
 
59
+ def escape(s)
60
+ s.dump[1..-2]
61
+ end
62
+
63
+ def unescape(s)
64
+ "\"#{s}\"".undump
65
+ end
66
+
59
67
  # Returns the editable field as html for use in editing dynamic fields from a Job class.
60
68
  def editable_field_html(klass, field_name, value, f)
61
69
  # When editing a job the values are of the correct type.
@@ -75,7 +83,7 @@ module RocketJobMissionControl
75
83
  if options
76
84
  f.select(field_name, options, {include_blank: options.include?(nil), selected: value}, {class: "selectize form-control"})
77
85
  else
78
- f.text_field(field_name, value: value, class: "form-control", placeholder: placeholder)
86
+ f.text_area(field_name, value: value ? value : "", class: "form-control", placeholder: placeholder)
79
87
  end
80
88
  when "Boolean", "Mongoid::Boolean"
81
89
  options = extract_inclusion_values(klass, field_name) || [nil, "true", "false"]
@@ -11,5 +11,9 @@ module RocketJobMissionControl
11
11
  categories.each { |category| return category if category_name == (category["name"] || :main).to_sym }
12
12
  nil
13
13
  end
14
+
15
+ def rocket_job_mission_control
16
+ @@rocket_job_mission_control_engine_url_helpers ||= RocketJobMissionControl::Engine.routes.url_helpers
17
+ end
14
18
  end
15
19
  end
@@ -26,5 +26,9 @@ module RocketJobMissionControl
26
26
  map[server.state] || "callout-info"
27
27
  end
28
28
  end
29
+
30
+ def rocket_job_mission_control
31
+ @@rocket_job_mission_control_engine_url_helpers ||= RocketJobMissionControl::Engine.routes.url_helpers
32
+ end
29
33
  end
30
34
  end
@@ -42,8 +42,8 @@ module RocketJobMissionControl
42
42
  categories << props unless props.empty?
43
43
  end
44
44
  properties[:output_categories] = categories unless categories.empty?
45
- else
46
- properties[name] = value unless default_job.public_send(name) == updated_job.public_send(name)
45
+ elsif default_job.public_send(name) != updated_job.public_send(name)
46
+ properties[name] = value.is_a?(String) ? value.gsub(/\r\n/, "\n") : value
47
47
  end
48
48
  end
49
49
  properties
@@ -27,6 +27,8 @@ module RocketJobMissionControl
27
27
  next unless field&.type
28
28
 
29
29
  case field.type.name
30
+ when "String"
31
+ value.gsub(/\r\n/, "\n")
30
32
  when "Hash"
31
33
  begin
32
34
  value = value.blank? ? nil : JSON.parse(value)
@@ -1,13 +1,13 @@
1
1
  <% if flash.present? %>
2
- <div class='flash text-center'>
2
+ <div class="flash text-center">
3
3
  <% flash.each do |key, msg| %>
4
- <div class='alert alert-<%=key%> alert-dismissable' role='alert'>
5
- <button class='close' data-dismiss='alert'>
4
+ <div class="alert alert-<%=key%> alert-dismissable" role="alert">
5
+ <button class="close" data-dismiss="alert">
6
6
  <span>&times;</span>
7
7
  </button>
8
8
 
9
9
  <% if msg.kind_of? Array %>
10
- <ul class='list-unstyled margin-bottom-0'>
10
+ <ul class="list-unstyled margin-bottom-0">
11
11
  <% msg.each do |m| %>
12
12
  <li><%= m.html_safe %></li>
13
13
  <% end %>
@@ -2,87 +2,26 @@
2
2
  <div class='row'>
3
3
  <div class='col-md-12'>
4
4
  <table>
5
- <% @attributes.each_pair do |key, value| %>
6
- <% next if value.is_a?(Array) || value.is_a?(Hash) %>
7
- <% key = key.to_s.titleize %>
5
+ <% @attributes.keys.sort.each do |key| %>
6
+ <%
7
+ value = @attributes[key]
8
+ key = key.to_s.titleize
9
+ %>
8
10
  <tr>
9
11
  <td><label><%= key %>:</label></td>
10
12
  <% if value.nil? %>
11
13
  <td><label>nil</label></td>
12
14
  <% else %>
13
- <td><%= value %></td>
15
+ <td>
16
+ <% if value.is_a?(String) %>
17
+ <pre><code><%= simple_format(value) %></code></pre>
18
+ <% else %>
19
+ <%= value.ai(html: true, plain: true) %>
20
+ <% end %>
21
+ </td>
14
22
  <% end %>
15
23
  </tr>
16
24
  <% end %>
17
- <% @attributes.each_pair do |key, value| %>
18
- <% next unless value.is_a?(Array) %>
19
- <% key = key.to_s.titleize %>
20
- <% if value.empty? %>
21
- <tr>
22
- <td><label><%= key %>:</label></td>
23
- <td><label>[]</label></td>
24
- </tr>
25
- <% else %>
26
- <% first = true %>
27
- <% value.each do |item| %>
28
- <% if first %>
29
- <tr>
30
- <td><label><%= key %>:</label></td>
31
- <% if item.is_a?(Hash) || item.is_a?(Array) %>
32
- <td>
33
- <pre><code><%= pretty_print_array_or_hash(item) %></code></pre>
34
- </td>
35
- <% else %>
36
- <td><%= item %></td>
37
- <% end %>
38
- </tr>
39
- <% first = false %>
40
- <% else %>
41
- <tr>
42
- <td></td>
43
- <% if item.is_a?(Hash) || item.is_a?(Array) %>
44
- <td>
45
- <pre><code><%= pretty_print_array_or_hash(item) %></code></pre>
46
- </td>
47
- <% else %>
48
- <td><%= item %></td>
49
- <% end %>
50
- </tr>
51
- <% end %>
52
- <% end %>
53
- <% end %>
54
- <% end %>
55
- <% @attributes.each_pair do |key, value| %>
56
- <% next unless value.is_a?(Hash) %>
57
- <% key = key.to_s.titleize %>
58
- <tr>
59
- <th valign="top"><label><%= key %>:</label></th>
60
- <td>
61
- <% if value.empty? %>
62
- <label>{}</label>
63
- <% else %>
64
- <div class='row'>
65
- <div class='col-md-12'>
66
- <table>
67
- <% value.each_pair do |key2, value2| %>
68
- <tr>
69
- <td><label><%= key2.to_s.titleize %>:</label></td>
70
- <% if value2.is_a?(Hash) || value2.is_a?(Array) %>
71
- <td>
72
- <pre><code><%= pretty_print_array_or_hash(value2) %></code></pre>
73
- </td>
74
- <% else %>
75
- <td><%= value2 %></td>
76
- <% end %>
77
- </tr>
78
- <% end %>
79
- </table>
80
- </div>
81
- </div>
82
- <% end %>
83
- </td>
84
- </tr>
85
- <% end %>
86
25
  </table>
87
26
  </div>
88
27
  </div>
@@ -3,33 +3,29 @@
3
3
  <div class='col-md-12'>
4
4
  <table>
5
5
  <tr>
6
- <td><label>Created:</label></td>
6
+ <td><label>Created at:</label></td>
7
7
  <td><%= job_time(@job.created_at) %></td>
8
8
  </tr>
9
- <% if !@job.queued? %>
9
+ <% unless @job.queued? %>
10
10
  <tr>
11
- <td><label><%= job_state_name(@job) %>:</label></td>
11
+ <td><label><%= job_state_name(@job) %> at:</label></td>
12
12
  <td>
13
13
  <%= job_state_time(@job) %>
14
14
  <% unless @job.scheduled? %>
15
- , <%= RocketJob.seconds_as_duration(Time.now - (@job.completed_at || @job.started_at || @job.created_at)) %> ago
15
+ (<%= RocketJob.seconds_as_duration(Time.now - (@job.completed_at || @job.started_at || @job.created_at)) %> ago)
16
16
  <% end %>
17
17
  </td>
18
18
  </tr>
19
19
  <% end %>
20
20
  <% if @job.scheduled? %>
21
21
  <tr>
22
- <td><label>Run At:</label></td>
23
- <td><%= job_time(@job.run_at) %></td>
24
- </tr>
25
- <tr>
26
- <td><label>Runs In:</label></td>
27
- <td><%= RocketJob.seconds_as_duration(@job.run_at - Time.now) %></td>
22
+ <td><label>Scheduled to run at:</label></td>
23
+ <td><%= job_time(@job.run_at) %> (<%= RocketJob.seconds_as_duration(@job.run_at - Time.now) %> from now)</td>
28
24
  </tr>
29
25
  <% end %>
30
26
  <% if @job.expires_at %>
31
27
  <tr>
32
- <td><label>Expires At:</label></td>
28
+ <td><label>Expires at:</label></td>
33
29
  <td><%= job_time(@job.expires_at) %></td>
34
30
  </tr>
35
31
  <% end %>
@@ -46,10 +46,43 @@
46
46
  <td><%= @job.failure_count %></td>
47
47
  </tr>
48
48
  <% end %>
49
- <% if @job.log_level %>
49
+ <% if @job.respond_to?(:input_category) %>
50
50
  <tr>
51
- <td><label>Log Level</label></td>
52
- <td><%= @job.log_level %></td>
51
+ <td><label>Record Count:</label></td>
52
+ <td><%= @job.record_count %></td>
53
+ </tr>
54
+ <% if @job.completed? %>
55
+ <tr>
56
+ <td><label>Records Per Hour:</label></td>
57
+ <td><%= job_records_per_hour(@job) %></td>
58
+ </tr>
59
+ <% elsif @job.running? || @job.paused? || @job.failed? %>
60
+ <tr>
61
+ <td><label>Progress:</label></td>
62
+ <td><%= @job.percent_complete %> %</td>
63
+ </tr>
64
+ <% if @job.running? %>
65
+ <tr>
66
+ <td><label>Est. Time Remaining:</label></td>
67
+ <td><%= job_estimated_time_left(@job) %></td>
68
+ </tr>
69
+ <% end %>
70
+ <tr>
71
+ <td><label>Queued Slices:</label></td>
72
+ <td><%= @job.input.queued.count %></td>
73
+ </tr>
74
+ <tr>
75
+ <td><label>Active Slices:</label></td>
76
+ <td><%= @job.input.running.count %></td>
77
+ </tr>
78
+ <tr>
79
+ <td><label>Failed Slices:</label></td>
80
+ <td><%= @job.input.failed.count %></td>
81
+ </tr>
82
+ <% end %>
83
+ <tr>
84
+ <td><label>Slice Size:</label></td>
85
+ <td><%= @job.input_category.slice_size %></td>
53
86
  </tr>
54
87
  <% end %>
55
88
  <% if @job.respond_to?(:throttle_group) && @job.throttle_group %>
@@ -64,6 +97,12 @@
64
97
  <td><%= @job.throttle_running_workers %></td>
65
98
  </tr>
66
99
  <% end %>
100
+ <% if @job.log_level %>
101
+ <tr>
102
+ <td><label>Log Level</label></td>
103
+ <td><%= @job.log_level %></td>
104
+ </tr>
105
+ <% end %>
67
106
  <% if @job.worker_name %>
68
107
  <tr>
69
108
  <td><label>Worker Name:</label></td>