From 79df9da17cf54366ef027a941c131cb1a016068e Mon Sep 17 00:00:00 2001 From: Mark Wells Date: Wed, 26 Nov 2014 14:54:02 -0800 Subject: [PATCH] Thinktel CDR format and download script, #32088 --- FS/FS/cdr/thinktel.pm | 42 ++++++++++++++++ bin/cdr-thinktel.import | 126 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 168 insertions(+) create mode 100644 FS/FS/cdr/thinktel.pm create mode 100644 bin/cdr-thinktel.import diff --git a/FS/FS/cdr/thinktel.pm b/FS/FS/cdr/thinktel.pm new file mode 100644 index 000000000..ddb2127a6 --- /dev/null +++ b/FS/FS/cdr/thinktel.pm @@ -0,0 +1,42 @@ +package FS::cdr::thinktel; + +use strict; +use base qw( FS::cdr ); +use FS::cdr qw( _cdr_date_parser_maker _cdr_min_parser_maker ); + +our %info = ( + 'name' => 'Thinktel', + 'weight' => 541, + 'header' => 1, #0 default, set to 1 to ignore the first line, or + # to higher numbers to ignore that number of lines + 'type' => 'csv', #csv (default), fixedlength or xls + 'sep_char' => ',', #for csv, defaults to , + 'disabled' => 0, #0 default, set to 1 to disable + + #listref of what to do with each field from the CDR, in order + 'import_fields' => [ + 'charged_party', + 'src', + 'dst', + _cdr_date_parser_maker('startdate'), + 'billsec', # rounded call duration + 'dcontext', # Usage Type: 'Local', 'Canada', 'Incoming', ... + 'upstream_price', + 'upstream_src_regionname', + 'upstream_dst_regionname', + '', # upstream rate per minute + '', # "Label" + # raw seconds, to one decimal place + sub { my ($cdr, $sec) = @_; + $cdr->set('duration', sprintf('%.0f', $sec)); + }, + # newly added fields of unclear meaning: + # Subscription (UUID, seems to correspond to charged_party) + # Call Type (always "Normal" thus far) + # Carrier (always empty) + # Alt Destination Name (always empty) + ], +); + +1; + diff --git a/bin/cdr-thinktel.import b/bin/cdr-thinktel.import new file mode 100644 index 000000000..ccbd78c39 --- /dev/null +++ b/bin/cdr-thinktel.import @@ -0,0 +1,126 @@ +#!/usr/bin/perl + +use strict; +use Getopt::Std; +use Date::Format; +use File::Temp 'tempdir'; +use Net::FTP; +use FS::UID qw(adminsuidsetup datasrc dbh); +use FS::cdr; +use FS::cdr_batch; +use FS::Record qw(qsearch qsearchs); +use Date::Format 'time2str'; +use Date::Parse 'str2time'; + + +### +# parse command line +### + +use vars qw( $opt_d $opt_v $opt_c $opt_s $opt_e $opt_a ); +getopts('dvc:s:e:a'); + +my ($user, $login, $password) = @ARGV; +($user and $login and $password) or die &usage; + +my $dbh = adminsuidsetup $user; +$FS::UID::AutoCommit = 0; + +# index already-downloaded batches +my @previous = qsearch({ + 'table' => 'cdr_batch', + 'hashref' => { 'cdrbatch' => {op=>'like', value=>'thinktel%'} }, + 'order_by' => 'ORDER BY cdrbatch DESC', +}); +my %exists = map {$_->cdrbatch => 1} @previous; + +my $tempdir = tempdir( CLEANUP => !$opt_v ); + +my $format = 'thinktel'; +my $hostname = 'ucontrol.thinktel.ca'; + +my $ftp = Net::FTP->new($hostname, Debug => $opt_d) + or die "Can't connect to $hostname: $@\n"; + +$ftp->login($login, $password) + or die "Login failed: ".$ftp->message."\n"; + +### +# get the file list +### + +warn "Retrieving directory listing\n" if $opt_v; + +$ftp->cwd('/'); +my @files = $ftp->ls(); +warn scalar(@files)." CDR files found.\n" if $opt_v; +# apply date range +if ( $opt_a ) { + my $most_recent = $previous[0]; + if ($most_recent) { + if ($most_recent->cdrbatch =~ /^thinktel-(\d+)/) { + my $date = $1; + warn "limiting to dates > $date (from most recent batch)\n" if $opt_v; + @files = grep { /^(\d+)_/ && $1 > $date } @files; + } + } # else download them all +} +if ( $opt_s ) { + # start date + # normalize date format + $opt_s = time2str('%Y%m%d', str2time($opt_s)) if $opt_s =~ /\D/; + warn "limiting to dates > $opt_s\n" if $opt_v; + @files= grep { /^(\d+)_/ && $1 >= $opt_s } @files; +} +if ( $opt_e ) { + # end date + $opt_e = time2str('%Y%m%d', str2time($opt_e)) if $opt_e =~ /\D/; + warn "limiting to dates < $opt_e\n" if $opt_v; + @files= grep { /^(\d+)_/ && $1 < $opt_e } @files; +} +warn scalar(@files) ." files to be downloaded to '$tempdir'\n" if $opt_v; +foreach my $file (@files) { + + warn "downloading $file\n" if $opt_v; + $ftp->get($file, "$tempdir/$file"); + warn "processing $file\n" if $opt_v; + + my $batchname = "$format-$file"; + if ($exists{$batchname}) { + warn "already imported $file\n"; + next; + } + my $import_options = { + 'file' => "$tempdir/$file", + 'format' => $format, + 'batch_namevalue' => $batchname, + 'empty_ok' => 1, + }; + $import_options->{'cdrtypenum'} = $opt_c if $opt_c; + + my $error = FS::cdr::batch_import($import_options); + + if ( $error ) { + die "error processing $file: $error\n"; + } +} +warn "finished\n" if $opt_v; +$dbh->commit; + +### +# subs +### + +sub usage { + "Usage: \n cdr-thinktel.import [ options ] user login password + Options: + -v: be verbose + -d: enable FTP debugging (very noisy) + -c num: apply a cdrtypenum to the imported CDRs + -s date: start date + -e date: end date + -a: automatically choose start date from most recently downloaded batch + +"; +} + -- 2.11.0