a79477c51ab4e59b3222a72cc8b2828144454a0a
[freeside.git] / FS / bin / freeside-cdr-conexiant-import
1 #!/usr/bin/perl
2
3 use strict;
4
5 use Cpanel::JSON::XS;
6 use Getopt::Long;
7 use LWP::UserAgent;
8 use MIME::Base64;
9 use Net::HTTPS::Any qw(https_post https_get);
10
11 use FS::UID qw(adminsuidsetup);
12 use FS::Record qw(qsearchs);
13 use FS::cdr;
14 use FS::cdr_batch;
15
16 sub usage {
17 "Usage:
18 freeside-cdr-conexiant-import -h -u username -p apikey [-v] freesideuser
19
20 Downloads any existing CDR files with the BilledCallsOnly flag and 
21 imports records that have not been imported yet.  Silently skips 
22 records that have already been imported.
23 ";
24 }
25
26 # should really be using a module for this
27 `which unzip` or die "can't find unzip executable";
28
29 my ($username,$password,$verbose);
30 GetOptions(
31   "password=s"  => \$password,
32   "username=s"  => \$username,
33   "verbose"     => \$verbose,
34 );
35
36 my $fsuser = $ARGV[-1];
37
38 die usage() unless $fsuser;
39
40 adminsuidsetup($fsuser);
41
42 my ( $page, $response, %reply_headers ) = https_post(
43   'host'    => 'api.conexiant.net',
44   'port'    => '443',
45   'path'    => '/v1/Cdrs/SearchCdrsDownloads',
46   'headers' => {
47     'Authorization' => 'Basic ' . MIME::Base64::encode("$username:$password",'')
48   },
49   'content' => '{}',
50 );
51
52 die "Bad response from conexiant server: $response"
53   unless $response =~ /^200/;
54
55 my $result = decode_json($page);
56
57 die "Error from conexiant: " . ($result->{'ErrorInfo'} || 'No error message')
58   unless $result->{'Success'};
59
60 my $files = $result->{'Data'}->{'Result'};
61
62 die "Unexpected results from conexiant, not an array"
63   unless ref($files) eq 'ARRAY';
64
65 my $dir = $FS::UID::cache_dir. "/cache.". $FS::UID::datasrc;
66 my $ua  = LWP::UserAgent->new;
67
68 # Download files are created automatically at regular frequent intervals,
69 # but they contain overlapping data.
70 #
71 # FS::cdr::conexiant automatically skips previously imported cdrs,
72 # though if it does so for all records in a file, 
73 # then batch_import thinks the file is empty
74 foreach my $file (@$files) {
75   next unless $file->{'BilledCallsOnly'};
76   my $cdrbatch = 'conexiant-' . $file->{'Identifier'};
77   # files that were "empty" will unfortunately be re-downloaded,
78   # but the alternative is to leave an excess of empty batches in system,
79   # and re-downloading is harmless (all files expire after 48 hours anyway)
80   if (qsearchs('cdr_batch',{ 'cdrbatch' => $cdrbatch })) {
81     print "$cdrbatch already imported\n" if $verbose;
82     next;
83   }
84   if ($verbose) {
85     print "Downloading $cdrbatch\n".
86           "  Created ".$file->{'CreatedOn'}."\n".
87           "  Start   ".$file->{'QueryStart'}."\n".
88           "  End     ".$file->{'QueryEnd'}."\n".
89           "  Link    ".$file->{'ValidLink'}."\n";
90   }
91   my $zfh = new File::Temp( TEMPLATE => 'conexiant.XXXXXXXX',
92                            SUFFIX   => '.zip',
93                            DIR      => $dir,
94                          )
95     or die "can't open temporary file to store download: $!\n";
96   my $cfh = new File::Temp( TEMPLATE => 'conexiant.XXXXXXXX',
97                            SUFFIX   => '.csv',
98                            DIR      => $dir,
99                          )
100     or die "can't open temporary file to unzip download: $!\n";
101   # yeah, these files ain't secured in any way
102   my $response = $ua->get($file->{'ValidLink'}, ':content_file' => $zfh->filename);
103   unless ($response->is_success) {
104     die "Error downloading $cdrbatch: ".$response->status_line;
105   }
106   my $zfilename = $zfh->filename;
107   print $cfh `unzip -p $zfilename 'Conexiant Cdrs.csv'`;
108   seek($cfh,0,0);
109   print "Importing batch $cdrbatch\n" if $verbose;
110   my $error = FS::cdr::batch_import({
111     'batch_namevalue' => $cdrbatch,
112     'file'            => $cfh->filename,
113     'format'          => 'conexiant'
114   });
115   if ($error eq 'Empty file!') {
116     print "File contains no new cdrs, no batch created\n" if $verbose;
117     $error = '';
118   } elsif ($verbose && !$error) {
119     print "File successfully imported\n";
120   }
121   die "Error importing $cdrbatch: $error" if $error;
122 }
123
124 exit;
125
126
127