[8125, K-JAM, P4300, MDA Vario General] artpi:
I've written a PHP script that parser PMRecorder files.

It does more then that. It Parses BSCallTimes.xml , puts the data into Mysql table and then Merges the data with PMRecorder data, making PMRecorder files readable by Windows Media Player.

So:

1. You need Linux machine with PHP &Mysql (sorry)

2. You put all your PMRecorder files & BSCallTimes.xml into input directory

3. You should change your php.ini to give scripts more memory.

4. You make the sql table

5. You run script in the shell

6. In the archive directory you have .wav files to play in Windows Media Player and all the call data in sql table.

And here's the script:

<?php

$input="./input";

$sql_host='localhost';
$sql_user='';
$sql_pass='';
$sql_base='';
$sql_table='owczarek_rozmowy';
$wav_archive="./archiwum";

//A great function i found at http://www.bin-co.com/php/scripts/xml2array/

function xml2array($contents, $get_attributes=1) {
if(!$contents) return array();

if(!function_exists('xml_parser_create')) {
//print "'xml_parser_create()' function not found!";
return array();
}
//Get the XML parser of PHP - PHP must have this module for the parser to work
$parser = xml_parser_create();
xml_parser_set_option( $parser, XML_OPTION_CASE_FOLDING, 0 );
xml_parser_set_option( $parser, XML_OPTION_SKIP_WHITE, 1 );
xml_parse_into_struct( $parser, $contents, $xml_values );
xml_parser_free( $parser );

if(!$xml_values) return;//Hmm...

//Initializations
$xml_array = array();
$parents = array();
$opened_tags = array();
$arr = array();

$current = &$xml_array;

//Go through the tags.
foreach($xml_values as $data) {
unset($attributes,$value);//Remove existing values, or there will be trouble
extract($data);//We could use the array by itself, but this cooler.

$result = '';
if($get_attributes) {//The second argument of the function decides this.
$result = array();
if(isset($value)) $result['value'] = $value;

//Set the attributes too.
if(isset($attributes)) {
foreach($attributes as $attr => $val) {
if($get_attributes == 1) $result['attr'][$attr] = $val; //Set all the attributes in a array called 'attr'
/** :TODO: should we change the key name to '_attr'? Someone may use the tagname 'attr'. Same goes for 'value' too */
}
}
} elseif(isset($value)) {
$result = $value;
}

//See tag status and do the needed.
if($type == "open") {//The starting of the tag '<tag>'
$parent[$level-1] = &$current;

if(!is_array($current) or (!in_array($tag, array_keys($current)))) { //Insert New tag
$current[$tag] = $result;
$current = &$current[$tag];

} else { //There was another element with the same tag name
if(isset($current[$tag][0])) {
array_push($current[$tag], $result);
} else {
$current[$tag] = array($current[$tag],$result);
}
$last = count($current[$tag]) - 1;
$current = &$current[$tag][$last];
}

} elseif($type == "complete") { //Tags that ends in 1 line '<tag />'
//See if the key is already taken.
if(!isset($current[$tag])) { //New Key
$current[$tag] = $result;

} else { //If taken, put all things inside a list(array)
if((is_array($current[$tag]) and $get_attributes == 0)//If it is already an array...
or (isset($current[$tag][0]) and is_array($current[$tag][0]) and $get_attributes == 1)) {
array_push($current[$tag],$result); // ...push the new element into that array.
} else { //If it is not an array...
$current[$tag] = array($current[$tag],$result); //...Make it an array using using the existing value and the new value
}
}

} elseif($type == 'close') { //End of tag '</tag>'
$current = &$parent[$level-1];
}
}

return($xml_array);
}

mysql_connect($sql_host,$sql_user,$sql_pass);
mysql_select_db($sql_base);

//If there's a call log file in input directory.

if(file_exists($input."/BSCallTimes.xml"))
{

echo "Processing ".$input."/BSCallTimes.xml file \n";
$fd=fopen($input."/BSCallTimes.xml","r");
$content=fread($fd,filesize($input."/BSCallTimes.xml"));
fclose($fd);

$array=xml2array($content);

$calls=$array['BSCallTimesLog']['Call'];
for($i=0;$i<count($calls);$i++)
{
$call['type']=$calls[$i]['attr']['Type'];
$call['length']=$calls[$i]['attr']['RoundSeconds'];

// If it's an sms, let's put size instead of length.
if(substr($call['type'],0,3)=='msg')
$call['length']=$calls[$i]['attr']['Amount'];

//Time to parse date & time
$date=explode("/",$calls[$i]['attr']['Date']);
$time=explode(".",$calls[$i]['attr']['Time']);
$time2=explode(":",$time[0]);
$call['time']=mktime($time2[0],$time2[1],$time[1],$date[1],$date[2],$date[0]);

$call['number']=$calls[$i]['Number']['value'];
$call['caller']=$calls[$i]['Desc']['value'];

//What the hell do we need ? for?
if($call['caller']=='?')
$call['caller']='';

$wynik=mysql_query("SELECT * FROM $sql_table WHERE time='".$call['time']."';");

if(mysql_num_rows($wynik)>0)
{
//Is it already in the databese, but maybe we put it during call record parsing.
$wiersz=mysql_fetch_array($wynik);

if(strlen($wiersz['type'])<4)
{

//Yup, we can update the data.
mysql_query("UPDATE $sql_table SET type='".$call['type']."',length='".$call['length']."',number='".$call['number']."' WHERE time='".$call['time']."';");
echo "At:".time()." updated call at [".$call['time']."] - Type:[".$call['type']."], Length:[".$call['length']."], Number: [".$call['number']."]\n";
}
else
print("kartofel");
}
else
{
//Lets insert some data.
mysql_query("INSERT INTO $sql_table SET type='".$call['type']."',length='".$call['length']."',number='".$call['number']."',time='".$call['time']."',caller='".$call['caller']."';");
echo "At: ".time()." inserted call at [".$call['time']."] - Type:[".$call['type']."], Length:[".$call['length']."], Number: [".$call['number']."], Caller: [".$call['caller']."]\n";

}

}
echo "BSCallTimes Processed.\n";
}

//So, now that BSCallTimes file is processed, let's process other files.

$directory = opendir($input);
while($file = readdir($directory)) {

//If it's PMRecorder file:
If(substr($file,-2)=='wv')
{

$naz=explode(".",$file);

//So we don't do this again:
if(!file_exists($wav_archive."/".$naz[0].".wav"))
{

$pliczek=$input."/".$file;

echo "Processing file ".$pliczek."\n";

$fd=fopen($pliczek,"r");
$content=fread($fd,filesize($pliczek));
fclose($fd);

$wav=strstr($content,"RIFF");

$fd=fopen($wav_archive."/".$naz[0].".wav","w");
fwrite($fd,$wav);
fclose($fd);

echo "Wav file saved at ".$wav_archive."/".$naz[0].".wav"."\n";

$naglowki=substr($content,24,strpos($content,"RIFF")-24);
$nag=explode(chr(0).chr(0).chr(100),$naglowki);

$czysc1=array(chr(0),chr(100));
$czysc2=array("e","I","O","f",chr(0),chr(127));

//PMRecorder file name
$data[0]=$naz[0];
//Unix time
$data[1]=mktime($naz[0][8].$naz[0][9],$naz[0][10].$naz[0][11],$naz[0][12].$naz[0][13],$naz[0][0].$naz[0][1],$naz[0][2].$naz[0][3],$naz[0][4].$naz[0][5].$naz[0][6].$naz[0][7]);
//Caller name
$data[2]=str_replace($czysc1,"",$nag[0]);
//Caller number
$data[3]=str_replace($czysc2,"",$nag[1]);
preg_match ("#([a-z])#is",$data[3],$tmp);
//Number type (h/m/...)
$data[4]=$tmp[1];
//Filtered number
$data[3]=preg_replace("#([a-z])#is","",$data[3]);

//Once again some sql:

$wynik=mysql_query("SELECT * FROM $sql_table WHERE time >'".($data[1]-4)."' AND time<'".($data[1]+1)."';");

//Why so strange where clause? PMRecorder is a bit retarded in comparison with BSCAlltimes :)

if(mysql_num_rows($wynik)>0)
{
//Is it already in the databese, but maybe we put it during call record parsing.
$wiersz=mysql_fetch_array($wynik);

if(strlen($wiersz['wav_file'])<1)
{
//Yup, we can update the data.
mysql_query("UPDATE $sql_table SET wav_file='".$data[0]."',number_type='".$data[4]."',caller='".$data[2]."' WHERE time>'".($data[1]-4)."' AND time<'".($data[1]+1)."';");
echo "At:".time()." updated call at [".$data[1]."] - Wav file:[".$data[0]."], Caller:[".$data[2]."],Number type:[".$data[4]."],\n";
}

}
else
{
//Call wasnt inserted during bscalltimes file parsing. Let's do this!
//Lets insert some data.
mysql_query("INSERT INTO $sql_table SET wav_file='".$data[0]."',number_type='".$data[4]."',caller='".$data[2]."',time='".$data[1]."',number='".$data[3]."';");
echo "At:".time()." inserted call at [".$data[1]."] - Wav file:[".$data[0]."], Caller:[".$data[2]."],Number type:[".$data[4]."],Number:[".$data[3]."]\n";

}

echo "File ".$pliczek." processed.\n";
}

}

}
closedir($directory);

print($log);

?>