MT#18663 row bulk processing framework WIP #3
+input/output folder permission -> process umask fix +config file loading fallbacks +refactor to allow custom additions within "Projects" subdirs +settings file per project +make RestConnectors compiling +make thread states used in thread queue patterns more verbose/readable +multithreaded text file processor -linesplitter, fieldsplitter callbacks +poc: marpa r2 parsergenerator to parse Features_Define.cfg by declaring the syntax via BNF +try to make it work +evaluating the syntax tree to get a final row data structure turns out to be slow +hence moving parsing to processor threads +evaluating a Features_Define.cfg record into a perl data structure succeeded. +class hierarchy for file processors +main "migrate.pl" layout Change-Id: I1550e2689bb5640931787fc70e9b5b00432dd0a2changes/71/6871/8
parent
656e373f57
commit
0d40b0c4ff
@ -0,0 +1,494 @@
|
||||
package FileProcessor;
|
||||
use strict;
|
||||
|
||||
## no critic
|
||||
|
||||
use threads qw(yield);
|
||||
use threads::shared;
|
||||
use Thread::Queue;
|
||||
|
||||
use Time::HiRes qw(sleep);
|
||||
|
||||
use Globals qw(
|
||||
$enablemultithreading
|
||||
$cpucount
|
||||
);
|
||||
use Logging qw(
|
||||
getlogger
|
||||
filethreadingdebug
|
||||
fileprocessingstarted
|
||||
fileprocessingdone
|
||||
fetching_lines
|
||||
processing_lines
|
||||
);
|
||||
|
||||
|
||||
# fetching_rows
|
||||
# writing_rows
|
||||
# processing_rows
|
||||
|
||||
use LogError qw(
|
||||
processzerofilesize
|
||||
fileprocessingfailed
|
||||
fileerror
|
||||
notimplementederror
|
||||
);
|
||||
|
||||
use Utils qw(threadid);
|
||||
|
||||
require Exporter;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT_OK = qw();
|
||||
|
||||
my $thread_sleep_secs = 0.1;
|
||||
|
||||
my $RUNNING = 1;
|
||||
my $COMPLETED = 2;
|
||||
my $ERROR = 4;
|
||||
|
||||
sub new {
|
||||
|
||||
my $class = shift;
|
||||
my $self = bless {}, $class;
|
||||
|
||||
$self->{encoding} = undef;
|
||||
$self->{buffersize} = undef;
|
||||
$self->{threadqueuelength} = undef;
|
||||
$self->{numofthreads} = undef;
|
||||
#$self->{multithreading} = undef;
|
||||
$self->{blocksize} = undef;
|
||||
|
||||
$self->{line_separator} = undef;
|
||||
|
||||
return $self;
|
||||
|
||||
}
|
||||
|
||||
sub init_reader_context {
|
||||
|
||||
my $self = shift;
|
||||
my ($context) = @_;
|
||||
# init stuff available to the reader loop
|
||||
# invoked after thread was forked, as
|
||||
# required by e.g. Marpa R2
|
||||
|
||||
}
|
||||
|
||||
sub _extractlines {
|
||||
my ($context,$buffer_ref,$lines) = @_;
|
||||
my $separator = $context->{instance}->{line_separator};
|
||||
my $last_line;
|
||||
foreach my $line (split(/$separator/,$$buffer_ref,-1)) {
|
||||
$last_line = $line;
|
||||
push(@$lines,$line);
|
||||
}
|
||||
#$count--;
|
||||
$$buffer_ref = $last_line;
|
||||
pop @$lines;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
sub process {
|
||||
|
||||
my $self = shift;
|
||||
|
||||
my ($file,$process_code,$init_process_context_code,$multithreading) = @_;
|
||||
|
||||
if (ref $process_code eq 'CODE') {
|
||||
|
||||
if (-s $file > 0) {
|
||||
fileprocessingstarted($file,getlogger(__PACKAGE__));
|
||||
} else {
|
||||
processzerofilesize($file,getlogger(__PACKAGE__));
|
||||
return;
|
||||
}
|
||||
|
||||
my $errorstate = $RUNNING;
|
||||
my $tid = threadid();
|
||||
|
||||
if ($enablemultithreading and $multithreading and $cpucount > 1) { # and $multithreaded) { # definitely no multithreading when CSVDB is involved
|
||||
|
||||
my $reader;
|
||||
my %processors = ();
|
||||
my %errorstates :shared = ();
|
||||
my $queue = Thread::Queue->new();
|
||||
|
||||
filethreadingdebug('starting reader thread',getlogger(__PACKAGE__));
|
||||
|
||||
$reader = threads->create(\&_reader,
|
||||
{ queue => $queue,
|
||||
errorstates => \%errorstates,
|
||||
instance => $self,
|
||||
filename => $file,
|
||||
});
|
||||
|
||||
for (my $i = 0; $i < $self->{numofthreads}; $i++) {
|
||||
filethreadingdebug('starting processor thread ' . ($i + 1) . ' of ' . $self->{numofthreads},getlogger(__PACKAGE__));
|
||||
my $processor = threads->create(\&_process,
|
||||
{ queue => $queue,
|
||||
errorstates => \%errorstates,
|
||||
readertid => $reader->tid(),
|
||||
filename => $file,
|
||||
process_code => $process_code,
|
||||
init_process_context_code => $init_process_context_code,
|
||||
instance => $self,
|
||||
});
|
||||
if (!defined $processor) {
|
||||
filethreadingdebug('processor thread ' . ($i + 1) . ' of ' . $self->{numofthreads} . ' NOT started',getlogger(__PACKAGE__));
|
||||
}
|
||||
$processors{$processor->tid()} = $processor;
|
||||
}
|
||||
|
||||
$reader->join();
|
||||
filethreadingdebug('reader thread joined',getlogger(__PACKAGE__));
|
||||
while ((scalar keys %processors) > 0) {
|
||||
foreach my $processor (values %processors) {
|
||||
if (defined $processor and $processor->is_joinable()) {
|
||||
$processor->join();
|
||||
delete $processors{$processor->tid()};
|
||||
filethreadingdebug('processor thread tid ' . $processor->tid() . ' joined',getlogger(__PACKAGE__));
|
||||
}
|
||||
}
|
||||
sleep($thread_sleep_secs);
|
||||
}
|
||||
|
||||
$errorstate = (_get_other_threads_state(\%errorstates,$tid) & ~$RUNNING);
|
||||
|
||||
} else {
|
||||
|
||||
my $context = { instance => $self,
|
||||
filename => $file,};
|
||||
my $rowblock_result = 1;
|
||||
eval {
|
||||
|
||||
my $init_reader_context_code = $self->can('init_reader_context');
|
||||
if (defined $init_reader_context_code) {
|
||||
&$init_reader_context_code($self,$context);
|
||||
}
|
||||
if ('CODE' eq ref $init_process_context_code) {
|
||||
&$init_process_context_code($context);
|
||||
}
|
||||
my $extractlines_code = (ref $self)->can('extractlines');
|
||||
if (!defined $extractlines_code) {
|
||||
if (defined $self->{line_separator}) {
|
||||
$extractlines_code = \&_extractlines;
|
||||
} else {
|
||||
notimplementederror((ref $self) . ': ' . 'extractlines class method not implemented and line separator pattern not defined',getlogger(__PACKAGE__));
|
||||
}
|
||||
}
|
||||
my $extractfields_code = (ref $self)->can('extractfields');
|
||||
if (!defined $extractfields_code) {
|
||||
notimplementederror((ref $self) . ': ' . 'extractfields class method not implemented',getlogger(__PACKAGE__));
|
||||
}
|
||||
|
||||
local *INPUTFILE;
|
||||
if (not open (INPUTFILE, '<:encoding(' . $self->{encoding} . ')', $file)) {
|
||||
fileerror('processing file - cannot open file ' . $file . ': ' . $!,getlogger(__PACKAGE__));
|
||||
return;
|
||||
}
|
||||
binmode INPUTFILE;
|
||||
|
||||
my $buffer = undef;
|
||||
my $chunk = undef;
|
||||
my $n = 0;
|
||||
$context->{charsread} = 0;
|
||||
$context->{linesread} = 0;
|
||||
|
||||
my $i = 0;
|
||||
while (1) {
|
||||
fetching_lines($file,$i,$self->{blocksize},getlogger(__PACKAGE__));
|
||||
my @lines = ();
|
||||
while ((scalar @lines) < $self->{blocksize} and defined ($n = read(INPUTFILE,$chunk,$self->{buffersize})) and $n != 0) {
|
||||
if (defined $buffer) {
|
||||
$buffer .= $chunk;
|
||||
} else {
|
||||
$buffer = $chunk;
|
||||
}
|
||||
$context->{charsread} += $n;
|
||||
last unless &$extractlines_code($context,\$buffer,\@lines);
|
||||
}
|
||||
|
||||
if (not defined $n) {
|
||||
fileerror('processing file - error reading file ' . $file . ': ' . $!,getlogger(__PACKAGE__));
|
||||
close(INPUTFILE);
|
||||
last;
|
||||
} else {
|
||||
if ($n == 0 && defined $buffer) {
|
||||
push(@lines,$buffer);
|
||||
}
|
||||
my @rowblock = ();
|
||||
foreach my $line (@lines) {
|
||||
$context->{linesread} += 1;
|
||||
my $row = &$extractfields_code($context,\$line);
|
||||
push(@rowblock,$row) if defined $row;
|
||||
}
|
||||
my $realblocksize = scalar @rowblock;
|
||||
if ($realblocksize > 0) {
|
||||
processing_lines($tid,$i,$realblocksize,getlogger(__PACKAGE__));
|
||||
#processing_rows($tid,$i,$realblocksize,$rowcount,getlogger(__PACKAGE__));
|
||||
|
||||
$rowblock_result = &$process_code($context,\@rowblock,$i);
|
||||
|
||||
$i += $realblocksize;
|
||||
if ($n == 0 || not $rowblock_result) {
|
||||
last;
|
||||
}
|
||||
} else {
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
close(INPUTFILE);
|
||||
|
||||
};
|
||||
|
||||
if ($@) {
|
||||
$errorstate = $ERROR;
|
||||
} else {
|
||||
$errorstate = (not $rowblock_result) ? $ERROR : $COMPLETED;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if ($errorstate == $COMPLETED) {
|
||||
fileprocessingdone($file,getlogger(__PACKAGE__));
|
||||
return 1;
|
||||
} else {
|
||||
fileprocessingfailed($file,getlogger(__PACKAGE__));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
sub _reader {
|
||||
|
||||
my $context = shift;
|
||||
|
||||
my $tid = threadid();
|
||||
{
|
||||
lock $context->{errorstates};
|
||||
$context->{errorstates}->{$tid} = $RUNNING;
|
||||
}
|
||||
|
||||
filethreadingdebug('[' . $tid . '] reader thread tid ' . $tid . ' started',getlogger(__PACKAGE__));
|
||||
|
||||
my $blockcount = 0;
|
||||
eval {
|
||||
|
||||
my $init_reader_context_code = $context->{instance}->can('init_reader_context');
|
||||
if (defined $init_reader_context_code) {
|
||||
&$init_reader_context_code($context->{instance},$context);
|
||||
}
|
||||
my $extractlines_code = (ref $context->{instance})->can('extractlines');
|
||||
if (!defined $extractlines_code) {
|
||||
if (defined $context->{instance}->{line_separator}) {
|
||||
$extractlines_code = \&_extractlines;
|
||||
} else {
|
||||
notimplementederror((ref $context->{instance}) . ': ' . 'extractlines class method not implemented and line separator pattern not defined',getlogger(__PACKAGE__));
|
||||
}
|
||||
}
|
||||
|
||||
my $extractfields_code = (ref $context->{instance})->can('extractfields');
|
||||
if (!defined $extractfields_code) {
|
||||
notimplementederror((ref $context->{instance}) . ': ' . 'extractfields class method not implemented',getlogger(__PACKAGE__));
|
||||
}
|
||||
|
||||
local *INPUTFILE_READER;
|
||||
if (not open (INPUTFILE_READER, '<:encoding(' . $context->{instance}->{encoding} . ')', $context->{filename})) {
|
||||
fileerror('processing file - cannot open file ' . $context->{filename} . ': ' . $!,getlogger(__PACKAGE__));
|
||||
return;
|
||||
}
|
||||
binmode INPUTFILE_READER;
|
||||
|
||||
filethreadingdebug('[' . $tid . '] reader thread waiting for consumer threads',getlogger(__PACKAGE__));
|
||||
while ((_get_other_threads_state($context->{errorstates},$tid) & $RUNNING) == 0) { #wait on cosumers to come up
|
||||
#yield();
|
||||
sleep($thread_sleep_secs);
|
||||
}
|
||||
|
||||
my $buffer = undef;
|
||||
my $chunk = undef;
|
||||
my $n = 0;
|
||||
$context->{charsread} = 0;
|
||||
$context->{linesread} = 0;
|
||||
|
||||
my $i = 0;
|
||||
my $state = $RUNNING; #start at first
|
||||
while (($state & $RUNNING) == $RUNNING and ($state & $ERROR) == 0) { #as long there is one running consumer and no defunct consumer
|
||||
fetching_lines($context->{filename},$i,$context->{instance}->{blocksize},getlogger(__PACKAGE__));
|
||||
my @lines = ();
|
||||
while ((scalar @lines) < $context->{instance}->{blocksize} and defined ($n = read(INPUTFILE_READER,$chunk,$context->{instance}->{buffersize})) and $n != 0) {
|
||||
if (defined $buffer) {
|
||||
$buffer .= $chunk;
|
||||
} else {
|
||||
$buffer = $chunk;
|
||||
}
|
||||
$context->{charsread} += 1;
|
||||
last unless &$extractlines_code($context,\$buffer,\@lines);
|
||||
yield();
|
||||
}
|
||||
if (not defined $n) {
|
||||
fileerror('processing file - error reading file ' . $context->{filename} . ': ' . $!,getlogger(__PACKAGE__));
|
||||
close(INPUTFILE_READER);
|
||||
last;
|
||||
} else {
|
||||
if ($n == 0 && defined $buffer) {
|
||||
push(@lines,$buffer);
|
||||
}
|
||||
my @rowblock :shared = ();
|
||||
foreach my $line (@lines) {
|
||||
$context->{linesread} += 1;
|
||||
my $row = &$extractfields_code($context,\$line);
|
||||
push(@rowblock,shared_clone($row)) if defined $row;
|
||||
yield();
|
||||
}
|
||||
my $realblocksize = scalar @rowblock;
|
||||
my %packet :shared = ();
|
||||
$packet{rows} = \@rowblock;
|
||||
$packet{size} = $realblocksize;
|
||||
$packet{row_offset} = $i;
|
||||
if ($realblocksize > 0) {
|
||||
$context->{queue}->enqueue(\%packet); #$packet);
|
||||
$blockcount++;
|
||||
#wait if thequeue is full and there there is one running consumer
|
||||
while (((($state = _get_other_threads_state($context->{errorstates},$tid)) & $RUNNING) == $RUNNING) and $context->{queue}->pending() >= $context->{instance}->{threadqueuelength}) {
|
||||
#yield();
|
||||
sleep($thread_sleep_secs);
|
||||
}
|
||||
$i += $realblocksize;
|
||||
if ($n == 0) {
|
||||
filethreadingdebug('[' . $tid . '] reader thread is shutting down (end of data) ...',getlogger(__PACKAGE__));
|
||||
last;
|
||||
}
|
||||
} else {
|
||||
$context->{queue}->enqueue(\%packet); #$packet);
|
||||
filethreadingdebug('[' . $tid . '] reader thread is shutting down (end of data - empty block) ...',getlogger(__PACKAGE__));
|
||||
last;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (not (($state & $RUNNING) == $RUNNING and ($state & $ERROR) == 0)) {
|
||||
filethreadingdebug('[' . $tid . '] reader thread is shutting down (' .
|
||||
(($state & $RUNNING) == $RUNNING ? 'still running consumer threads' : 'no running consumer threads') . ', ' .
|
||||
(($state & $ERROR) == 0 ? 'no defunct thread(s)' : 'defunct thread(s)') . ') ...'
|
||||
,getlogger(__PACKAGE__));
|
||||
}
|
||||
close(INPUTFILE_READER);
|
||||
};
|
||||
|
||||
filethreadingdebug($@ ? '[' . $tid . '] reader thread error: ' . $@ : '[' . $tid . '] reader thread finished (' . $blockcount . ' blocks)',getlogger(__PACKAGE__));
|
||||
lock $context->{errorstates};
|
||||
if ($@) {
|
||||
$context->{errorstates}->{$tid} = $ERROR;
|
||||
} else {
|
||||
$context->{errorstates}->{$tid} = $COMPLETED;
|
||||
}
|
||||
return $context->{errorstates}->{$tid};
|
||||
}
|
||||
|
||||
sub _process {
|
||||
|
||||
my $context = shift;
|
||||
|
||||
my $rowblock_result = 1;
|
||||
my $tid = threadid();
|
||||
{
|
||||
lock $context->{errorstates};
|
||||
$context->{errorstates}->{$tid} = $RUNNING;
|
||||
}
|
||||
|
||||
filethreadingdebug('[' . $tid . '] processor thread tid ' . $tid . ' started',getlogger(__PACKAGE__));
|
||||
|
||||
my $blockcount = 0;
|
||||
eval {
|
||||
if ('CODE' eq ref $context->{init_process_context_code}) {
|
||||
&{$context->{init_process_context_code}}($context);
|
||||
}
|
||||
while (not _get_stop_consumer_thread($context,$tid)) {
|
||||
my $packet = $context->{queue}->dequeue_nb();
|
||||
if (defined $packet) {
|
||||
if ($packet->{size} > 0) {
|
||||
|
||||
processing_lines($tid,$packet->{row_offset},$packet->{size},getlogger(__PACKAGE__));
|
||||
|
||||
$rowblock_result = &{$context->{process_code}}($context, $packet->{rows},$packet->{row_offset});
|
||||
|
||||
$blockcount++;
|
||||
|
||||
if (not $rowblock_result) {
|
||||
filethreadingdebug('[' . $tid . '] shutting down processor thread (processing block NOK) ...',getlogger(__PACKAGE__));
|
||||
last;
|
||||
}
|
||||
|
||||
} else {
|
||||
filethreadingdebug('[' . $tid . '] shutting down processor thread (end of data - empty block) ...',getlogger(__PACKAGE__));
|
||||
last;
|
||||
}
|
||||
} else {
|
||||
#yield();
|
||||
sleep($thread_sleep_secs); #2015-01
|
||||
}
|
||||
}
|
||||
};
|
||||
filethreadingdebug($@ ? '[' . $tid . '] processor thread error: ' . $@ : '[' . $tid . '] processor thread finished (' . $blockcount . ' blocks)',getlogger(__PACKAGE__));
|
||||
lock $context->{errorstates};
|
||||
if ($@) {
|
||||
$context->{errorstates}->{$tid} = $ERROR;
|
||||
} else {
|
||||
$context->{errorstates}->{$tid} = (not $rowblock_result) ? $ERROR : $COMPLETED;
|
||||
}
|
||||
return $context->{errorstates}->{$tid};
|
||||
}
|
||||
|
||||
sub _get_other_threads_state {
|
||||
my ($errorstates,$tid) = @_;
|
||||
my $result = 0;
|
||||
if (!defined $tid) {
|
||||
$tid = threadid();
|
||||
}
|
||||
if (defined $errorstates and ref $errorstates eq 'HASH') {
|
||||
lock $errorstates;
|
||||
foreach my $threadid (keys %$errorstates) {
|
||||
if ($threadid != $tid) {
|
||||
$result |= $errorstates->{$threadid};
|
||||
}
|
||||
}
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
|
||||
sub _get_stop_consumer_thread {
|
||||
my ($context,$tid) = @_;
|
||||
my $result = 1;
|
||||
my $other_threads_state;
|
||||
my $reader_state;
|
||||
my $queuesize;
|
||||
{
|
||||
my $errorstates = $context->{errorstates};
|
||||
lock $errorstates;
|
||||
$other_threads_state = _get_other_threads_state($errorstates,$tid);
|
||||
$reader_state = $errorstates->{$context->{readertid}};
|
||||
}
|
||||
$queuesize = $context->{queue}->pending();
|
||||
if (($other_threads_state & $ERROR) == 0 and ($queuesize > 0 or $reader_state == $RUNNING)) {
|
||||
$result = 0;
|
||||
#keep the consumer thread running if there is no defunct thread and queue is not empty or reader is still running
|
||||
}
|
||||
|
||||
if ($result) {
|
||||
filethreadingdebug('[' . $tid . '] consumer thread is shutting down (' .
|
||||
(($other_threads_state & $ERROR) == 0 ? 'no defunct thread(s)' : 'defunct thread(s)') . ', ' .
|
||||
($queuesize > 0 ? 'blocks pending' : 'no blocks pending') . ', ' .
|
||||
($reader_state == $RUNNING ? 'reader thread running' : 'reader thread not running') . ') ...'
|
||||
,getlogger(__PACKAGE__));
|
||||
}
|
||||
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
1;
|
||||
@ -0,0 +1,64 @@
|
||||
package FileProcessors::CSVFile;
|
||||
use strict;
|
||||
|
||||
## no critic
|
||||
|
||||
use File::Basename;
|
||||
use Cwd;
|
||||
use lib Cwd::abs_path(File::Basename::dirname(__FILE__) . '/../');
|
||||
|
||||
use Globals qw(
|
||||
$cpucount
|
||||
);
|
||||
|
||||
use Logging qw(
|
||||
getlogger
|
||||
);
|
||||
|
||||
use FileProcessor;
|
||||
|
||||
require Exporter;
|
||||
our @ISA = qw(Exporter FileProcessor);
|
||||
our @EXPORT_OK = qw();
|
||||
|
||||
my $default_lineseparator = '\\n\\r|\\r|\\n';
|
||||
my $default_fieldseparator = ",";
|
||||
my $default_encoding = 'UTF-8';
|
||||
|
||||
my $buffersize = 100 * 1024;
|
||||
my $threadqueuelength = 10;
|
||||
my $numofthreads = $cpucount; #3;
|
||||
#my $multithreading = 0;
|
||||
my $blocksize = 100;
|
||||
|
||||
sub new {
|
||||
|
||||
my $class = shift;
|
||||
|
||||
my $self = FileProcessor->new(@_);
|
||||
|
||||
$self->{line_separator} = shift // $default_lineseparator;
|
||||
$self->{field_separator} = shift // $default_fieldseparator;
|
||||
$self->{encoding} = shift // $default_encoding;
|
||||
$self->{buffersize} = $buffersize;
|
||||
$self->{threadqueuelength} = $threadqueuelength;
|
||||
$self->{numofthreads} = $numofthreads;
|
||||
#$self->{multithreading} = $multithreading;
|
||||
$self->{blocksize} = $blocksize;
|
||||
|
||||
bless($self,$class);
|
||||
|
||||
#restdebug($self,__PACKAGE__ . ' file processor created',getlogger(__PACKAGE__));
|
||||
|
||||
return $self;
|
||||
|
||||
}
|
||||
|
||||
sub extractfields {
|
||||
my ($context,$line_ref) = @_;
|
||||
my $separator = $context->{instance}->{field_separator};
|
||||
my @fields = split(/$separator/,$$line_ref,-1);
|
||||
return \@fields;
|
||||
}
|
||||
|
||||
1;
|
||||
@ -0,0 +1,96 @@
|
||||
package Projects::Migration::IPGallery::FeaturesDefineParser;
|
||||
use strict;
|
||||
|
||||
## no critic
|
||||
|
||||
use File::Basename;
|
||||
use Cwd;
|
||||
use lib Cwd::abs_path(File::Basename::dirname(__FILE__) . '/../../../');
|
||||
|
||||
use Marpa::R2;
|
||||
use Data::Dumper::Concise;
|
||||
|
||||
require Exporter;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT_OK = qw(
|
||||
create_grammar
|
||||
parse
|
||||
);
|
||||
|
||||
my $grammar = << '__GRAMMAR__';
|
||||
lexeme default = latm => 1
|
||||
|
||||
:start ::= Record
|
||||
:default ::= action => ::first
|
||||
|
||||
Record ::= SubscriberNumber '{' Options '}' action => _build_record
|
||||
Options ::= Option+ action => _build_options
|
||||
Option ::= OptionName action => _build_option
|
||||
| OptionName '{' OptionValues '}' action => _build_setoption
|
||||
OptionValues ::= OptionValue+ action => _build_setoptionitems
|
||||
|
||||
SubscriberNumber ~ [0-9]+
|
||||
OptionName ~ [-a-zA-Z_0-9]+
|
||||
OptionValue ~ [-a-zA-Z_0-9]+
|
||||
whitespace ~ [\s]+
|
||||
:discard ~ whitespace
|
||||
__GRAMMAR__
|
||||
|
||||
sub _build_record {
|
||||
|
||||
my ($closure,$subscribernumber,$leftcb,$options,$rightcb) = @_;
|
||||
return { $subscribernumber => $options };
|
||||
|
||||
}
|
||||
|
||||
sub _build_options {
|
||||
|
||||
my ($closure,@options) = @_;
|
||||
return \@options;
|
||||
|
||||
}
|
||||
|
||||
sub _build_option {
|
||||
|
||||
my ($closure,$optionname) = @_;
|
||||
return $optionname;
|
||||
|
||||
}
|
||||
|
||||
sub _build_setoption {
|
||||
|
||||
my ($closure,$optionname,$leftcb,$optionvalues,$rightcb) = @_;
|
||||
return { $optionname => $optionvalues };
|
||||
|
||||
}
|
||||
|
||||
sub _build_setoptionitems {
|
||||
|
||||
my ($closure,@optionvalues) = @_;
|
||||
return \@optionvalues;
|
||||
|
||||
}
|
||||
|
||||
sub create_grammar {
|
||||
|
||||
return Marpa::R2::Scanless::G->new({
|
||||
source => \$grammar,
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
sub parse {
|
||||
|
||||
my ($input_ref,$grammar) = @_;
|
||||
my $recce = Marpa::R2::Scanless::R->new({
|
||||
grammar => $grammar,
|
||||
semantics_package => __PACKAGE__,
|
||||
});
|
||||
$recce->read($input_ref);
|
||||
my $closure = {};
|
||||
my $value_ref = $recce->value($closure);
|
||||
return $value_ref ? ${$value_ref} : undef;
|
||||
|
||||
}
|
||||
|
||||
1;
|
||||
@ -0,0 +1,108 @@
|
||||
package Projects::Migration::IPGallery::FileProcessors::FeaturesDefineFile;
|
||||
use strict;
|
||||
|
||||
## no critic
|
||||
|
||||
use File::Basename;
|
||||
use Cwd;
|
||||
use lib Cwd::abs_path(File::Basename::dirname(__FILE__) . '/../../../../');
|
||||
|
||||
use Globals qw(
|
||||
$cpucount
|
||||
);
|
||||
|
||||
use Logging qw(
|
||||
getlogger
|
||||
);
|
||||
use LogError qw(
|
||||
fileprocessingerror
|
||||
fileprocessingwarn
|
||||
);
|
||||
|
||||
use FileProcessor;
|
||||
use Projects::Migration::IPGallery::FeaturesDefineParser qw(
|
||||
create_grammar
|
||||
parse
|
||||
);
|
||||
|
||||
require Exporter;
|
||||
our @ISA = qw(Exporter FileProcessor);
|
||||
our @EXPORT_OK = qw();
|
||||
|
||||
my $lineseparator = '\\n(?=(?:\d+\\n))';
|
||||
my $encoding = 'UTF-8';
|
||||
|
||||
my $buffersize = 1400; # 512 * 1024;
|
||||
my $threadqueuelength = 10;
|
||||
my $numofthreads = $cpucount; #3;
|
||||
#my $multithreading = 0;
|
||||
my $blocksize = 2000;
|
||||
|
||||
my $stoponparseerrors = 0; #1;
|
||||
my $parselines = 0;
|
||||
|
||||
sub new {
|
||||
|
||||
my $class = shift;
|
||||
|
||||
my $self = FileProcessor->new(@_);
|
||||
|
||||
$self->{line_separator} = $lineseparator;
|
||||
$self->{encoding} = $encoding;
|
||||
$self->{buffersize} = $buffersize;
|
||||
$self->{threadqueuelength} = $threadqueuelength;
|
||||
$self->{numofthreads} = $numofthreads;
|
||||
#$self->{multithreading} = $multithreading;
|
||||
$self->{blocksize} = $blocksize;
|
||||
$self->{parselines} = $parselines;
|
||||
$self->{stoponparseerrors} = $stoponparseerrors;
|
||||
|
||||
bless($self,$class);
|
||||
|
||||
#restdebug($self,__PACKAGE__ . ' file processor created',getlogger(__PACKAGE__));
|
||||
|
||||
return $self;
|
||||
|
||||
}
|
||||
|
||||
sub init_reader_context {
|
||||
|
||||
my $self = shift;
|
||||
my ($context) = @_;
|
||||
|
||||
if ($self->{parselines}) {
|
||||
eval {
|
||||
$context->{grammar} = create_grammar();
|
||||
};
|
||||
if ($@) {
|
||||
fileprocessingerror($context->{filename},$@,getlogger(__PACKAGE__));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
sub extractfields {
|
||||
my ($context,$line_ref) = @_;
|
||||
|
||||
return undef if length($$line_ref) == 0;
|
||||
|
||||
if ($context->{instance}->{parselines}) {
|
||||
my $row = undef;
|
||||
eval {
|
||||
$row = parse($line_ref,$context->{grammar});
|
||||
};
|
||||
if ($@) {
|
||||
if ($context->{instance}->{stoponparseerrors}) {
|
||||
fileprocessingerror($context->{filename},'record ' . $context->{linesread} . ' - ' . $@,getlogger(__PACKAGE__));
|
||||
} else {
|
||||
fileprocessingwarn($context->{filename},'record ' . $context->{linesread} . ' - ' . $@,getlogger(__PACKAGE__));
|
||||
}
|
||||
}
|
||||
return $row;
|
||||
} else {
|
||||
return $$line_ref;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
1;
|
||||
@ -0,0 +1,79 @@
|
||||
package Projects::Migration::IPGallery::Import;
|
||||
use strict;
|
||||
|
||||
## no critic
|
||||
|
||||
use File::Basename;
|
||||
use Cwd;
|
||||
use lib Cwd::abs_path(File::Basename::dirname(__FILE__) . '/../../../');
|
||||
|
||||
use Projects::Migration::IPGallery::Settings qw(
|
||||
$defaultsettings
|
||||
update_settings
|
||||
);
|
||||
use Logging qw (
|
||||
getlogger
|
||||
);
|
||||
use LogError qw(
|
||||
fileprocessingwarn
|
||||
fileprocessingerror
|
||||
);
|
||||
|
||||
#use FileProcessors::CSVFile;
|
||||
use Projects::Migration::IPGallery::FileProcessors::FeaturesDefineFile;
|
||||
use Projects::Migration::IPGallery::FeaturesDefineParser qw(
|
||||
create_grammar
|
||||
parse
|
||||
);
|
||||
|
||||
require Exporter;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT_OK = qw(
|
||||
import_features_define
|
||||
);
|
||||
|
||||
|
||||
sub import_features_define {
|
||||
|
||||
my ($file) = @_;
|
||||
my $multithreading = 1;
|
||||
my $importer = Projects::Migration::IPGallery::FileProcessors::FeaturesDefineFile->new();
|
||||
return $importer->process($file,sub {
|
||||
my ($context,$rows,$row_offset) = @_;
|
||||
my $rownum = $row_offset;
|
||||
foreach my $line (@$rows) {
|
||||
my $row = undef;
|
||||
if (not $importer->{parselines}) {
|
||||
eval {
|
||||
$row = parse(\$line,$context->{grammar});
|
||||
};
|
||||
if ($@) {
|
||||
if ($importer->{stoponparseerrors}) {
|
||||
fileprocessingerror($context->{filename},'record ' . ($rownum + 1) . ' - ' . $@,getlogger(__PACKAGE__));
|
||||
} else {
|
||||
fileprocessingwarn($context->{filename},'record ' . ($rownum + 1) . ' - ' . $@,getlogger(__PACKAGE__));
|
||||
}
|
||||
}
|
||||
}
|
||||
next unless defined $row;
|
||||
$rownum++;
|
||||
# continue to write to sqlite ...
|
||||
}
|
||||
return 1;
|
||||
}, sub {
|
||||
my ($context)= @_;
|
||||
if (not $importer->{parselines}) {
|
||||
eval {
|
||||
$context->{grammar} = create_grammar();
|
||||
};
|
||||
if ($@) {
|
||||
fileprocessingerror($context->{filename},$@,getlogger(__PACKAGE__));
|
||||
}
|
||||
}
|
||||
},$multithreading);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
1;
|
||||
@ -0,0 +1,50 @@
|
||||
package Projects::Migration::IPGallery::Settings;
|
||||
use strict;
|
||||
|
||||
## no critic
|
||||
|
||||
use File::Basename;
|
||||
use Cwd;
|
||||
use lib Cwd::abs_path(File::Basename::dirname(__FILE__) . '/../../../');
|
||||
|
||||
require Exporter;
|
||||
our @ISA = qw(Exporter);
|
||||
our @EXPORT_OK = qw(
|
||||
update_settings
|
||||
$defaultsettings
|
||||
);
|
||||
|
||||
our $defaultsettings = 'settings.cfg';
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
sub update_settings {
|
||||
|
||||
my ($data,$configfile,
|
||||
$split_tuplecode,
|
||||
$format_number,
|
||||
$configurationinfocode,
|
||||
$configurationwarncode,
|
||||
$configurationerrorcode,
|
||||
$fileerrorcode,
|
||||
$configlogger) = @_;
|
||||
|
||||
if (defined $data) {
|
||||
|
||||
print "$configlogger narf";
|
||||
&$configurationinfocode("testinfomessage",$configlogger);
|
||||
# databases - dsp
|
||||
#$accounting_host = $config->{accounting_host} if exists $config->{accounting_host};
|
||||
|
||||
return 1;
|
||||
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
1;
|
||||
@ -0,0 +1 @@
|
||||
working_path = /var/sipwise/Migration/IPGallery
|
||||
@ -0,0 +1,119 @@
|
||||
use strict;
|
||||
|
||||
## no critic
|
||||
|
||||
use File::Basename;
|
||||
use Cwd;
|
||||
use lib Cwd::abs_path(File::Basename::dirname(__FILE__) . '/../../../');
|
||||
|
||||
use Getopt::Long;
|
||||
|
||||
use Globals qw(
|
||||
$defaultconfig
|
||||
);
|
||||
use Projects::Migration::IPGallery::Settings qw(
|
||||
$defaultsettings
|
||||
update_settings
|
||||
);
|
||||
use Logging qw(
|
||||
init_log
|
||||
getlogger
|
||||
$attachmentlogfile
|
||||
);
|
||||
use LogError qw (
|
||||
completion
|
||||
success
|
||||
);
|
||||
use LoadConfig qw(
|
||||
load_config
|
||||
$SIMPLE_CONFIG_TYPE
|
||||
$YAML_CONFIG_TYPE
|
||||
);
|
||||
use Utils qw(getscriptpath);
|
||||
use Mail qw(wrap_mailbody
|
||||
$signature
|
||||
$normalpriority
|
||||
$lowpriority
|
||||
$highpriority);
|
||||
|
||||
#use ConnectorPool qw();
|
||||
|
||||
use Projects::Migration::IPGallery::Import qw(
|
||||
import_features_define
|
||||
);
|
||||
|
||||
my @MODES = ();
|
||||
|
||||
if (init() && main()) {
|
||||
exit(0);
|
||||
} else {
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sub init {
|
||||
|
||||
#GetOptions ("host=s" => \$host,
|
||||
# "port=i" => \$port,
|
||||
# "file=s" => \$output_filename,
|
||||
# "dir=s" => \$output_dir,
|
||||
# "user=s" => \$user,
|
||||
# "pass=s" => \$pass,
|
||||
# "period=s" => \$period,
|
||||
# 'verbose+' => \$verbose) or fatal("Error in command line arguments");
|
||||
my $configfile = $defaultconfig;
|
||||
my $settingsfile = $defaultsettings;
|
||||
|
||||
my $result = load_config($configfile);
|
||||
init_log();
|
||||
$result &= load_config($settingsfile,\&update_settings,$SIMPLE_CONFIG_TYPE);
|
||||
#update_working_path('/var/sipwise');
|
||||
#my $logger = getlogger(getscriptpath());
|
||||
return $result;
|
||||
|
||||
}
|
||||
|
||||
|
||||
sub main() {
|
||||
|
||||
my @messages = ();
|
||||
my @attachmentfiles = ();
|
||||
my $result = 0;
|
||||
my $completion = 0;
|
||||
|
||||
if (1 or ('xx' eq "mode")) { #$mode) {
|
||||
$result = import_features_define_task(\@messages);
|
||||
$completion = 1;
|
||||
} else {
|
||||
push(@messages,'unknow option yy, must be one of' . @MODES);
|
||||
}
|
||||
|
||||
push(@attachmentfiles,$attachmentlogfile);
|
||||
if ($completion) {
|
||||
completion(join("\n\n",@messages),\@attachmentfiles,getlogger(getscriptpath()));
|
||||
} else {
|
||||
success(join("\n\n",@messages),\@attachmentfiles,getlogger(getscriptpath()));
|
||||
}
|
||||
|
||||
#ConnectorPool::destroy_dbs();
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
sub cleanup_task {
|
||||
|
||||
}
|
||||
|
||||
sub import_features_define_task {
|
||||
|
||||
my ($messages) = shift;
|
||||
if (import_features_define(
|
||||
'/home/rkrenn/test/Features_Define.cfg'
|
||||
)) {
|
||||
push(@$messages,'sucessfully inserted x records...');
|
||||
return 1;
|
||||
} else {
|
||||
push(@$messages,'some error happened');
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
@ -0,0 +1 @@
|
||||
x = y
|
||||
@ -0,0 +1,105 @@
|
||||
#!/usr/bin/perl
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
use Marpa::R2;
|
||||
use Data::Dumper;
|
||||
|
||||
|
||||
my $input = do { local $/; <DATA> };
|
||||
|
||||
my $dsl = << '__GRAMMAR__';
|
||||
|
||||
lexeme default = latm => 1
|
||||
|
||||
:start ::= List
|
||||
:default ::= action => ::first
|
||||
|
||||
List ::= Hash+ action => list
|
||||
Hash ::= String '{' Pairs '}' action => hash
|
||||
Pairs ::= Pair+ action => list
|
||||
Pair ::= String Value ';' action => pair
|
||||
| Hash
|
||||
Value ::= Simple
|
||||
| Bracketed
|
||||
Bracketed ::= '[' String ']' action => second
|
||||
Simple ::= String
|
||||
|
||||
String ~ [-a-zA-Z_0-9]+
|
||||
whitespace ~ [\s] +
|
||||
:discard ~ whitespace
|
||||
|
||||
__GRAMMAR__
|
||||
|
||||
sub hash { +{ $_[1] => $_[3] } }
|
||||
|
||||
sub pair { +{ $_[1] => $_[2] } }
|
||||
|
||||
sub second { [ @_[ 2 .. $#_-1 ] ] }
|
||||
|
||||
sub list { shift; \@_ }
|
||||
|
||||
my $grammar = Marpa::R2::Scanless::G->new( { source => \$dsl } );
|
||||
my $recce = Marpa::R2::Scanless::R->new(
|
||||
{ grammar => $grammar, semantics_package => 'main' } );
|
||||
#my $input = '42 * 1 + 7';
|
||||
$recce->read( \$input );
|
||||
|
||||
my $value_ref = $recce->value;
|
||||
my $value = $value_ref ? ${$value_ref} : 'No Parse';
|
||||
|
||||
print Dumper $value;
|
||||
|
||||
#my $parser = 'Marpa::R2::Scanless::G'->new({ source => \$grammar });
|
||||
|
||||
#print Dumper $parser->parse(\$input, 'main', { trace_terminals => 1 });
|
||||
|
||||
__DATA__
|
||||
bob {
|
||||
ed {
|
||||
larry {
|
||||
rule5 {
|
||||
option {
|
||||
disable-server-response-inspection no;
|
||||
}
|
||||
tag [ some_tag ];
|
||||
from [ prod-L3 ];
|
||||
to [ corp-L3 ];
|
||||
source [ any ];
|
||||
destination [ any ];
|
||||
source-user [ any ];
|
||||
category [ any ];
|
||||
application [ any ];
|
||||
service [ any ];
|
||||
hip-profiles [ any ];
|
||||
log-start no;
|
||||
log-end yes;
|
||||
negate-source no;
|
||||
negate-destination no;
|
||||
action allow;
|
||||
log-setting orion_log;
|
||||
}
|
||||
rule6 {
|
||||
option {
|
||||
disable-server-response-inspection no;
|
||||
}
|
||||
tag [ some_tag ];
|
||||
from [ prod-L3 ];
|
||||
to [ corp-L3 ];
|
||||
source [ any ];
|
||||
destination [ any ];
|
||||
source-user [ any ];
|
||||
category [ any ];
|
||||
application [ any ];
|
||||
service [ any ];
|
||||
hip-profiles [ any ];
|
||||
log-start no;
|
||||
log-end yes;
|
||||
negate-source no;
|
||||
negate-destination no;
|
||||
action allow;
|
||||
log-setting orion_log;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,62 @@
|
||||
|
||||
use strict;
|
||||
|
||||
my $buffersize = 100 * 1024;
|
||||
my $default_encoding = 'UTF-8';
|
||||
|
||||
_get_linecount('/home/rkrenn/test/Features_Define.cfg',$default_encoding,\&breaklines);
|
||||
|
||||
exit;
|
||||
|
||||
sub breaklines {
|
||||
my ($buffer_ref) = @_;
|
||||
my $spearator = "\n";
|
||||
my $count = 0;
|
||||
my $last_record;
|
||||
my $records = [];
|
||||
foreach my $record (split(/$spearator(?=(?:\d+$spearator))/,$$buffer_ref)) {
|
||||
$count++;
|
||||
$last_record = $record;
|
||||
push(@$records,$record);
|
||||
}
|
||||
#if ($last_record =~ /$spearator\}\s*$/) {
|
||||
# $$buffer_ref = '';
|
||||
#} else {
|
||||
$count--;
|
||||
$$buffer_ref = $last_record;
|
||||
pop @$records;
|
||||
#}
|
||||
return $count;
|
||||
}
|
||||
|
||||
sub _get_linecount {
|
||||
|
||||
my ($file,$encoding,$breaklines_code) = @_;
|
||||
|
||||
#local $/ = $lineseparator;
|
||||
local *INPUTFILE_LINECOUNT;
|
||||
if (not open (INPUTFILE_LINECOUNT, '<:encoding(' . $encoding . ')', $file)) {
|
||||
print('get line count - cannot open file ' . $file . ': ' . $!);
|
||||
return undef;
|
||||
}
|
||||
binmode INPUTFILE_LINECOUNT;
|
||||
|
||||
my $linecount = 0;
|
||||
|
||||
my $buffer = '';
|
||||
my $chunk = undef;
|
||||
my $n = 0;
|
||||
while (defined ($n = read(INPUTFILE_LINECOUNT,$chunk,$buffersize)) && $n != 0) {
|
||||
$buffer .= $chunk;
|
||||
$linecount += &$breaklines_code(\$buffer);
|
||||
}
|
||||
if (not defined $n) {
|
||||
print('get line count - error reading file ' . $file . ': ' . $!);
|
||||
close(INPUTFILE_LINECOUNT);
|
||||
return undef;
|
||||
}
|
||||
close(INPUTFILE_LINECOUNT);
|
||||
|
||||
return $linecount;
|
||||
|
||||
}
|
||||
@ -0,0 +1,215 @@
|
||||
#!/usr/bin/perl
|
||||
use warnings;
|
||||
use strict;
|
||||
|
||||
use Marpa::R2;
|
||||
use Data::Dumper;
|
||||
|
||||
|
||||
my $input = do { local $/; <DATA> };
|
||||
|
||||
my $dsl = << '__GRAMMAR__';
|
||||
lexeme default = latm => 1
|
||||
|
||||
:start ::= Records
|
||||
:default ::= action => ::first
|
||||
|
||||
Records ::= Record+ action => list
|
||||
Record ::= SubscriberNumber '{' Options '}'
|
||||
Options ::= Option+ action => list
|
||||
Option ::= OptionName | OptionName '{' OptionValues '}'
|
||||
OptionValues ::= OptionValue+ action => list
|
||||
|
||||
SubscriberNumber ~ [0-9]+
|
||||
OptionName ~ [-a-zA-Z_0-9]+
|
||||
OptionValue ~ [-a-zA-Z_0-9]+
|
||||
whitespace ~ [\s]+
|
||||
:discard ~ whitespace
|
||||
__GRAMMAR__
|
||||
|
||||
sub hash {
|
||||
print "hash";
|
||||
+{ $_[1] => $_[3] }
|
||||
}
|
||||
|
||||
sub pair {
|
||||
print "pair";
|
||||
+{ $_[1] => $_[2] }
|
||||
}
|
||||
|
||||
sub second {
|
||||
print "second";
|
||||
[ @_[ 2 .. $#_-1 ] ]
|
||||
}
|
||||
|
||||
sub list {
|
||||
shift;
|
||||
print "list";
|
||||
\@_
|
||||
}
|
||||
|
||||
my $grammar = Marpa::R2::Scanless::G->new( { source => \$dsl } );
|
||||
my $recce = Marpa::R2::Scanless::R->new(
|
||||
{ grammar => $grammar, semantics_package => 'main' } );
|
||||
#my $input = '42 * 1 + 7';
|
||||
$recce->read( \$input );
|
||||
|
||||
my $value_ref = $recce->value;
|
||||
my $value = $value_ref ? ${$value_ref} : 'No Parse';
|
||||
|
||||
print Dumper $value;
|
||||
|
||||
#my $parser = 'Marpa::R2::Scanless::G'->new({ source => \$grammar });
|
||||
|
||||
#print Dumper $parser->parse(\$input, 'main', { trace_terminals => 1 });
|
||||
|
||||
__DATA__
|
||||
35627883323
|
||||
{
|
||||
RegisteredIC
|
||||
{
|
||||
Selective_Call_Waiting
|
||||
Selective_Ring
|
||||
Ring_By_DayTime
|
||||
Ring_By_Call_Origin
|
||||
ReAnswer
|
||||
Selective_CW_Ring
|
||||
Ic_Selective_Barring
|
||||
Ic_Day_Time_Barring
|
||||
Ic_Date_Barring
|
||||
Ic_No_Answer
|
||||
Ic_Default_Ring
|
||||
Malicious
|
||||
Display_Calling_Party_CLI
|
||||
Call_Waiting_for_all_calls
|
||||
Cancel_Call_Waiting
|
||||
Hunting
|
||||
Leading_Number
|
||||
Block_Anonymous_Call
|
||||
Do_Not_Disturb
|
||||
Restrict_Automatic_Recall
|
||||
Restrict_Automatic_CallBack
|
||||
Ic_Cancel_All_Forwards
|
||||
Ic_On-Line_Malicious
|
||||
Ic_Barring_Pattern
|
||||
}
|
||||
RegisteredOG
|
||||
{
|
||||
Speed_Dial_one_Digit
|
||||
Speed_Dial_two_Digits
|
||||
Save_Dialed_Number
|
||||
Og_Selective_Barring
|
||||
Og_Day_Time_Barring
|
||||
Og_Date_Barring
|
||||
Og_Display_Name
|
||||
Feature_Keys
|
||||
Pre_Paid
|
||||
Metering
|
||||
Block_CLI
|
||||
Confidential_Number
|
||||
Automatic_CallBack
|
||||
Automatic_Recall
|
||||
Force_CLI
|
||||
Last_Number_Redial
|
||||
Og_Three_Way_Calling
|
||||
Og_Hold
|
||||
Og_Barring_Pattern
|
||||
}
|
||||
Log_Malicious_Calls
|
||||
Display_Calling_Party_CLI
|
||||
Cancel_Call_Waiting
|
||||
On_Line_Malicious
|
||||
Block_CLI
|
||||
Automatic_CallBack
|
||||
Automatic_Recall
|
||||
Force_CLI
|
||||
Last_Number_Redial
|
||||
Hold
|
||||
Default_Ring
|
||||
{
|
||||
1
|
||||
}
|
||||
Display_Name
|
||||
{
|
||||
O
|
||||
}
|
||||
}
|
||||
35627464746
|
||||
{
|
||||
RegisteredIC
|
||||
{
|
||||
Selective_Call_Waiting
|
||||
Selective_Ring
|
||||
Ring_By_DayTime
|
||||
Ring_By_Call_Origin
|
||||
ReAnswer
|
||||
Forward_All_Calls
|
||||
Forward_On_Busy
|
||||
Forward_on_No_Answer
|
||||
Forward_Unavailable
|
||||
Selective_CW_Ring
|
||||
Ic_Selective_Barring
|
||||
Ic_Day_Time_Barring
|
||||
Ic_Date_Barring
|
||||
Ic_No_Answer
|
||||
Ic_Default_Ring
|
||||
Malicious
|
||||
Display_Calling_Party_CLI
|
||||
Call_Waiting_for_all_calls
|
||||
Cancel_Call_Waiting
|
||||
Hunting
|
||||
Leading_Number
|
||||
Block_Anonymous_Call
|
||||
Do_Not_Disturb
|
||||
Restrict_Automatic_Recall
|
||||
Restrict_Automatic_CallBack
|
||||
Ic_Cancel_All_Forwards
|
||||
Ic_On-Line_Malicious
|
||||
Ic_Barring_Pattern
|
||||
}
|
||||
RegisteredOG
|
||||
{
|
||||
Speed_Dial_one_Digit
|
||||
Speed_Dial_two_Digits
|
||||
Save_Dialed_Number
|
||||
Og_Selective_Barring
|
||||
Og_Day_Time_Barring
|
||||
Og_Date_Barring
|
||||
Og_Display_Name
|
||||
Og_Web_Access
|
||||
Feature_Keys
|
||||
Pre_Paid
|
||||
Metering
|
||||
Block_CLI
|
||||
Confidential_Number
|
||||
Automatic_CallBack
|
||||
Automatic_Recall
|
||||
Force_CLI
|
||||
Last_Number_Redial
|
||||
Og_Three_Way_Calling
|
||||
Og_Hold
|
||||
Og_Barring_Pattern
|
||||
}
|
||||
Log_Malicious_Calls
|
||||
Display_Calling_Party_CLI
|
||||
Cancel_Call_Waiting
|
||||
On_Line_Malicious
|
||||
Block_CLI
|
||||
Automatic_CallBack
|
||||
Automatic_Recall
|
||||
Force_CLI
|
||||
Last_Number_Redial
|
||||
Hold
|
||||
Default_Ring
|
||||
{
|
||||
1
|
||||
}
|
||||
Web_Password
|
||||
{
|
||||
27464746
|
||||
}
|
||||
Display_Name
|
||||
{
|
||||
27464746
|
||||
}
|
||||
}
|
||||
@ -1 +1 @@
|
||||
working_path = /var/sipwise
|
||||
#working_path = /var/sipwise
|
||||
@ -1,60 +0,0 @@
|
||||
use strict;
|
||||
|
||||
## no critic
|
||||
|
||||
use File::Basename;
|
||||
use Cwd;
|
||||
use lib Cwd::abs_path(File::Basename::dirname(__FILE__));
|
||||
|
||||
use Getopt::Long;
|
||||
|
||||
use Globals qw(
|
||||
$defaultconfig
|
||||
);
|
||||
use Logging qw(
|
||||
init_log
|
||||
getlogger
|
||||
$attachmentlogfile
|
||||
);
|
||||
use LogError qw (
|
||||
completion
|
||||
success
|
||||
);
|
||||
use LoadConfig qw(load_config);
|
||||
use Utils qw(getscriptpath zerofill changemod timestampdigits);
|
||||
use Mail qw(wrap_mailbody
|
||||
$signature
|
||||
$normalpriority
|
||||
$lowpriority
|
||||
$highpriority);
|
||||
use ConnectorPool qw(destroy_dbs);
|
||||
|
||||
init();
|
||||
|
||||
exit(main());
|
||||
|
||||
sub init {
|
||||
|
||||
#GetOptions ("host=s" => \$host,
|
||||
# "port=i" => \$port,
|
||||
# "file=s" => \$output_filename,
|
||||
# "dir=s" => \$output_dir,
|
||||
# "user=s" => \$user,
|
||||
# "pass=s" => \$pass,
|
||||
# "period=s" => \$period,
|
||||
# 'verbose+' => \$verbose) or fatal("Error in command line arguments");
|
||||
my $configfile = $defaultconfig;
|
||||
|
||||
load_config($configfile);
|
||||
init_log();
|
||||
#update_working_path('/var/sipwise');
|
||||
#my $logger = getlogger(getscriptpath());
|
||||
return 0; #blah;
|
||||
|
||||
}
|
||||
|
||||
|
||||
sub main() {
|
||||
|
||||
return 0;
|
||||
}
|
||||
Loading…
Reference in new issue