jobs_controller.rb - warvox - VoIP based wardialing tool, forked from rapid7/warvox.
(HTM) git clone git://jay.scot/warvox
(DIR) Log
(DIR) Files
(DIR) Refs
(DIR) README
---
jobs_controller.rb (9313B)
---
1 class JobsController < ApplicationController
2 require 'shellwords'
3
4 def index
5 @reload_interval = 20_000
6
7 @submitted_jobs = Job.where(status: %w(submitted scheduled), completed_at: nil)
8 @active_jobs = Job.where(status: 'running', completed_at: nil)
9 @inactive_jobs = Job.order('id DESC').where('status NOT IN (?)', %w(submitted scheduled running)).paginate(
10 page: params[:page],
11 per_page: 30
12 )
13
14 @reload_interval = 5000 unless @active_jobs.empty?
15
16 @reload_interval = 3000 unless @submitted_jobs.empty?
17
18 respond_to do |format|
19 format.html
20 end
21 end
22
23 def results
24 @jobs = @project.jobs.order('id DESC').where('(task = ? OR task = ?) AND completed_at IS NOT NULL', 'dialer', 'import').paginate(
25 page: params[:page],
26 per_page: 30
27 )
28
29 respond_to do |format|
30 format.html
31 end
32 end
33
34 def view_results
35 @job = Job.find(params[:id])
36
37 @call_results = {
38 Timeout: @job.calls.where(answered: false ).count,
39 Busy: @job.calls.where(busy: true).count,
40 Answered: @job.calls.where(answered: true).count,
41 }
42
43
44 sort_by = params[:sort_by] || 'number'
45 sort_dir = params[:sort_dir] || 'asc'
46
47 @results = []
48 @results_total_count = @job.calls.count
49
50 if request.format.json?
51 if params[:iDisplayLength] == '-1'
52 @results_per_page = nil
53 else
54 @results_per_page = (params[:iDisplayLength] || 20).to_i
55 end
56 @results_offset = (params[:iDisplayStart] || 0).to_i
57
58 calls_search
59 @results = @job.calls.includes(:provider).where(@search_conditions).limit(@results_per_page).offset(@results_offset).order(calls_sort_option)
60 @results_total_display_count = @job.calls.includes(:provider).where(@search_conditions).count
61 end
62
63 respond_to do |format|
64 format.html
65 format.json do
66 render content_type: 'application/json', json: render_to_string(partial: 'view_results', results: @results, call_results: @call_results)
67 end
68 end
69 end
70
71 # Generate a SQL sort by option based on the incoming DataTables paramater.
72 #
73 # Returns the SQL String.
74 def calls_sort_option
75 column = case params[:iSortCol_0].to_s
76 when '1'
77 'number'
78 when '2'
79 'caller_id'
80 when '3'
81 'providers.name'
82 when '4'
83 'answered'
84 when '5'
85 'busy'
86 when '6'
87 'audio_length'
88 when '7'
89 'ring_length'
90 end
91 column + ' ' + (params[:sSortDir_0] =~ /^A/i ? 'asc' : 'desc') if column
92 end
93
94 def calls_search
95 @search_conditions = []
96 terms = params[:sSearch].to_s
97 terms = begin
98 Shellword.shellwords(terms)
99 rescue
100 terms.split(/\s+/)
101 end
102 where = ''
103 param = []
104 glue = ''
105 terms.each do |w|
106 next if w.casecmp('undefined').zero?
107 where << glue
108 case w
109 when 'answered'
110 where << 'answered = ? '
111 param << true
112 when 'busy'
113 where << 'busy = ? '
114 param << true
115 else
116 where << '( number ILIKE ? OR caller_id ILIKE ? ) '
117 param << "%#{w}%"
118 param << "%#{w}%"
119 end
120 glue = 'AND ' if glue.empty?
121 @search_conditions = [where, *param]
122 end
123 end
124
125 def new_dialer
126 @job = Job.new
127 @job.project = if @project
128 @project
129 else
130 Project.last
131 end
132
133 if params[:result_ids]
134 nums = ''
135 Call.find_each(conditions: { id: params[:result_ids] }) do |call|
136 nums << call.number + "\n"
137 end
138 @job.range = nums
139 end
140
141 respond_to do |format|
142 format.html
143 end
144 end
145
146 def purge_calls
147 unless params[:result_ids].blank?
148 Call.delete_all(id: params[:result_ids])
149 CallMedium.delete_all(call_id: params[:result_ids])
150 flash[:notice] = "Purged #{params[:result_ids].length} calls"
151 end
152
153 if params[:id]
154 @job = Job.find(params[:id])
155 redirect_to view_results_path(@job.project_id, @job.id)
156 else
157 redirect_to analyze_path(@project)
158 end
159 end
160
161 def dialer
162 @job = Job.new(job_params)
163 @job.created_by = @current_user.login
164 @job.task = 'dialer'
165 @job.range.to_s.gsub!(/[^0-9X:,\n]/, '')
166 @job.cid_mask.to_s.gsub!(/[^0-9X]/, '') if @job.cid_mask != 'SELF'
167
168 if @job.range_file.to_s != ''
169 @job.range = @job.range_file.read.gsub(/[^0-9X:,\n]/, '')
170 end
171
172 respond_to do |format|
173 if @job.schedule
174 flash[:notice] = 'Job was successfully created.'
175 format.html { redirect_to action: :index }
176 else
177 format.html { render action: 'new_dialer' }
178 end
179 end
180 end
181
182 def new_analyze
183 @job = Job.new
184 @job.project = if @project
185 @project
186 else
187 Project.last
188 end
189
190 if params[:result_ids]
191 nums = ''
192 Call.find_each(conditions: { id: params[:result_ids] }) do |call|
193 nums << call.number + "\n"
194 end
195 @job.range = nums
196 end
197
198 respond_to do |format|
199 format.html
200 end
201 end
202
203 def new_identify
204 @job = Job.new
205 @job.project = if @project
206 @project
207 else
208 Project.last
209 end
210
211 if params[:result_ids]
212 nums = ''
213 Call.find_each(conditions: { id: params[:result_ids] }) do |call|
214 nums << call.number + "\n"
215 end
216 @job.range = nums
217 end
218
219 respond_to do |format|
220 format.html
221 end
222 end
223
224 def reanalyze_job
225 @job = Job.find(params[:id])
226 @new = Job.new(task: 'analysis', scope: 'job', target_id: @job.id, force: true,
227 project_id: @project.id, status: 'submitted')
228 @new.created_by = @current_user.login
229 respond_to do |format|
230 if @new.schedule
231 flash[:notice] = 'Analysis job was successfully created.'
232 format.html { redirect_to jobs_path }
233 else
234 flash[:notice] = 'Analysis job could not run: ' + @new.errors.inspect
235 format.html { redirect_to results_path(@project) }
236 end
237 end
238 end
239
240 def analyze_job
241 @job = Job.find(params[:id])
242
243 # Handle analysis of specific call IDs via checkbox submission
244 if params[:result_ids]
245 @new = Job.new(task: 'analysis', scope: 'calls', target_ids: params[:result_ids],
246 project_id: @project.id, status: 'submitted')
247 else
248 # Otherwise analyze the entire Job
249 @new = Job.new(task: 'analysis', scope: 'job', target_id: @job.id,
250 project_id: @project.id, status: 'submitted')
251 end
252
253 @new.created_by = @current_user.login
254
255 respond_to do |format|
256 if @new.schedule
257 flash[:notice] = 'Analysis job was successfully created.'
258 format.html { redirect_to jobs_path }
259 else
260 flash[:notice] = 'Analysis job could not run: ' + @new.errors.inspect
261 format.html { redirect_to results_path(@project) }
262 end
263 end
264 end
265
266 def analyze_project
267 # Handle analysis of specific call IDs via checkbox submission
268 if params[:result_ids]
269 @new = Job.new(task: 'analysis', scope: 'calls', target_ids: params[:result_ids],
270 project_id: @project.id, status: 'submitted')
271 else
272 # Otherwise analyze the entire Project
273 @new = Job.new(task: 'analysis', scope: 'project', target_id: @project.id,
274 project_id: @project.id, status: 'submitted')
275 end
276
277 @new.created_by = @current_user.login
278
279 respond_to do |format|
280 if @new.schedule
281 flash[:notice] = 'Analysis job was successfully created.'
282 format.html { redirect_to jobs_path }
283 else
284 flash[:notice] = 'Analysis job could not run: ' + @new.errors.inspect
285 format.html { redirect_to results_path(@project) }
286 end
287 end
288 end
289
290 def identify_job
291 @job = Job.find(params[:id])
292
293 # Handle identification of specific lines via checkbox submission
294 if params[:result_ids]
295 @new = Job.new(task: 'identify', scope: 'calls', target_ids: params[:result_ids],
296 project_id: @project.id, status: 'submitted')
297 else
298 # Otherwise analyze the entire Job
299 @new = Job.new(task: 'identify', scope: 'job', target_id: @job.id,
300 project_id: @project.id, status: 'submitted')
301 end
302
303 @new.created_by = @current_user.login
304
305 respond_to do |format|
306 if @new.schedule
307 flash[:notice] = 'Identify job was successfully created.'
308 format.html { redirect_to jobs_path }
309 else
310 flash[:notice] = 'Identify job could not run: ' + @new.errors.inspect
311 format.html { redirect_to results_path(@project) }
312 end
313 end
314 end
315
316 def stop
317 @job = Job.find(params[:id])
318 @job.stop
319 flash[:notice] = 'Job has been cancelled'
320 redirect_to action: 'index'
321 end
322
323 def destroy
324 @job = Job.find(params[:id])
325 @job.destroy
326
327 respond_to do |format|
328 format.html { redirect_to(jobs_url) }
329 format.xml { head :ok }
330 end
331 end
332
333 private
334
335 def job_params
336 params.require(:job).permit(:project_id, :range, :range_file, :seconds, :lines, :cid_mask)
337 end
338 end