Introduction
Introduction Statistics Contact Development Disclaimer Help
Swap lightbox, working results pages - warvox - VoIP based wardialing tool, for…
Log
Files
Refs
README
---
commit 9974997874fab6f83540def599d2031acacbf5f1
parent 70379df629033bdd61080eba61894c2e9b745c62
Author: HD Moore <[email protected]>
Date: Wed, 2 Jan 2013 02:49:15 -0600
Swap lightbox, working results pages
Diffstat:
M app/assets/javascripts/application… | 2 +-
A app/assets/javascripts/bootstrap-l… | 354 +++++++++++++++++++++++++++…
D app/assets/javascripts/jquery.ligh… | 472 ---------------------------…
M app/assets/stylesheets/application… | 1 +
A app/assets/stylesheets/bootstrap-l… | 65 +++++++++++++++++++++++++++…
M app/controllers/analyze_controller… | 4 ++--
M app/controllers/calls_controller.rb | 59 +----------------------------…
M app/controllers/jobs_controller.rb | 98 ++++++++++++++++++-----------…
M app/models/job.rb | 59 +++++++++++++++++++++++------…
M app/views/analyze/view.html.erb | 33 ++++++++++-------------------…
M app/views/calls/index.html.erb | 22 +++++++++++-----------
M app/views/jobs/index.html.erb | 2 +-
A app/views/jobs/results.html.erb | 64 +++++++++++++++++++++++++++++…
M app/views/layouts/application.html… | 3 ++-
A app/views/shared/_lightbox_freq.ht… | 13 +++++++++++++
A app/views/shared/_lightbox_sig.htm… | 13 +++++++++++++
A app/views/shared/lightbox_sig.html… | 17 +++++++++++++++++
M bin/analyze_result.rb | 10 +++++++---
M config/routes.rb | 18 +++++++++---------
M lib/warvox/jobs/analysis.rb | 50 +++++++++++++++++++----------…
M lib/warvox/jobs/base.rb | 4 ++++
21 files changed, 708 insertions(+), 655 deletions(-)
---
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/app…
@@ -3,7 +3,7 @@
//= require jquery
//= require jquery_ujs
//= require twitter/bootstrap
-//= require jquery.lightbox-0.5
+//= require bootstrap-lightbox
//= require dataTables/jquery.dataTables
//= require dataTables/jquery.dataTables.bootstrap
//= require highcharts
diff --git a/app/assets/javascripts/bootstrap-lightbox.js b/app/assets/javascri…
@@ -0,0 +1,353 @@
+/*!=========================================================
+* bootstrap-lightbox v0.4.1 - 11/20/2012
+* http://jbutz.github.com/bootstrap-lightbox/
+* HEAVILY based off bootstrap-modal.js
+* ==========================================================
+* Copyright (c) 2012 Jason Butz (http://jasonbutz.info)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+* ========================================================= */
+
+
+!function ($) {
+ // browser:true, jquery:true, node:true, laxbreak:true
+ "use strict"; // jshint ;_;
+
+
+/* LIGHTBOX CLASS DEFINITION
+ * ========================= */
+
+ var Lightbox = function (element, options)
+ {
+ this.options = options;
+ this.$element = $(element)
+ .delegate('[data-dismiss="lightbox"]', 'click.dismiss.…
+
+ this.options.remote && this.$element.find('.lightbox-body').lo…
+
+ this.cloneSize();
+ }
+
+ Lightbox.prototype = {
+ constructor: Lightbox,
+
+ toggle: function ()
+ {
+ return this[!this.isShown ? 'show' : 'hide']();
+ },
+
+ show: function ()
+ {
+ var that = this;
+ var e = $.Event('show')
+
+ this.$element.trigger(e);
+
+ if (this.isShown || e.isDefaultPrevented()) return;
+
+
+ this.isShown = true;
+
+ this.escape();
+
+ this.backdrop(function ()
+ {
+ var transition = $.support.transition && that.…
+
+ if (!that.$element.parent().length)
+ {
+ that.$element.appendTo(document.body);…
+ }
+
+ that.$element
+ .show();
+
+ if (transition)
+ {
+ that.$element[0].offsetWidth; // force…
+ }
+
+ that.$element
+ .addClass('in')
+ .attr('aria-hidden', false);
+
+ that.enforceFocus();
+
+ transition ?
+ that.$element.one($.support.transition…
+ (function(){ that.centerImage(); that.…
+
+ });
+ },
+ hide: function (e)
+ {
+ e && e.preventDefault();
+
+ var that = this;
+
+ e = $.Event('hide');
+
+ this.$element.trigger(e);
+
+ if (!this.isShown || e.isDefaultPrevented()) return;
+
+ this.isShown = false;
+
+ this.escape();
+
+ $(document).off('focusin.lightbox');
+
+ this.$element
+ .removeClass('in')
+ .attr('aria-hidden', true);
+
+ $.support.transition && this.$element.hasClass('fade')…
+ this.hideWithTransition() :
+ this.hideLightbox();
+ },
+ enforceFocus: function ()
+ {
+ var that = this;
+ $(document).on('focusin.lightbox', function (e)
+ {
+ if (that.$element[0] !== e.target && !that.$el…
+ {
+ that.$element.focus();
+ }
+ });
+ },
+ escape: function ()
+ {
+ var that = this;
+ if (this.isShown && this.options.keyboard)
+ {
+ this.$element.on('keyup.dismiss.lightbox', fun…
+ {
+ e.which == 27 && that.hide();
+ });
+ }
+ else if (!this.isShown)
+ {
+ this.$element.off('keyup.dismiss.lightbox');
+ }
+ },
+ hideWithTransition: function ()
+ {
+ var that = this;
+ var timeout = setTimeout(function ()
+ {
+ that.$element.off($.support.transition.end);
+ that.hideLightbox();
+ }, 500);
+
+ this.$element.one($.support.transition.end, function ()
+ {
+ clearTimeout(timeout);
+ that.hideLightbox();
+ });
+ },
+ hideLightbox: function (that)
+ {
+ this.$element
+ .hide()
+ .trigger('hidden');
+
+ this.backdrop();
+ },
+ removeBackdrop: function ()
+ {
+ this.$backdrop.remove();
+ this.$backdrop = null;
+ },
+ backdrop: function (callback)
+ {
+ var that = this;
+ var animate = this.$element.hasClass('fade') ? 'fade' …
+
+ if (this.isShown && this.options.backdrop)
+ {
+ var doAnimate = $.support.transition && animat…
+
+ this.$backdrop = $('<div class="modal-backdrop…
+ .appendTo(document.body);
+
+ this.$backdrop.click(
+ this.options.backdrop == 'static' ?
+ $.proxy(this.$element[0].focus…
+ $.proxy(this.hide, this)
+ );
+
+ if (doAnimate) this.$backdrop[0].offsetWidth; …
+
+ this.$backdrop.addClass('in');
+
+ doAnimate ?
+ this.$backdrop.one($.support.transitio…
+ callback();
+
+ }
+ else if (!this.isShown && this.$backdrop)
+ {
+ this.$backdrop.removeClass('in');
+
+ $.support.transition && this.$element.hasClass…
+ this.$backdrop.one($.support.transitio…
+ this.removeBackdrop();
+
+ }
+ else if (callback)
+ {
+ callback();
+ }
+ },
+ centerImage: function()
+ {
+ var that = this;
+ var resizedOffs = 0;
+ var $img;
+
+ that.h = that.$element.height();
+ that.w = that.$element.width();
+
+ if(that.options.resizeToFit)
+ {
+
+ resizedOffs = 10;
+ $img = that.$element.find('.lightbox-content')…
+ // Save original filesize
+ if(!$img.data('osizew')) $img.data('osizew', $…
+ if(!$img.data('osizeh')) $img.data('osizeh', $…
+
+ var osizew = $img.data('osizew');
+ var osizeh = $img.data('osizeh');
+
+ // Resize for window dimension < than image
+ // Reset previous
+ $img.css('max-width', 'none');
+ $img.css('max-height', 'none');
+
+
+ var sOffs = 40; // STYLE ?
+ if(that.$element.find('.lightbox-header').leng…
+ $img.css('max-width', $(window).width() - sOff…
+ $img.css('max-height', $(window).height() - sO…
+
+ that.w = $img.width();
+ that.h = $img.height();
+ }
+
+ that.$element.css({
+ "position": "fixed",
+ "left": ( $(window).width() / 2 ) - ( that.w …
+ "top": ( $(window).height() / 2 ) - ( that.h …
+ });
+ that.enforceFocus();
+ },
+ cloneSize: function() // The cloneSize function is only run on…
+ {
+ var that = this;
+ // Clone the element and append it to the body
+ // this allows us to get an idea for the size of the …
+ that.$clone = that.$element.filter(':first').clone()
+ .css(
+ {
+ 'position': 'absolute',
+ 'top' : -2000,
+ 'display' : 'block',
+ 'visibility': 'visible',
+ 'opacity': 100
+ })
+ .removeClass('fade')
+ .appendTo('body');
+
+ that.h = that.$clone.height();
+ that.w = that.$clone.width();
+ that.$clone.remove();
+
+ // try and center the element based on the
+ // height and width retrieved from the clone
+ that.$element.css({
+ "position": "fixed",
+ "left": ( $(window).width() / 2 ) - ( that.w …
+ "top": ( $(window).height() / 2 ) - ( that.h …
+ });
+ }
+ }
+
+
+/* LIGHTBOX PLUGIN DEFINITION
+ * ======================= */
+
+ $.fn.lightbox = function (option)
+ {
+ return this.each(function ()
+ {
+ var $this = $(this);
+ var data = $this.data('lightbox');
+ var options = $.extend({}, $.fn.lightbox.defaults, $th…
+ if (!data) $this.data('lightbox', (data = new Lightbox…
+
+ if (typeof option == 'string')
+ data[option]()
+ else if (options.show)
+ data.show()
+ });
+ };
+
+ $.fn.lightbox.defaults = {
+ backdrop: true,
+ keyboard: true,
+ show: true,
+ resizeToFit: true
+ };
+
+ $.fn.lightbox.Constructor = Lightbox;
+
+
+/* LIGHTBOX DATA-API
+ * ================== */
+
+ $(document).on('click.lightbox.data-api', '[data-toggle="lightbox"]', …
+ {
+ var $this = $(this);
+ var href = $this.attr('href');
+ var $target = $($this.attr('data-target') || (href && href.rep…
+ var option = $target.data('lightbox') ? 'toggle' : $.extend({ …
+ var img = $this.attr('data-image') || false;
+ var $imgElem;
+
+ e.preventDefault();
+
+ if(img)
+ {
+ $target.data('original-content', $target.find('.lightb…
+ $target.find('.lightbox-content').html('<img border="0…
+ }
+
+ $target
+ .lightbox(option)
+ .one('hide', function ()
+ {
+ $this.focus()
+ })
+ .one('hidden',function ()
+ {
+ if( img )
+ {
+ $target.find('.lightbox-content').html…
+ img = undefined;
+ }
+ });
+ })
+
+}(window.jQuery);
+\ No newline at end of file
diff --git a/app/assets/javascripts/jquery.lightbox-0.5.js b/app/assets/javascr…
@@ -1,472 +0,0 @@
-/**
- * jQuery lightBox plugin
- * This jQuery plugin was inspired and based on Lightbox 2 by Lokesh Dhakar (h…
- * and adapted to me for use like a plugin from jQuery.
- * @name jquery-lightbox-0.5.js
- * @author Leandro Vieira Pinho - http://leandrovieira.com
- * @version 0.5
- * @date April 11, 2008
- * @category jQuery plugin
- * @copyright (c) 2008 Leandro Vieira Pinho (leandrovieira.com)
- * @license CCAttribution-ShareAlike 2.5 Brazil - http://creativecommons.org/l…
- * @example Visit http://leandrovieira.com/projects/jquery/lightbox/ for more …
- */
-
-// Offering a Custom Alias suport - More info: http://docs.jquery.com/Plugins/…
-(function($) {
- /**
- * $ is an alias to jQuery object
- *
- */
- $.fn.lightBox = function(settings) {
- // Settings to configure the jQuery lightBox plugin how you li…
- settings = jQuery.extend({
- // Configuration related to overlay
- overlayBgColor: '#000', …
- overlayOpacity: 0.8, …
- // Configuration related to navigation
- fixedNavigation: false, …
- // Configuration related to images
- imageLoading: '/assets/lightbox…
- imageBtnPrev: '/assets/lightbox…
- imageBtnNext: '/assets/lightbox…
- imageBtnClose: '/assets/lightbo…
- imageBlank: '/assets/li…
- // Configuration related to container image box
- containerBorderSize: 10, …
- containerResizeSpeed: 400, // (i…
- // Configuration related to texts in caption. For exam…
- txtImage: 'Image', …
- txtOf: 'of', …
- // Configuration related to keyboard navigation
- keyToClose: 'c', …
- keyToPrev: 'p', …
- keyToNext: 'n', …
- // Don't alter these variables in any way
- imageArray: [],
- activeImage: 0
- },settings);
- // Caching the jQuery object with all elements matched
- var jQueryMatchedObj = this; // This, in this context, refer t…
- /**
- * Initializing the plugin calling the start function
- *
- * @return boolean false
- */
- function _initialize() {
- _start(this,jQueryMatchedObj); // This, in this contex…
- return false; // Avoid the browser following the link
- }
- /**
- * Start the jQuery lightBox plugin
- *
- * @param object objClicked The object (link) whick the user h…
- * @param object jQueryMatchedObj The jQuery object with all e…
- */
- function _start(objClicked,jQueryMatchedObj) {
- // Hime some elements to avoid conflict with overlay i…
- $('embed, object, select').css({ 'visibility' : 'hidde…
- // Call the function to create the markup structure; s…
- _set_interface();
- // Unset total images in imageArray
- settings.imageArray.length = 0;
- // Unset image active information
- settings.activeImage = 0;
- // We have an image set? Or just an image? Let's see i…
- if ( jQueryMatchedObj.length == 1 ) {
- settings.imageArray.push(new Array(objClicked.…
- } else {
- // Add an Array (as many as we have), with hre…
- for ( var i = 0; i < jQueryMatchedObj.length; …
- settings.imageArray.push(new Array(jQu…
- }
- }
- while ( settings.imageArray[settings.activeImage][0] !…
- settings.activeImage++;
- }
- // Call the function that prepares image exibition
- _set_image_to_view();
- }
- /**
- * Create the jQuery lightBox plugin interface
- *
- * The HTML markup will be like that:
- <div id="jquery-overlay"></div>
- <div id="jquery-lightbox">
- <div id="lightbox-container-image-box">
- <div id="lightbox-container-image">
- <img src="../fotos/XX.jpg" id=…
- <div id="lightbox-nav">
- <a href="#" id="lightb…
- <a href="#" id="lightb…
- </div>
- <div id="lightbox-loading">
- <a href="#" id="lightb…
- <img src="..//…
- </a>
- </div>
- </div>
- </div>
- <div id="lightbox-container-image-data-box">
- <div id="lightbox-container-image-data…
- <div id="lightbox-image-detail…
- <span id="lightbox-ima…
- <span id="lightbox-ima…
- </div>
- <div id="lightbox-secNav">
- <a href="#" id="lightb…
- <img src="..//…
- </a>
- </div>
- </div>
- </div>
- </div>
- *
- */
- function _set_interface() {
- // Apply the HTML markup into body tag
- $('body').append('<div id="jquery-overlay"></div><div …
- // Get page sizes
- var arrPageSizes = ___getPageSize();
- // Style overlay and show it
- $('#jquery-overlay').css({
- backgroundColor: settings.overlayBgColo…
- opacity: settings.overl…
- width: arrPageS…
- height: arrPage…
- }).fadeIn();
- // Get page scroll
- var arrPageScroll = ___getPageScroll();
- // Calculate top and left offset for the jquery-lightb…
- $('#jquery-lightbox').css({
- top: arrPageScroll[1] + (arrPageSizes[3…
- left: arrPageScroll[0]
- }).show();
- // Assigning click events in elements to close overlay
- $('#jquery-overlay,#jquery-lightbox').click(function()…
- _finish();
- });
- // Assign the _finish function to lightbox-loading-lin…
- $('#lightbox-loading-link,#lightbox-secNav-btnClose').…
- _finish();
- return false;
- });
- // If window was resized, calculate the new overlay di…
- $(window).resize(function() {
- // Get page sizes
- var arrPageSizes = ___getPageSize();
- // Style overlay and show it
- $('#jquery-overlay').css({
- width: arrPageSizes[0],
- height: arrPageSizes[1]
- });
- // Get page scroll
- var arrPageScroll = ___getPageScroll();
- // Calculate top and left offset for the jquer…
- $('#jquery-lightbox').css({
- top: arrPageScroll[1] + (arrPag…
- left: arrPageScroll[0]
- });
- });
- }
- /**
- * Prepares image exibition; doing a image???s preloader to ca…
- *
- */
- function _set_image_to_view() { // show the loading
- // Show the loading
- $('#lightbox-loading').show();
- if ( settings.fixedNavigation ) {
- $('#lightbox-image,#lightbox-container-image-d…
- } else {
- // Hide some elements
- $('#lightbox-image,#lightbox-nav,#lightbox-nav…
- }
- // Image preload process
- var objImagePreloader = new Image();
- objImagePreloader.onload = function() {
- $('#lightbox-image').attr('src',settings.image…
- // Perfomance an effect in the image container…
- _resize_container_image_box(objImagePreloader.…
- // clear onLoad, IE behaves irratically…
- objImagePreloader.onload=function(){};
- };
- objImagePreloader.src = settings.imageArray[settings.a…
- };
- /**
- * Perfomance an effect in the image container resizing it
- *
- * @param integer intImageWidth The image???s width that will …
- * @param integer intImageHeight The image???s height that wil…
- */
- function _resize_container_image_box(intImageWidth,intImageHei…
- // Get current width and height
- var intCurrentWidth = $('#lightbox-container-image-box…
- var intCurrentHeight = $('#lightbox-container-image-bo…
- // Get the width and height of the selected image plus…
- var intWidth = (intImageWidth + (settings.containerBor…
- var intHeight = (intImageHeight + (settings.containerB…
- // Diferences
- var intDiffW = intCurrentWidth - intWidth;
- var intDiffH = intCurrentHeight - intHeight;
- // Perfomance the effect
- $('#lightbox-container-image-box').animate({ width: in…
- if ( ( intDiffW == 0 ) && ( intDiffH == 0 ) ) {
- if ( $.browser.msie ) {
- ___pause(250);
- } else {
- ___pause(100);
- }
- }
- $('#lightbox-container-image-data-box').css({ width: i…
- $('#lightbox-nav-btnPrev,#lightbox-nav-btnNext').css({…
- };
- /**
- * Show the prepared image
- *
- */
- function _show_image() {
- $('#lightbox-loading').hide();
- $('#lightbox-image').fadeIn(function() {
- _show_image_data();
- _set_navigation();
- });
- _preload_neighbor_images();
- };
- /**
- * Show the image information
- *
- */
- function _show_image_data() {
- $('#lightbox-container-image-data-box').slideDown('fas…
- $('#lightbox-image-details-caption').hide();
- if ( settings.imageArray[settings.activeImage][1] ) {
- $('#lightbox-image-details-caption').html(sett…
- }
- // If we have a image set, display 'Image X of X'
- if ( settings.imageArray.length > 1 ) {
- $('#lightbox-image-details-currentNumber').htm…
- }
- }
- /**
- * Display the button navigations
- *
- */
- function _set_navigation() {
- $('#lightbox-nav').show();
-
- // Instead to define this configuration in CSS file, w…
- $('#lightbox-nav-btnPrev,#lightbox-nav-btnNext').css({…
-
- // Show the prev button, if not the first image in set
- if ( settings.activeImage != 0 ) {
- if ( settings.fixedNavigation ) {
- $('#lightbox-nav-btnPrev').css({ 'back…
- .unbind()
- .bind('click',function() {
- settings.activeImage =…
- _set_image_to_view();
- return false;
- });
- } else {
- // Show the images button for Next but…
- $('#lightbox-nav-btnPrev').unbind().ho…
- $(this).css({ 'background' : '…
- },function() {
- $(this).css({ 'background' : '…
- }).show().bind('click',function() {
- settings.activeImage = setting…
- _set_image_to_view();
- return false;
- });
- }
- }
-
- // Show the next button, if not the last image in set
- if ( settings.activeImage != ( settings.imageArray.len…
- if ( settings.fixedNavigation ) {
- $('#lightbox-nav-btnNext').css({ 'back…
- .unbind()
- .bind('click',function() {
- settings.activeImage =…
- _set_image_to_view();
- return false;
- });
- } else {
- // Show the images button for Next but…
- $('#lightbox-nav-btnNext').unbind().ho…
- $(this).css({ 'background' : '…
- },function() {
- $(this).css({ 'background' : '…
- }).show().bind('click',function() {
- settings.activeImage = setting…
- _set_image_to_view();
- return false;
- });
- }
- }
- // Enable keyboard navigation
- _enable_keyboard_navigation();
- }
- /**
- * Enable a support to keyboard navigation
- *
- */
- function _enable_keyboard_navigation() {
- $(document).keydown(function(objEvent) {
- _keyboard_action(objEvent);
- });
- }
- /**
- * Disable the support to keyboard navigation
- *
- */
- function _disable_keyboard_navigation() {
- $(document).unbind();
- }
- /**
- * Perform the keyboard actions
- *
- */
- function _keyboard_action(objEvent) {
- // To ie
- if ( objEvent == null ) {
- keycode = event.keyCode;
- escapeKey = 27;
- // To Mozilla
- } else {
- keycode = objEvent.keyCode;
- escapeKey = objEvent.DOM_VK_ESCAPE;
- }
- // Get the key in lower case form
- key = String.fromCharCode(keycode).toLowerCase();
- // Verify the keys to close the ligthBox
- if ( ( key == settings.keyToClose ) || ( key == 'x' ) …
- _finish();
- }
- // Verify the key to show the previous image
- if ( ( key == settings.keyToPrev ) || ( keycode == 37 …
- // If we???re not showing the first image, cal…
- if ( settings.activeImage != 0 ) {
- settings.activeImage = settings.active…
- _set_image_to_view();
- _disable_keyboard_navigation();
- }
- }
- // Verify the key to show the next image
- if ( ( key == settings.keyToNext ) || ( keycode == 39 …
- // If we???re not showing the last image, call…
- if ( settings.activeImage != ( settings.imageA…
- settings.activeImage = settings.active…
- _set_image_to_view();
- _disable_keyboard_navigation();
- }
- }
- }
- /**
- * Preload prev and next images being showed
- *
- */
- function _preload_neighbor_images() {
- if ( (settings.imageArray.length -1) > settings.active…
- objNext = new Image();
- objNext.src = settings.imageArray[settings.act…
- }
- if ( settings.activeImage > 0 ) {
- objPrev = new Image();
- objPrev.src = settings.imageArray[settings.act…
- }
- }
- /**
- * Remove jQuery lightBox plugin HTML markup
- *
- */
- function _finish() {
- $('#jquery-lightbox').remove();
- $('#jquery-overlay').fadeOut(function() { $('#jquery-o…
- // Show some elements to avoid conflict with overlay i…
- $('embed, object, select').css({ 'visibility' : 'visib…
- }
- /**
- / THIRD FUNCTION
- * getPageSize() by quirksmode.com
- *
- * @return Array Return an array with page width, height and w…
- */
- function ___getPageSize() {
- var xScroll, yScroll;
- if (window.innerHeight && window.scrollMaxY) {
- xScroll = window.innerWidth + window.scrollMax…
- yScroll = window.innerHeight + window.scrollMa…
- } else if (document.body.scrollHeight > document.body.…
- xScroll = document.body.scrollWidth;
- yScroll = document.body.scrollHeight;
- } else { // Explorer Mac...would also work in Explorer…
- xScroll = document.body.offsetWidth;
- yScroll = document.body.offsetHeight;
- }
- var windowWidth, windowHeight;
- if (self.innerHeight) { // all except Explorer
- if(document.documentElement.clientWidth){
- windowWidth = document.documentElement…
- } else {
- windowWidth = self.innerWidth;
- }
- windowHeight = self.innerHeight;
- } else if (document.documentElement && document.docume…
- windowWidth = document.documentElement.clientW…
- windowHeight = document.documentElement.client…
- } else if (document.body) { // other Explorers
- windowWidth = document.body.clientWidth;
- windowHeight = document.body.clientHeight;
- }
- // for small pages with total height less then height …
- if(yScroll < windowHeight){
- pageHeight = windowHeight;
- } else {
- pageHeight = yScroll;
- }
- // for small pages with total width less then width of…
- if(xScroll < windowWidth){
- pageWidth = xScroll;
- } else {
- pageWidth = windowWidth;
- }
- arrayPageSize = new Array(pageWidth,pageHeight,windowW…
- return arrayPageSize;
- };
- /**
- / THIRD FUNCTION
- * getPageScroll() by quirksmode.com
- *
- * @return Array Return an array with x,y page scroll values.
- */
- function ___getPageScroll() {
- var xScroll, yScroll;
- if (self.pageYOffset) {
- yScroll = self.pageYOffset;
- xScroll = self.pageXOffset;
- } else if (document.documentElement && document.docume…
- yScroll = document.documentElement.scrollTop;
- xScroll = document.documentElement.scrollLeft;
- } else if (document.body) {// all other Explorers
- yScroll = document.body.scrollTop;
- xScroll = document.body.scrollLeft;
- }
- arrayPageScroll = new Array(xScroll,yScroll);
- return arrayPageScroll;
- };
- /**
- * Stop the code execution from a escified time in milisecond
- *
- */
- function ___pause(ms) {
- var date = new Date();
- curDate = null;
- do { var curDate = new Date(); }
- while ( curDate - date < ms);
- };
- // Return the jQuery object for chaining. The unbind method is…
- return this.unbind('click').click(_initialize);
- };
-})(jQuery); // Call and execute the function immediately passing the jQuery ob…
diff --git a/app/assets/stylesheets/application.css.scss b/app/assets/styleshee…
@@ -7,5 +7,6 @@
*= require formtastic
*= require formtastic-bootstrap
*= require formtastic-overrides
+ *= require bootstrap-lightbox
*= require dataTables/jquery.dataTables.bootstrap
*/
diff --git a/app/assets/stylesheets/bootstrap-lightbox.css b/app/assets/stylesh…
@@ -0,0 +1,65 @@
+/*!=========================================================
+* bootstrap-lightbox v0.4.1 - 11/20/2012
+* http://jbutz.github.com/bootstrap-lightbox/
+* HEAVILY based off bootstrap-modal.js
+* ==========================================================
+* Copyright (c) 2012 Jason Butz (http://jasonbutz.info)
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+* http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+* ========================================================= */
+.lightbox {
+ background-color: transparent;
+ text-align: center;
+ line-height: 0;
+ z-index: 1050;
+ position: relative;
+ top: 70px;
+ outline: none;
+}
+.lightbox .hide {
+ display: none;
+}
+.lightbox .in {
+ display: block;
+}
+.lightbox-content {
+ display: inline-block;
+ padding: 10px;
+ background-color: #ffffff;
+ border: 1px solid #999;
+ border: 1px solid rgba(0, 0, 0, 0.3);
+ *border: 1px solid #999;
+ /* IE6-7 */
+
+ -webkit-border-radius: 6px;
+ -moz-border-radius: 6px;
+ border-radius: 6px;
+ -webkit-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
+ -moz-box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
+ box-shadow: 0 3px 7px rgba(0, 0, 0, 0.3);
+ -webkit-background-clip: padding-box;
+ -moz-background-clip: padding-box;
+ background-clip: padding-box;
+}
+.lightbox-header .close {
+ color: white;
+ margin-right: -16px;
+ margin-top: -16px;
+ font-size: 2em;
+ opacity: .8;
+ filter: alpha(opacity=80);
+}
+.lightbox-header .close :hover {
+ opacity: .4;
+ filter: alpha(opacity=40);
+}
diff --git a/app/controllers/analyze_controller.rb b/app/controllers/analyze_co…
@@ -30,14 +30,14 @@ class AnalyzeController < ApplicationController
:page => params[:page],
:order => 'number ASC',
:per_page => 10,
- :conditions => [ 'completed = ? and processed = ? and …
+ :conditions => [ 'answered = ? and analysis_completed_…
)
else
@results = Call.where(:job_id => @job_id).paginate(
:page => params[:page],
:order => 'number ASC',
:per_page => 10,
- :conditions => [ 'completed = ? and processed = ? and …
+ :conditions => [ 'answered = ? and analysis_completed_…
)
end
diff --git a/app/controllers/calls_controller.rb b/app/controllers/calls_contro…
@@ -3,11 +3,10 @@ class CallsController < ApplicationController
# GET /calls
# GET /calls.xml
def index
- @jobs = Job.where(:status => 'answered').paginate(
+ @jobs = @project.jobs.where('task = ? AND completed_at IS NOT NULL', 'dial…
:page => params[:page],
:order => 'id DESC',
:per_page => 30
-
)
respond_to do |format|
@@ -16,62 +15,6 @@ class CallsController < ApplicationController
end
end
- # GET /calls/1/reanalyze
- def reanalyze
- Call.update_all(['processed = ?', false], ['job_id = ?', params[:id]…
- j = Job.find(params[:id])
- j.processed = false
- j.save
-
- redirect_to :action => 'analyze'
- end
-
- # GET /calls/1/process
- # GET /calls/1/process.xml
- def analyze
- @job_id = params[:id]
- @job = Job.find(@job_id)
-
- if(@job.processed)
- redirect_to :controller => 'analyze', :action => 'view', :id =…
- return
- end
-
- @dial_data_total = Call.count(
- :conditions => [ 'job_id = ? and answered = ?', @job_id, true ]
- )
-
- @dial_data_done = Call.count(
- :conditions => [ 'job_id = ? and processed = ?', @job_id, true…
- )
-
- ltypes = Call.find( :all, :select => 'DISTINCT line_type', :conditions…
- 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_i…
- )
- end
-
- @lines_by_type = res_types
-
- @dial_data_todo = Call.where(:job_id => @job_id).paginate(
- :page => params[:page],
- :order => 'number ASC',
- :per_page => 50,
- :conditions => [ 'answered = ? and processed = ? and busy = ?'…
- )
-
- if @dial_data_todo.length > 0
- res = @job.schedule(:analysis)
- unless res
- flash[:error] = "Unable to launch analysis job"
- end
- end
- end
-
# GET /calls/1/view
# GET /calls/1/view.xml
def view
diff --git a/app/controllers/jobs_controller.rb b/app/controllers/jobs_controll…
@@ -15,6 +15,28 @@ class JobsController < ApplicationController
end
end
+ def results
+
+ @jobs = @project.jobs.where('task = ? AND completed_at IS NOT NULL', 'dial…
+ :page => params[:page],
+ :order => 'id DESC',
+ :per_page => 30
+ )
+
+ respond_to do |format|
+ format.html # index.html.erb
+ format.xml { render :xml => @calls }
+ end
+ end
+
+ def view_results
+ @job = Job.find(params[:id])
+ @calls = @job.calls.paginate(
+ :page => params[:page],
+ :order => 'id DESC',
+ :per_page => 30
+ )
+ end
def new_dialer
@job = Job.new
@@ -53,55 +75,51 @@ class JobsController < ApplicationController
end
end
- def stop
- @job = Job.find(params[:id])
- @job.stop
- flash[:notice] = "Job has been cancelled"
- redirect_to :action => 'index'
+ def reanalyze_job
+ @job = Job.find(params[:id])
+ @new = Job.new({
+ :task => 'analysis', :scope => 'job', :target_id => @job.id, :…
+ :project_id => @project.id, :status => 'submitted'
+ })
+ 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 }
+ else
+ flash[:notice] = 'Analysis job could not run: ' + @new.errors.in…
+ format.html { redirect_to results_path(@project) }
+ format.xml { render :xml => @job.errors, :status => :unprocessable_en…
+ end
+ end
end
- def create
-
- @job = Job.new(params[:job])
-
- if(Provider.find_all_by_enabled(true).length == 0)
- @job.errors.add(:base, "No providers have been configured or e…
- respond_to do |format|
- format.html { render :action => "new" }
- format.xml { render :xml => @job.errors, :status => :…
- end
- return
- end
-
- @job.status = 'submitted'
- @job.progress = 0
- @job.started_at = nil
- @job.completed_at = nil
- @job.range = @job_range.gsub(/[^0-9X:,\n]/m, '')
- @job.cid_mask = @cid_mask.gsub(/[^0-9X]/m, '') if @job.cid_mask !=…
-
- if(@job.range_file.to_s != "")
- @job.range = @job.range_file.read.gsub(/[^0-9X:,\n]/m, '')
- end
-
+ def analyze_job
+ @job = Job.find(params[:id])
+ @new = Job.new({
+ :task => 'analysis', :scope => 'job', :target_id => @job.id,
+ :project_id => @project.id, :status => 'submitted'
+ })
respond_to do |format|
- if @job.save
- flash[:notice] = 'Job was successfully created.'
-
- res = @job.schedule(:dialer)
- unless res
- flash[:error] = "Unable to launch dialer job"
- end
-
- format.html { redirect_to :action => 'index' }
- format.xml { render :xml => @job, :status => :created, :location => @…
+ if @new.schedule
+ flash[:notice] = 'Analysis job was successfully created.'
+ format.html { redirect_to jobs_path }
+ format.xml { render :xml => @job, :status => :created }
else
- format.html { render :action => "new" }
+ flash[:notice] = 'Analysis job could not run: ' + @new.errors.in…
+ format.html { redirect_to results_path(@project) }
format.xml { render :xml => @job.errors, :status => :unprocessable_en…
end
end
end
+ def stop
+ @job = Job.find(params[:id])
+ @job.stop
+ flash[:notice] = "Job has been cancelled"
+ redirect_to :action => 'index'
+ end
+
def destroy
@job = Job.find(params[:id])
@job.destroy
diff --git a/app/models/job.rb b/app/models/job.rb
@@ -23,6 +23,15 @@ class Job < ActiveRecord::Base
record.errors[:lines] << "Lines should…
end
when 'analysis'
+ unless ['job', 'project', 'global'].include?(r…
+ record.errors[:scope] << "Scope must b…
+ end
+ if record.scope == "job" and Job.where(:id => …
+ record.errors[:job_id] << "The job_id …
+ end
+ if record.scope == "project" and Job.where(:id…
+ record.errors[:project_id] << "The pro…
+ end
when 'import'
else
record.errors[:base] << "Invalid task specifie…
@@ -31,22 +40,12 @@ class Job < ActiveRecord::Base
end
- has_many :calls
- belongs_to :project
- validates_with JobValidator
-
- def stop
- self.class.update_all({ :status => 'cancelled'}, { :id => self…
- end
+ # XXX: Purging a single job will be slow, but deleting the project is …
+ has_many :calls, :dependent => :destroy
- def update_progress(pct)
- if pct >= 100
- self.class.update_all({ :progress => pct, :completed_a…
- else
- self.class.update_all({ :progress => pct }, { :id => s…
- end
- end
+ belongs_to :project
+ attr_accessible :task, :status
validates_presence_of :project_id
@@ -62,6 +61,30 @@ class Job < ActiveRecord::Base
attr_accessible :range, :seconds, :lines, :cid_mask
+ attr_accessor :scope
+ attr_accessor :force
+ attr_accessor :target_id
+
+ attr_accessible :scope, :force, :target_id
+
+
+ validates_with JobValidator
+
+ def stop
+ self.class.update_all({ :status => 'cancelled'}, { :id => self…
+ end
+
+ def update_progress(pct)
+ if pct >= 100
+ self.class.update_all({ :progress => pct, :completed_a…
+ else
+ self.class.update_all({ :progress => pct }, { :id => s…
+ end
+ end
+
+ def details
+ Marshal.load(self.args) rescue {}
+ end
def schedule
case task
@@ -75,7 +98,13 @@ class Job < ActiveRecord::Base
})
return self.save
when 'analysis'
- #
+ self.status = 'submitted'
+ self.args = Marshal.dump({
+ :scope => self.scope, # job / pr…
+ :force => !!(self.force), # true / f…
+ :target_id => self.target_id.to_i # job_id o…
+ })
+ return self.save
else
raise ::RuntimeError, "Unsupported Job type"
end
diff --git a/app/views/analyze/view.html.erb b/app/views/analyze/view.html.erb
@@ -10,7 +10,7 @@
</tr>
</table>
-<%= raw(will_paginate @results) %>
+<%= will_paginate @results, :renderer => BootstrapPagination::Rails %>
<table class='table table-striped table-bordered' width='90%'>
<thead>
@@ -27,34 +27,27 @@
<object
type="application/x-shockwave-flash"
- data="/assets/musicplayer.swf?song_url=<%=resource_ana…
+ 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="movie" value="/assets/musicplayer.swf?son…
<param name="wmode" value="transparent"></param>
</object>
<b><%= call.number %></b>
<hr width='100%' size='1'/>
- CallerID: <%= call.cid%><br/>
+ CallerID: <%= call.caller_id%><br/>
Provider: <%=h call.provider.name %><br/>
- Audio: <%=h call.seconds %> Seconds<br/>
- Ringer: <%=h call.ringtime %> Seconds<br/>
+ Audio: <%=h call.audio_length %> Seconds<br/>
+ Ringer: <%=h call.ring_length %> Seconds<br/>
</td>
<td align='center'>
<b><%=h call.line_type.upcase %></b><br/>
- <a href="<%=resource_analyze_path(@job_id, call.id, "big_sig_d…
- <a href="<%=resource_analyze_path(@job_id, call.id, "big_freq"…
- <% (call.signatures||"").split("\n").each do |s|
- sid,mat,name = s.split(':', 3)
- str = [mat.to_i * 6.4, 255].min
- col = ("%.2x" % (255 - str)) * 3
- %>
- <div style="color: #<%= col%>;"><%=h name%> (<%=h sid …
- <% end %>
+ <%= render :partial => 'shared/lightbox_sig', :locals => { :ca…
+ <%= render :partial => 'shared/lightbox_freq', :locals => { :c…
<% if call.fprint and call.fprint.length > 0 %>
- <a href="<%=view_matches_path(call.id)%>">View Matches…
+ <a href="<%=view_matches_path(@project, call.id)%>">Vi…
<% end %>
</td>
</tr>
@@ -62,10 +55,4 @@
</tbody>
</table>
-<%= raw(will_paginate @results) %>
-
-<script type="text/javascript">
-$(function() {
- $('a.lightbox').lightBox();
-});
-</script>
+<%= will_paginate @results, :renderer => BootstrapPagination::Rails %>
diff --git a/app/views/calls/index.html.erb b/app/views/calls/index.html.erb
@@ -1,7 +1,7 @@
<% if @jobs.length > 0 %>
<h1 class='title'>Completed Jobs</h1>
-<%= raw(will_paginate @jobs) %>
+<%= will_paginate @jobs, :renderer => BootstrapPagination::Rails %>
<table class='table table-striped table-bordered' width='90%'>
<thead>
<tr>
@@ -15,22 +15,22 @@
</thead>
<tbody>
-<% @jobs.sort{|a,b| b.id <=> a.id}.each do |job| %>
+<% @jobs.each do |job| %>
<tr>
- <td><%=h job.id %></td>
- <td><%=h job.range %></td>
- <td><%=h job.cid_mask %></td>
- <td><%=h (
- Call.count(:conditions => ['job_id = ? and processed = ?', job…
+ <td><%= job.id %></td>
+ <td><%= job.range %></td>
+ <td><%= job.cid_mask %></td>
+ <td><%= (
+ job.calls.where("analysis_completed_at IS NOT NULL").count.to_…
"/" +
- Call.count(:conditions => ['job_id = ?', job.id]).to_s
+ job.calls.count.to_s
)%></td>
- <td><%=h job.started_at.localtime.strftime("%Y-%m-%d %H:%M:%S") %></td>
+ <td><%= job.started_at.localtime.strftime("%Y-%m-%d %H:%M:%S") %></td>
<td>
<a class="btn btn-mini" href="<%= view_call_path(@project,job) %>" rel…
- <% if(job.analysis_completed_at) %>
+ <% if job.calls.where("analysis_completed_at IS NOT NULL").cou…
<a class="btn btn-mini" href="<%= analyze_call_path(@p…
<a class="btn btn-mini" href="<%= reanalyze_call_path(…
<% else %>
@@ -45,7 +45,7 @@
</tbody>
</table>
-<%= raw(will_paginate @jobs) %>
+<%= will_paginate @jobs, :renderer => BootstrapPagination::Rails %>
<% else %>
diff --git a/app/views/jobs/index.html.erb b/app/views/jobs/index.html.erb
@@ -1,4 +1,4 @@
-<% if(@submitted_jobs.length > 0) %>
+<% if @submitted_jobs.length > 0 %>
<h1 class='title'>Submitted Jobs</h1>
diff --git a/app/views/jobs/results.html.erb b/app/views/jobs/results.html.erb
@@ -0,0 +1,64 @@
+<% if @jobs.length > 0 %>
+<h1 class='title'>Completed Jobs</h1>
+
+<%= will_paginate @jobs, :renderer => BootstrapPagination::Rails %>
+<table class='table table-striped table-bordered' width='90%'>
+ <thead>
+ <tr>
+ <th>ID</th>
+ <th>Range</th>
+ <th>CallerID</th>
+ <th>Connected</th>
+ <th>Date</th>
+ <th>User</th>
+ <th>Actions</th>
+ </tr>
+ </thead>
+ <tbody>
+
+<% @jobs.each do |job|
+
+ cnt_dialed = job.calls.count.to_i
+ cnt_answered = job.calls.where("answered = ? and busy = ?", true, fals…
+ pct_answered = 0
+ unless cnt_dialed == 0
+ pct_answered = ((cnt_answered.to_f / cnt_dialed.to_f) * 100).t…
+ end
+%>
+ <tr>
+ <td><%= job.id %></td>
+ <td><%= job.details[:range].to_s %></td>
+ <td><%= job.details[:cid_mask].to_s %></td>
+ <td><span rel="tooltip" title="<%= pct_answered %>% answered"><%= cnt_answ…
+
+
+ <td><%= job.created_at.strftime("%Y-%m-%d %H:%M:%s") %></td>
+ <td><%= job.created_by %></td>
+ <td>
+ <a class="btn btn-mini" href="<%= view_results_path(@project,job) %>" …
+
+ <% if job.calls.where("analysis_completed_at IS NOT NULL").cou…
+ <a class="btn btn-mini" href="<%= view_analyze_path(@p…
+ <a class="btn btn-mini" href="<%= reanalyze_job_path(@…
+ <% else %>
+ <a class="btn btn-mini" href="<%= analyze_job_path(@pr…
+ <% end %>
+
+ <a class="btn btn-mini" href="<%= job_path(job) %>" data-confirm="…
+ </td>
+ </tr>
+
+<% end %>
+</tbody>
+</table>
+
+<%= will_paginate @jobs, :renderer => BootstrapPagination::Rails %>
+
+<% else %>
+
+<h1 class='title'>No Completed Jobs</h1>
+<br/>
+
+<% end %>
+
+<a class="btn" href="<%= new_dialer_job_path %>"><i class="icon-plus"></i> Sta…
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/applica…
@@ -23,6 +23,7 @@
<%= javascript_tag do %>
$(document).ready(function() {
$("a").tooltip();
+ $("span").tooltip();
});
<% end %>
</head>
@@ -39,7 +40,7 @@
h(truncate(@project.na…
' <i class="icon-chevr…
</li>
- <%= menu_item "Results", calls_path(@project) …
+ <%= menu_item "Results", results_path(@project…
<%= menu_item "Analysis", analyze_path(@projec…
<% end %>
diff --git a/app/views/shared/_lightbox_freq.html.erb b/app/views/shared/_light…
@@ -0,0 +1,13 @@
+<%
+ lid = "call_#{call.id}_freq"
+%>
+<div id="<%= lid %>" class="lightbox hide fade" tabindex="-1" role="dialog" ar…
+ <div class='lightbox-header'>
+ <button type="button" class="close" data-dismiss="lightbox" ar…
+ </div>
+ <div class='lightbox-content'>
+ <img src="<%=resource_analyze_path(call.id, "big_freq")%>">
+ </div>
+</div>
+
+<a data-toggle="lightbox" href="#<%= lid %>"><img src="<%=resource_analyze_pat…
diff --git a/app/views/shared/_lightbox_sig.html.erb b/app/views/shared/_lightb…
@@ -0,0 +1,13 @@
+<%
+ lid = "call_#{call.id}_sig"
+%>
+<div id="<%= lid %>" class="lightbox hide fade" tabindex="-1" role="dialog" ar…
+ <div class='lightbox-header'>
+ <button type="button" class="close" data-dismiss="lightbox" ar…
+ </div>
+ <div class='lightbox-content'>
+ <img src="<%=resource_analyze_path(call.id, "big_sig_dots")%>">
+ </div>
+</div>
+
+<a data-toggle="lightbox" href="#<%= lid %>"><img src="<%=resource_analyze_pat…
diff --git a/app/views/shared/lightbox_sig.html.erb b/app/views/shared/lightbox…
@@ -0,0 +1,17 @@
+<%
+ lid = "call_#{call.id}_sig"
+%>
+<a href="<%=resource_analyze_path(call.id, "big_sig_dots")%>" class="lightbox">
+<img src="<%=resource_analyze_path(call.id, "small_sig")%>" />
+</a>
+
+<div id="<%= lid %>" class="lightbox hide fade" tabindex="-1" role="dialog" ar…
+ <div class='lightbox-header'>
+ <button type="button" class="close" data-dismiss="lightbox" ar…
+ </div>
+ <div class='lightbox-content'>
+ <img src="<%=resource_analyze_path(call.id, "big_sig_dots")%>">
+ </div>
+</div>
+
+<a data-toggle="lightbox" href="#<%= lid %>"><img src="<%=resource_analyze_pat…
diff --git a/bin/analyze_result.rb b/bin/analyze_result.rb
@@ -20,12 +20,16 @@ num = ARGV.shift || exit(0)
$0 = "warvox(analyzer): #{inp} #{num}"
+begin
+
$stdout.write(
Marshal.dump(
- WarVOX::Jobs::CallAnalysis.new(
- 0
- ).analyze_call(
+ WarVOX::Jobs::Analysis.analyze_call(
inp, num
)
)
)
+
+rescue ::Errno::EPIPE
+ # Hide pipe errors (parent is killed when task was cancelled)
+end
diff --git a/config/routes.rb b/config/routes.rb
@@ -18,26 +18,26 @@ Web::Application.routes.draw do
match '/jobs/analyzer' => 'jobs#analyzer', :as => :analyzer_job
match '/jobs/:id/stop' => 'jobs#stop', :as => :stop_job
+ 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/reanalyze' => 'jobs#reanalyze_job…
+
+
- match '/projects/:project_id/calls/' => 'calls#index', :as =>…
- match '/projects/:project_id/calls/:id/view' => 'calls#view', :as => …
- match '/projects/:project_id/calls/:id/analyze' => 'calls#analyze', :as …
- match '/projects/:project_id/calls/:id/reanalyze' => 'calls#reanalyze', :a…
- match '/projects/:project_id/calls/:id/purge' => 'calls#purge', :as =>…
- delete '/projects/:project_id/calls/:id' => 'calls#destroy'
match '/projects/:project_id/analyze' => 'analyze#index', :as =>…
- match '/projects/:project_id/analyze/:id/resource/:result_id/:type' => 'anal…
+ match '/calls/:result_id/:type' => 'analyze#resource', :as…
match '/projects/:project_id/analyze/:id/view' => 'analyze#view', :as => …
- match '/projects/:project_id/analyze/:call_id/matches' => 'analyze#view_m…
- match '/projects/:project_id/analyze/:id/show' => 'analyze#show', :as => …
+ match '/projects/:project_id/analyze/:call_id/matches' => 'analyze#view_m…
resources :settings
resources :providers
resources :users
resources :projects
resources :jobs
+ resources :calls
match '/about' => 'home#about', :as => :about
match '/help' => 'home#help', :as => :help
diff --git a/lib/warvox/jobs/analysis.rb b/lib/warvox/jobs/analysis.rb
@@ -65,15 +65,15 @@ class Analysis < Base
case @conf[:scope]
when 'job'
if @conf[:force]
- query = {:job_id => job.id, :answered => true,…
+ query = {:job_id => @conf[:target_id], :answer…
else
- query = {:job_id => job.id, :answered => true,…
+ query = {:job_id => @conf[:target_id], :answer…
end
when 'project'
if @conf[:force]
- query = {:project_id => job.project_id, :answe…
+ query = {:project_id => @conf[:target_id], :an…
else
- query = {:project_id => job.project_id, :answe…
+ query = {:project_id => @conf[:target_id], :an…
end
when 'global'
if @conf[:force]
@@ -89,23 +89,29 @@ class Analysis < Base
@total_calls = Call.count(:conditions => query)
@completed_calls = 0
+ WarVOX::Log.debug("Conditions are #{query.inspect}")
+
Call.find_each(:conditions => query) do |call|
- while @tasks.length < max_threads
- call.analysis_started_at = Time.now.utc
- call.analysis_job_id = job.id
- @tasks << Thread.new(call) { |c| ::ActiveRecor…
- end
- clear_stale_tasks
+ if @tasks.length < max_threads
+ WarVOX::Log.debug("Spawning job for Call #{cal…
+ @tasks << Thread.new(call.id, job.id) { |c,j| …
+ else
+ clear_stale_tasks
- # Update progress every 10 seconds or so
- if Time.now.to_f - last_update.to_f > 10
- update_progress((@completed_calls / @total_cal…
- last_update = Time.now
- end
+ # Update progress every 10 seconds or so
+ if Time.now.to_f - last_update.to_f > 10
+ update_progress((@completed_calls / @t…
+ last_update = Time.now
+ end
- clear_zombies()
+ clear_zombies()
+ end
end
+ @tasks.map {|t| t.join }
+ clear_stale_tasks
+ clear_zombies
+
}
end
@@ -121,8 +127,14 @@ class Analysis < Base
}
end
- def run_analyze_call(dr)
- $stderr.puts "DEBUG: Processing audio for #{dr.number}..."
+ def run_analyze_call(cid, jid)
+
+ dr = Call.find(cid)
+ dr.analysis_started_at = Time.now.utc
+ dr.analysis_job_id = jid
+ dr.save
+
+ WarVOX::Log.debug("Worker processing audio for #{dr.number}...…
bin = File.join(WarVOX::Base, 'bin', 'analyze_result.rb')
tmp = Tempfile.new("Analysis")
@@ -163,7 +175,7 @@ class Analysis < Base
end
# Takes the raw file path as an argument, returns a hash
- def analyze_call(input, num=nil)
+ def self.analyze_call(input, num=nil)
return if not input
return if not File.exist?(input)
diff --git a/lib/warvox/jobs/base.rb b/lib/warvox/jobs/base.rb
@@ -22,6 +22,10 @@ class Base
end
def clear_zombies
+ self.class.clear_zombies
+ end
+
+ def self.clear_zombies
begin
# Clear zombies just in case...
while(Process.waitpid(-1, Process::WNOHANG))
You are viewing proxied material from jay.scot. The copyright of proxied material belongs to its original authors. Any comments or complaints in relation to proxied material should be directed to the original authors of the content concerned. Please see the disclaimer for more details.