diff --git a/agc_2-X/branches/agc_30/bin/agcd.pl b/agc_2-X/branches/agc_30/bin/agcd.pl new file mode 100644 index 00000000..5116c3f8 --- /dev/null +++ b/agc_2-X/branches/agc_30/bin/agcd.pl @@ -0,0 +1,56 @@ +#!/usr/bin/perl + +use strict; +use lib '../lib'; + +use Astguiclient::Server; + +Astguiclient::Server->run( port => '4573' ); + + +__END__ + +=head1 NAME + +check_ast_status.pl + +=head1 SYNOPSIS + +check_ast_status.pl start|stop|restart|check + +=head1 DESCRIPTION + +Check the running Astguiclient processes, making sure they are +running. + +=head1 OPTIONS + +=over 8 + +=item + +Description here. + +=back + +=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. diff --git a/agc_2-X/branches/agc_30/bin/ast_status.pl b/agc_2-X/branches/agc_30/bin/ast_status.pl new file mode 100755 index 00000000..04512f23 --- /dev/null +++ b/agc_2-X/branches/agc_30/bin/ast_status.pl @@ -0,0 +1,163 @@ +#!/usr/bin/perl + +use strict; +use lib '../lib'; + +use Astguiclient::Config; +use Astguiclient::Util; +use Text::SimpleTable; +use File::Spec; +use Time::HiRes qw( usleep ); +use Getopt::Long; +use Pod::Usage; + +my $file = Astguiclient::Config->file(); + +my @procs = @{ $file->{'Processes'} }; + +my %opts; +GetOptions(\%opts, 'help|h', 'debug|d=i', 'config|c=s'); +pod2usage(1) if $opts{'help'}; + +my $cmd = $ARGV[0]; +if( $cmd eq 'check' ) { + check(); +} elsif( $cmd eq 'start' ) { + start(); +} elsif( $cmd eq 'stop' ) { + stop(); +} elsif( $cmd eq 'restart' ) { + stop(); + start(); +} elsif( $cmd eq 'checkstart' ) { + checkstart(); +} else { + print "Unrecognized command.\n"; + pod2usage(1); +} + +sub check { + my $t1 = Text::SimpleTable->new( [ 20, 'Process'] , [ 8, 'Status' ] ); + foreach my $proc ( @procs ) { + my $pidfile = File::Spec->catfile( Astguiclient::Util->app_root(), 'run', $proc ); + if( not -f $pidfile ) { + # No pid file means the process is down. + $t1->row( $proc, 'OFF' ); + } else { + open(FH, $pidfile ) or die "Can't open pidfile $pidfile: $!"; + my $pid = ; + + # Test if the process is up. + if( kill 0 => $pid ) { + $t1->row( $proc, 'ON' ); + } else { + # If the pid file exists and the process doesn't. Most likely + # the process crashed. + $t1->row( $proc, 'OFF - CRASHED' ); + } + } + } + + print $t1->draw; +} + +sub start { + my(@start) = @_; + + @start = @procs unless @start; + print "Starting processes\n"; + foreach my $start (@start) { + my $script = File::Spec->catfile( Astguiclient::Util->app_root(), 'bin', $start ); + print "$script\t\t"; + `$script`; + print "[ on ]\n" + } +} + +sub restart { + stop(); + start(); +} + +sub stop { + my(@stop) = @_; + + @stop = @procs unless @stop; + print "Stoping processes\n"; + foreach my $proc ( @procs ) { + my $pidfile = File::Spec->catfile( Astguiclient::Util->app_root(), 'run', $proc ); + _pidfile_kill($pidfile); + } +} + +sub _pidfile_kill { + my $pidfile = shift; + open(FH, $pidfile ) or die "Can't open pidfile $pidfile: $!"; + my $pid = ; + close(FH); + + kill("TERM", $pid); + usleep(100000); + kill("KILL", $pid) if( kill( 0, $pid)); +} + +#`/usr/bin/screen -d -m -S ASTlisten $PATHhome/AST_manager_listen.pl`; +#`/usr/bin/screen -d -m -S ASTsend $PATHhome/AST_manager_send.pl`; +#`/usr/bin/screen -d -m -S ASTupdate $PATHhome/AST_update.pl`; +#`/usr/bin/screen -d -m -S ASTVDadapt $PATHhome/AST_VDadapt.pl --debug`; +#`/usr/bin/screen -d -m -S ASTVDremote $PATHhome/AST_VDremote_agents.pl`; + +__END__ + +=head1 NAME + +ast_status.pl + +=head1 SYNOPSIS + +ast_status.pl start|stop|restart|check|checkstart + +=head1 DESCRIPTION + +Check the running Astguiclient processes, making sure they are +running. + +=head1 OPTIONS + +=over 8 + +=item start + +=item stop + +=item restart + +=item check + +=item checkstart + +If the process is down or crashed and shouldn't be then start it. + +=back + +=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. diff --git a/agc_2-X/branches/agc_30/etc/agcd.conf b/agc_2-X/branches/agc_30/etc/agcd.conf new file mode 100644 index 00000000..e8785e9e --- /dev/null +++ b/agc_2-X/branches/agc_30/etc/agcd.conf @@ -0,0 +1,24 @@ +### server information +min_servers 3 +max_servers 8 +min_spare_servers 3 + +max_requests 1000 + +### user and group to become +#user astguiclient +#group astguiclient + +### logging ? +log_file ../log/agcd.log +log_level 3 +pid_file ../run/agcd.pid + +### access control + +### background the process? +#background 1 + +### ports to bind +host 127.0.0.1 +port 4573 diff --git a/agc_2-X/branches/agc_30/etc/astguiclient.yaml b/agc_2-X/branches/agc_30/etc/astguiclient.yaml new file mode 100644 index 00000000..1ea9fd29 --- /dev/null +++ b/agc_2-X/branches/agc_30/etc/astguiclient.yaml @@ -0,0 +1,14 @@ +Server: + Server_ip: +Database: + Host: localhost + User: jaywhy + Password: 'password' + Port: 3306 + DB_name: astguiclient +Processes: + - AST_manager_listen + - AST_manager_send + - AST_update + - AST_VDadapt + - AST_VDremote_agents diff --git a/agc_2-X/branches/agc_30/lib/Astguiclient.pm b/agc_2-X/branches/agc_30/lib/Astguiclient.pm new file mode 100644 index 00000000..97270da6 --- /dev/null +++ b/agc_2-X/branches/agc_30/lib/Astguiclient.pm @@ -0,0 +1,61 @@ +package Astguiclient; + +use strict; + +use Astguiclient::Config (); +use Astguiclient::DBI (); +use base 'Class::Accessor::Fast'; + +__PACKAGE__->mk_accessors( + qw( config dbi ) +); + +=head1 NAME + +Astguiclient - Main application module. + +=head1 DESCRIPTION + +This is Astguiclient. + +=head2 new + +=cut + +sub new { + my $class = shift; + + my $self = bless {}, $class; + + # Setup accessors; + $self->config( Astguiclient::Config->new() ); + $self->dbi( Astguiclient::DBI->connect( $self->config ) ); +} + +=head2 load + +=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.pm b/agc_2-X/branches/agc_30/lib/Astguiclient/AGI.pm new file mode 100644 index 00000000..cc3b4a7a --- /dev/null +++ b/agc_2-X/branches/agc_30/lib/Astguiclient/AGI.pm @@ -0,0 +1,174 @@ +package Astguiclient::AGI; + +use strict; +use Time::HiRes qw( gettimeofday tv_interval usleep ); +use base qw/Astguiclient Class::Accessor::Fast/; + +__PACKAGE__->mk_accessor(qw//); + +=head1 NAME + +Astguiclient::AGI - Module used for AGI scripts. + +=head1 DESCRIPTION + +Give description here + +=head2 new + +=cut + +sub new { + my $class = shift; + return bless {}, $class; +} + +=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, $unique_id); + $dbh->do("DELETE FROM live_inbound WHERE uniqueid = ? AND server_ip = ?", undef, $unique_id, $self->file->{'server_ip'}); + + #NOTE: Not sure of the logic here. + #"UPDATE park_log set status='HUNGUP',hangup_time='$now_date',parked_sec='$parked_sec',talked_sec='$talked_sec' where uniqueid='$unique_id' and server_ip='$VARserver_ip'"; + #"SELECT UNIX_TIMESTAMP(parked_time),UNIX_TIMESTAMP(grab_time) FROM park_log where uniqueid='$unique_id' and server_ip='$VARserver_ip' LIMIT 1;"; + } else { + $dbh->do("INSERT INTO call_log + (uniqueid,channel,channel_group,type,server_ip,extension, + number_dialed,start_time,end_time,caller_code) + VALUES(?,?,?,?,?,?,?,?,'',?)", + undef, + $unique_id,$channel,$channel_group,$type,$VARserver_ip, + $extension,$number_dialed,$now_date,$now_date_epoch,$callerid + ); + } +} + +=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. +# Is the campaign() basically a singleton? +# Where else is this log functionality? +# Is there other transfer or voicemail calls? +# Where should this campaign method be put? +# Write the campaign first.. +sub vdad_transfer { + my $self = shift; + + my %campaign = $self->campaign($campaign_id); + + # When a call is answered, this timer begins. + my $drop_start_timer; + + # Time for the start of the loop + my $start_time = [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_time, [gettimeofday] ) > $call_wait_time ) { + my $status = $self->agi->check_status(); + + # Line is down or busy. + if( ( $status < 3 ) || + ( $status == 7 ) ) { + $self->_log_call( $status ); + last; + } elsif( $status == 6 ) { # Line is answered + $start_timer = [gettimeofday]; + } + + $self->_transfer_to_agent(); + + if( tv_interval( $start_timer, [gettimeofday] ) { + $self->_send_to_voicemail(); + last; + } + } + + $self->_log_call( $call_status ); +} + +sub _log_call { + my($self, $call_status) = @_; + + 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'"); + +} + +sub _send_to_voicemail { + my $self = shift; + + $self->agi->set_context( $ext_context ); + $self->agi->set_extension( $drop_exten ); +} + +sub _transfer_to_agent { + my $self = shift; + + 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 = ? and callerid = ? and channel= ? + ORDER BY last_call_time limit 1", + undef, + #XXX + ); + + $self->agi->set_context( $ext_context ); + $self->agi->set_extension( $drop_exten ); + + $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/Config.pm b/agc_2-X/branches/agc_30/lib/Astguiclient/Config.pm new file mode 100644 index 00000000..3e1317a4 --- /dev/null +++ b/agc_2-X/branches/agc_30/lib/Astguiclient/Config.pm @@ -0,0 +1,76 @@ +package Astguiclient::Config; + +use strict; +use YAML::Syck; + +use vars qw( $SERVER $FILE ); + +=head1 name + +Astguiclient::Config - Manage the configuration file. + +=head1 DESCRIPTION + +=head2 new + +Object constructor + +=cut + +sub new { + my $class = shift; + return bless {}, $class; +} + +=head2 load + +Load the configuration file. + +=cut + +sub file { + my $self = shift; + + return $FILE if defined $FILE; + + my $file = Astguiclient::Util->app_root . '/etc/astguiclient.yaml'; + $FILE = LoadFile($file); +} + +sub server { + my $self = shift; + + return $SERVER if defined $SERVER; + + $SERVER = Astguiclient->dbi->selectrow_hashref( + "SELECT * FROM servers where server_ip = ?", + undef, + Astguiclient->config->file->{'Server'}{'Server_ip'} + ); +} + +=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/DBI.pm b/agc_2-X/branches/agc_30/lib/Astguiclient/DBI.pm new file mode 100644 index 00000000..1cbc29d3 --- /dev/null +++ b/agc_2-X/branches/agc_30/lib/Astguiclient/DBI.pm @@ -0,0 +1,48 @@ +package Astguiclient::DBI; + +use strict; +use DBI; + +=head1 NAME + +Astguiclient::DBI - The database. + +=head1 DESCRIPTION + +=head2 connect + +=cut + +sub connect { + my($class, $c) = @_; + + my $dsn = "DBI:mysql:datbase=$c->file->{'Database'}{'DB_name'};host=$c->file->{'Database'}{'Host'};port=$c->file->{'Database'}{'Port'}"; + + return DBI->connect( $dsn, $c->file->{'Database'}{'User'}, $c->file->{'Database'}{'Password'} ); +} + +=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/Log.pm b/agc_2-X/branches/agc_30/lib/Astguiclient/Log.pm new file mode 100644 index 00000000..24656a15 --- /dev/null +++ b/agc_2-X/branches/agc_30/lib/Astguiclient/Log.pm @@ -0,0 +1,54 @@ +package Astguiclient::Log + +=head1 NAME + +Astguiclient::Log - Log functions + +=head1 DESCRIPTION + +=head2 + +Returns the root directory where Astguiclient has been installed. + +=cut + +sub app_root { + my $self = shift; + + if( not defined $APP_ROOT ) { + # Pop out bin/ from the cwd + my @dirs = File::Spec->splitdir( Cwd::cwd() ); + pop @dirs; + $APP_ROOT = File::Spec->catdir( @dirs ); + } + + return $APP_ROOT; +} + +=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/Server.pm b/agc_2-X/branches/agc_30/lib/Astguiclient/Server.pm new file mode 100644 index 00000000..df0927a1 --- /dev/null +++ b/agc_2-X/branches/agc_30/lib/Astguiclient/Server.pm @@ -0,0 +1,73 @@ +package Astguiclient::Server; + +use strict; +use vars qw(@ISA); + +use Net::Server::PreFork; # any personality will do +use Astguiclient::AGI; + +@ISA = qw(Net::Server::PreFork); + +=head1 name + +Astguiclient::Server - Preforking fastagi server. + +=head1 DESCRIPTION + +=head2 process_request + +This will process the agi request from asterisk. + +=cut + +sub process_request { + my $self = shift; + my $agc = $self->{server}{agc}; + + my %input = $agc->agi->ReadParse; + my($method, $path) = $input{'request'} =~ m/\/(\w+)\?*([^\.]*)$/; + my %params; + my(@pairs) = split(/[&;]/,$path); + foreach (@pairs) { + my($p,$v) = split('=',$_,2); + $params{$p} = $v; + } + + $self->input( \%params ); + $agc->$method(); +} + +=head2 child_init_hook + +=cut + +sub child_init_hook { + my $self = shift; + $self->{server}{agc} = Astguiclient::AGI->new; +} + +=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/Util.pm b/agc_2-X/branches/agc_30/lib/Astguiclient/Util.pm new file mode 100644 index 00000000..577f4c5d --- /dev/null +++ b/agc_2-X/branches/agc_30/lib/Astguiclient/Util.pm @@ -0,0 +1,57 @@ +package Astguiclient::Util; + +use File::Spec; +use Cwd; + +our @dirs; + +=head1 NAME + +Astguiclient::Util - Util functions + +=head1 DESCRIPTION + +=head2 app_root + +Returns the root directory where Astguiclient has been installed. + +=cut + +sub app_root { + my $self = shift; + + if( not defined $APP_ROOT ) { + # Pop out bin/ from the cwd + my @dirs = File::Spec->splitdir( Cwd::cwd() ); + pop @dirs; + $APP_ROOT = File::Spec->catdir( @dirs ); + } + + return $APP_ROOT; +} + +=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;