Une nouvelle version de la bibliothèque, compatible ADIF v3, est disponible (http://xv4y NULL.radioclub NULL.asia/2015/03/10/bibliotheque-php-de-traitement-de-fichiers-logs-adif-v3/).
Comme promis, je mets à disposition de la communauté ma version de la librairie de traitement (parser) de fichiers logs ADIF v2 (http://adif NULL.org/). Elle accepte les fichiers issus des logiciels les plus courants actuellement (N1MM, DXKeeper, HAM Radio Deluxe, WinLog…) et en extrait les différents champs.
Aucune vérification n’est faite sur la cohérence des informations et celle-ci dépend donc du logiciel de cahier de trafic qui a généré ces fichiers. Contrairement au parser ADIF de KJ4IWX depuis lequel j’étais parti au début, cette librairie n’a aucune limite de taille et elle peut tout à fait traiter des logs de plusieurs centaines de milliers de lignes. Tout dépend du traitement que vous faites ensuite, mais sur une machine aux performances actuelles, on peut facilement espérer insérer 2000 QSOs par minute dans une base de données. Sur QScope (http://www NULL.qscope NULL.org/) où la qualité d’origine des logs importés est très aléatoire de nombreuses vérifications sont nécessaires et la vitesse chute à environ 500 QSOs par minute.
<?php
/*
=== ADIF v2 Parser library v1.00 (2013-10-11) ===
This Library his based on work by Jason Harris KJ4IWX but has been simplified and improvedfor better ADIF compatiblity by Yannick DEVOS XV4Y
Copyright 2011-2013 Jason Harris KJ4IWX (Apache v2.00 License)
Copyright 2013 Yannick DEVOS XV4Y (GNU GPL v3.00 License)
Any commercial use is subject to authorization from the respective authors
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
---
This PHP library is designed to work with the Jelix 1.5 PHP Framework and PHP 5.4.
However, it can simply be called by any PHP program.
Usage (with Jelix):
$ADIFParser = jClasses::createInstance('yourmodule~ADIFParser');
$file_handler = fopen($complete_path_to_the_file,'r');
$ADIFParser->initialize($file_handler);
while(($record = $ADIFParser->get_record($file_handler))!=-1) { // Check for end of file
if ($record!=false) { // If line is empty we skip
if(count($record) == 0) {
break;
};
echo ($record['call']);
echo ($record['qso_date']);
echo ($record['mode']);
// Do whatever you like with the ADIF fields...
};
};
fclose($file_handler);
Fore more infos find contacts at:
http://xv4y.radioclub.asia/
http://www.qscope.org/
*/
class ADIFParser
{
var $data; //the adif data
var $i; //the iterator
var $headers = array();
public function initialize($fhandler) //this function locates the <EOH>
{
$eoh=$eof=false;
$this->data='';
while (!$eoh && !$eof) {
$newdata = fgets($fhandler);
if (!$newdata) {
$eof = true;
} else {
if (stripos($newdata, "<eoh>")===false) {
$this->data .= $newdata;
} else {
$eoh = true;
}
};
}
if($eoh == false) //did we find the end of headers?
{
return 0;
};
//get headers
$this->i = 0;
$in_tag = false;
$tag = "";
$value_length = "";
$value = "";
$pos = strlen($this->data)-1;
while($this->i < $pos)
{
//skip comments
if($this->data[$this->i] == "#")
{
while($this->i < $pos)
{
if($this->data[$this->i] == "\n")
{
break;
}
$this->i++;
}
}else{
//find the beginning of a tag
if($this->data[$this->i] == "<")
{
$this->i++;
//record the key
while($this->data[$this->i] < $pos && $this->data[$this->i] != ':')
{
$tag = $tag.$this->data[$this->i];
$this->i++;
}
$this->i++; //iterate past the :
//find out how long the value is
while($this->data[$this->i] < $pos && $this->data[$this->i] != '>')
{
$value_length = $value_length.$this->data[$this->i];
$this->i++;
}
$this->i++; //iterate past the >
$len = (int)$value_length;
//copy the value into the buffer
while($len > 0 && $this->i < $pos)
{
$value = $value.$this->data[$this->i];
$len--;
$this->i++;
};
$this->headers[strtolower(trim($tag))] = $value; //convert it to lowercase and trim it in case of \r
//clear all of our variables
$tag = "";
$value_length = "";
$value = "";
}
}
$this->i++;
};
return 1;
}
//the following function does the processing of the array into its key and value pairs
public function record_to_array(&$record)
{
$return = array();
for($a = 0; $a < strlen($record); $a++)
{
if($record[$a] == '<') //find the start of the tag
{
$tag_name = "";
$value = "";
$len_str = "";
$len = 0;
$a++; //go past the <
while($record[$a] != ':') //get the tag
{
$tag_name = $tag_name.$record[$a]; //append this char to the tag name
$a++;
};
$a++; //iterate past the colon
while($record[$a] != '>' && $record[$a] != ':')
{
$len_str = $len_str.$record[$a];
$a++;
};
if($record[$a] == ':')
{
while($record[$a] != '>')
{
$a++;
};
};
$len = (int)$len_str;
while($len > 0)
{
$a++;
$value = $value.$record[$a];
$len--;
};
$return[strtolower($tag_name)] = $value;
};
//skip comments
if($record[$a] == "#")
{
while($a < strlen($record))
{
if($record[$a] == "\n")
{
break;
}
$a++;
}
}
};
return $return;
}
//finds the next record in the file
public function get_record($fhandle)
{
$record ='';
$out_condition = false;
while (!$out_condition) {
$newdata = fgets($fhandle);
if ($newdata===false) {
$out_condition = true;
return -1; // This is the end of file
} else {
$end = stripos($newdata , "<eor>");
if($end !== false) { //we got a full line
$record .= substr($newdata, 0, $end);
$out_condition = true;
return $this->record_to_array($record); //process and return output
} else {
$record .= $newdata; // The line is not complete and we need to fetch a new string
}
}
}
}
public function get_header($key)
{
if(array_key_exists(strtolower($key), $this->headers))
{
return $this->headers[strtolower($key)];
}else{
return NULL;
}
}
}
?>