naf 2.0.4 → 2.1.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 (61) hide show
  1. data/README.rdoc +28 -4
  2. data/RELEASE_NOTES.rdoc +8 -0
  3. data/app/assets/javascripts/dataTablesTemplates/application_schedules.js +72 -0
  4. data/app/assets/javascripts/dataTablesTemplates/applications.js +12 -21
  5. data/app/controllers/naf/application_schedule_affinity_tabs_controller.rb +5 -8
  6. data/app/controllers/naf/application_schedules_controller.rb +98 -0
  7. data/app/controllers/naf/applications_controller.rb +6 -98
  8. data/app/controllers/naf/historical_jobs_controller.rb +18 -8
  9. data/app/helpers/naf/application_helper.rb +47 -22
  10. data/app/models/logical/naf/application.rb +9 -126
  11. data/app/models/logical/naf/application_schedule.rb +186 -0
  12. data/app/models/logical/naf/construction_zone/boss.rb +4 -5
  13. data/app/models/logical/naf/construction_zone/foreman.rb +34 -13
  14. data/app/models/logical/naf/construction_zone/proletariat.rb +1 -0
  15. data/app/models/logical/naf/construction_zone/work_order.rb +11 -4
  16. data/app/models/logical/naf/job_fetcher.rb +1 -0
  17. data/app/models/naf/application.rb +5 -16
  18. data/app/models/naf/application_schedule.rb +117 -43
  19. data/app/models/naf/historical_job.rb +6 -3
  20. data/app/models/naf/queued_job.rb +3 -0
  21. data/app/models/naf/run_interval_style.rb +20 -0
  22. data/app/models/naf/running_job.rb +3 -0
  23. data/app/models/process/naf/data_migration/backfill_application_schedule_run_interval.rb +85 -0
  24. data/app/models/process/naf/log_archiver.rb +1 -1
  25. data/app/models/process/naf/log_reader.rb +141 -0
  26. data/app/models/process/naf/runner.rb +6 -49
  27. data/app/views/naf/application_schedule_affinity_tabs/_form.html.erb +1 -1
  28. data/app/views/naf/{applications → application_schedules}/_application_schedule_prerequisites.html.erb +1 -1
  29. data/app/views/naf/application_schedules/_form.html.erb +120 -0
  30. data/app/views/naf/application_schedules/edit.html.erb +11 -0
  31. data/app/views/naf/application_schedules/index.html.erb +47 -0
  32. data/app/views/naf/application_schedules/index.json.erb +8 -0
  33. data/app/views/naf/application_schedules/new.html.erb +11 -0
  34. data/app/views/naf/application_schedules/show.html.erb +130 -0
  35. data/app/views/naf/applications/_form.html.erb +44 -106
  36. data/app/views/naf/applications/_search_container.html.erb +29 -29
  37. data/app/views/naf/applications/index.html.erb +1 -10
  38. data/app/views/naf/applications/index.json.erb +22 -6
  39. data/app/views/naf/applications/show.html.erb +47 -97
  40. data/app/views/naf/logger_styles/_form.html.erb +0 -3
  41. data/app/views/naf/machines/_form.html.erb +3 -4
  42. data/config/routes.rb +3 -4
  43. data/db/migrate/20131219195439_add_run_interval_styles_table.rb +49 -0
  44. data/db/migrate/20140113183243_drop_run_start_minute_from_application_schedules.rb +18 -0
  45. data/lib/naf/version.rb +1 -1
  46. data/naf.gemspec +1 -1
  47. data/spec/controllers/naf/application_schedule_affinity_tabs_controller_spec.rb +34 -27
  48. data/spec/controllers/naf/applications_controller_spec.rb +0 -48
  49. data/spec/factories/naf.rb +14 -8
  50. data/spec/models/logical/naf/application_spec.rb +9 -37
  51. data/spec/models/logical/naf/machine_spec.rb +1 -1
  52. data/spec/models/naf/application_schedule_spec.rb +38 -50
  53. data/spec/models/naf/application_spec.rb +3 -3
  54. data/spec/models/naf/historical_job_spec.rb +4 -2
  55. data/spec/models/naf/queued_job_spec.rb +2 -0
  56. data/spec/models/naf/run_interval_style_spec.rb +28 -0
  57. data/spec/models/naf/running_job_spec.rb +2 -0
  58. metadata +19 -7
  59. data/app/models/logical/naf/job_creator.rb +0 -151
  60. data/app/views/naf/applications/_application_schedule.html.erb +0 -80
  61. data/spec/models/logical/naf/job_creator_spec.rb +0 -102
@@ -41,23 +41,29 @@ module Naf
41
41
  end
42
42
 
43
43
  def new
44
+ @historical_job = Naf::HistoricalJob.new
44
45
  end
45
46
 
46
47
  def create
47
48
  @historical_job = Naf::HistoricalJob.new(params[:historical_job])
48
- if params[:historical_job][:application_id] && app = Naf::Application.find(params[:historical_job][:application_id])
49
- if schedule = app.application_schedule
50
- @historical_job = Logical::Naf::JobCreator.new.queue_application_schedule(schedule)
49
+ if params[:historical_job][:application_id] &&
50
+ app = Naf::Application.find(params[:historical_job][:application_id])
51
+
52
+ if schedule = app.application_schedules.first
53
+ @historical_job = ::Logical::Naf::ConstructionZone::Boss.new.enqueue_application_schedule(schedule)
51
54
  if @historical_job.blank?
52
- render json: { success: false,
53
- title: ::Naf::Application.find_by_id(params[:historical_job][:application_id]).title }.to_json
55
+ render json: {
56
+ success: false,
57
+ title: ::Naf::Application.find_by_id(params[:historical_job][:application_id]).title
58
+ }.to_json
54
59
 
55
60
  return
56
61
  end
57
62
  else
58
63
  @historical_job.command = app.command
59
64
  @historical_job.application_type_id = app.application_type_id
60
- @historical_job.application_run_group_restriction_id = Naf::ApplicationRunGroupRestriction.no_limit.id
65
+ @historical_job.application_run_group_restriction_id =
66
+ Naf::ApplicationRunGroupRestriction.no_limit.id
61
67
  @queued_job = ::Naf::QueuedJob.new
62
68
  end
63
69
  else
@@ -67,7 +73,8 @@ module Naf
67
73
  if @queued_job.present?
68
74
  @queued_job.application_type_id = @historical_job.application_type_id
69
75
  @queued_job.command = @historical_job.command
70
- @queued_job.application_run_group_restriction_id = @historical_job.application_run_group_restriction_id
76
+ @queued_job.application_run_group_restriction_id =
77
+ @historical_job.application_run_group_restriction_id
71
78
  @queued_job.application_run_group_name = @historical_job.application_run_group_name
72
79
  @queued_job.application_run_group_limit = @historical_job.application_run_group_limit
73
80
  @queued_job.priority = @historical_job.priority
@@ -123,7 +130,10 @@ module Naf
123
130
  end
124
131
 
125
132
  format.html do
126
- redirect_to(@historical_job, notice: "Job '#{@historical_job.command}' was successfully updated.")
133
+ redirect_to(
134
+ @historical_job,
135
+ notice: "Job '#{@historical_job.command}' was successfully updated."
136
+ )
127
137
  end
128
138
  format.json do
129
139
  render json: { success: true,
@@ -21,7 +21,8 @@ module Naf
21
21
  NAF_CREATE_BLOCKED_RESOURCES = []
22
22
  NAF_ALL_VISIBLE_RESOURCES = {
23
23
  'historical_jobs' => '',
24
- 'applications' => '',
24
+ 'scripts' => ['applications',
25
+ 'application_schedules'],
25
26
  'machines' => '',
26
27
  'runners' => ['machine_runners',
27
28
  'machine_runner_invocations'],
@@ -39,7 +40,8 @@ module Naf
39
40
 
40
41
  def naf_last_queued_at_link(app)
41
42
  if historical_job = app.last_queued_job
42
- link_to "#{time_ago_in_words(historical_job.created_at, true)} ago, #{historical_job.created_at.localtime.strftime("%Y-%m-%d %r")}",
43
+ link_to "#{time_ago_in_words(historical_job.created_at, true)} ago, " +
44
+ "#{historical_job.created_at.localtime.strftime("%Y-%m-%d %r")}",
43
45
  naf.historical_job_path(historical_job)
44
46
  else
45
47
  ""
@@ -49,15 +51,22 @@ module Naf
49
51
  def naf_highlight_tab?(tab)
50
52
  case tab
51
53
  when "machines"
52
- [tab, "machine_affinity_slots"].include?(controller_name)
54
+ [tab,
55
+ "machine_affinity_slots"].include?(controller_name)
53
56
  when "runners"
54
- ["machine_runners", "machine_runner_invocations"].include?(controller_name)
57
+ ["machine_runners",
58
+ "machine_runner_invocations"].include?(controller_name)
55
59
  when "historical_jobs"
56
- [tab, "historical_job_affinity_tabs"].include?(controller_name)
57
- when "applications"
58
- [tab, "application_schedule_affinity_tabs"].include?(controller_name)
60
+ [tab,
61
+ "historical_job_affinity_tabs"].include?(controller_name)
62
+ when "scripts"
63
+ [tab,
64
+ "applications",
65
+ "application_schedules",
66
+ "application_schedule_affinity_tabs"].include?(controller_name)
59
67
  when "loggers"
60
- ["logger_styles", "logger_names"].include?(controller_name)
68
+ ["logger_styles",
69
+ "logger_names"].include?(controller_name)
61
70
  when "janitorial_assignments"
62
71
  ["Naf::JanitorialArchiveAssignment",
63
72
  "Naf::JanitorialCreateAssignment",
@@ -81,10 +90,10 @@ module Naf
81
90
  action: 'show',
82
91
  id: params[:historical_job_id]
83
92
  when "application_schedule_affinity_tabs"
84
- link_to "Back to Application",
85
- controller: 'applications',
93
+ link_to "Back to Application Schedule",
94
+ controller: 'application_schedules',
86
95
  action: 'show',
87
- id: params[:application_id]
96
+ id: params[:application_schedule_id]
88
97
  when "machine_affinity_slots"
89
98
  link_to "Back to Machine",
90
99
  controller: 'machines',
@@ -98,7 +107,8 @@ module Naf
98
107
  def naf_nested_resource_index?
99
108
  ["historical_job_affinity_tabs",
100
109
  "application_schedule_affinity_tabs",
101
- "machine_affinity_slots"].include?(controller_name) and !params[:id]
110
+ "machine_affinity_slots",
111
+ "application_schedules"].include?(controller_name) and !params[:id]
102
112
  end
103
113
 
104
114
  def naf_table_title
@@ -112,8 +122,6 @@ module Naf
112
122
  "Jobs"
113
123
  else
114
124
  case controller_name
115
- when "application_schedule_affinity_tabs"
116
- Application.find(params[:application_id]).title + ", Affinity Tabs"
117
125
  when "machine_affinity_slots"
118
126
  machine = Machine.find(params[:machine_id])
119
127
  name = machine.server_name
@@ -159,6 +167,8 @@ module Naf
159
167
  link_to "Loggers", naf.logger_styles_path
160
168
  when "runners"
161
169
  link_to "Runners", naf.machine_runners_path
170
+ when "scripts"
171
+ link_to "Scripts", naf.applications_path
162
172
  when "janitorial_assignments"
163
173
  link_to "Janitorial Assignments", naf.janitorial_archive_assignments_path
164
174
  when "janitorial_archive_assignments"
@@ -173,9 +183,14 @@ module Naf
173
183
  end
174
184
 
175
185
  def naf_generate_create_link
176
- return "" if NAF_READ_ONLY_RESOURCES.include?(controller_name) or NAF_CREATE_BLOCKED_RESOURCES.include?(controller_name)
177
- return link_to "Add a Job", naf.new_historical_job_path, { class: 'add_job' } if naf_display_job_search_link?
178
- link_to "Create new #{naf_model_name}", { controller: controller_name, action: 'new' }
186
+ return '' if NAF_READ_ONLY_RESOURCES.include?(controller_name) ||
187
+ NAF_CREATE_BLOCKED_RESOURCES.include?(controller_name)
188
+
189
+ return link_to "Add a Job",
190
+ naf.new_historical_job_path,
191
+ { class: 'add_job' } if naf_display_job_search_link?
192
+
193
+ return link_to "Create new #{naf_model_name}", { controller: controller_name, action: 'new' }
179
194
  end
180
195
 
181
196
  def naf_display_job_search_link?
@@ -194,18 +209,25 @@ module Naf
194
209
 
195
210
  def naf_generate_edit_link
196
211
  return "" if NAF_READ_ONLY_RESOURCES.include?(controller_name)
197
- link_to "Edit", { controller: controller_name, action: 'edit', id: params[:id] }, class: 'edit'
212
+ link_to "Edit",
213
+ { controller: controller_name, action: 'edit', id: params[:id] },
214
+ class: 'edit'
198
215
  end
199
216
 
200
217
  def naf_generate_back_link
201
- link_to "Back to #{naf_make_header(controller_name)}", { controller: controller_name, action: 'index' }, class: 'back'
218
+ link_to "Back to #{naf_make_header(controller_name)}",
219
+ { controller: controller_name, action: 'index' },
220
+ class: 'back'
202
221
  end
203
222
 
204
223
  def naf_generate_destroy_link
205
- return "" if NAF_READ_ONLY_RESOURCES.include?(controller_name) or NAF_DESTROY_BLOCKED_RESOURCES.include?(controller_name)
224
+ return '' if NAF_READ_ONLY_RESOURCES.include?(controller_name) ||
225
+ NAF_DESTROY_BLOCKED_RESOURCES.include?(controller_name)
226
+
206
227
  case controller_name
207
228
  when "application_schedule_affinity_tabs"
208
- link_to "Destroy", application_application_schedule_application_schedule_affinity_tab_url(@application, @application_schedule, @record),
229
+ link_to "Destroy",
230
+ application_schedule_application_schedule_affinity_tab_url(@application_schedule, @record),
209
231
  { confirm: "Are you sure you want to destroy this #{naf_model_name}?",
210
232
  method: :delete,
211
233
  class: 'destroy' }
@@ -231,7 +253,10 @@ module Naf
231
253
  fields = f.fields_for(association, new_object, child_index: "new_#{association}") do |builder|
232
254
  render(association.to_s, f: builder)
233
255
  end
234
- link_to_function(name, "add_fields(this, \"#{association}\", \"#{escape_javascript(fields)}\")", id: 'add_prerequisite')
256
+ link_to_function(
257
+ name,
258
+ "add_fields(this, \"#{association}\", \"#{escape_javascript(fields)}\")", id: 'add_prerequisite'
259
+ )
235
260
  end
236
261
 
237
262
  def add_color(status)
@@ -10,23 +10,12 @@ module Logical
10
10
  :title,
11
11
  :short_name,
12
12
  :script_type_name,
13
- :application_run_group_name,
14
- :application_run_group_restriction_name,
15
- :application_run_group_limit,
16
- :enabled,
17
- :enqueue_backlogs,
18
- :run_time,
19
- :affinities,
20
- :prerequisites,
21
- :deleted,
22
- :visible]
13
+ :application_schedules,
14
+ :deleted]
23
15
 
24
- FILTER_FIELDS = [:deleted,
25
- :enabled,
26
- :visible]
16
+ FILTER_FIELDS = [:deleted]
27
17
 
28
18
  SEARCH_FIELDS = [:title,
29
- :application_run_group_name,
30
19
  :command,
31
20
  :short_name]
32
21
 
@@ -35,31 +24,17 @@ module Logical
35
24
  end
36
25
 
37
26
  def self.search(search)
38
- application_scope = ::Naf::Application.
39
- joins("LEFT JOIN #{::Naf.schema_name}.application_schedules ON #{::Naf.schema_name}.application_schedules.application_id = #{::Naf.schema_name}.applications.id").
40
- order("id desc")
27
+ application_scope = ::Naf::Application.order("id desc")
41
28
 
42
29
  FILTER_FIELDS.each do |field|
43
30
  if search.present? and search[field].present?
44
- application_scope =
45
- if field == :enabled || field == :visible
46
- application_scope.where(application_schedules: { field => search[field] })
47
- else
48
- application_scope.where(field => search[field])
49
- end
31
+ application_scope = application_scope.where(field => search[field])
50
32
  end
51
33
  end
52
34
 
53
35
  SEARCH_FIELDS.each do |field|
54
36
  if search.present? and search[field].present?
55
- application_scope =
56
- if field == :application_run_group_name
57
- application_scope.where(
58
- ["lower(#{::Naf.schema_name}.application_schedules.application_run_group_name) ~ ?", Regexp.escape(search[field].downcase)]
59
- )
60
- else
61
- application_scope.where(["lower(#{field}) ~ ?", Regexp.escape(search[field].downcase)])
62
- end
37
+ application_scope = application_scope.where(["lower(#{field}) ~ ?", Regexp.escape(search[field].downcase)])
63
38
  end
64
39
  end
65
40
 
@@ -74,103 +49,11 @@ module Logical
74
49
  @app.command
75
50
  end
76
51
 
77
- def run_start_minute
78
- output = ""
79
- if schedule = @app.application_schedule and schedule.run_start_minute.present?
80
- minutes = schedule.run_start_minute % 60
81
- hours = schedule.run_start_minute / 60
82
- output << hours.to_s + ":"
83
- output << "%02d" % minutes
84
- output = Time.parse(output).strftime("%I:%M %p")
85
- end
86
-
87
- return output
88
- end
89
-
90
- def run_time
91
- run_time = run_start_minute.blank? ? run_interval : run_start_minute
92
- run_time = "not scheduled" if run_time.blank?
93
-
94
- run_time
95
- end
96
-
97
- def run_interval
98
- output = ""
99
- if schedule = @app.application_schedule and schedule.run_interval.present?
100
- time = schedule.run_interval
101
- output =
102
- if time == 0
103
- "run constantly"
104
- elsif time < 60
105
- pluralize(time, "minute")
106
- elsif time % 60 == 0
107
- pluralize(time / 60, "hour")
108
- else
109
- pluralize(time / 60, "hour") + ', ' + pluralize(time % 60, "minute")
110
- end
111
- end
112
-
113
- output
114
- end
115
-
116
- def prerequisites
117
- if schedule = @app.application_schedule and schedule.application_schedule_prerequisites.present?
118
- schedule.prerequisites.map do |schedule_prerequisite|
119
- schedule_prerequisite.application.short_name_if_it_exist
120
- end.join(", \n")
121
- end
122
- end
123
-
124
- def application_run_group_name
125
- if schedule = @app.application_schedule
126
- if schedule.application_run_group_name.blank?
127
- "not set"
128
- else
129
- schedule.application_run_group_name
130
- end
131
- end
132
- end
133
-
134
52
  def method_missing(method_name, *arguments, &block)
135
- case method_name
136
- when :application_run_group_restriction_name,
137
- :application_run_group_name,
138
- :run_start_minute,
139
- :priority,
140
- :application_run_group_limit,
141
- :visible,
142
- :enabled
143
- if schedule = @app.application_schedule
144
- schedule.send(method_name, *arguments, &block)
145
- else
146
- nil
147
- end
53
+ if @app.respond_to?(method_name)
54
+ @app.send(method_name, *arguments, &block)
148
55
  else
149
- if @app.respond_to?(method_name)
150
- @app.send(method_name, *arguments, &block)
151
- else
152
- super
153
- end
154
- end
155
- end
156
-
157
- def enqueue_backlogs
158
- application_schedule.try(:enqueue_backlogs)
159
- end
160
-
161
- def affinities
162
- if @app.application_schedule.try(:application_schedule_affinity_tabs).present?
163
- @app.application_schedule.application_schedule_affinity_tabs.map do |tab|
164
- if tab.affinity_short_name.present?
165
- if tab.affinity_parameter.present? && tab.affinity_parameter > 0
166
- tab.affinity_short_name + "(#{tab.affinity_parameter})"
167
- else
168
- tab.affinity_short_name
169
- end
170
- else
171
- tab.affinity_classification_name + '_' + tab.affinity_name
172
- end
173
- end.join(", \n")
56
+ super
174
57
  end
175
58
  end
176
59
 
@@ -0,0 +1,186 @@
1
+ module Logical
2
+ module Naf
3
+ class ApplicationSchedule
4
+
5
+ attr_reader :schedule
6
+
7
+ include ActionView::Helpers::TextHelper
8
+
9
+ COLUMNS = [:id,
10
+ :application,
11
+ :application_run_group_name,
12
+ :application_run_group_restriction_name,
13
+ :run_interval_style,
14
+ :run_interval,
15
+ :application_run_group_quantum,
16
+ :application_run_group_limit,
17
+ :enqueue_backlogs,
18
+ :affinities,
19
+ :prerequisites,
20
+ :enabled,
21
+ :visible]
22
+
23
+ # Mapping of datatable column positions and job attributes
24
+ ORDER = { '0' => "id",
25
+ '1' => "application_id",
26
+ '2' => "application_run_group_name",
27
+ '3' => "application_run_group_restriction_id",
28
+ '4' => "run_interval_style_id",
29
+ '5' => "run_interval",
30
+ '6' => "application_run_group_quantum",
31
+ '7' => "application_run_group_limit",
32
+ '8' => "enqueue_backlogs" }
33
+
34
+ def initialize(naf_schedule)
35
+ @schedule = naf_schedule
36
+ end
37
+
38
+ def self.search(search)
39
+ direction = search['sSortDir_0']
40
+ order = ORDER[search['iSortCol_0']]
41
+ ::Naf::ApplicationSchedule.
42
+ order("#{order} #{direction}").
43
+ all.map{ |physical_app_schedule| new(physical_app_schedule) }
44
+ end
45
+
46
+ def to_hash
47
+ Hash[ COLUMNS.map{ |m| [m, send(m)] } ]
48
+ end
49
+
50
+ def run_interval_style
51
+ schedule.run_interval_style.name
52
+ end
53
+
54
+ def affinities
55
+ output = ''
56
+ if schedule.try(:application_schedule_affinity_tabs).present?
57
+ output = schedule.application_schedule_affinity_tabs.map do |tab|
58
+ if tab.affinity_short_name.present?
59
+ if tab.affinity_parameter.present? && tab.affinity_parameter > 0
60
+ tab.affinity_short_name + "(#{tab.affinity_parameter})"
61
+ else
62
+ tab.affinity_short_name
63
+ end
64
+ else
65
+ tab.affinity_classification_name + '_' + tab.affinity_name
66
+ end
67
+ end.join(", \n")
68
+ end
69
+
70
+ return output
71
+ end
72
+
73
+ def prerequisites
74
+ if schedule.try(:application_schedule_prerequisites).present?
75
+ schedule.prerequisites.map do |schedule_prerequisite|
76
+ schedule_prerequisite.application.short_name_if_it_exist
77
+ end.join(", \n")
78
+ end
79
+ end
80
+
81
+ def display
82
+ output = ''
83
+
84
+ name = schedule.run_interval_style.name
85
+ if name == 'at beginning of day'
86
+ output << "daily(#{run_interval})"
87
+ elsif name == 'at beginning of hour'
88
+ output << "hourly(#{run_interval})"
89
+ elsif name == 'after previous run'
90
+ output << "run(#{run_interval})"
91
+ elsif name == 'keep running'
92
+ output << 'always'
93
+ end
94
+
95
+ if schedule.application_run_group_quantum.present?
96
+ output << "-#{schedule.application_run_group_quantum}"
97
+ else
98
+ output << "-1"
99
+ end
100
+ if schedule.application_run_group_limit.present?
101
+ output << "/#{schedule.application_run_group_limit}"
102
+ end
103
+
104
+ output
105
+ end
106
+
107
+ def help_title
108
+ output = 'Run this application '
109
+
110
+ name = schedule.run_interval_style.name
111
+ if name == 'at beginning of day'
112
+ output << "every day at #{run_interval}. "
113
+ elsif name == 'at beginning of hour'
114
+ output << "after #{schedule.run_interval} minute(s) of every hour. "
115
+ elsif name == 'after previous run'
116
+ output << "every #{schedule.run_interval} minute(s). "
117
+ elsif name == 'keep running'
118
+ output << 'constantly. '
119
+ end
120
+
121
+ output << "This schedule will queue #{schedule.application_run_group_quantum} job(s), and "
122
+ output << "will not queue more than the group's limit of #{schedule.application_run_group_limit} job(s)."
123
+
124
+ output
125
+ end
126
+
127
+ def run_interval
128
+ output = ''
129
+ time = schedule.run_interval
130
+ if schedule.run_interval_style.name == 'at beginning of day'
131
+ output = exact_time_of_day(time)
132
+ else
133
+ output = interval_time2(time)
134
+ end
135
+
136
+ output
137
+ end
138
+
139
+ def exact_time_of_day(time)
140
+ output = ''
141
+ minutes = schedule.run_interval % 60
142
+ hours = schedule.run_interval / 60
143
+ output << hours.to_s + ':'
144
+ output << '%02d' % minutes
145
+ output = Time.parse(output).strftime('%I:%M %p')
146
+
147
+ return output
148
+ end
149
+
150
+ def interval_time2(time)
151
+ if time < 9
152
+ ":0#{time}"
153
+ else
154
+ ":#{time}"
155
+ end
156
+ end
157
+
158
+ def interval_time(time)
159
+ if time < 60
160
+ pluralize(time, 'minute')
161
+ elsif time % 60 == 0
162
+ pluralize(time / 60, 'hour')
163
+ else
164
+ pluralize(time / 60, 'hour') + ', ' + pluralize(time % 60, 'minute')
165
+ end
166
+ end
167
+
168
+ def application_run_group_name
169
+ if schedule.application_run_group_name.present?
170
+ schedule.application_run_group_name
171
+ else
172
+ 'not set'
173
+ end
174
+ end
175
+
176
+ def method_missing(method_name, *arguments, &block)
177
+ if @schedule.respond_to?(method_name)
178
+ @schedule.send(method_name, *arguments, &block)
179
+ else
180
+ super
181
+ end
182
+ end
183
+
184
+ end
185
+ end
186
+ end