TT#45484 Add "force_delete" option to callrecordings

Change-Id: I49c736a833583028f0a3f5382c93e4a08c81ed00
changes/04/24704/2
Irina Peshinskaya 7 years ago
parent c68e4ed8c9
commit d003c66e7e

@ -47,6 +47,12 @@ sub query_params {
param => 'tz',
description => 'Format start_time according to the optional time zone provided here, e.g. Europe/Berlin.',
},
{
param => 'force_delete',
type => 'item_params',
apply_to => {'item' => {DELETE => 1}},
description => 'Force callrecording info deletion from database despite callrecording files deletion errors.',
},
];
}

@ -6,6 +6,7 @@ use Sipwise::Base;
use parent qw/NGCP::Panel::Role::EntitiesItem NGCP::Panel::Role::API::CallRecordings/;
use NGCP::Panel::Utils::Subscriber;
use HTTP::Status qw(:constants);
__PACKAGE__->set_config({
allowed_roles => [qw/admin reseller subscriberadmin subscriber/],
@ -17,7 +18,18 @@ sub allowed_methods{
sub delete_item {
my ($self, $c, $item) = @_;
NGCP::Panel::Utils::Subscriber::delete_callrecording( c => $c, recording => $item );
try {
NGCP::Panel::Utils::Subscriber::delete_callrecording(
c => $c,
recording => $item,
#TODO: Now we don't use any way to document such parameters, need to be created
force_delete => $c->request->params->{force_delete},
);
} catch($e) {
$c->log->error("failed to delete callrecording: $e");
$self->error($c, HTTP_INTERNAL_SERVER_ERROR, "Failed to delete callrecording.");
return;
}
return 1;
}

@ -4118,26 +4118,44 @@ sub delete_recording :Chained('recording') :PathPart('delete') :Args(0) {
$c->detach('/denied_page')
if(($c->user->roles eq "admin" || $c->user->roles eq "reseller") && $c->user->read_only);
try {
my $recording = $c->stash->{recording};
my $data = { $recording->get_inflated_columns };
$c->model('DB')->schema->txn_do( sub {
NGCP::Panel::Utils::Subscriber::delete_callrecording( c => $c, recording => $recording );
});
NGCP::Panel::Utils::Message::info(
c => $c,
data => $data,
desc => $c->loc('Successfully deleted recording'),
);
} catch($e) {
NGCP::Panel::Utils::Message::error(
c => $c,
error => $e,
desc => $c->loc('Failed to delete recording'),
);
my $posted = ($c->request->method eq 'POST');
my $form = NGCP::Panel::Form::get("NGCP::Panel::Form::Subscriber::CallRecordingDelete", $c);
$form->process(
posted => $posted,
params => $c->request->params,
);
if($posted && $form->validated) {
try {
my $recording = $c->stash->{recording};
my $data = { $recording->get_inflated_columns };
$c->model('DB')->schema->txn_do( sub {
NGCP::Panel::Utils::Subscriber::delete_callrecording(
c => $c,
recording => $recording,
force_delete => $form->values->{force_delete}
);
});
NGCP::Panel::Utils::Message::info(
c => $c,
data => $data,
desc => $c->loc('Successfully deleted recording'),
);
} catch($e) {
NGCP::Panel::Utils::Message::error(
c => $c,
error => $e,
desc => $c->loc('Failed to delete recording'),
);
}
NGCP::Panel::Utils::Navigation::back_or($c,
$c->uri_for_action('/subscriber/details', [$c->req->captures->[0]]));
}
NGCP::Panel::Utils::Navigation::back_or($c,
$c->uri_for_action('/subscriber/details', [$c->req->captures->[0]]));
$c->stash(form => $form);
$c->stash(edit_flag => 1);
return;
}

@ -0,0 +1,45 @@
package NGCP::Panel::Form::Subscriber::CallRecordingDelete;
use Sipwise::Base;
use HTML::FormHandler::Moose;
extends 'HTML::FormHandler';
use HTML::FormHandler::Widget::Block::Bootstrap;
has '+widget_wrapper' => ( default => 'Bootstrap' );
has_field 'submitid' => ( type => 'Hidden' );
sub build_render_list {[qw/submitid fields actions/]}
sub build_form_element_class { [qw/form-horizontal/] }
has_field 'force_delete' => (
type => 'Boolean',
label => 'Force delete',
element_attr => {
rel => ['tooltip'],
title => ['Call recording infromation will be removed from database even in case of recording files absence or other impossibility to remove recording files.']
},
);
has_field 'save' => (
type => 'Submit',
value => 'Delete',
element_class => [qw/btn btn-primary/],
do_label => 0,
);
has_block 'fields' => (
tag => 'div',
class => [qw/modal-body/],
render_list => [qw/force_delete/],
);
has_block 'actions' => (
tag => 'div',
class => [qw/modal-footer/],
render_list => [qw/save/],
);
1;
# vim: set tabstop=4 expandtab:

@ -2026,11 +2026,17 @@ sub get_voicemail_content_type {
sub delete_callrecording {
my %params = @_;
my($recording) = @params{qw/recording/};
my($recording, $force_delete) = @params{qw/recording force_delete/};
foreach my $stream($recording->recording_streams->all) {
#if we met some error deleting file - we will fail and transaction will be rollbacked
unlink($stream->full_filename);
if (! -e $stream->full_filename) {
if ( !$force_delete ) {
die("Callrecording file ".$stream->full_filename." is absent");
}
} elsif( !unlink($stream->full_filename) && !$force_delete ) {
die($!);
}
}
$recording->recording_streams->delete;
$recording->recording_metakeys->delete;

@ -245,7 +245,8 @@ function process_pbx_items(moveId,direction){
helper.dt_buttons = [
{ name = c.loc('Call Details'), uri = "/subscriber/" _ subscriber.id _ "/calls?callid=' + encodeURIComponent(full.call_id_url) + '", class = 'btn-small btn-tertiary', icon = 'icon-search' },
{ name = c.loc('Recorded Files'), uri = "details/recording/'+full.id+'/streams", class = 'btn-small btn-tertiary', icon = 'icon-play' },
{ name = c.loc('Delete'), uri = "details/recording/'+full.id+'/delete", class = 'btn-small btn-secondary', icon = 'icon-trash' },
#we will confirm deletion in the form
{ name = c.loc('Delete recording'), uri = "details/recording/'+full.id+'/delete", class = 'btn-small btn-secondary', icon = 'icon-trash' },
];
ELSE;
helper.dt_buttons = [

Loading…
Cancel
Save