TT#23275 TT#21348 hash2obj util method

+ working example for api/conversation ->
  process_cdr_item

Change-Id: I12357d6105618743f6a1270a0c5995f8db8b60a2
changes/84/16084/1
Rene Krenn 8 years ago
parent cf3f2fbcee
commit ab869fa2a4

@ -14,7 +14,7 @@ use NGCP::Panel::Form;
use Tie::IxHash;
my %call_fields = ();
tie(%call_fields, 'Tie::IxHash');
my $call_fields_tied = tie(%call_fields, 'Tie::IxHash');
$call_fields{source_user_id} = 'me.source_user_id';
$call_fields{source_account_id} = 'me.source_account_id';
$call_fields{source_clir} = 'me.source_clir';
@ -32,6 +32,39 @@ $call_fields{call_status} = 'me.call_status';
$call_fields{start_time} = 'me.start_time';
$call_fields{duration} = 'me.duration';
$call_fields{call_id} = 'me.call_id';
$call_fields{rating_status} = 'me.rating_status';
$call_fields{source_customer_cost} = 'me.source_customer_cost';
$call_fields{destination_customer_cost} = 'me.destination_customer_cost';
$call_fields{source_customer_free_time} = 'me.source_customer_free_time';
my $cdr_proto = _hash2obj(
classname => 'cdr_item',
accessors => {
(map { $_ => _get_alias($call_fields_tied->Indices($_) + 1); } keys %call_fields),
#call_id => sub { #override
# my $self = shift;
# use Data::Dumper;
# my $test = { %$self };
# delete $test->{c};
# $self->{c}->log->debug(Dumper([map { $_ => _get_alias($call_fields_tied->Indices($_) + 1); } keys %call_fields]));
# return $self->{'field15'};
#},
get_column => sub {
my ($self,$colname) = @_;
return $self->{$colname};
},
source_subscriber => sub {
my $self = shift;
return $self->{c}->model('DB')->resultset('voip_subscribers')->find({ uuid => $self->source_user_id() });
},
destination_subscriber => sub {
my $self = shift;
return $self->{c}->model('DB')->resultset('voip_subscribers')->find({ uuid => $self->destination_user_id() });
},
},
);
my %voicemail_fields = ();
tie(%voicemail_fields, 'Tie::IxHash');
$voicemail_fields{duration} = 'me.duration';
@ -118,29 +151,8 @@ sub _item_rs {
my ($uuid,$contract_id,$reseller_id,$provider_id,$show);
if ($params->{subscriber_id}) {
my $subscriber;
eval {
$subscriber = $c->model('DB')->resultset('voip_subscriber')->find($params->{subscriber_id});
};
if ($subscriber) {
$uuid = $subscriber->uuid;
} else {
#die invalid subscriber_id '$params->{subscriber_id}'
}
}
if ($params->{customer_id}) {
# ensure integer, allow terminated
my $contract;
eval {
$contract = $c->model('DB')->resultset('contract')->find($params->{subscriber_id});
};
if ($contract) {
$contract_id = $contract->id;
} else {
#die invalid customer_id '$params->{customer_id}'
}
}
(my $subscriber,$uuid) = $self->_get_subscriber($c,$params);
(my $contract,$contract_id) = $self->_get_contract($c,$params);
if ($c->user->roles eq "subscriber") {
$uuid = $c->user->voip_subscriber->uuid;
@ -178,6 +190,41 @@ sub _item_rs {
}
sub _get_subscriber {
my ($self, $c, $params) = @_;
$params //= $c->req->params;
my ($subscriber,$uuid);
if ($params->{subscriber_id}) {
eval {
$subscriber = $c->model('DB')->resultset('voip_subscribers')->find($params->{subscriber_id});
};
if ($subscriber) {
$uuid = $subscriber->uuid;
} else {
#die invalid subscriber_id '$params->{subscriber_id}'
}
}
return ($subscriber,$uuid);
}
sub _get_contract {
my ($self, $c, $params) = @_;
$params //= $c->req->params;
my ($contract,$contract_id);
if ($params->{customer_id}) {
# ensure integer, allow terminated
eval {
$contract = $c->model('DB')->resultset('contracts')->find($params->{customer_id});
};
if ($contract) {
$contract_id = $contract->id;
} else {
#die invalid customer_id '$params->{customer_id}'
}
}
return ($contract,$contract_id);
}
sub _apply_timestamp_from_to {
my $self = shift;
my %params = @_;
@ -640,7 +687,8 @@ sub process_hal_resource {
my($self, $c, $item, $resource, $form) = @_;
use Data::Dumper;
$c->log->debug(Dumper($item));
#$c->log->debug(Dumper($item));
#$c->log->debug(Dumper($resource));
my $datetime_fmt = DateTime::Format::Strptime->new(
pattern => '%F %T',
@ -654,24 +702,71 @@ sub process_hal_resource {
# todo: mashal specific fields, per conversation event type ...
if ('call' eq $resource->{type}) {
my $cdr_item = NGCP::Panel::Utils::CallList::process_cdr_item($c,_hash2obj(
classname => ref $cdr_proto,
hash => $resource,
private => { c => $c, },
),{
subscriber => ($self->_get_subscriber($c))[0],
customer => ($self->_get_contract($c))[0],
},
);
# todo: populate $resource ...
$c->log->debug(Dumper($cdr_item));
}
return $resource;
}
sub hal_links {
my($self, $c, $item, $resource, $form) = @_;
return [
('call' eq $item->{type} ?
NGCP::Panel::Utils::DataHalLink->new(relation => 'ngcp:calls', href => sprintf("/api/calls/%d", $item->{id})) : ()),
('voicemail' eq $item->{type} ?
NGCP::Panel::Utils::DataHalLink->new(relation => 'ngcp:voicemails', href => sprintf("/api/voicemails/%d", $item->{id})) : ()),
('sms' eq $item->{type} ?
NGCP::Panel::Utils::DataHalLink->new(relation => 'ngcp:sms', href => sprintf("/api/sms/%d", $item->{id})) : ()),
('fax' eq $item->{type} ?
NGCP::Panel::Utils::DataHalLink->new(relation => 'ngcp:faxes', href => sprintf("/api/faxes/%d", $item->{id})) : ()),
('call' eq $resource->{type} ?
NGCP::Panel::Utils::DataHalLink->new(relation => 'ngcp:calls', href => sprintf("/api/calls/%d", $resource->{id})) : ()),
('voicemail' eq $resource->{type} ?
NGCP::Panel::Utils::DataHalLink->new(relation => 'ngcp:voicemails', href => sprintf("/api/voicemails/%d", $resource->{id})) : ()),
('sms' eq $resource->{type} ?
NGCP::Panel::Utils::DataHalLink->new(relation => 'ngcp:sms', href => sprintf("/api/sms/%d", $resource->{id})) : ()),
('fax' eq $resource->{type} ?
NGCP::Panel::Utils::DataHalLink->new(relation => 'ngcp:faxes', href => sprintf("/api/faxes/%d", $resource->{id})) : ()),
# todo - add xmpp mam rail:
# ('xmpp' eq $item->{type} ?
# NGCP::Panel::Utils::DataHalLink->new(relation => 'ngcp:xmpp', href => sprintf("/api/xmpp/%d", $item->{id})) : ()),
];
}
sub _hash2obj {
my %params = @_;
my ($hash,$private,$classname,$accessors) = @params{qw/hash private classname accessors/};
my $obj;
$obj = $hash if 'HASH' eq ref $hash;
$obj //= {};
$obj = { %$obj, %$private } if 'HASH' eq ref $private;
unless (defined $classname and length($classname) > 0) {
my @chars = ('A'..'Z');
$classname //= '';
$classname .= $chars[rand scalar @chars] for 1..8;
}
$classname = __PACKAGE__ . '::' . $classname unless $classname =~ /::/;
bless($obj,$classname);
no strict "refs";
return $obj if scalar %{$classname . '::'};
print "registering class $classname\n";
$accessors //= {};
foreach my $accessor (keys %$accessors) {
print "registering accessor $classname::$accessor\n";
*{$classname . '::' . $accessor} = sub {
my $self = shift;
return &{$accessors->{$accessor}}($self,@_);
} if 'CODE' eq ref $accessors->{$accessor};
*{$classname . '::' . $accessor} = sub {
my $self = shift;
return $self->{$accessors->{$accessor}};
} if '' eq ref $accessors->{$accessor};
}
return $obj;
}
1;

@ -0,0 +1,98 @@
use strict;
use warnings;
use Data::Dumper;
my $cdr_hash1 = {
field1 => "value1",
field2 => "value2",
field3 => "value3",
};
my $cdr_hash2 = {
field1 => "value4",
field2 => "value5",
field3 => "value6",
};
my $item1 = hash2obj(
hash => $cdr_hash1,
classname => "myCDRItem",
private => {},
accessors => {
source_user => sub {
my $self = shift;
return $self->{field1};
},
destination_user_in => sub {
my $self = shift;
return $self->{field2};
},
start_time => sub {
my $self = shift;
return $self->{field2};
},
}
);
my $item2 = hash2obj(
hash => $cdr_hash2,
#classname => "myCDRItem",
private => {},
accessors => {
source_user => sub {
my $self = shift;
return $self->{field1};
},
destination_user_in => sub {
my $self = shift;
return $self->{field2} . 'xx';
},
start_time => sub {
my $self = shift;
return $self->{field2};
},
}
);
print $item1->destination_user_in;
print $item2->destination_user_in;
print $item2->field1;
exit;
sub hash2obj {
#my $self = shift;
my %params = @_;
my ($hash,$classname,$accessors) = @params{qw/hash classname accessors/};
my $obj;
$obj = $hash if 'HASH' eq ref $hash;
$obj //= {};
unless (defined $classname and length($classname) > 0) {
my @chars = ('A'..'Z');
$classname //= '';
$classname .= $chars[rand scalar @chars] for 1..8;
}
$classname = __PACKAGE__ . '::' . $classname unless $classname =~ /::/;
bless($obj,$classname);
no strict "refs"; # for below and to register new methods in package
return $obj if scalar %{$classname . '::'};
print "registering class $classname\n";
$accessors //= {};
my %accessors = ( (map { $_ => undef; } keys %$obj), %$accessors); # create accessors for fields too
for my $accessor (keys %accessors) {
print "registering accessor $classname::$accessor\n";
# see http://search.cpan.org/~gsar/perl-5.6.1/pod/perltootc.pod
# accessor can be a coderef ...
*{$classname . '::' . $accessor} = sub {
my $self = shift;
&{$accessors{$accessor}}($self,shift) if scalar @_; #setter
return &{$accessors{$accessor}}($self); #getter
} if 'CODE' eq ref $accessors{$accessor};
# ... or hash field name:
*{$classname . '::' . $accessor} = sub {
my $self = shift;
$self->{$accessors{$accessor}} = shift if scalar @_; #setter
return $self->{$accessors{$accessor}}; #getter
} if '' eq ref $accessors{$accessor};
}
return $obj;
}
Loading…
Cancel
Save