Introduction
Introduction Statistics Contact Development Disclaimer Help
Tons of bug fixes after usability testing, still a few more to go - warvox - Vo…
Log
Files
Refs
README
---
commit 4abcd8f39f245c31f30752f92c4979dbf18879e7
parent c617d707a5b387aa960188673371bbef88994ab9
Author: HD Moore <[email protected]>
Date: Thu, 5 Mar 2009 07:36:47 +0000
Tons of bug fixes after usability testing, still a few more to go
Diffstat:
M lib/warvox/jobs.rb | 47 +++++++++++++++--------------…
M lib/warvox/jobs/analysis.rb | 10 ++++++----
M lib/warvox/jobs/base.rb | 29 +++++++++++++++++++++++++----
M lib/warvox/jobs/dialer.rb | 38 ++++++++++-------------------…
M web/app/controllers/analyze_contro… | 4 ++--
M web/app/controllers/dial_jobs_cont… | 3 +--
M web/app/controllers/dial_results_c… | 29 +++++++++++++++++++++++++++…
M web/app/models/dial_job.rb | 8 ++++----
M web/app/views/dial_jobs/index.html… | 6 +++---
M web/app/views/dial_jobs/new.html.e… | 6 +++---
M web/app/views/dial_results/analyze… | 35 ++++++++-------------------…
M web/app/views/home/index.html.erb | 4 ++--
M web/config/database.yml | 6 +++---
13 files changed, 119 insertions(+), 106 deletions(-)
---
diff --git a/lib/warvox/jobs.rb b/lib/warvox/jobs.rb
@@ -3,44 +3,41 @@ class JobQueue
attr_accessor :active_job, :active_thread, :queue, :queue_thread
def initialize
+ @mutex = Mutex.new
@queue = []
@queue_thread = Thread.new{ manage_queue }
+
super
end
- # XXX synchronize
- def deschedule(job_id)
-
- if(@active_job and @active_job.name == job_id)
- @active_thread.kill
- @active_job = @active_thread = nil
- end
-
- res = []
- @queue.each do |j|
- res << j if j.name == job_id
- end
-
- if(res.length > 0)
- res.each {|j| @queue.delete(j) }
+ def scheduled?(klass, job_id)
+ @mutex.synchronize do
+ [@active_job, *(@queue)].each do |c|
+ next if not c
+ return true if (c.class == klass and c.name ==…
+ end
end
+ false
end
- def schedule(job)
- @queue.push(job)
+ def schedule(klass, job_id)
+ return false if scheduled?(klass, job_id)
+ @queue.push(klass.new(job_id))
end
def manage_queue
begin
while(true)
- if(@active_job and @active_job.status == 'completed')
- @active_job = nil
- @active_thread = nil
- end
-
- if(not @active_job and @queue.length > 0)
- @active_job = @queue.shift
- @active_thread = Thread.new { @active_job.star…
+ @mutex.synchronize do
+ if(@active_job and @active_job.status == 'comp…
+ @active_job = nil
+ @active_thread = nil
+ end
+
+ if(not @active_job and @queue.length > 0)
+ @active_job = @queue.shift
+ @active_thread = Thread.new { @active_…
+ end
end
Kernel.select(nil, nil, nil, 1)
diff --git a/lib/warvox/jobs/analysis.rb b/lib/warvox/jobs/analysis.rb
@@ -231,8 +231,10 @@ class Analysis < Base
system("gnuplot #{plotter.path}")
File.unlink(plotter.path)
File.unlink(datfile.path)
+ File.unlink(frefile.path)
plotter.close
datfile.close
+ frefile.path
# Generate a MP3 audio file
system("sox -s -w -r 8000 -t raw -c 1 #{rawfile.path} …
@@ -240,13 +242,13 @@ class Analysis < Base
File.unlink("#{bname}.wav")
File.unlink(rawfile.path)
rawfile.close
-
- # XXX: Dump the frequencies
-
+
# Save the changes
r.processed = true
r.processed_at = Time.now
- r.save
+ db_save(r)
+
+ clear_zombies()
end
end
diff --git a/lib/warvox/jobs/base.rb b/lib/warvox/jobs/base.rb
@@ -7,10 +7,6 @@ class Base
'base'
end
- def name
- 'noname'
- end
-
def stop
@status = 'active'
end
@@ -18,6 +14,31 @@ class Base
def start
@status = 'completed'
end
+
+ def db_save(obj)
+ max_tries = 10
+ cur_tries = 0
+ begin
+ obj.save
+ rescue ::SQLite3::BusyException => e
+ cur_tries += 1
+ if(cur_tries > max_tries)
+ raise e
+ return
+ end
+ Kernel.select(nil, nil, nil, 0.25)
+ retry
+ end
+ end
+
+ def clear_zombies
+ begin
+ # Clear zombies just in case...
+ while(Process.waitpid(-1, Process::WNOHANG))
+ end
+ rescue ::Exception
+ end
+ end
end
end
end
diff --git a/lib/warvox/jobs/dialer.rb b/lib/warvox/jobs/dialer.rb
@@ -70,7 +70,7 @@ class Dialer < Base
model = get_job
model.status = 'active'
model.started_at = Time.now
- model.save
+ db_save(model)
start_dialing()
@@ -86,7 +86,7 @@ class Dialer < Base
model = get_job
model.status = 'completed'
model.completed_at = Time.now
- model.save
+ db_save(model)
end
def start_dialing
@@ -177,32 +177,18 @@ class Dialer < Base
end
# END SPAWN THREADS
tasks.map{|t| t.join if t}
-
- # Save data to the database
- begin
-
- # Iterate through the results
- @calls.each do |r|
- tries = 0
- begin
- r.save
- rescue ::Exception => e
- $stderr.puts "ERROR: #{r.inspe…
- tries += 1
- Kernel.select(nil, nil, nil, 0…
- retry if tries < 5
- end
- end
-
- # Update the progress bar
- model = get_job
- model.progress = ((@nums_total - @nums.length)…
- model.save
- rescue ::SQLite3::BusyException => e
- $stderr.puts "ERROR: Database lock hit trying …
- retry
+ # Iterate through the results
+ @calls.each do |r|
+ db_save(r)
end
+
+ # Update the progress bar
+ model = get_job
+ model.progress = ((@nums_total - @nums.length) / @nums…
+ db_save(model)
+
+ clear_zombies()
end
# ALL DONE
diff --git a/web/app/controllers/analyze_controller.rb b/web/app/controllers/an…
@@ -20,8 +20,8 @@ class AnalyzeController < ApplicationController
:conditions => [ 'completed = ? and processed = ? and busy = ?…
)
- @g1 = Ezgraphix::Graphic.new(:c_type => 'pie2d', :div_name => 'calls_p…
- @g1.render_options(:caption => 'Line Types')
+ @g1 = Ezgraphix::Graphic.new(:c_type => 'col3d', :div_name => 'calls_p…
+ @g1.render_options(:caption => 'Detected Lines by Type', :y_name => 'L…
@g2 = Ezgraphix::Graphic.new(:c_type => 'pie2d', :div_name => 'calls_p…
@g2.render_options(:caption => 'Ring Time')
diff --git a/web/app/controllers/dial_jobs_controller.rb b/web/app/controllers/…
@@ -79,8 +79,7 @@ class DialJobsController < ApplicationController
flash[:notice] = 'Job was successfully created.'
# Launch it
- dialer = WarVOX::Jobs::Dialer.new(@dial_job.id)
- WarVOX::JobManager.schedule(dialer)
+ WarVOX::JobManager.schedule(::WarVOX::Jobs::Dialer, @dial_job.id)
format.html { redirect_to(@dial_job) }
format.xml { render :xml => @dial_job, :status => :created, :location…
diff --git a/web/app/controllers/dial_results_controller.rb b/web/app/controlle…
@@ -38,6 +38,32 @@ class DialResultsController < ApplicationController
@job_id = params[:id]
@job = DialJob.find(@job_id)
+ @dial_data_total = DialResult.find_all_by_dial_job_id(
+ @job_id,
+ :conditions => [ 'completed = ? and busy = ?', true, false ]
+ ).length
+
+ @dial_data_done_set = DialResult.find_all_by_dial_job_id(
+ @job_id,
+ :conditions => [ 'processed = ?', true]
+ )
+ @dial_data_done = @dial_data_done_set.length
+
+ @g1 = Ezgraphix::Graphic.new(:c_type => 'col3d', :div_name => 'calls_p…
+ @g1.render_options(:caption => 'Detected Lines by Type', :y_name => 'L…
+
+ @g2 = Ezgraphix::Graphic.new(:c_type => 'pie2d', :div_name => 'calls_p…
+ @g2.render_options(:caption => 'Analysis Progress')
+
+ res_types = {}
+ @dial_data_done_set.each do |r|
+ res_types[ r.line_type.capitalize.to_sym ] ||= 0
+ res_types[ r.line_type.capitalize.to_sym ] += 1 …
+ end
+
+ @g1.data = res_types
+ @g2.data = {:Remaining => @dial_data_total-@dial_data_done, :Complete …
+
@dial_data_todo = DialResult.paginate_all_by_dial_job_id(
@job_id,
:page => params[:page],
@@ -52,8 +78,7 @@ class DialResultsController < ApplicationController
end
if(@dial_data_todo.length > 0)
- analyzer = WarVOX::Jobs::Analysis.new(@job_id)
- WarVOX::JobManager.schedule(analyzer)
+ WarVOX::JobManager.schedule(::WarVOX::Jobs::Analysis, @job_id)
end
end
diff --git a/web/app/models/dial_job.rb b/web/app/models/dial_job.rb
@@ -6,16 +6,16 @@ class DialJob < ActiveRecord::Base
validates_numericality_of :seconds, :less_than => 301, :greater_than =…
def validate
- if(range.gsub(/[^0-9X]/, '').length != 10)
- errors.add(:range, "The range must be exactly 10 chara…
+ if(range.gsub(/[^0-9X]/, '').empty?)
+ errors.add(:range, "The range must be at least 1 chara…
end
if(range.scan(/X/).length > 5)
errors.add(:range, "The range must contain no more tha…
end
- if(cid_mask != "SELF" and cid_mask.gsub(/[^0-9X]/, '').length …
- errors.add(:range, "The Caller ID must be exactly 10 c…
+ if(cid_mask != "SELF" and cid_mask.gsub(/[^0-9X]/, '').empty?)
+ errors.add(:range, "The Caller ID must be at least 1 c…
end
if(cid_mask != "SELF" and cid_mask.scan(/X/).length > 5)
diff --git a/web/app/views/dial_jobs/index.html.erb b/web/app/views/dial_jobs/i…
@@ -77,7 +77,7 @@
<% form_for(@new_job) do |f| %>
<%= f.error_messages %>
<p>
- <%= f.label :range, 'The target telephone range (123-456-XXXX)' %><br />
+ <%= f.label :range, 'The target telephone range (1-123-456-XXXX)' %><br />
<%= f.text_field :range %>
</p>
<p>
@@ -89,8 +89,8 @@
<%= f.text_field :lines, :value => 10 %>
</p>
<p>
- <%= f.label :lines, 'The source Caller ID range (555-555-55XX)' %><br />
- <%= f.text_field :cid_mask, :value => '000-000-XXXX' %>
+ <%= f.label :lines, 'The source Caller ID range (1-555-555-55XX)' %><br />
+ <%= f.text_field :cid_mask, :value => '1-123-456-XXXX' %>
</p>
<p>
<%= f.submit "Create" %>
diff --git a/web/app/views/dial_jobs/new.html.erb b/web/app/views/dial_jobs/new…
@@ -3,7 +3,7 @@
<% form_for(@dial_job) do |f| %>
<%= f.error_messages %>
<p>
- <%= f.label :range, 'The target telephone range (123-456-XXXX)' %><br />
+ <%= f.label :range, 'The target telephone range (1-123-456-XXXX)' %><br />
<%= f.text_field :range %>
</p>
<p>
@@ -15,8 +15,8 @@
<%= f.text_field :lines, :value => 10 %>
</p>
<p>
- <%= f.label :lines, 'The source Caller ID range (555-555-55XX or SELF)' %>…
- <%= f.text_field :cid_mask, :value => '000-000-XXXX' %>
+ <%= f.label :lines, 'The source Caller ID range (1-555-555-55XX or SELF)' …
+ <%= f.text_field :cid_mask, :value => '1-123-456-XXXX' %>
</p>
<p>
<%= f.submit "Create" %>
diff --git a/web/app/views/dial_results/analyze.html.rb b/web/app/views/dial_re…
@@ -1,40 +1,23 @@
<% if @dial_data_todo.length > 0 %>
-<h1 class='title'>Processing <%= @dial_data_todo.length %> Calls...</h1>
+<h1 class='title'>
+ Analyzing Calls ( completed <%= @dial_data_done %> of <%= @dial_data_t…
+ - <%= @dial_data_total-@dial_data_done %> left )...
+</h1>
<table width='100%' align='center' border=0 cellspacing=0 cellpadding=6>
<tr>
- <td align='center'> </td>
- <td align='center'> </td>
-</tr>
-</table>
-
-<table class='table_scaffold' width='100%'>
- <tr>
- <th>Number</th>
- <th>CallerID</th>
- <th>Provider</th>
- <th>Call Time</th>
- <th>Ring Time</th>
- </tr>
-
-<% for dial_result in @dial_data_todo.sort{|a,b| a.number <=> b.number } %>
- <tr>
- <td><%=h dial_result.number %></td>
- <td><%=h dial_result.cid %></td>
- <td><%=h dial_result.provider.name %></td>
- <td><%=h dial_result.seconds %></td>
- <td><%=h dial_result.ringtime %></td>
- </tr>
+<% if @dial_data_done > 0 %>
+ <td align='center'><%= render_ezgraphix @g1 %></td>
+ <td align='center'><%= render_ezgraphix @g2 %></td>
<% end %>
+</tr>
</table>
<script language="javascript">
- setTimeout("location.reload(true);", 3000);
+ setTimeout("location.reload(true);", 5000);
</script>
-<%= will_paginate @dial_data_todo %>
-
<% else %>
<h1 class='title'>No Completed Calls Found</h1>
diff --git a/web/app/views/home/index.html.erb b/web/app/views/home/index.html.…
@@ -16,7 +16,7 @@ In order to make phone calls, WarVOX needs to be configured w…
<p>Once one or more service providers have been configured, click the <a href=…
</p>
-<p>The phone number range is specified by entering the full 10-digit phone num…
+<p>The phone number range is specified by entering the phone number (including…
</p>
<p>
@@ -27,7 +27,7 @@ The seconds field indicates the number of seconds to spend on…
The outgoing line count is limited by the number of providers available and th…
</p>
-<p>The Caller ID is specified by entering the full 10-digit phone number, with…
+<p>The Caller ID is specified by entering the phone number (including country …
</p>
<p>
diff --git a/web/config/database.yml b/web/config/database.yml
@@ -4,7 +4,7 @@ development:
adapter: sqlite3
database: db/development.sqlite3
pool: 5
- timeout: 25000
+ timeout: 5000
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
@@ -13,10 +13,10 @@ test:
adapter: sqlite3
database: db/test.sqlite3
pool: 5
- timeout: 25000
+ timeout: 5000
production:
adapter: sqlite3
database: db/production.sqlite3
pool: 5
- timeout: 25000
+ timeout: 5000
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.