You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
ngcp-panel/lib/NGCP/Panel/Utils/Sounds.pm

252 lines
8.1 KiB

package NGCP::Panel::Utils::Sounds;
use strict;
use warnings;
use IPC::System::Simple qw/capturex/;
use File::Temp qw/tempfile/;
use NGCP::Panel::Utils::Sems;
use NGCP::Panel::Utils::Preferences;
use File::Slurp;
use File::Basename;
sub transcode_file {
my ($tmpfile, $source_codec, $target_codec) = @_;
my $out;
my @conv_args;
## quite snappy, but breaks SOAP (sigpipe's) and the catalyst devel server
## need instead to redirect like below
SWITCH: for ($target_codec) {
/^PCMA$/ && do {
@conv_args = ($tmpfile, qw/--type raw --bits 8 --channels 1 -e a-law - rate 8k/);
last SWITCH;
};
/^WAV$/ && do {
if ($source_codec eq 'PCMA') {
# this can actually only come from inside
# certain files will be stored as PCMA (for handles with name "music_on_hold")
@conv_args = ( qw/-A --rate 8k --channels 1 --type raw/, $tmpfile, "--type", "wav", "-");
}
else {
@conv_args = ($tmpfile, qw/--type wav --bits 16 - rate 8k/);
}
last SWITCH;
};
/^MP3$/ && do {
@conv_args = ($tmpfile, qw/--type mp3 --bits 16 - rate 8k/);
last SWITCH;
};
/^OGG$/ && do {
@conv_args = ($tmpfile, qw/--type ogg --bits 16 - rate 8k/);
last SWITCH;
};
# default
} # SWITCH
$out = capturex([0], "/usr/bin/sox", @conv_args);
return $out;
}
sub transcode_data {
my ($data, $source_codec, $target_codec) = @_;
my ($fh, $filename) = tempfile;
print $fh (ref $data ? $$data : $data);
close $fh;
my $out = transcode_file($filename, $source_codec, $target_codec);
unlink $filename;
return \$out;
}
sub stash_soundset_list {
my (%params) = @_;
my $c = $params{c};
my $contract = $params{contract};
my $sets_rs = $c->model('DB')->resultset('voip_sound_sets');
if($contract) {
$sets_rs = $sets_rs->search({ 'me.contract_id' => $contract->id });
}
my $dt_fields = [
{ name => 'id', search => 1, title => $c->loc('#') },
{ name => 'name', search => 1, title => $c->loc('Name') },
{ name => 'description', search => 1, title => $c->loc('Description') },
];
if($c->user->roles eq "admin") {
splice @{ $dt_fields }, 1, 0,
{ name => 'reseller.name', search => 1, title => $c->loc('Reseller') };
splice @{ $dt_fields }, 2, 0,
{ name => 'contract.contact.email', search => 1, title => $c->loc('Customer') };
} elsif($c->user->roles eq "reseller") {
splice @{ $dt_fields }, 1, 0,
{ name => 'contract.contact.email', search => 1, title => $c->loc('Customer') };
$sets_rs = $sets_rs->search({ 'me.reseller_id' => $c->user->reseller_id });
} elsif($c->user->roles eq "subscriberadmin" && !$contract) {
$sets_rs = $sets_rs->search({ 'me.contract_id' => $c->user->account_id });
}
$c->stash->{soundset_dt_columns} = NGCP::Panel::Utils::Datatables::set_columns($c, $dt_fields);
$c->stash(sets_rs => $sets_rs);
return;
}
sub get_handles_rs {
my (%params) = @_;
my $c = $params{c};
my $set_rs = $params{set_rs};
my $handles_rs = $c->model('DB')->resultset('voip_sound_groups')
->search({
},{
select => ['groups.name', \'handles.name', \'handles.id', 'files.filename', 'files.loopplay', 'files.codec', 'files.id'],
as => [ 'groupname', 'handlename', 'handleid', 'filename', 'loopplay', 'codec', 'fileid'],
alias => 'groups',
from => [
{ groups => 'provisioning.voip_sound_groups' },
[
{ handles => 'provisioning.voip_sound_handles', -join_type=>'left'},
{ 'groups.id' => 'handles.group_id'},
],
[
{ files => 'provisioning.voip_sound_files', -join_type => 'left'},
{ 'handles.id' => { '=' => \'files.handle_id'}, 'files.set_id' => $set_rs->id},
],
],
order_by => { -asc => 'handles.name' }
});
if($set_rs->contract_id) {
$handles_rs = $handles_rs->search({
'groups.name' => { '-in' => [qw/pbx music_on_hold digits custom_announcements/] }
});
}
unless($c->config->{features}->{cloudpbx}) {
$handles_rs = $handles_rs->search({ 'groups.name' => { '!=' => 'pbx' } });
}
unless($c->config->{features}->{cloudpbx} || $c->config->{features}->{musiconhold}) {
$handles_rs = $handles_rs->search({ 'groups.name' => { '!=' => 'music_on_hold' } });
}
unless($c->config->{features}->{callingcard}) {
$handles_rs = $handles_rs->search({ 'groups.name' => { '!=' => 'calling_card' } });
}
unless($c->config->{features}->{mobilepush}) {
$handles_rs = $handles_rs->search({ 'groups.name' => { '!=' => 'mobile_push' } });
}
return $handles_rs;
}
sub apply_default_soundset_files{
my (%params) = @_;
my ($c, $lang, $set_id, $handles_rs, $loopplay, $override, $error_ref) = @params{qw/c lang set_id handles_rs loopplay override error_ref/};
$loopplay = $loopplay ? 1 : 0;
my $schema = $c->model('DB');
my $base = "/var/lib/ngcp-soundsets";
foreach my $h($handles_rs->all) {
my $hname = $h->get_column("handlename");
my @paths = (
"$base/system/$lang/$hname.wav",
"$base/customer/$lang/$hname.wav",
"/var/lib/asterisk/sounds/$lang/digits/$hname.wav",
);
my $path;
foreach my $p(@paths) {
if(-f $p) {
$path = $p;
last;
}
}
next unless(defined $path);
my $data_ref;
my $codec = 'WAV';
my $handle_id = $h->get_column("handleid");
my $file_id = $h->get_column("fileid");
my $fres;
my $fname = basename($path);
read_file($path, buf_ref => \$data_ref);
unless (${data_ref}) {
$$error_ref = "Cannot upload an empty sound file, $fname";
die $$error_ref;
}
if (defined $file_id) {
if ($override) {
$c->log->debug("override $path as $hname for existing id $file_id");
$fres = $schema->resultset('voip_sound_files')->find($file_id);
$fres->update({
filename => $fname,
data => ${data_ref},
loopplay => $loopplay,
});
} else {
$c->log->debug("skip $path as $hname exists via id $file_id and override is not set");
}
} else {
$c->log->debug("inserting $path as $hname with new id");
$fres = $schema->resultset('voip_sound_files')
->create({
filename => $fname,
data => ${data_ref},
handle_id => $handle_id,
set_id => $set_id,
loopplay => $loopplay,
codec => $codec,
});
}
next unless defined($fres);
my $group_name = $fres->handle->group->name;
NGCP::Panel::Utils::Sems::clear_audio_cache($c, $fres->set_id,
$fres->handle->name, $group_name);
}
}
sub contract_sound_set_propagate {
my ($c, $contract, $value) = @_;
for my $bill_subscriber ($contract->voip_subscribers->all) {
my $prov_subscriber = $bill_subscriber->provisioning_voip_subscriber;
if ($prov_subscriber) {
&subcriber_sound_set_update_or_create($c, $prov_subscriber, $value);
}
}
}
sub subcriber_sound_set_update_or_create {
my ($c, $prov_subscriber, $value) = @_;
my $pref_rs = NGCP::Panel::Utils::Preferences::get_usr_preference_rs(c => $c,
prov_subscriber => $prov_subscriber, attribute => 'contract_sound_set',
);
my $row = $pref_rs->first;
if (!$row) {
$pref_rs->create({ value => $value });
} else {
# Update only undefined sound set value.
$row->update({ value => $value }) if ! defined $row->value;
}
}
1;
# vim: set tabstop=4 expandtab: