URI: 
       Bump the session timeout - warvox - VoIP based wardialing tool, forked from rapid7/warvox.
   DIR Log
   DIR Files
   DIR Refs
   DIR README
       ---
   DIR commit 951083434c6a1646d60513f8a2b5810ee03f5136
   DIR parent e9ab316926a10a27fdeb44d6c746cb26dccab2c9
  HTML Author: HD Moore <hd_moore@rapid7.com>
       Date:   Sun, 13 Jan 2013 16:27:49 -0600
       
       Bump the session timeout
       
       Diffstat:
         M app/assets/stylesheets/formtastic-… |      20 ++++++++++++++++++++
         M app/controllers/analyze_controller… |     114 +++++++++++++++++++++++++++----
         M app/controllers/jobs_controller.rb  |     127 ++++++++++++++++++++++++++-----
         M app/helpers/application_helper.rb   |       4 ++--
         M app/models/job.rb                   |       6 +++++-
         M app/models/user.rb                  |       1 +
         M app/views/analyze/index.html.erb    |      48 ++++++++++++++++++++++++++++++-
         M app/views/analyze/view_matches.htm… |      10 +++++++++-
         M app/views/jobs/index.html.erb       |       4 ++--
         M app/views/jobs/new_dialer.html.erb  |      11 ++++++++---
         M app/views/jobs/results.html.erb     |       2 +-
         M app/views/projects/show.html.erb    |       4 ++--
         M app/views/providers/edit.html.erb   |       1 +
         M app/views/shared/_call_signal.html… |       4 ++++
         M app/views/shared/_lightbox_sig.htm… |       2 +-
         M config/routes.rb                    |      15 ++++++++++++++-
       
       16 files changed, 326 insertions(+), 47 deletions(-)
       ---
   DIR diff --git a/app/assets/stylesheets/formtastic-overrides.css b/app/assets/stylesheets/formtastic-overrides.css
       @@ -13,6 +13,26 @@
          width: auto;
        }
        
       +.formtastic .boolean label {
       +        padding: 4px;
       +        font-weight: bold;
       +        font-size: 14px;
       +}
       +
       +.formtastic .boolean .control-label {
       +        display: none;
       +}
       +
       +.formtastic .boolean input {
       +        -moz-appearance: none;
       +        -webkit-appearance: none;
       +        appearance: none;
       +        height: 20px;
       +        width: 20px;
       +        margin-right: 20px;
       +        margin-left: 0;
       +}
       +
        .formtastic .numeric input {
                width: 5em;
        }
   DIR diff --git a/app/controllers/analyze_controller.rb b/app/controllers/analyze_controller.rb
       @@ -13,25 +13,30 @@ class AnalyzeController < ApplicationController
                  @job      = Job.find(@job_id)
                @shown    = params[:show]
        
       -        ltypes = Call.find( :all, :select => 'DISTINCT line_type', :conditions => ["job_id = ?", @job_id] ).map{|r| r.line_type}
       -        res_types = {}
       +        if request.format.html?
       +                ltypes = Call.find( :all, :select => 'DISTINCT line_type', :conditions => ["job_id = ?", @job_id] ).map{|r| r.line_type}
       +                res_types = {}
       +
       +                ltypes.each do |k|
       +                        next if not k
       +                        res_types[k.capitalize.to_sym] = Call.count(
       +                                :conditions => ['job_id = ? and line_type = ?', @job_id, k]
       +                        )
       +                end
        
       -        ltypes.each do |k|
       -                next if not k
       -                res_types[k.capitalize.to_sym] = Call.count(
       -                        :conditions => ['job_id = ? and line_type = ?', @job_id, k]
       -                )
       +                @lines_by_type = res_types
                end
        
       -        @lines_by_type = res_types
       -
            sort_by  = params[:sort_by] || 'number'
            sort_dir = params[:sort_dir] || 'asc'
        
            @results = []
       -    @results_total_count = @job.calls.where("job_id = ? AND analysis_completed_at IS NOT NULL", @job_id).count()
       +    @results_total_count = 0
        
            if request.format.json?
       +
       +      @results_total_count = Call.where("job_id = ? AND analysis_completed_at IS NOT NULL", @job.id).count()
       +
              if params[:iDisplayLength] == '-1'
                @results_per_page = nil
              else
       @@ -40,8 +45,10 @@ class AnalyzeController < ApplicationController
              @results_offset = (params[:iDisplayStart] || 0).to_i
        
                  calls_search
       -      @results = @job.calls.includes(:provider).where(@search_conditions).limit(@results_per_page).offset(@results_offset).order(calls_sort_option)
       -      @results_total_display_count = @job.calls.includes(:provider).where(@search_conditions).count()
       +
       +          @results_total_display_count = Call.where(@search_conditions).count()
       +      @results = Call.where(@search_conditions).includes(:provider).limit(@results_per_page).offset(@results_offset).order(calls_sort_option)
       +
            end
        
                respond_to do |format|
       @@ -55,18 +62,68 @@ class AnalyzeController < ApplicationController
        
          def view_matches
                  @result = Call.find(params[:call_id])
       -          @job_id = @result.job_id
                  @match_scopes = [
                          { :scope => 'job', :label => 'This Job' },
                          { :scope => 'project', :label => 'This Project' },
                          { :scope => 'global', :label => 'All Projects' }
                  ]
        
       -          @match_scope = params[:match_scope] || "job"
       +          @job_id = params[:job_id]
       +
       +        if @job_id
       +                  @match_scope = params[:match_scope] || "job"
       +        else
       +                @match_scope = params[:match_scope] || "project"
       +        end
        
                @results = @result.paginate_matches(@match_scope, 30.0, params[:page], 30)
          end
        
       +
       +
       +  def index
       +        @shown    = params[:show]
       +
       +        ltypes = Line.find( :all, :select => 'DISTINCT line_type', :conditions => ["project_id = ?", @project.id] ).map{|r| r.line_type}
       +        res_types = {}
       +
       +        ltypes.each do |k|
       +                next if not k
       +                res_types[k.capitalize.to_sym] = Line.count(
       +                        :conditions => ['project_id = ? and line_type = ?', @project.id, k]
       +                )
       +        end
       +
       +        @lines_by_type = res_types
       +
       +    sort_by  = params[:sort_by] || 'number'
       +    sort_dir = params[:sort_dir] || 'asc'
       +
       +    @results = []
       +    @results_total_count = @project.calls.where("analysis_completed_at IS NOT NULL").count()
       +
       +    if request.format.json?
       +      if params[:iDisplayLength] == '-1'
       +        @results_per_page = nil
       +      else
       +        @results_per_page = (params[:iDisplayLength] || 20).to_i
       +      end
       +      @results_offset = (params[:iDisplayStart] || 0).to_i
       +
       +          project_search
       +      @results = Call.where(@search_conditions).includes(:provider).limit(@results_per_page).offset(@results_offset).order(calls_sort_option)
       +      @results_total_display_count = Call.where(@search_conditions).includes(:provider).count()
       +    end
       +
       +        respond_to do |format|
       +      format.html
       +      format.json {
       +              render :content_type => 'application/json', :json => render_to_string(:partial => 'index', :results => @results, :lines_by_type => @lines_by_type )
       +      }
       +    end
       +
       +  end
       +
          def resource
                  ctype = 'text/html'
                cpath = nil
       @@ -146,8 +203,35 @@ class AnalyzeController < ApplicationController
                                        param << "%#{w}%"
                        end
                        glue = "AND " if glue.empty?
       -                @search_conditions = [ where, *param ]
                end
       +    @search_conditions = [ where, *param ]
       +  end
       +
       +  def project_search
       +          @search_conditions = []
       +          terms = params[:sSearch].to_s
       +          terms = Shellword.shellwords(terms) rescue terms.split(/\s+/)
       +        where = "project_id = ? AND analysis_completed_at IS NOT NULL "
       +        param = [ @project.id ]
       +        glue  = "AND "
       +        terms.each do |w|
       +                next if w == "undefined"
       +                where << glue
       +                case w
       +                        when /^F(\d+)$/i   # F2100 = peak frequency between 2095hz and 2105hz
       +                                freq = $1.to_i
       +                                where << "( peak_freq > ? AND peak_freq < ? ) "
       +                                param << freq - 5.0
       +                                param << freq + 5.0
       +                        else
       +                                where << "( number ILIKE ? OR caller_id ILIKE ? OR line_type ILIKE ? ) "
       +                                param << "%#{w}%"
       +                                param << "%#{w}%"
       +                                param << "%#{w}%"
       +                end
       +                glue = "AND " if glue.empty?
       +        end
       +        @search_conditions = [ where, *param ]
          end
        
        
   DIR diff --git a/app/controllers/jobs_controller.rb b/app/controllers/jobs_controller.rb
       @@ -18,12 +18,11 @@ class JobsController < ApplicationController
                        end
        
                        if @submitted_jobs.length > 0
       -                        @reload_interval = 1000
       +                        @reload_interval = 3000
                        end
        
                        respond_to do |format|
       -                        format.html # index.html.erb
       -                        format.xml        { render :xml => @active_jobs + @submitted_jobs }
       +                        format.html
                        end
                end
        
       @@ -35,8 +34,7 @@ class JobsController < ApplicationController
                        )
        
                        respond_to do |format|
       -                        format.html # index.html.erb
       -                        format.xml        { render :xml => @calls }
       +                        format.html
                        end
                end
        
       @@ -144,7 +142,6 @@ class JobsController < ApplicationController
        
                        respond_to do |format|
                                format.html
       -                        format.xml        { render :xml => @job }
                         end
                end
        
       @@ -160,8 +157,8 @@ class JobsController < ApplicationController
                        @job = Job.new(params[:job])
                        @job.created_by = @current_user.login
                        @job.task = 'dialer'
       -                @job.range.gsub!(/[^0-9X:,\n]/, '')
       -                @job.cid_mask.gsub!(/[^0-9X]/, '') if @job.cid_mask != "SELF"
       +                @job.range.to_s.gsub!(/[^0-9X:,\n]/, '')
       +                @job.cid_mask.to_s.gsub!(/[^0-9X]/, '') if @job.cid_mask != "SELF"
        
                        if @job.range_file.to_s != ""
                                @job.range = @job.range_file.read.gsub(/[^0-9X:,\n]/, '')
       @@ -170,15 +167,55 @@ class JobsController < ApplicationController
                        respond_to do |format|
                                if @job.schedule
                                        flash[:notice] = 'Job was successfully created.'
       -                        format.html { redirect_to :action => :index }
       -                                format.xml        { render :xml => @job, :status => :created }
       +                                format.html { redirect_to :action => :index }
                                else
                                        format.html { render :action => "new_dialer" }
       -                                format.xml        { render :xml => @job.errors, :status => :unprocessable_entity }
                                end
                        end
                end
        
       +        def new_analyze
       +                @job = Job.new
       +                if @project
       +                        @job.project = @project
       +                else
       +                        @job.project = Project.last
       +                end
       +
       +                if params[:result_ids]
       +                        nums = ""
       +                        Call.find_each(:conditions => { :id => params[:result_ids] }) do |call|
       +                                nums << call.number + "\n"
       +                        end
       +                        @job.range = nums
       +                end
       +
       +                respond_to do |format|
       +                        format.html
       +                 end
       +        end
       +
       +        def new_identify
       +                @job = Job.new
       +                if @project
       +                        @job.project = @project
       +                else
       +                        @job.project = Project.last
       +                end
       +
       +                if params[:result_ids]
       +                        nums = ""
       +                        Call.find_each(:conditions => { :id => params[:result_ids] }) do |call|
       +                                nums << call.number + "\n"
       +                        end
       +                        @job.range = nums
       +                end
       +
       +                respond_to do |format|
       +                        format.html
       +                 end
       +        end
       +
                def reanalyze_job
                        @job = Job.find(params[:id])
                        @new = Job.new({
       @@ -189,12 +226,10 @@ class JobsController < ApplicationController
                        respond_to do |format|
                                if @new.schedule
                                        flash[:notice] = 'Analysis job was successfully created.'
       -                        format.html { redirect_to jobs_path }
       -                                format.xml        { render :xml => @job, :status => :created }
       +                                format.html { redirect_to jobs_path }
                                else
                                        flash[:notice] = 'Analysis job could not run: ' + @new.errors.inspect
                                        format.html { redirect_to results_path(@project) }
       -                                format.xml        { render :xml => @job.errors, :status => :unprocessable_entity }
                                end
                        end
                end
       @@ -221,12 +256,70 @@ class JobsController < ApplicationController
                        respond_to do |format|
                                if @new.schedule
                                        flash[:notice] = 'Analysis job was successfully created.'
       -                        format.html { redirect_to jobs_path }
       -                                format.xml        { render :xml => @job, :status => :created }
       +                                format.html { redirect_to jobs_path }
                                else
                                        flash[:notice] = 'Analysis job could not run: ' + @new.errors.inspect
                                        format.html { redirect_to results_path(@project) }
       -                                format.xml        { render :xml => @job.errors, :status => :unprocessable_entity }
       +                        end
       +                end
       +        end
       +
       +
       +        def analyze_project
       +
       +                # Handle analysis of specific call IDs via checkbox submission
       +                if params[:result_ids]
       +                        @new = Job.new({
       +                                :task => 'analysis', :scope => 'calls', :target_ids => params[:result_ids],
       +                                :project_id => @project.id, :status => 'submitted'
       +                        })
       +                else
       +                # Otherwise analyze the entire Project
       +                        @new = Job.new({
       +                                :task => 'analysis', :scope => 'project', :target_id => @project.id,
       +                                :project_id => @project.id, :status => 'submitted'
       +                        })
       +                end
       +
       +                @new.created_by = @current_user.login
       +
       +                respond_to do |format|
       +                        if @new.schedule
       +                                flash[:notice] = 'Analysis job was successfully created.'
       +                                format.html { redirect_to jobs_path }
       +                        else
       +                                flash[:notice] = 'Analysis job could not run: ' + @new.errors.inspect
       +                                format.html { redirect_to results_path(@project) }
       +                        end
       +                end
       +        end
       +
       +        def identify_job
       +                @job = Job.find(params[:id])
       +
       +                # Handle identification of specific lines via checkbox submission
       +                if params[:result_ids]
       +                        @new = Job.new({
       +                                :task => 'identify', :scope => 'calls', :target_ids => params[:result_ids],
       +                                :project_id => @project.id, :status => 'submitted'
       +                        })
       +                else
       +                # Otherwise analyze the entire Job
       +                        @new = Job.new({
       +                                :task => 'identify', :scope => 'job', :target_id => @job.id,
       +                                :project_id => @project.id, :status => 'submitted'
       +                        })
       +                end
       +
       +                @new.created_by = @current_user.login
       +
       +                respond_to do |format|
       +                        if @new.schedule
       +                                flash[:notice] = 'Identify job was successfully created.'
       +                                format.html { redirect_to jobs_path }
       +                        else
       +                                flash[:notice] = 'Identify job could not run: ' + @new.errors.inspect
       +                                format.html { redirect_to results_path(@project) }
                                end
                        end
                end
   DIR diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
       @@ -68,7 +68,7 @@ module ApplicationHelper
                end
        
                def format_job_rate(job)
       -                pluralize(job.rate.to_i, "call") + "/s"
       +                pluralize( (job.rate * 60.0).to_i, "call") + "/min"
                end
        
                #
       @@ -171,7 +171,7 @@ module ApplicationHelper
                end
        
                def call_ring_length_html(call)
       -                json_data_scrub(h(call.ring_lenght.to_s)).to_json.html_safe
       +                json_data_scrub(h(call.ring_length.to_s)).to_json.html_safe
                end
        
        
   DIR diff --git a/app/models/job.rb b/app/models/job.rb
       @@ -27,6 +27,9 @@ class Job < ActiveRecord::Base
                                        unless record.lines.to_i > 0 and record.lines.to_i < 10000
                                                record.errors[:lines] << "Lines should be between 1 and 10,000"
                                        end
       +
       +                                $stderr.puts "Errors: #{record.errors.map{|x| x.inspect}}"
       +
                                when 'analysis'
                                        unless ['calls', 'job', 'project', 'global'].include?(record.scope)
                                                record.errors[:scope] << "Scope must be calls, job, project, or global"
       @@ -66,7 +69,7 @@ class Job < ActiveRecord::Base
                attr_accessor :seconds
                attr_accessor :cid_mask
        
       -        attr_accessible :range, :seconds, :lines, :cid_mask
       +        attr_accessible :range, :seconds, :lines, :cid_mask, :range_file
        
                attr_accessor :scope
                attr_accessor :force
       @@ -104,6 +107,7 @@ class Job < ActiveRecord::Base
                                        :seconds  => self.seconds.to_i,
                                        :cid_mask => self.cid_mask
                                })
       +
                                return self.save
        
                        when 'analysis'
   DIR diff --git a/app/models/user.rb b/app/models/user.rb
       @@ -4,5 +4,6 @@ class User < ActiveRecord::Base
                        c.validate_email_field = false
                        c.merge_validates_length_of_password_field_options :minimum => 8
                        c.merge_validates_length_of_password_confirmation_field_options :minimum => 8
       +                c.logged_in_timeout = 1.day
                end
        end
   DIR diff --git a/app/views/analyze/index.html.erb b/app/views/analyze/index.html.erb
       @@ -1 +1,47 @@
       -<h1 class='title'>Analysis</h1>
       +<% include_view_javascript %>
       +
       +<h1 class='title'>Analysis of Project <%= @project.name %></h1>
       +
       +<table class='table table-striped table-condensed'>
       +<tr>
       +        <td align='center'>
       +                <%= render :partial => 'shared/graphs/lines_by_type' %>
       +        </td>
       +</tr>
       +</table>
       +
       +
       +<%= form_tag do %>
       +
       +<div class="control-bar">
       +<table width='100%' border=0 cellpadding=6>
       +<tbody><tr>
       +<td>
       +        <%= submit_checkboxes_to(raw('<i class="icon-refresh"></i> ReDial'), new_dialer_project_job_path(@project), { :class => "btn any" }) %>
       +</td>
       +<td>
       +        <%= submit_checkboxes_to(raw('<i class="icon-trash"></i> Delete'), purge_calls_project_job_path, { :class => "btn any ", :confirm => 'Delete selected calls?' }) %>
       +</td>
       +</tr></tbody></table>
       +
       +</div>
       +
       +
       +<div class="analysis-control-bar"> </div>
       +
       +<span id="results-path" class="invisible"><%= analyze_path(@project, :format => :json) %></span>
       +
       +<table id='results-table' class='table table-striped table-condensed sortable list' >
       +  <thead>
       +  <tr>
       +        <th><%= check_box_tag "all_results", false %></th>
       +    <th>Number</th>
       +    <th>Type</th>
       +    <th>Signal</th>
       +  </tr>
       +  </thead>
       +  <tbody id="results-list">
       +  </tbody>
       +</table>
       +
       +<% end %>
   DIR diff --git a/app/views/analyze/view_matches.html.erb b/app/views/analyze/view_matches.html.erb
       @@ -2,7 +2,15 @@
        
        <% call = @result %>
        
       -<h1 class='title'><%= @result.number %> (<a href="<%=view_analyze_path(@project.id, call.job_id)%>">Back to Job Analysis</a>)</h1>
       +<h1 class='title'>
       +<%= @result.number %>
       +<% if @job_id %>
       +(<a href="<%= view_analyze_path(@project.id, call.job_id)%>">Back to Job Analysis</a>)
       +<% else %>
       +(<a href="<%= analyze_path(@project.id)%>">Back to Project Analysis</a>)
       +<% end %>
       +</h1>
       +
        <table class='table table-striped table-condensed'>
          <thead>
          <tr>
   DIR diff --git a/app/views/jobs/index.html.erb b/app/views/jobs/index.html.erb
       @@ -20,7 +20,7 @@
            <td><%= time_ago_in_words(job.created_at) %> ago</td>
        
            <td>
       -                <a class="btn" href="<%= job_path(job) %>" data-confirm="Remove this job?" data-method="delete" rel="nofollow tooltip" title="Remove Job"><i class="icon-trash"></i></a>
       +                <a class="btn" href="<%= job_path(job) %>" data-confirm="Remove this job?" data-method="delete" rel="nofollow tooltip" title="Remove Job"><i class="icon-remove"></i></a>
                </td>
            <td><%= link_to( h(truncate(job.project.name, :length => 25)), project_path(job.project)) %></td>
          </tr>
       @@ -78,7 +78,7 @@
        <h1 class='title'>No Active Jobs</h1>
        <% end %>
        
       -<a class="btn" href="<%= new_dialer_job_path %>"><i class="icon-plus"></i> New Scan </a>
       +<a class="btn" href="<%= new_dialer_job_path %>"><i class="icon-phone"></i> <strong>Wardial</strong></a>
        
        <% if(@inactive_jobs.length > 0) %>
        <br/><br/>
   DIR diff --git a/app/views/jobs/new_dialer.html.erb b/app/views/jobs/new_dialer.html.erb
       @@ -1,7 +1,12 @@
       -<h1 class='title'>Phone Scan</h1>
       +<h1 class='title'>Wardial Configuration</h1>
        
        <%= semantic_form_for(@job, :url => dialer_job_path, :html => { :multipart => true, :method => :put }) do |f| %>
       +
       +        <% if @project %>
       +        <%= f.input :project_id, :as => :hidden, :input_html => { :value => @project.id } %>
       +        <% else %>
                <%= f.input :project, :as => :select %>
       +        <% end %>
        
                <%= f.input :range, :as => :text,
                        :label => 'Target telephone range(s)',
       @@ -10,8 +15,8 @@
                %>
                <%= f.input :range_file, :as => :file, :label => 'Or upload a file containing the target ranges' %>
                <%= f.input :seconds,  :as => :number, :label => 'Seconds of audio to capture', :input_html => { :value => 53 } %>
       -        <%= f.input :lines,  :as => :number, :label => 'Maximum number of outgoing lines', :input_html => { :value => 1 } %>
       -        <%= f.input :cid_mask,  :as => :string, :label => 'The source Caller ID range (1-555-555-55XX or SELF)', :input_html => { :value => '1-123-456-XXXX' } %>
       +        <%= f.input :lines,  :as => :number, :label => 'Maximum number of outgoing lines', :input_html => { :value => 10 } %>
       +        <%= f.input :cid_mask,  :as => :string, :label => 'The source Caller ID range (1-555-555-55XX or SELF)', :input_html => { :value => '1-555-555-XXXX' } %>
        
                <%= f.action :submit, :label => 'Dial', :button_html => { :class => 'btn btn-large fbtn' }  %>
        
   DIR diff --git a/app/views/jobs/results.html.erb b/app/views/jobs/results.html.erb
       @@ -84,4 +84,4 @@
        
        <% end %>
        
       -<a class="btn" href="<%= new_dialer_job_path %>"><i class="icon-plus"></i> New Scan </a>
       +<a class="btn" href="<%= new_dialer_project_job_path(@project) %>"><i class="icon-phone"></i> <strong>Wardial</strong></a>
   DIR diff --git a/app/views/projects/show.html.erb b/app/views/projects/show.html.erb
       @@ -16,9 +16,9 @@
                <div class="span9">
                        <div class="row-fluid">
                                <div class="span2">&nbsp;</div>
       -                        <div class="span2"><a href="<%= new_dialer_job_path %>" class="btn" rel="tooltip" title="Gather data by dialing a range of numbers"><i class="icon-phone"></i> <strong>Wardial</strong></a></div>
       +                        <div class="span2"><a href="<%= new_dialer_project_job_path(@project) %>" class="btn" rel="tooltip" title="Gather data by dialing a range of numbers"><i class="icon-phone"></i> <strong>Wardial</strong></a></div>
                                <% if @boxes[:answered][:cnt] > 0 %>
       -                        <div class="span2"><a href="#" class="btn" rel="tooltip" title="Analyze call data to determine line types and frequencies"><i class="icon-cogs"></i> <strong>Analyze</strong></a></div>
       +                        <div class="span2"><a href="<%= new_analyze_job_path %>" class="btn" rel="tooltip" title="Analyze call data to determine line types and frequencies"><i class="icon-cogs"></i> <strong>Analyze</strong></a></div>
                                <div class="span2"><a href="#" class="btn" rel="tooltip" title="Look up meta-information about specific lines"><i class="icon-user"></i> <strong>Identify</strong></a></div>
                                <div class="span2"><a href="#" class="btn" rel="tooltip" title="Signal analysis and other research tools"><i class="icon-star"></i> <strong>Research</strong></a></div>
                                <% else %>
   DIR diff --git a/app/views/providers/edit.html.erb b/app/views/providers/edit.html.erb
       @@ -1,6 +1,7 @@
        <h1 class='title'>Update Provider</h1>
        
        <%= semantic_form_for(@provider) do |f| %>
       +        <%= f.input :enabled, :as => :boolean %>
                <%= f.input :name, :as => :string, :label => 'Name', :hint => 'A friendly name for this provider', :autofocus => true %>
                <%= f.input :host, :as => :string, :label => 'IAX2 Server', :hint => 'The IP address or hostname of the IAX2 service' %>
                <%= f.input :port, :as => :number, :label => 'IAX2 Port', :hint => 'The port of the IAX2 service' %>
   DIR diff --git a/app/views/shared/_call_signal.html.erb b/app/views/shared/_call_signal.html.erb
       @@ -2,5 +2,9 @@
        <%= render :partial => 'shared/lightbox_freq', :locals => { :call => call } %>
        
        <% if call.fprint and call.fprint.length > 0 and call != @result %>
       +        <% if @job_id %>
                <a class="btn" href="<%= view_matches_path(call.project_id, call.job_id, call.id) %>" rel="tooltip" title="Search for Matches"><i class="icon-search"></i></a>
       +        <% else %>
       +        <a class="btn" href="<%= view_matches_project_path(call.project_id, call.id) %>" rel="tooltip" title="Search for Matches"><i class="icon-search"></i></a>
       +        <% end%>
        <% end %>
   DIR diff --git a/app/views/shared/_lightbox_sig.html.erb b/app/views/shared/_lightbox_sig.html.erb
       @@ -7,4 +7,4 @@
                </div>
        </div>
        
       -<a data-toggle="lightbox" href="#<%= lid %>"><img src="<%=resource_analyze_path(call.id, "small_sig")%>"/></a>
       +<a data-toggle="lightbox" href="#<%= lid %>"><img src="<%=resource_analyze_path(call.id, "small_sig")%>" /></a>
   DIR diff --git a/config/routes.rb b/config/routes.rb
       @@ -9,22 +9,35 @@ Web::Application.routes.draw do
        
        
          match  '/jobs/dial'            => 'jobs#new_dialer',   :as => :new_dialer_job
       +  match  '/projects/:project_id/jobs/dial'            => 'jobs#new_dialer',   :as => :new_dialer_project_job
       +
          match  '/jobs/dialer'          => 'jobs#dialer',       :as => :dialer_job
       -  match  '/jobs/analyze'         => 'jobs#new_analyzer', :as => :new_analyzer_job
       +  match  '/jobs/analyze'         => 'jobs#new_analyze',  :as => :new_analyze_job
          match  '/jobs/analyzer'        => 'jobs#analyzer',     :as => :analyzer_job
       +  match  '/jobs/identify'        => 'jobs#new_identify', :as => :new_identify_job
       +  match  '/jobs/identifier'      => 'jobs#identifier',   :as => :identifier_job
       +
          match  '/jobs/:id/stop'        => 'jobs#stop',         :as => :stop_job
          match  '/jobs/:id/calls/purge' => "jobs#purge_calls",  :as => :purge_calls_job
        
       +  match  '/projects/:project_id/calls/purge' => "jobs#purge_calls",  :as => :purge_calls_project_job
       +
          match  '/projects/:project_id/scans'          => 'jobs#results', :as => :results
          match  '/projects/:project_id/scans/:id'      => 'jobs#view_results', :as => :view_results
          match  '/projects/:project_id/scans/:id/analyze'    => 'jobs#analyze_job', :as => :analyze_job
          match  '/projects/:project_id/scans/:id/reanalyze'  => 'jobs#reanalyze_job', :as => :reanalyze_job
        
       +  match  '/projects/:project_id/all/analyze'      => 'jobs#analyze_project', :as => :analyze_project_job
       +  match  '/projects/:project_id/all/identify'     => 'jobs#identify_project', :as => :identify_project_job
       +
       +
       +
          match '/projects/:project_id/analyze'             => 'analyze#index', :as => :analyze
          match '/call/:result_id.:type'                   => 'analyze#resource', :as => :resource_analyze
          match '/projects/:project_id/analyze/:id/view'    => 'analyze#view', :as => :view_analyze
        
          match '/projects/:project_id/analyze/:job_id/:call_id/matches'    => 'analyze#view_matches', :as => :view_matches
       +  match '/projects/:project_id/analyze/:call_id/matches'    => 'analyze#view_matches', :as => :view_matches_project
        
          resources :settings
          resources :providers