| Merge up result work - warvox - VoIP based wardialing tool, forked from rapid7/… | |
| Log | |
| Files | |
| Refs | |
| README | |
| --- | |
| commit 6069c70a7796461ccfccd692329f44e93e8d15e0 | |
| parent 5d5ff7536bcc334921225494e5eb292653bee43f | |
| Author: HD Moore <[email protected]> | |
| Date: Sun, 6 Jan 2013 01:59:56 -0600 | |
| Merge up result work | |
| Diffstat: | |
| A app/assets/images/player.swf | 0 | |
| A app/assets/images/ubaplayer-btn.png | 0 | |
| A app/assets/images/ubaplayer-loadin… | 0 | |
| M app/assets/javascripts/application… | 1 + | |
| A app/assets/javascripts/jquery.ubap… | 223 +++++++++++++++++++++++++++… | |
| A app/assets/javascripts/jquery.ubap… | 5 +++++ | |
| A app/assets/javascripts/swfobject.js | 5 +++++ | |
| M app/assets/stylesheets/bootstrap_a… | 113 +++++++++++++++++++++++++++… | |
| M app/controllers/analyze_controller… | 10 +++++++++- | |
| M app/helpers/analyze_helper.rb | 10 +++++----- | |
| M app/helpers/application_helper.rb | 58 +++++++++++++++++++++++++++--… | |
| M app/models/call.rb | 23 +++++++++++++++++++++++ | |
| M app/views/analyze/view.html.erb | 39 ++++++++++++-----------------… | |
| M app/views/analyze/view_matches.htm… | 110 +++++++++++++++++----------… | |
| M app/views/calls/index.html.erb | 2 +- | |
| M app/views/home/about.html.erb | 2 +- | |
| M app/views/jobs/index.html.erb | 30 ++++++++++++++++++++++-------- | |
| M app/views/jobs/results.html.erb | 10 ++++++---- | |
| D app/views/jobs/show.html.erb | 39 -----------------------------… | |
| M app/views/jobs/view_results.html.e… | 4 ++-- | |
| M app/views/layouts/application.html… | 24 ++++++++++++++++++++++-- | |
| M app/views/providers/index.html.erb | 2 +- | |
| A app/views/shared/_audio_player.htm… | 1 + | |
| A app/views/shared/_call_info.html.e… | 1 + | |
| M app/views/shared/graphs/_call_resu… | 2 -- | |
| M app/views/shared/graphs/_lines_by_… | 2 -- | |
| M config/routes.rb | 8 ++------ | |
| M lib/warvox/jobs/analysis.rb | 21 +++++++++++++++------ | |
| A public/crossdomain.xml | 5 +++++ | |
| 29 files changed, 583 insertions(+), 167 deletions(-) | |
| --- | |
| diff --git a/app/assets/images/player.swf b/app/assets/images/player.swf | |
| Binary files differ. | |
| diff --git a/app/assets/images/ubaplayer-btn.png b/app/assets/images/ubaplayer-… | |
| Binary files differ. | |
| diff --git a/app/assets/images/ubaplayer-loading.gif b/app/assets/images/ubapla… | |
| Binary files differ. | |
| diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/app… | |
| @@ -2,6 +2,7 @@ | |
| // This file is automatically included by javascript_include_tag :defaults | |
| //= require jquery | |
| //= require jquery_ujs | |
| +//= require jquery.ubaplayer | |
| //= require twitter/bootstrap | |
| //= require bootstrap-lightbox | |
| //= require dataTables/jquery.dataTables | |
| diff --git a/app/assets/javascripts/jquery.ubaplayer.js b/app/assets/javascript… | |
| @@ -0,0 +1,223 @@ | |
| +/*! UbaPlayer - v1.0.1 - 2012-06-06 | |
| +* https://github.com/brianhadaway/UbaPlayer | |
| +* Copyright (c) 2012 Brian Hadaway; Licensed MIT, GPL */ | |
| + | |
| +(function($){ | |
| + var defaults = { | |
| + audioButtonClass: "audioButton", | |
| + autoPlay: null, | |
| + codecs: [{name:"OGG", codec: 'audio/ogg; codecs="vorbis… | |
| + continuous: false, | |
| + extension: null, | |
| + flashAudioPlayerPath: "libs/swf/player.swf", | |
| + flashExtension: ".mp3", | |
| + flashObjectID: "audioPlayer", | |
| + loadingClass: "loading", | |
| + loop: false, | |
| + playerContainer: "player", | |
| + playingClass: "playing", | |
| + swfobjectPath: "libs/swfobject/swfobject.js", | |
| + volume: 0.5 | |
| + }, | |
| + currentTrack, | |
| + isPlaying = false, | |
| + isFlash = false, | |
| + audio, | |
| + $buttons, | |
| + $tgt, | |
| + $el, | |
| + playTrack, | |
| + resumeTrack, | |
| + pauseTrack, | |
| + methods = { | |
| + play: function(element){ | |
| + $tgt = element; | |
| + currentTrack = _methods.getFileNameWithoutExtension($t… | |
| + isPlaying = true; | |
| + $tgt.addClass(defaults.loadingClass); | |
| + $buttons.removeClass(defaults.playingClass); | |
| + | |
| + if(isFlash){ | |
| + if(audio) { | |
| + _methods.removeListeners(window); | |
| + } | |
| + audio = document.getElementById(defaults.flash… | |
| + _methods.addListeners(window); | |
| + audio.playFlash(currentTrack + defaults.extens… | |
| + } else { | |
| + if(audio) { | |
| + audio.pause(); | |
| + _methods.removeListeners(audio); | |
| + } | |
| + audio = new Audio(""); | |
| + _methods.addListeners(audio); | |
| + audio.id = "audio"; | |
| + audio.loop = defaults.loop ? "loop" : ""; | |
| + audio.volume = defaults.volume; | |
| + audio.src = currentTrack + defaults.extension; | |
| + audio.play(); | |
| + } | |
| + }, | |
| + | |
| + pause: function(){ | |
| + if(isFlash){ | |
| + audio.pauseFlash(); | |
| + } else { | |
| + audio.pause(); | |
| + } | |
| + | |
| + $tgt.removeClass(defaults.playingClass); | |
| + isPlaying = false; | |
| + }, | |
| + | |
| + resume: function(){ | |
| + if(isFlash){ | |
| + audio.playFlash(); | |
| + } else { | |
| + audio.play(); | |
| + } | |
| + $tgt.addClass(defaults.playingClass); | |
| + isPlaying = true; | |
| + }, | |
| + | |
| + playing: function(){ | |
| + return isPlaying; | |
| + } | |
| + }, | |
| + | |
| + _methods = { | |
| + init: function( options ){ | |
| + var types; | |
| + | |
| + //set defaults | |
| + $.extend(defaults, options); | |
| + $el = this; | |
| + | |
| + //listen for clicks on the controls | |
| + $(".controls").bind("click",function(event){ | |
| + _methods.updateTrackState(event); | |
| + return false; | |
| + }); | |
| + $buttons = $("."+defaults.audioButtonClass); | |
| + | |
| + types = defaults.codecs; | |
| + for(var i = 0, ilen = types.length; i < ilen; i++){ | |
| + var type = types[i]; | |
| + if(_methods.canPlay(type)){ | |
| + defaults.extension = [".", type.name.t… | |
| + break; | |
| + } | |
| + } | |
| + | |
| + if(!defaults.extension || isFlash){ | |
| + isFlash = true; | |
| + defaults.extension = defaults.flashExtension; | |
| + } | |
| + | |
| + if(isFlash){ | |
| + $el.html("<div id='" + defaults.playerContaine… | |
| + $.getScript(defaults.swfobjectPath,function(){ | |
| + swfobject.embedSWF(defaults.flashAudio… | |
| + }); | |
| + } else { | |
| + if(defaults.autoPlay){ | |
| + methods.play(defaults.autoPlay); | |
| + } | |
| + } | |
| + }, | |
| + | |
| + updateTrackState: function( evt ){ | |
| + $tgt = $(evt.target); | |
| + if(!$tgt.hasClass("audioButton")){ | |
| + return; | |
| + } | |
| + if(!audio || (audio && currentTrack !== _methods.getFi… | |
| + methods.play($tgt); | |
| + } else if(!isPlaying) { | |
| + methods.resume(); | |
| + } else { | |
| + methods.pause(); | |
| + } | |
| + }, | |
| + | |
| + addListeners: function(elem) { | |
| + $(elem).bind({"canplay" : _methods.onLoaded, | |
| + "error" : _methods.onError, | |
| + "ended" : _methods.onEnded}); | |
| + }, | |
| + | |
| + removeListeners: function(elem) { | |
| + $(elem).unbind({"canplay" : _methods.onLoaded, | |
| + "error" : _methods.onError, | |
| + "ended" : _methods.onEnded}); | |
| + }, | |
| + | |
| + onLoaded: function () { | |
| + $buttons.removeClass(defaults.loadingClass); | |
| + $tgt.addClass(defaults.playingClass); | |
| + | |
| + audio.play(); | |
| + }, | |
| + | |
| + onError: function () { | |
| + $buttons.removeClass(defaults.loadingClass); | |
| + if(isFlash){ | |
| + _methods.removeListeners(window); | |
| + } else { | |
| + _methods.removeListeners(audio); | |
| + } | |
| + }, | |
| + | |
| + onEnded: function () { | |
| + isPlaying = false; | |
| + $tgt.removeClass(defaults.playingClass); | |
| + currentTrack = ""; | |
| + if(isFlash){ | |
| + _methods.removeListeners(window); | |
| + } else { | |
| + _methods.removeListeners(audio); | |
| + } | |
| + | |
| + if(defaults.continuous){ | |
| + var $next = $tgt.next().length ? $tgt.next() :… | |
| + methods.play($next); | |
| + } | |
| + | |
| + }, | |
| + | |
| + canPlay: function(type) { | |
| + if(!document.createElement("audio").canPlayType){ | |
| + return false; | |
| + } else { | |
| + return document.createElement("audio").canPlay… | |
| + } | |
| + }, | |
| + | |
| + swfLoaded: function(){ | |
| + if(defaults.autoPlay){ | |
| + setTimeout(function(){methods.play(defaults.au… | |
| + } | |
| + }, | |
| + | |
| + getFileNameWithoutExtension: function(fileName){ | |
| + //this function take a full file name and returns an e… | |
| + //ex. entering foo.mp3 returns foo | |
| + //ex. entering foo returns foo (no change) | |
| + | |
| + var fileNamePieces = fileName.split('.'); | |
| + fileNamePieces.pop(); | |
| + return fileNamePieces.join("."); | |
| + } | |
| + }; | |
| + | |
| + $.fn.ubaPlayer = function(method){ | |
| + if(methods[method]){ | |
| + return methods[method].apply(this, Array.prototype.sli… | |
| + } else if ( typeof method === "object" || ! method ) { | |
| + return _methods.init.apply( this, arguments ); | |
| + } else { | |
| + $.error( "Method " + method + " does not exist on jqu… | |
| + } | |
| + }; | |
| + | |
| +})(jQuery); | |
| diff --git a/app/assets/javascripts/jquery.ubaplayer.min.js b/app/assets/javasc… | |
| @@ -0,0 +1,4 @@ | |
| +/*! UbaPlayer - v1.0.1 - 2012-06-06 | |
| +* https://github.com/brianhadaway/UbaPlayer | |
| +* Copyright (c) 2012 Brian Hadaway; Licensed MIT, GPL */ | |
| +(function(a){var b={audioButtonClass:"audioButton",autoPlay:null,codecs:[{name… | |
| +\ No newline at end of file | |
| diff --git a/app/assets/javascripts/swfobject.js b/app/assets/javascripts/swfob… | |
| @@ -0,0 +1,4 @@ | |
| +/* SWFObject v2.2 <http://code.google.com/p/swfobject/> | |
| + is released under the MIT License <http://www.opensource.org/licenses/… | |
| +*/ | |
| +var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="S… | |
| +\ No newline at end of file | |
| diff --git a/app/assets/stylesheets/bootstrap_and_overrides.css.less b/app/asse… | |
| @@ -38,9 +38,111 @@ body { | |
| @navbarBackground: #ea5709; | |
| @navbarBackgroundHighlight: #4A1C04; | |
| +.call-detail { | |
| + font-size: 10px; | |
| +} | |
| + | |
| + | |
| +// Start Ubaplayer | |
| +.audio-player { | |
| + list-style: none; | |
| + margin: 0; | |
| + padding: 0; | |
| +} | |
| + | |
| +#fallback { | |
| + display: none; | |
| +} | |
| + | |
| +.audioButton { | |
| + background: url("/assets/ubaplayer-btn.png") no-repeat 0 7px; | |
| + display: block; | |
| + cursor: pointer; | |
| + margin-left: 10px; | |
| + padding: 7px 10px 15px 25px; | |
| + color: @darkGray; | |
| + font-size: 18px; | |
| + font-weight: bold; | |
| +} | |
| + | |
| +.audioButton:hover { | |
| + background-position: 0 -33px; | |
| + color: @darkGray; | |
| + text-decoration: none; | |
| +} | |
| + | |
| +.audioButton.playing { | |
| + background-position: 0 -73px; | |
| + color: @darkGray; | |
| +} | |
| + | |
| +.audioButton.playing:hover { | |
| + background-position: 0 -113px; | |
| + color: @darkGray; | |
| +} | |
| + | |
| +.audioButton.loading, | |
| +.audioButton.loading:hover { | |
| + background: url("/assets/ubaplayer-loading.gif") no-repeat 0 7px; | |
| + text-indent: 0!important; | |
| +} | |
| + | |
| +#player { | |
| + display: none; | |
| +} | |
| + | |
| +// End of Ubaplayer | |
| + | |
| + | |
| +.fwd_match_span { | |
| + width: 100px; | |
| + padding-left: 20px; | |
| + padding-right: 20px; | |
| + padding-bottom: 5px; | |
| + padding-top: 5px; | |
| + font-weight: bold; | |
| + color: white; | |
| + text-align: center; | |
| +} | |
| + | |
| +.filter-label { | |
| + line-height: 16px; | |
| + font-size: 16px; | |
| + margin-right: 5px; | |
| + padding-top: 5px; | |
| + font-weight: bold; | |
| +} | |
| + | |
| +.filter-select { | |
| + line-height: 14px; | |
| + font-size: 14px; | |
| + width: 120px; | |
| + font-weight: bold; | |
| +} | |
| -.stooltip { | |
| +.popover-title { | |
| + line-height: 12px; | |
| + font-size: 12px; | |
| + text-align: center; | |
| + font-weight: bold; | |
| +} | |
| + | |
| +.popover-content { | |
| + | |
| +} | |
| + | |
| +.xtooltip { | |
| + border-bottom: 1px dotted @blue; | |
| + cursor: help; | |
| +} | |
| + | |
| +.xpopover { | |
| border-bottom: 1px dotted @blue; | |
| + cursor: help; | |
| +} | |
| + | |
| +.progress-bar { | |
| + margin-bottom: -2px; | |
| } | |
| .progress_pct { | |
| @@ -49,21 +151,20 @@ body { | |
| } | |
| .task_args_formatted { | |
| - width: 400px; | |
| - margin: 5px; | |
| + padding:10px; | |
| } | |
| .task_args_var { | |
| - font-size: 14px; | |
| + font-size: 12px; | |
| float: left; | |
| - width: 100px; | |
| - overflow: hidden; | |
| font-weight: bold; | |
| text-align: right; | |
| } | |
| .task_args_val { | |
| font-size: 14px; | |
| text-align: left; | |
| + padding-left: 5px; | |
| + float: auto; | |
| } | |
| .check-item { | |
| font-size: 18px; | |
| diff --git a/app/controllers/analyze_controller.rb b/app/controllers/analyze_co… | |
| @@ -53,7 +53,15 @@ class AnalyzeController < ApplicationController | |
| def view_matches | |
| @result = Call.find(params[:call_id]) | |
| @job_id = @result.job_id | |
| - @results = @result.matches.select{|x| x.matchscore.to_f > 10.0 } | |
| + @match_scopes = [ | |
| + { :scope => 'job', :label => 'This Job' }, | |
| + { :scope => 'project', :label => 'This Project' }, | |
| + { :scope => 'global', :label => 'All Projects' } | |
| + ] | |
| + | |
| + @match_scope = params[:match_scope] || "job" | |
| + | |
| + @results = @result.paginate_matches(@match_scope, 30.0, params[:page],… | |
| end | |
| def resource | |
| diff --git a/app/helpers/analyze_helper.rb b/app/helpers/analyze_helper.rb | |
| @@ -2,12 +2,12 @@ module AnalyzeHelper | |
| def fwd_match_html(pct) | |
| - %Q|<span class="fwd_match_span" style='padding-right: 150px; border: 1… | |
| - | |
| + %Q|<span class="badge fwd_match_span" style='background-color: #{pct_t… | |
| + | |
| #{"%.3f" % pct.to_f}% Match | |
| - | |
| + | |
| </span> | |
| - | |
| + | |
| | | |
| end | |
| @@ -16,7 +16,7 @@ def rev_match_html(pct) | |
| end | |
| def pct_to_color(pct) | |
| - "#" + "80" + (pct.to_i * 2.55).to_i.to_s(16).rjust(2, "0") + "80" | |
| + "#" + "20" + (pct.to_i * 2.00).to_i.to_s(16).rjust(2, "0") + "20" | |
| end | |
| end | |
| diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper… | |
| @@ -3,11 +3,11 @@ module ApplicationHelper | |
| def select_tag_for_filter(nvpairs, params) | |
| _url = ( url_for :overwrite_params => { }).split('?')[0] | |
| - _html = %{<label for="show">Filter: </label> } | |
| - _html << %{<select name="show" id="show" } | |
| + _html = %{<span class="pull-left filter-label">Filter: </span> } | |
| + _html << %{<select name="show" class="filter-select" } | |
| _html << %{onchange="window.location='#{_url}' + '?show=' + this.val… | |
| nvpairs.each do |pair| | |
| - _html << %{<option value="#{pair[:scope]}" } | |
| + _html << %{<option value="#{h(pair[:scope])}" } | |
| if params[:show] == pair[:scope] || ((params[:show].nil? || params… | |
| _html << %{ selected="selected" } | |
| end | |
| @@ -18,6 +18,23 @@ module ApplicationHelper | |
| raw(_html) | |
| end | |
| + def select_match_scope(nvpairs, params) | |
| + _url = ( url_for :overwrite_params => { }).split('?')[0] | |
| + _html = %{<span class="pull-left filter-label">Matching Scope: </spa… | |
| + _html << %{<select name="match_scope" class="filter-select" } | |
| + _html << %{onchange="window.location='#{_url}' + '?match_scope=' + t… | |
| + nvpairs.each do |pair| | |
| + _html << %{<option value="#{h(pair[:scope])}" } | |
| + if params[:match_scope] == pair[:scope] || ((params[:match_scope].… | |
| + _html << %{ selected="selected" } | |
| + end | |
| + _html << %{>#{pair[:label]} } | |
| + _html << %{</option>} | |
| + end | |
| + _html << %{</select>} | |
| + raw(_html) | |
| + end | |
| + | |
| def set_focus(element_id) | |
| javascript_tag(" $elem = $(\"#{element_id}\"); if (null !== $e… | |
| end | |
| @@ -28,22 +45,49 @@ module ApplicationHelper | |
| ttip = raw("<div class='task_args_formatted'>") | |
| info.each_pair do |k,v| | |
| - ttip << raw("<div class='task_args_var'>") + h… | |
| - ttip << raw("<div class='task_args_val'>") + h… | |
| + ttip << raw("<div class='task_args_var'>") + h… | |
| + ttip << raw("<div class='task_args_val'>") + h… | |
| end | |
| ttip << raw("</div>\n") | |
| - outp = raw("<span rel='tooltip' title=\"#{ttip}\" data… | |
| + outp = raw("<span class='xpopover' rel='popover' data-… | |
| outp | |
| rescue ::Exception => e | |
| job.status.to_s.capitalize | |
| end | |
| end | |
| + def format_call_type_details(call) | |
| + ttip = raw("<div class='task_args_formatted'>") | |
| + | |
| + | |
| + ttip << raw("<div class='task_args_var'>Call Time:</di… | |
| + ttip << raw("<div class='task_args_val'>") + h(call.cr… | |
| + | |
| + ttip << raw("<div class='task_args_var'>CallerID:</div… | |
| + ttip << raw("<div class='task_args_val'>") + h(call.ca… | |
| + | |
| + ttip << raw("<div class='task_args_var'>Provider:</div… | |
| + ttip << raw("<div class='task_args_val'>") + h(call.pr… | |
| + | |
| + | |
| + ttip << raw("<div class='task_args_var'>Audio:</div> ") | |
| + ttip << raw("<div class='task_args_val'>") + h(call.au… | |
| + | |
| + | |
| + ttip << raw("<div class='task_args_var'>Ring:</div> ") | |
| + ttip << raw("<div class='task_args_val'>") + h(call.ri… | |
| + | |
| + ttip << raw("</div>\n") | |
| + outp = raw("<span class='xpopover' rel='popover' data-… | |
| + outp | |
| + end | |
| + | |
| + | |
| def format_job_status(job) | |
| case job.status | |
| when 'error' | |
| ttip = h(job.error.to_s) | |
| - outp = raw("<span rel='tooltip' title=\"#{ttip}\" data… | |
| + outp = raw("<span class='xpopover' rel='popover' data-… | |
| outp | |
| else | |
| job.status.to_s.capitalize | |
| diff --git a/app/models/call.rb b/app/models/call.rb | |
| @@ -26,6 +26,29 @@ class Call < ActiveRecord::Base | |
| } | |
| + def paginate_matches(scope, min_match, page, per_page) | |
| + | |
| + scope_limit = "" | |
| + case scope | |
| + when 'job' | |
| + scope_limit = "calls.job_id = \'#{job_id}\' AND " | |
| + when 'project' | |
| + scope_limit = "calls.project_id = \'#{project_id}\' AN… | |
| + end | |
| + | |
| + query = | |
| + 'SELECT calls.*, ' + | |
| + " (( icount(\'{#{fprint.map{|x| x.to_s}.join(",… | |
| + 'FROM calls ' + | |
| + 'WHERE icount(calls.fprint) > 0 AND ' + | |
| + scope_limit + | |
| + "calls.id != \'#{id}\' " + | |
| + "AND (( icount(\'{#{fprint.map{|x| x.to_s}.join(",")}}… | |
| + 'ORDER BY matchscore DESC' | |
| + | |
| + Call.paginate_by_sql(query, :page => page, :per_page => per_pa… | |
| + end | |
| + | |
| def media | |
| CallMedium.find_or_create_by_call_id_and_project_id(self[:id],… | |
| end | |
| diff --git a/app/views/analyze/view.html.erb b/app/views/analyze/view.html.erb | |
| @@ -1,7 +1,5 @@ | |
| <h1 class='title'>Analysis of Job ID <%= @job_id %></h1> | |
| -<%= select_tag_for_filter(@filters, params) %> | |
| - | |
| <table width='100%' align='center' border=0 cellspacing=0 cellpadding=6> | |
| <tr> | |
| <td align='center'> | |
| @@ -12,42 +10,35 @@ | |
| <%= will_paginate @results, :renderer => BootstrapPagination::Rails %> | |
| -<table class='table table-striped table-bordered' width='90%'> | |
| +<div class='pull-right'> | |
| + <%= select_tag_for_filter(@filters, params) %> | |
| +</div> | |
| + | |
| +<table class='table table-striped table-condensed'> | |
| <thead> | |
| <tr> | |
| <th>Number</th> | |
| + <th>Type</th> | |
| <th>Signal</th> | |
| + <th>Actions</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| - | |
| <% @results.each do |call| %> | |
| <tr> | |
| <td align='center'> | |
| - | |
| - <object | |
| - type="application/x-shockwave-flash" | |
| - data="/assets/musicplayer.swf?song_url=<%=resource_ana… | |
| - width="20" | |
| - height="17" | |
| - style="margin-bottom: -5px;" | |
| - > | |
| - <param name="movie" value="/assets/musicplayer.swf?son… | |
| - <param name="wmode" value="transparent"></param> | |
| - </object> | |
| - <b><%= call.number %></b> | |
| - <hr width='100%' size='1'/> | |
| - CallerID: <%= call.caller_id%><br/> | |
| - Provider: <%=h call.provider.name %><br/> | |
| - Audio: <%=h call.audio_length %> Seconds<br/> | |
| - Ringer: <%=h call.ring_length %> Seconds<br/> | |
| + <%= render :partial => 'shared/call_info', :locals => { :call … | |
| + </td> | |
| + <td align='center'> | |
| + <%= format_call_type_details(call) %> | |
| </td> | |
| <td align='center'> | |
| - <b><%=h call.line_type.upcase %></b><br/> | |
| - <%= render :partial => 'shared/lightbox_sig', :locals => { :ca… | |
| + <span class='pull-left'><%= render :partial => 'shared/lightbo… | |
| <%= render :partial => 'shared/lightbox_freq', :locals => { :c… | |
| + </td> | |
| + <td> | |
| <% if call.fprint and call.fprint.length > 0 %> | |
| - <a href="<%=view_matches_path(@project, call.job_id, c… | |
| + <a class="btn btn-mini" href="<%= view_matches_path(@p… | |
| <% end %> | |
| </td> | |
| </tr> | |
| diff --git a/app/views/analyze/view_matches.html.erb b/app/views/analyze/view_m… | |
| @@ -1,86 +1,96 @@ | |
| <% call = @result %> | |
| <h1 class='title'><%= @result.number %> (<a href="<%=view_analyze_path(@projec… | |
| -<table class='table table-striped table-bordered' width='90%'> | |
| +<table class='table table-striped table-condensed'> | |
| + <thead> | |
| <tr> | |
| <th>Number</th> | |
| + <th>Type</th> | |
| <th>Signal</th> | |
| </tr> | |
| - | |
| + </thead> | |
| + <tbody> | |
| <tr> | |
| <td align='center'> | |
| - | |
| - <object | |
| - type="application/x-shockwave-flash" | |
| - data="/assets/musicplayer.swf?song_url=<%=resource_ana… | |
| - width="20" | |
| - height="17" | |
| - style="margin-bottom: -5px;" | |
| - > | |
| - <param name="movie" value="/assets/musicplayer.swf?son… | |
| - <param name="wmode" value="transparent"></param> | |
| - </object> | |
| - | |
| - <b><%= call.number %></b> | |
| - <hr width='100%' size='1'/> | |
| - CallerID: <%= call.caller_id%><br/> | |
| - Provider: <%= call.provider.name %><br/> | |
| - Audio: <%= call.audio_length %> Seconds<br/> | |
| - Ringer: <%= call.ring_length %> Seconds<br/> | |
| + <%= render :partial => 'shared/call_info', :locals => { :call … | |
| + </td> | |
| + <td align='center'> | |
| + <%= format_call_type_details(call) %> | |
| </td> | |
| <td align='center'> | |
| - <b><%=h call.line_type.upcase %></b><br/> | |
| - <%= render :partial => 'shared/lightbox_sig', :locals => { :ca… | |
| + <span class='pull-left'><%= render :partial => 'shared/lightbo… | |
| <%= render :partial => 'shared/lightbox_freq', :locals => { :c… | |
| </td> | |
| </tr> | |
| - | |
| + </tbody> | |
| </table><br/><br/> | |
| -<h1 class='title'>Matches for <%= @result.number %></h1> | |
| +<% if @results.length > 0 %> | |
| + | |
| -<table class='table table-striped table-bordered' width='90%'> | |
| + | |
| +<h1 class='title'><%= pluralize(@results.total_entries, 'Possible Match') %> f… | |
| + | |
| + | |
| +<div class='pull-right'> | |
| + <%= select_match_scope(@match_scopes, params) %> | |
| +</div> | |
| + | |
| +<%= will_paginate @results, :renderer => BootstrapPagination::Rails %> | |
| + | |
| +<table class='table table-striped table-condensed'> | |
| <thead> | |
| <tr> | |
| + <th>Score</th> | |
| <th>Number</th> | |
| +<% case @match_scope %> | |
| +<% when 'project' %> | |
| + <th>Job</th> | |
| +<% when 'global' %> | |
| + <th>Project</th> | |
| +<% end %> | |
| + <th>Type</th> | |
| <th>Signal</th> | |
| + <th>Actions</th> | |
| </tr> | |
| </thead> | |
| <tbody> | |
| - | |
| <% @results.each do |call| %> | |
| <tr> | |
| <td align='center'> | |
| - | |
| - <br/><%= raw(fwd_match_html(call.matchscore)) %><br/><br/> | |
| - | |
| - <object | |
| - type="application/x-shockwave-flash" | |
| - data="/assets/musicplayer.swf?song_url=<%=resource_ana… | |
| - width="20" | |
| - height="17" | |
| - style="margin-bottom: -5px;" | |
| - > | |
| - <param name="movie" value="/assets/musicplayer.swf?son… | |
| - <param name="wmode" value="transparent"></param> | |
| - </object> | |
| - | |
| - <b><%= call.number %></b> | |
| - <hr width='100%' size='1'/> | |
| - CallerID: <%= call.caller_id%><br/> | |
| - Provider: <%=h call.provider.name %><br/> | |
| - Audio: <%=h call.audio_length %> Seconds<br/> | |
| - Ringer: <%=h call.ring_length %> Seconds<br/> | |
| + <%= raw(fwd_match_html(call.matchscore)) %> | |
| + </td> | |
| + <td align='center'> | |
| + <%= render :partial => 'shared/call_info', :locals => { :call … | |
| + </td> | |
| +<% case @match_scope %> | |
| +<% when 'project' %> | |
| + <td align='center'><%= call.job.id %></td> | |
| +<% when 'global' %> | |
| + <td align='center'><%= link_to h(call.project.name), project_path(call.pro… | |
| +<% end %> | |
| + <td align='center'> | |
| + <%= format_call_type_details(call) %> | |
| </td> | |
| <td align='center'> | |
| - <b><%=h call.line_type.upcase %></b><br/> | |
| - <%= render :partial => 'shared/lightbox_sig', :locals => { :ca… | |
| + <span class='pull-left'><%= render :partial => 'shared/lightbo… | |
| <%= render :partial => 'shared/lightbox_freq', :locals => { :c… | |
| - <% if call.fprint %> | |
| - <a href="<%=view_matches_path(call.project_id, call.jo… | |
| + </td> | |
| + <td> | |
| + <% if call.fprint and call.fprint.length > 0 %> | |
| + <a class="btn btn-mini" href="<%= view_matches_path(@p… | |
| <% end %> | |
| </td> | |
| </tr> | |
| <% end %> | |
| </tbody> | |
| </table> | |
| + | |
| +<%= will_paginate @results, :renderer => BootstrapPagination::Rails %> | |
| + | |
| + | |
| +<% else %> | |
| + | |
| +<h1 class='title'>No Matches for <%= @result.number %> (<%= @result.created_at… | |
| + | |
| +<% end %> | |
| diff --git a/app/views/calls/index.html.erb b/app/views/calls/index.html.erb | |
| @@ -2,7 +2,7 @@ | |
| <h1 class='title'>Completed Jobs</h1> | |
| <%= will_paginate @jobs, :renderer => BootstrapPagination::Rails %> | |
| -<table class='table table-striped table-bordered' width='90%'> | |
| +<table class='table table-striped table-condensed' width='90%'> | |
| <thead> | |
| <tr> | |
| <th>ID</th> | |
| diff --git a/app/views/home/about.html.erb b/app/views/home/about.html.erb | |
| @@ -72,7 +72,7 @@ and research purposes only. The latest version of WarVOX can … | |
| <h1 class='title'>Configuration</h1> | |
| -<table width='100%' class='table table-bordered'> | |
| +<table width='100%' class='table table-condensed'> | |
| <tr> | |
| <td> | |
| diff --git a/app/views/jobs/index.html.erb b/app/views/jobs/index.html.erb | |
| @@ -7,7 +7,7 @@ | |
| <th>ID</th> | |
| <th>Task</th> | |
| <th>Status</th> | |
| - <th>Submitted Time</th> | |
| + <th>Launched</th> | |
| <th>Actions</th> | |
| </tr> | |
| @@ -36,7 +36,7 @@ | |
| <th>ID</th> | |
| <th>Task</th> | |
| <th>Progress</th> | |
| - <th>Submitted Time</th> | |
| + <th>Launched</th> | |
| <th>Actions</th> | |
| </tr> | |
| @@ -44,8 +44,8 @@ | |
| <tr class='active_job_row'> | |
| <td><%= job.id %></td> | |
| <td><%= format_job_details(job) %></td> | |
| - <td valign='center'> | |
| - <div class="progress progress-success progress-striped"> | |
| + <td> | |
| + <div class="progress progress-success progress-striped progres… | |
| <div class="bar" style="width: <%= job.progress %>%"> | |
| <span class='progress_pct'><%= job.progress %>… | |
| </div> | |
| @@ -53,6 +53,12 @@ | |
| </td> | |
| <td><%= job.created_at.localtime.strftime("%Y-%m-%d %H:%M:%S %Z") %></td> | |
| <td> | |
| + <% if job.task == "dialer" %> | |
| + <a class="btn btn-mini" href="<%= view_results_path(job.pr… | |
| + <% end %> | |
| + <% if job.task == "analysis" %> | |
| + <a class="btn btn-mini" href="<%= view_analyze_path(job.pr… | |
| + <% end %> | |
| <a class="btn btn-mini" href="<%= stop_job_path(job) %>" data-… | |
| </td> | |
| </tr> | |
| @@ -72,7 +78,7 @@ | |
| <br/><br/> | |
| <h1 class='title'>Inactive Jobs</h1> | |
| -<%= raw(will_paginate @inactive_jobs) %> | |
| +<%= will_paginate @inactive_jobs, :renderer => BootstrapPagination::Rails %> | |
| <table class='table table-striped table-condensed' width='90%'> | |
| <tr> | |
| <th>ID</th> | |
| @@ -83,8 +89,16 @@ | |
| <th>Project</th> | |
| </tr> | |
| -<% @inactive_jobs.each do |job| %> | |
| - <tr class='active_job_row'> | |
| +<% @inactive_jobs.each do |job| | |
| + special = "" | |
| + case job.status | |
| + when "error" | |
| + special = "error" | |
| + when "stopped" | |
| + special = "warning" | |
| + end | |
| +%> | |
| + <tr class='<%= special %>'> | |
| <td><%= job.id %></td> | |
| <td><%= format_job_details(job) %></td> | |
| <td><%= format_job_status(job) %></td> | |
| @@ -94,7 +108,7 @@ | |
| </tr> | |
| <% end %> | |
| </table> | |
| -<%= raw(will_paginate @inactive_jobs) %> | |
| +<%= will_paginate @inactive_jobs, :renderer => BootstrapPagination::Rails %> | |
| <br /> | |
| <script language="javascript"> | |
| diff --git a/app/views/jobs/results.html.erb b/app/views/jobs/results.html.erb | |
| @@ -36,17 +36,17 @@ | |
| <td><%= format_job_details(job) %></td> | |
| <td> | |
| <% if job.task == "dialer" %> | |
| - <%= job.details[:range].to_s %> / | |
| + <%= truncate(job.details[:range].to_s, :length => 15) … | |
| <%= job.details[:cid_mask].to_s %> | |
| <% end %> | |
| - <span rel="tooltip" class="stooltip" title="<%= job.detail… | |
| + <span rel="tooltip" class="xtooltip" title="<%= job.detail… | |
| <%= truncate(job.details[:directory].to_s, :length => … | |
| <% if job.task == "importer" %> | |
| <% end %> | |
| </td> | |
| - <td><span rel="tooltip" class="stooltip" title="<%= pct_answered %>% answe… | |
| - <td><span rel="tooltip" class="stooltip" title="<%= pct_analyzed %>% analy… | |
| + <td><span rel="tooltip" class="xtooltip" title="<%= pct_answered %>% answe… | |
| + <td><span rel="tooltip" class="xtooltip" title="<%= pct_analyzed %>% analy… | |
| <td><%= job.created_at.strftime("%Y-%m-%d %H:%M:%S") %></td> | |
| @@ -62,7 +62,9 @@ | |
| <a class="btn btn-mini" href="<%= analyze_job_… | |
| <% end %> | |
| <% else %> | |
| + <% if cnt_answered > 0 %> | |
| <a class="btn btn-mini" href="<%= analyze_job_path(@pr… | |
| + <% end %> | |
| <% end %> | |
| <a class="btn btn-mini" href="<%= job_path(job) %>" data-confirm="… | |
| diff --git a/app/views/jobs/show.html.erb b/app/views/jobs/show.html.erb | |
| @@ -1,39 +0,0 @@ | |
| -<h1 class='title'>Show Job</h1> | |
| -<p> | |
| - <b>Range:</b> | |
| - <%=h @job.range %> | |
| -</p> | |
| - | |
| -<p> | |
| - <b>Seconds:</b> | |
| - <%=h @job.seconds %> | |
| -</p> | |
| - | |
| -<p> | |
| - <b>Lines:</b> | |
| - <%=h @job.lines %> | |
| -</p> | |
| - | |
| -<p> | |
| - <b>Status:</b> | |
| - <%=h @job.status %> | |
| -</p> | |
| - | |
| -<p> | |
| - <b>Progress:</b> | |
| - <%=h @job.progress %> | |
| -</p> | |
| - | |
| -<p> | |
| - <b>Started at:</b> | |
| - <%=h @job.started_at %> | |
| -</p> | |
| - | |
| -<p> | |
| - <b>Completed at:</b> | |
| - <%=h @job.completed_at %> | |
| -</p> | |
| - | |
| - | |
| -<%= link_to 'Edit', edit_job_path(@job) %> | | |
| -<%= link_to 'Back', jobs_path %> | |
| diff --git a/app/views/jobs/view_results.html.erb b/app/views/jobs/view_results… | |
| @@ -16,13 +16,13 @@ | |
| <%= will_paginate @results, :renderer => BootstrapPagination::Rails %> | |
| -<table class='table table-striped table-bordered' width='90%' id='results'> | |
| +<table class='table table-striped table-condensed' width='90%' id='results'> | |
| <thead> | |
| <tr> | |
| <th>Number</th> | |
| <th>CallerID</th> | |
| <th>Provider</th> | |
| - <th>Completed</th> | |
| + <th>Answered</th> | |
| <th>Busy</th> | |
| <th>Seconds</th> | |
| <th>Ring Time</th> | |
| diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/applica… | |
| @@ -22,8 +22,26 @@ | |
| <%= javascript_tag do %> | |
| $(document).ready(function() { | |
| - $("a").tooltip(); | |
| - $("span").tooltip(); | |
| + | |
| + $(".xtooltip").tooltip(); | |
| + | |
| + $(".xpopover").popover({ | |
| + html: true, | |
| + placement: 'right', | |
| + trigger: 'hover', | |
| + delay: { show: 300, hide: 300 }, | |
| + animation: false, | |
| + }); | |
| + | |
| + var ap = $("#audio_player"); | |
| + if (ap && null != ap) { | |
| + $("#ubaPlayer").ubaPlayer({ | |
| + codecs: [{name:"MP3", codec: 'audio/mp… | |
| + flashAudioPlayerPath: "/assets/player.… | |
| + swfobjectPath: "/assets/swfobject.js", | |
| + playerContainer: "audio_player" | |
| + }); | |
| + } | |
| }); | |
| <% end %> | |
| </head> | |
| @@ -85,6 +103,8 @@ | |
| <p>WarVOX v<%=WarVOX::VERSION %> © Rapid7, Inc. 2009-20… | |
| </footer> | |
| + <div id="audio_player"></div> | |
| + | |
| </div> | |
| </div> | |
| </div> <!-- /container --> | |
| diff --git a/app/views/providers/index.html.erb b/app/views/providers/index.htm… | |
| @@ -2,7 +2,7 @@ | |
| <h1 class='title'>VoIP Providers (IAX)</h1> | |
| <%= will_paginate @providers, :renderer => BootstrapPagination::Rails %> | |
| -<table class='table table-striped table-bordered' width='90%'> | |
| +<table class='table table-striped table-condensed' width='90%'> | |
| <tr> | |
| <th>Active</th> | |
| <th>Provider Name</th> | |
| diff --git a/app/views/shared/_audio_player.html.erb b/app/views/shared/_audio_… | |
| @@ -0,0 +1 @@ | |
| +<ul class="controls audio-player"><li><a class="audioButton" href="<%=resource… | |
| diff --git a/app/views/shared/_call_info.html.erb b/app/views/shared/_call_info… | |
| @@ -0,0 +1 @@ | |
| +<%= render :partial => 'shared/audio_player', :locals => { :call => call } %> | |
| diff --git a/app/views/shared/graphs/_call_results.html.erb b/app/views/shared/… | |
| @@ -58,5 +58,3 @@ line_data << raw("{ name: 'Answered', data: [ #{@call_results… | |
| <% end %> | |
| - | |
| -</div> | |
| diff --git a/app/views/shared/graphs/_lines_by_type.html.erb b/app/views/shared… | |
| @@ -58,5 +58,3 @@ end | |
| <% end %> | |
| - | |
| -</div> | |
| diff --git a/config/routes.rb b/config/routes.rb | |
| @@ -20,14 +20,11 @@ Web::Application.routes.draw do | |
| match '/projects/:project_id/results' => 'jobs#results', :as => :r… | |
| match '/projects/:project_id/results/:id' => 'jobs#view_results', :as … | |
| - match '/projects/:project_id/results/:id/analyze' => 'jobs#analyze_job', :… | |
| + match '/projects/:project_id/results/:id/analyze' => 'jobs#analyze_job',… | |
| match '/projects/:project_id/results/:id/reanalyze' => 'jobs#reanalyze_job… | |
| - | |
| - | |
| - | |
| match '/projects/:project_id/analyze' => 'analyze#index', :as =>… | |
| - match '/calls/:result_id/:type' => 'analyze#resource', :as… | |
| + match '/call/:result_id.:type' => 'analyze#resource', :as … | |
| match '/projects/:project_id/analyze/:id/view' => 'analyze#view', :as => … | |
| match '/projects/:project_id/analyze/:job_id/:call_id/matches' => 'analyz… | |
| @@ -43,6 +40,5 @@ Web::Application.routes.draw do | |
| match '/help' => 'home#help', :as => :help | |
| match '/check' => 'home#check', :as => :check | |
| - | |
| root :to => "projects#index" | |
| end | |
| diff --git a/lib/warvox/jobs/analysis.rb b/lib/warvox/jobs/analysis.rb | |
| @@ -329,20 +329,29 @@ class Analysis < Base | |
| plotter.puts("set output \"#{png_big_freq.path}\"") | |
| plotter.puts("plot \"#{frefile.path}\" using 1:2 title \"#{num… | |
| - plotter.puts("set ylabel \"Signal\"") | |
| - plotter.puts("set xlabel \"Seconds\"") | |
| - plotter.puts("set terminal png small size 160,120 transparent") | |
| + | |
| + plotter.puts("unset border") | |
| + plotter.puts("unset xtics") | |
| + plotter.puts("unset ytics") | |
| + plotter.puts("set ylabel \"\"") | |
| + plotter.puts("set xlabel \"\"") | |
| + plotter.puts("set terminal png small size 80,60 transparent") | |
| plotter.puts("set format x ''") | |
| plotter.puts("set format y ''") | |
| plotter.puts("set output \"#{png_sig.path}\"") | |
| + plotter.puts("set style line 1 lt 1 lw 3 pt 3 linecolor rgb \"… | |
| plotter.puts("plot \"#{datfile.path}\" using 1:2 notitle with … | |
| - plotter.puts("set ylabel \"Power\"") | |
| - plotter.puts("set xlabel \"Frequency\"") | |
| - plotter.puts("set terminal png small size 160,120 transparent") | |
| + plotter.puts("unset border") | |
| + plotter.puts("unset xtics") | |
| + plotter.puts("unset ytics") | |
| + plotter.puts("set ylabel \"\"") | |
| + plotter.puts("set xlabel \"\"") | |
| + plotter.puts("set terminal png small size 80,60 transparent") | |
| plotter.puts("set format x ''") | |
| plotter.puts("set format y ''") | |
| plotter.puts("set output \"#{png_sig_freq.path}\"") | |
| + plotter.puts("set style line 1 lt 1 lw 3 pt 3 linecolor rgb \"… | |
| plotter.puts("plot \"#{frefile.path}\" using 1:2 notitle with … | |
| plotter.flush | |
| diff --git a/public/crossdomain.xml b/public/crossdomain.xml | |
| @@ -0,0 +1,5 @@ | |
| +<?xml version="1.0"?> | |
| +<!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross… | |
| +<cross-domain-policy> | |
| + <allow-access-from domain="*" /> | |
| +</cross-domain-policy> |