From 7b452f905b69f01827a79218e79d415db7b9dfaa Mon Sep 17 00:00:00 2001 From: jaywhy Date: Wed, 11 Oct 2006 21:34:33 +0000 Subject: [PATCH] Refactored some of the code. git-svn-id: svn://192.168.202.10@350 3d104415-ff17-0410-8863-d5cf3c621b8a --- .../branches/agc_30/lib/Astguiclient/AGI.pm | 155 +++-------------- .../agc_30/lib/Astguiclient/AGI/CallLog.pm | 62 +++++++ .../agc_30/lib/Astguiclient/AGI/Transfer.pm | 161 ++++++++++++++++++ .../agc_30/lib/Astguiclient/Daemon/AGI.pm | 39 +++-- agc_2-X/branches/agc_30/t/00-load.t | 3 +- 5 files changed, 277 insertions(+), 143 deletions(-) create mode 100644 agc_2-X/branches/agc_30/lib/Astguiclient/AGI/CallLog.pm create mode 100644 agc_2-X/branches/agc_30/lib/Astguiclient/AGI/Transfer.pm diff --git a/agc_2-X/branches/agc_30/lib/Astguiclient/AGI.pm b/agc_2-X/branches/agc_30/lib/Astguiclient/AGI.pm index 4bb11232..ac9f1f40 100644 --- a/agc_2-X/branches/agc_30/lib/Astguiclient/AGI.pm +++ b/agc_2-X/branches/agc_30/lib/Astguiclient/AGI.pm @@ -1,11 +1,13 @@ package Astguiclient::AGI; use strict; -use Asterisk::AGI; -use Time::HiRes qw( gettimeofday tv_interval usleep ); use base qw/Astguiclient Class::Accessor::Fast/; -__PACKAGE__->mk_accessors( qw/ agi input / ); +use Asterisk::AGI; +use Astguiclient::AGI::CallLog; +use Astguiclient::AGI::Transfer; + +__PACKAGE__->mk_accessors( qw/ agi method path params / ); =head1 NAME @@ -28,151 +30,50 @@ sub new { return $self; } -=head2 call_log +=head2 input =cut -sub call_log { +sub input { my $self = shift; - my $dbh = $self->dbi; - - if( $self->agi->{'extension'} =~ /h/i ) { - $dbh->do("UPDATE call_log SET end_time = NOW() WHERE uniqueid = ?", undef, $self->input->{'uniqueid'}); - } else { - my $i = $self->input; - $dbh->do("INSERT INTO call_log - SET uniqueid = ?, channel = ?, type = ?, server_ip = ?, - extension = ?, start_time = now(), end_time = ?" - undef, - $i->{'uniqueid'},$i->{'channel'},$i->{type}, - $self->config->file->{'Server'}{'Server_ip'},$i->{'extension'} - ); - } -} - -=head2 vdad_transfer - -Runs when a call comes in from the VICIDIAL_auto_dialer. This script will -Send the calls out to the reps that are logged in. - -0 Channel is down and available -1 Channel is down, but reserved -2 Channel is off hook -3 Digits (or equivalent) have been dialed -4 Line is ringing -5 Remote end is ringing -6 Line is up -7 Line is busy - -=cut - -#NOTE: This function isn't nearly complete. -# Where else is this log functionality? -# Is there other transfer or voicemail calls? -sub vdad_transfer { - my $self = shift; - - # Caller id houses the leadid and campaignid, sent by place_call() - my($lead_id, $campaign_id) = split(/:/, $self->input->{callerid}); - - my $campaign = $self->campaign->find( id => $campaign_id ); - - # When a call is answered, this timer begins. - my $drop_start_timer; - - # Time for the start of the loop - my $start_timer = [gettimeofday]; - - # Amount of time you should wait for answer before hanging up(how many rings essentially) - my $call_wait_time = '30'; - - TRANSFER: while( tv_interval( $start_timer, [gettimeofday] ) > $call_wait_time ) { - my $status = $self->agi->check_status(); - - # Line is down or busy. - if( ( $status < 3 ) || - ( $status == 7 ) ) { - last TRANSFER; - } elsif( $status == 6 ) { # Line is answered - $drop_start_timer = [gettimeofday]; - } - - $self->_transfer_to_agent( $campaign ); + if( not defined $self->{input} ) { + $self->{input} = $self->agi->ReadParse(); - if( tv_interval( $drop_start_timer, [gettimeofday] ) ) { - $self->_send_to_voicemail( $campaign ); - last; - } - - usleep(1*990*1000); } -#XXX $self->_log_call( $call_status ); + return $self->{input} } -sub _log_call { - my($self, $call_status) = @_; - -#XXX -# if( lc($call_status) eq 'drop' ) { -# $self->dbh->do("DELETE FROM vicidial_auto_calls where callerid = ?", undef, $callerid); -# } - -# $self->dbh->do("UPDATE vicidial_log set status = ?,end_time = NOW() WHERE uniqueid = ?", undef, $status, $unique_id); -# $self->dbh->do("UPDATE vicidial_list set status='DROP' where lead_id = '$CIDlead_id'"); - -} - -=head2 _send_to_voicemail - -Transfer a call to voicemail of the campaign. +=head2 _parse_request =cut -sub _send_to_voicemail { - my( $self, $campaign ) = @_; +sub _parse_request { + my $self = shift; + my($method, $path) = $self->{input}{'request'} =~ m/\/(\w+)\?*([^\.]*)$/; - $self->_transfer( $campaign->{voicemail_ext} ); + my %params; + my(@pairs) = split(/[&;]/,$path); + foreach (@pairs) { + my($p,$v) = split('=',$_,2); + $params{$p} = $v; + } + + $self->params( \%params ); + $self->method( $method ); + $self->path( $path ); } -=head2 _transfer - -Transfers a call. +=head2 param =cut -sub _transfer { - my( $self, $ext ) = @_; - - $self->agi->set_context( 'default' ); - $self->agi->set_extension( $ext ); +sub param { + my($self, $param) = @_; + return $self->params->{$param}; } -=head2 _transfer_to_agent - -Transfer the call to an available agent. - -=cut - -sub _transfer_to_agent { - my( $self, $campaign ) = @_; - - my($conf_exten, $user, $extension) = $self->dbi->selectrow_arary(" - SELECT conf_exten,extension FROM vicidial_live_agents - WHERE status = 'QUEUE' and server_ip = ? and campaign_id = ? - ORDER BY last_call_time limit 1", - undef, - Astguiclient->config->file->{'Server_ip'}, $campaign->{campaign_id}, - ); - - $self->_transfer( $extension ); - - #XXX$self->dbh->do("UPDATE vicidial_auto_calls set status='XFER' WHERE callerid = ?", undef, $callerid); - -} - - =head1 AUTHOR Jason Yates diff --git a/agc_2-X/branches/agc_30/lib/Astguiclient/AGI/CallLog.pm b/agc_2-X/branches/agc_30/lib/Astguiclient/AGI/CallLog.pm new file mode 100644 index 00000000..9288c961 --- /dev/null +++ b/agc_2-X/branches/agc_30/lib/Astguiclient/AGI/CallLog.pm @@ -0,0 +1,62 @@ +package Astguiclient::AGI; + +use strict; + +=head1 NAME + +Astguiclient::AGI::CallLog - Handles FastAGI call logging. + +=head1 DESCRIPTION + +The module handles FastAGI call logging. The module acts sort of like +a plugin by exporting mixins. + + +=head2 call_log + +=cut + +sub call_log { + my $self = shift; + + my $dbh = $self->dbi; + + if( $self->agi->{'extension'} =~ /h/i ) { + $dbh->do("UPDATE call_log SET end_time = NOW() WHERE uniqueid = ?", undef, $self->input->{'uniqueid'}); + } else { + my $i = $self->input; + $dbh->do("INSERT INTO call_log + SET uniqueid = ?, channel = ?, type = ?, server_ip = ?, + extension = ?, start_time = now(), end_time = ?", + undef, + $i->{'uniqueid'},$i->{'channel'},$i->{type}, + $self->config->file->{'Server'}{'Server_ip'},$i->{'extension'} + ); + } +} + +=head1 AUTHOR + +Jason Yates + +=head1 COPYRIGHT AND LICENSE + +Copyright (C) 2006 Matt Florell + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut + +1; diff --git a/agc_2-X/branches/agc_30/lib/Astguiclient/AGI/Transfer.pm b/agc_2-X/branches/agc_30/lib/Astguiclient/AGI/Transfer.pm new file mode 100644 index 00000000..1db79152 --- /dev/null +++ b/agc_2-X/branches/agc_30/lib/Astguiclient/AGI/Transfer.pm @@ -0,0 +1,161 @@ +package Astguiclient::AGI; + +use strict; +use Time::HiRes qw( gettimeofday tv_interval usleep ); + +=head1 NAME + +Astguiclient::AGI - Module used for AGI scripts. + +=head1 DESCRIPTION + +The module handles transfering calls. The module acts sort of like +a plugin by exporting mixins. + +=head2 vdad_transfer + +Runs when a call comes in from the VICIDIAL_auto_dialer. This script will +Send the calls out to the reps that are logged in. + +0 Channel is down and available +1 Channel is down, but reserved +2 Channel is off hook +3 Digits (or equivalent) have been dialed +4 Line is ringing +5 Remote end is ringing +6 Line is up +7 Line is busy + +=cut + +#NOTE: This function isn't nearly complete. +# Where else is this log functionality? +# Is there other transfer or voicemail calls? +sub vdad_transfer { + my $self = shift; + + # Caller id houses the leadid and campaignid, sent by place_call() + my($lead_id, $campaign_id) = split(/:/, $self->input->{callerid}); + + my $campaign = $self->campaign->find( id => $campaign_id ); + + # When a call is answered, this timer begins. + my $drop_start_timer; + + # Time for the start of the loop + my $start_timer = [gettimeofday]; + + # Amount of time you should wait for answer before hanging up(how many rings essentially) + my $call_wait_time = '30'; + + TRANSFER: while( tv_interval( $start_timer, [gettimeofday] ) > $call_wait_time ) { + my $status = $self->agi->check_status(); + + # Line is down or busy. + if( ( $status < 3 ) || + ( $status == 7 ) ) { + last TRANSFER; + } elsif( $status == 6 ) { # Line is answered + $drop_start_timer = [gettimeofday]; + } + + $self->_transfer_to_agent( $campaign ); + + if( tv_interval( $drop_start_timer, [gettimeofday] ) ) { + $self->_send_to_voicemail( $campaign ); + last; + } + + usleep(1*990*1000); + } + +#XXX $self->_log_call( $call_status ); +} + +sub _log_call { + my($self, $call_status) = @_; + +#XXX +# if( lc($call_status) eq 'drop' ) { +# $self->dbh->do("DELETE FROM vicidial_auto_calls where callerid = ?", undef, $callerid); +# } + +# $self->dbh->do("UPDATE vicidial_log set status = ?,end_time = NOW() WHERE uniqueid = ?", undef, $status, $unique_id); +# $self->dbh->do("UPDATE vicidial_list set status='DROP' where lead_id = '$CIDlead_id'"); + +} + +=head2 _send_to_voicemail + +Transfer a call to voicemail of the campaign. + +=cut + +sub _send_to_voicemail { + my( $self, $campaign ) = @_; + + $self->_transfer( $campaign->{voicemail_ext} ); +} + +=head2 _transfer + +Transfers a call. + +=cut + +sub _transfer { + my( $self, $ext ) = @_; + + $self->agi->set_context( 'default' ); + $self->agi->set_extension( $ext ); +} + +=head2 _transfer_to_agent + +Transfer the call to an available agent. + +=cut + +sub _transfer_to_agent { + my( $self, $campaign ) = @_; + + my($conf_exten, $user, $extension) = $self->dbi->selectrow_arary(" + SELECT conf_exten,extension FROM vicidial_live_agents + WHERE status = 'QUEUE' and server_ip = ? and campaign_id = ? + ORDER BY last_call_time limit 1", + undef, + Astguiclient->config->file->{'Server_ip'}, $campaign->{campaign_id}, + ); + + $self->_transfer( $extension ); + + #XXX$self->dbh->do("UPDATE vicidial_auto_calls set status='XFER' WHERE callerid = ?", undef, $callerid); + +} + + +=head1 AUTHOR + +Jason Yates + +=head1 COPYRIGHT AND LICENSE + +Copyright (C) 2006 Matt Florell + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + +=cut + +1; diff --git a/agc_2-X/branches/agc_30/lib/Astguiclient/Daemon/AGI.pm b/agc_2-X/branches/agc_30/lib/Astguiclient/Daemon/AGI.pm index 665f156e..bd8e11c9 100644 --- a/agc_2-X/branches/agc_30/lib/Astguiclient/Daemon/AGI.pm +++ b/agc_2-X/branches/agc_30/lib/Astguiclient/Daemon/AGI.pm @@ -22,26 +22,35 @@ This will process the agi request from asterisk. sub process_request { my $self = shift; - my $agc = $self->{server}{agc}; - - my %input = $agc->agi->ReadParse; - use Data::Dumper; - print STDERR Dumper(\%input); - my($method, $path) = $input{'request'} =~ m/\/(\w+)\?*([^\.]*)$/; - my %params; - my(@pairs) = split(/[&;]/,$path); - foreach (@pairs) { - my($p,$v) = split('=',$_,2); - $params{$p} = $v; - } - $agc->input( \%params ); - if( $agc->can( $method ) ) { + $self->_parse_request(); + $self->_handle_request(); +} + +=head2 _handle_request + +=cut + +sub _handle_request { + my $self = shift; + + my $agc = $self->agc; + if( $agc->can( $agc->method ) ) { + my $method = $agc->method; $agc->$method(); } else { # Can't find that method. $agc->agi->execute( 'NOOP' ); #NOTE is this the right thing todo? } -} +} + +=head2 agc + +=cut + +sub agc { + my $self = shift; + return $self->{server}{agc}; +} =head2 child_init_hook diff --git a/agc_2-X/branches/agc_30/t/00-load.t b/agc_2-X/branches/agc_30/t/00-load.t index c90b2409..4056786a 100644 --- a/agc_2-X/branches/agc_30/t/00-load.t +++ b/agc_2-X/branches/agc_30/t/00-load.t @@ -1,7 +1,8 @@ #!/usr/bin/perl -w use strict; -use Test::More tests => 2; +use Test::More tests => 3; use_ok("Astguiclient"); use_ok("Astguiclient::Daemon::AGI"); +use_ok("Astguiclient::AGI");