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.
252 lines
8.1 KiB
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:
|