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