Ticket #3416 (closed Feature Requests: fixed)

Opened 1 month ago

Last modified 1 month ago

ARI - Voicemails get deleted when moving between folders

Reported by: aaelghat1 Assigned to: sasargen
Priority: minor Milestone: 2.6
Component: ARI Version: 2.5-branch
Keywords: Cc:
Confirmation: Need Feedback SVN Revision (if applicable):
Backend Engine: All Backend Engine Version:

Description (Last modified by p_lindheimer)

Voicemails will get deleted when moving them between folders using the ARI interface in the following circumstance:

I use Serge Mankovski's "Voicemail RSS" contribution which allows voicemails to be podcast. That contribution will iterate through the recordings in the voicemail directories and create mp3 files in the format below...

msg0000.7025f35d463ebbafa101db8a88c71b681aa8443d.mp3 msg0001.9a2755d835707fbfa72f41005d378e3d488c991b.mp3

Once those files are out there, the moving of files between folders will end up in one file getting moved and the rest getting deleted or overwritten because the algorithm that does the moving doesn't account for the long file name with the msg???? prefix. Even the wav and txt files are affected. If I move files from one folder to a destination folder using the interface, the destination folder will end up with files that have the following format:

msg00.b00a00e00da00d00c00b00f00c00b00ca00.mp00 msg00.b00ae00ed00cfa00fcf00a00f00a00b00b00b00f00.mp00 msg00.gsm msg00.txt msg00.WAV msg00.wav

I believe since all the files are being copied over as msg00 the files are overwriting each other when they are copied. Since they get deleted from the source directory, the recordings are unrecoverable.

I believe the applicable code is in voicemail.module in the moveVoicemailData function. Even if you determine that you can't fix this in FreePBX, I'd appreciate some direction on what I'd need to change to fix it for me (I'm not that good with PHP), as the RSS component is critical. I've copied the unaltered FreePBX applicable code from voicemail.module below.

Thank you.

  function moveVoicemailData($files,$context_rx,$extension_rx,$folder_rx) {

    global $ASTERISK_VOICEMAIL_PATH;

    $perm = fileperms($ASTERISK_VOICEMAIL_PATH);
    $uid = fileowner($ASTERISK_VOICEMAIL_PATH);
    $gid = filegroup($ASTERISK_VOICEMAIL_PATH);

    // recieving path
    $paths = split(';',$ASTERISK_VOICEMAIL_PATH);
    $path_rx = appendPath($paths[0],$context_rx);
    if (!is_dir($path_rx)) {
      mkdir($path_rx, $perm); 
      chown($path_rx,intval($uid));
      chgrp($path_rx,intval($gid));
    }
    $path_rx = appendPath($path_rx,$extension_rx);
    if (!is_dir($path_rx)) {
      mkdir($path_rx, $perm); 
      chown($path_rx,intval($uid));
      chgrp($path_rx,intval($gid));
    }
    $path_rx = appendPath($path_rx,$folder_rx);
    if (!is_dir($path_rx)) {
      mkdir($path_rx, $perm); 
      chown($path_rx,intval($uid));
      chgrp($path_rx,intval($gid));
    }

    // get recieving folder last message number
    if (is_dir($path_rx)) {

      $lastNum = -1;
      $lastNumLen = 4;

      $dh = opendir($path_rx);
      while (false != ($filename = readdir($dh))) {
        if($filename!="." && $filename!="..") {

          $msg_path = $path_rx;
          $msg_path = appendPath($msg_path,$filename);
          if (is_file($msg_path)) {
            $path_parts = pathinfo($msg_path);
            $num = preg_replace("/[a-zA-Z]|\./",'', $path_parts['basename']);
            if ($num > $lastNum) {
              $lastNum = $num;
              $lastNumLen = strlen($lastNum);
            }
          } 
        }
      } 
    }
    else {
      $_SESSION['ari_error'] = sprintf(_("Could not create folder %s on the server"),$folder_rx);
      return;
    }

    // copy files to new location, incrementing each message number 
    asort($files);
    foreach($files as $key => $path) {

      // get file parts for search
      $path_parts = pathinfo($path);
      $path = $path_parts['dirname'];
      $path = fixPathSlash($path);
      list($name,$ext) = split("\.",$path_parts['basename']);
      if (is_dir($path)) {

        $lastNum++;
        $hdl = opendir($path);
        while ($fn = readdir($hdl)) {
          if (preg_match("/" . $name . "/",$fn)) {
            $src = $path . $fn;
            $path_parts = pathinfo($src);
            $folder_rx = preg_replace("/\d+/",sprintf("%0" . $lastNumLen . "d",$lastNum),$path_parts['basename']);
            $dst = appendPath($path_rx,$folder_rx);
            if (is_writable($src) && is_writable($path_rx)) {

              $perm = fileperms($src);
              $uid = fileowner($src);
              $gid = filegroup($src);

              copy($src,$dst);

              if (is_writable($dst)) {
                chmod($dst, $perm); 
                chown($dst,intval($uid));
                chgrp($dst,intval($gid));
              }

              unlink($src);
            }
            else {
              $_SESSION['ari_error'] = sprintf(_("Permission denied on folder %s or %s"),$src,$path_rx);
              return;
            }
          } 
        }
        closedir($hdl);
      }
    }
  }

  /*

Change History

11/26/08 23:20:52 changed by p_lindheimer

  • type changed from Bugs to Feature Requests.
  • description changed.

changing to feature request, as copying works fine between directories when the files are in the expected Asterisk format. If someone wants to supply a patch that works on the proper format and keeps these mods happy, we can review for inclusion.

11/27/08 08:33:35 changed by sasargen

  • confirmation changed from Unreviewed to Need Feedback.

gregmac had looked at the Voicemail RSS plugin and mentioned that it had some issues (see #1100). However, serge.mankovski.com is down today, so I can't look at the plugin code.

aaelghat1, please update your voicemail.module file with the following code and provide feedback.

Untested code with quick fix for original reporters error is below. When getting last message number in receiving folder, change from parsing entire file name to parsing just the part of the filename before the first '.'.

    // get recieving folder last message number
    if (is_dir($path_rx)) {

      $lastNum = -1;
      $lastNumLen = 4;

      $dh = opendir($path_rx);
      while (false != ($filename = readdir($dh))) {
        if($filename!="." && $filename!="..") {

          $msg_path = $path_rx;
          $msg_path = appendPath($msg_path,$filename);
          if (is_file($msg_path)) {
            $path_parts = pathinfo($msg_path);
            //fix for Serge Mankovski's "Voicemail RSS"
            //split file basename into two pieces at the first '.'
            //so that files like msg0000.7025f35d463ebbafa101db8a88c71b681aa8443d.mp3
            //don't interfere with finding the true last file number
            list($name,$ext) = split("\.",$path_parts['basename'],2);
            $num = preg_replace("/[a-zA-Z]|\./",'', $name);
            if ($num > $lastNum) {
              $lastNum = $num;
              $lastNumLen = strlen($lastNum);
            }
          } 
        }
      } 
    }

When making file name for receiving folder, change from replacing digits in entire file name to replacing digits in the part of the filename before the first '.'.

    // copy files to new location, incrementing each message number 
    asort($files);
    foreach($files as $key => $path) {

      // get file parts for search
      $path_parts = pathinfo($path);
      $path = $path_parts['dirname'];
      $path = fixPathSlash($path);
      list($name,$ext) = split("\.",$path_parts['basename']);
      if (is_dir($path)) {

        $lastNum++;
        $hdl = opendir($path);
        while ($fn = readdir($hdl)) {
          if (preg_match("/" . $name . "/",$fn)) {
            $src = $path . $fn;
            $path_parts = pathinfo($src);
            //fix for Serge Mankovski's "Voicemail RSS"
            //split file basename into two pieces at the first '.'
            //so that files like msg0000.7025f35d463ebbafa101db8a88c71b681aa8443d.mp3
            //don't get clobbered by preg_replace() of digits
            list($name,$ext) = split("\.",$path_parts['basename'],2);
            $folder_rx = preg_replace("/\d+/",sprintf("%0" . $lastNumLen . "d",$lastNum),$name) . $ext);
            $dst = appendPath($path_rx,$folder_rx);
            if (is_writable($src) && is_writable($path_rx)) {

(follow-up: ↓ 4 ) 11/29/08 09:17:39 changed by aaelghat1

Thanks you for taking a stab at changing the code. I made the changes. When I move files from one folder to the next the screen blanks out and in my PHP error log I get the following line:

[29-Nov-2008 10:42:43] PHP Parse error: parse error, unexpected ')' in /var/www/html/recordings/modules/voicemail.module on line 718

Line 718 is the line that has:

$folder_rx = preg_replace("/\d+/",sprintf("%0" . $lastNumLen . "d",$lastNum),$name) . $ext);

I see that there are two left parentheses, and three right parentheses, and I tried deleting one of each of the right paranthesis, but then no files made it to the new folder.

(in reply to: ↑ 3 ) 11/29/08 12:25:28 changed by sasargen

Sorry for the typo. Line should not have the final right paren. Here is the proper version:

$folder_rx = preg_replace("/\d+/",sprintf("%0" . $lastNumLen . "d",$lastNum),$name) . $ext; 

11/29/08 15:33:46 changed by aaelghat1

OK, I think we're getting close...

I copied in the modified line and moved files from a source folder to a destination folder. The file names look like the ones below - they all had the first dot removed....

msg00038d3d0326e65abb5f47f3201ad470653f841b901c.mp3

msg0003gsm

msg0003txt

msg0003wav

msg0003WAV

msg0004b96312c5fc5003d032b80262406a3e2838e48366.mp3

msg0004gsm

msg0004txt

msg0004wav

msg0004WAV

msg0005676146f66897a1fe8db6bafb49e35bdf3ea3b1d3.mp3

msg0005gsm

msg0005txt

msg0005WAV

msg0005wav

11/30/08 05:57:39 changed by sasargen

Oops, forgot about adding the dot back in. Try this line:

$folder_rx = preg_replace("/\d+/",sprintf("%0" . $lastNumLen . "d",$lastNum),$name) . "." . $ext; 

11/30/08 06:51:36 changed by aaelghat1

I changed the line, tested it, and it worked like a charm.

I really appreciate your help on this - people were losing their recordings, and having this fixed is a big load off my mind. Thanks again.

12/01/08 05:36:39 changed by sasargen

  • status changed from new to closed.
  • resolution set to fixed.

(In [7304]) fixes #3416, prevents ARI forwarding from mangling voicemail mp3 files created by Serge Mankovski's Voicemail RSS plug-in