mirror of
https://github.com/wavelog/wavelog.git
synced 2026-03-22 10:24:14 +00:00
Merge pull request #2584 from DB4SCW/cbrimport
Refine CBR import and make it more obvious it exists
This commit is contained in:
@@ -188,19 +188,25 @@ class Cabrillo extends CI_Controller {
|
||||
//get flag about the presence of the serial number
|
||||
$serial_number_present = ($this->input->post('serial_number_present', true) == 1);
|
||||
|
||||
//get flag about the presence of the trx number
|
||||
$trx_number_present = ($this->input->post('trx_number_present', true) == 1);
|
||||
|
||||
//parse the uploaded file
|
||||
$parsed_cbr = $this->cbr_parser->parse_from_file('./uploads/'.$data['upload_data']['file_name'], $serial_number_present);
|
||||
$parsed_cbr = $this->cbr_parser->parse_from_file('./uploads/'.$data['upload_data']['file_name'], $serial_number_present, $trx_number_present);
|
||||
|
||||
//return with error, reset upload filesize
|
||||
if(count($parsed_cbr["QSOS"]) < 1)
|
||||
//if parsing fails, return with error, reset upload filesize
|
||||
if(isset($parsed_cbr['error']))
|
||||
{
|
||||
$data['error'] = __("Broken CBR file - no QSO data or incomplete header found.");
|
||||
//get error message from parser
|
||||
$data['error'] = $parsed_cbr['error'];
|
||||
|
||||
//reset upload filesize
|
||||
$data['max_upload'] = ini_get('upload_max_filesize');
|
||||
|
||||
//delete uploaded file
|
||||
unlink('./uploads/' . $data['upload_data']['file_name']);
|
||||
|
||||
//return view
|
||||
$this->load->view('interface_assets/header', $data);
|
||||
$this->load->view('adif/import', $data);
|
||||
$this->load->view('interface_assets/footer');
|
||||
@@ -263,23 +269,25 @@ class Cabrillo extends CI_Controller {
|
||||
$stxstring = null;
|
||||
$srxstring = null;
|
||||
|
||||
//process all sent exchanges
|
||||
//process all sent exchanges, handle those that are shorter than maximum gracefully
|
||||
for ($i=1; $i <= $sent_exchange_count; $i++) {
|
||||
if($stxstring == null)
|
||||
{
|
||||
$stxstring = $qso["SENT_EXCH_" . $i];
|
||||
}else{
|
||||
$stxstring = $stxstring . ' ' . $qso["SENT_EXCH_" . $i];
|
||||
if(isset($qso["SENT_EXCH_" . $i])){
|
||||
if($stxstring == null){
|
||||
$stxstring = $qso["SENT_EXCH_" . $i];
|
||||
}else{
|
||||
$stxstring = $stxstring . ' ' . $qso["SENT_EXCH_" . $i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//process all sent exchanges
|
||||
//process all sent exchanges, handle those that are shorter than maximum gracefully
|
||||
for ($i=1; $i <= $rcvd_exchange_count; $i++) {
|
||||
if($srxstring == null)
|
||||
{
|
||||
$srxstring = $qso["RCVD_EXCH_" . $i];
|
||||
}else{
|
||||
$srxstring = $srxstring . ' ' . $qso["RCVD_EXCH_" . $i];
|
||||
if(isset($qso["RCVD_EXCH_" . $i])){
|
||||
if($srxstring == null){
|
||||
$srxstring = $qso["RCVD_EXCH_" . $i];
|
||||
}else{
|
||||
$srxstring = $srxstring . ' ' . $qso["RCVD_EXCH_" . $i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<?php
|
||||
class CBR_Parser
|
||||
{
|
||||
public function parse_from_file($filename, $serial_number_present = false) : array
|
||||
public function parse_from_file($filename, $serial_number_present = false, $trx_number_present = false) : array
|
||||
{
|
||||
//load file, call parser
|
||||
return $this->parse(mb_convert_encoding(file_get_contents($filename), "UTF-8"), $serial_number_present);
|
||||
return $this->parse(mb_convert_encoding(file_get_contents($filename), "UTF-8"), $serial_number_present, $trx_number_present);
|
||||
}
|
||||
|
||||
public function parse(string $input, $serial_number_present = false) : array
|
||||
public function parse(string $input, $serial_number_present = false, $trx_number_present = false) : array
|
||||
{
|
||||
//split the input into lines
|
||||
$lines = explode("\n", trim($input));
|
||||
@@ -35,6 +35,11 @@ class CBR_Parser
|
||||
$qso_mode = false;
|
||||
}
|
||||
|
||||
//if we encounter a QTC, skip that line
|
||||
if(strpos($line, 'QTC:') === 0){
|
||||
continue;
|
||||
}
|
||||
|
||||
//if we encounter "END-OF-LOG", stop processing lines
|
||||
if (strpos($line, 'END-OF-LOG') === 0) {
|
||||
break;
|
||||
@@ -59,13 +64,38 @@ class CBR_Parser
|
||||
//split the line into the elements
|
||||
$qso_elements = preg_split('/\s+/', trim($line));
|
||||
|
||||
//check occurances of signal rapport values
|
||||
$counts = array_count_values($qso_elements);
|
||||
$count59s = ($counts["59"] ?? 0) + ($counts["599"] ?? 0);
|
||||
|
||||
//for those few contests who do not have signal exchange, synthesize one based on best efforts
|
||||
if($count59s < 2 and isset($header['CALLSIGN'])){
|
||||
|
||||
//get own callsign from header
|
||||
$own_callsign = $header['CALLSIGN'];
|
||||
|
||||
//get position of own callsign
|
||||
$index = array_search($own_callsign, $qso_elements);
|
||||
|
||||
//add synthesized sent signal rapport after own callsign
|
||||
if ($index !== false) {
|
||||
array_splice($qso_elements, $index + 1, 0, "59");
|
||||
}
|
||||
|
||||
//search for the next amateur radio callsign after my own and add another 59. Abort after first find
|
||||
for ($i = $index + 1; $i < count($qso_elements); $i++) {
|
||||
$value = $qso_elements[$i];
|
||||
if(preg_match('/(?=[A-Z0-9]*[A-Z])[A-Z0-9]{1,3}[0-9][A-Z0-9]{0,7}/', $value) === 1){
|
||||
array_splice($qso_elements, $i + 1, 0, "59");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//determine maximum qso field size
|
||||
$max_qso_fields = max($max_qso_fields, count($qso_elements));
|
||||
$max_qso_fields = max($max_qso_fields ?? 0, count($qso_elements));
|
||||
|
||||
//add qso elements to qso line array
|
||||
array_push($qso_lines_raw, $qso_elements);
|
||||
|
||||
//find all occurrences of "59"
|
||||
//find all occurrences of "59" or "599"
|
||||
$indices_of_59 = [];
|
||||
foreach ($qso_elements as $index => $value) {
|
||||
if ($value === "59" or $value === "599") {
|
||||
@@ -73,6 +103,15 @@ class CBR_Parser
|
||||
}
|
||||
}
|
||||
|
||||
//abort further processing if we find a line without a valid signal report (59 or 599)
|
||||
if(count($indices_of_59) < 1) {
|
||||
|
||||
//return error result
|
||||
$result = [];
|
||||
$result['error'] = __("Broken CBR file - no valid exchange or callsigns found");
|
||||
return $result;
|
||||
}
|
||||
|
||||
//find common indices position
|
||||
if ($common_59_indices === null) {
|
||||
//initialize common indices on the first iteration
|
||||
@@ -82,6 +121,9 @@ class CBR_Parser
|
||||
$common_59_indices = array_intersect($common_59_indices, $indices_of_59);
|
||||
}
|
||||
|
||||
//add qso elements to qso line array
|
||||
array_push($qso_lines_raw, $qso_elements);
|
||||
|
||||
//skip to next line
|
||||
continue;
|
||||
}
|
||||
@@ -89,30 +131,20 @@ class CBR_Parser
|
||||
|
||||
//abort further processing if no qso lines were found, return header only
|
||||
if(count($qso_lines_raw) < 1) {
|
||||
$result = [];
|
||||
$result["HEADER"] = $header;
|
||||
$result["QSOS"] = [];
|
||||
$result["SENT_59_POS"] = 0;
|
||||
$result["RCVD_59_POS"] = 0;
|
||||
$result["SENT_EXCHANGE_COUNT"] = 0;
|
||||
$result["RCVD_EXCHANGE_COUNT"] = 0;
|
||||
|
||||
//return result
|
||||
//return error result
|
||||
$result = [];
|
||||
$result['error'] = __("Broken CBR file - no QSO data found.");
|
||||
return $result;
|
||||
}
|
||||
|
||||
//abort if basic things (Callsign and Contest ID) are not included in the header
|
||||
$header_fields = array_keys($header);
|
||||
if(!in_array('CALLSIGN', $header_fields) or !in_array('CONTEST', $header_fields)){
|
||||
|
||||
//return error result
|
||||
$result = [];
|
||||
$result["HEADER"] = $header;
|
||||
$result["QSOS"] = [];
|
||||
$result["SENT_59_POS"] = 0;
|
||||
$result["RCVD_59_POS"] = 0;
|
||||
$result["SENT_EXCHANGE_COUNT"] = 0;
|
||||
$result["RCVD_EXCHANGE_COUNT"] = 0;
|
||||
|
||||
//return blank result
|
||||
$result['error'] = __("Broken CBR file - incomplete header found.");
|
||||
return $result;
|
||||
}
|
||||
|
||||
@@ -120,6 +152,15 @@ class CBR_Parser
|
||||
$sent_59_pos = min($common_59_indices);
|
||||
$rcvd_59_pos = max($common_59_indices);
|
||||
|
||||
//abort if position of sent and received signal exchange is identical
|
||||
if($sent_59_pos == $rcvd_59_pos){
|
||||
|
||||
//return error result
|
||||
$result = [];
|
||||
$result['error'] = __("Broken CBR file - no valid exchange or callsigns found");
|
||||
return $result;
|
||||
}
|
||||
|
||||
//get codeigniter instance
|
||||
$CI = &get_instance();
|
||||
|
||||
@@ -171,7 +212,7 @@ class CBR_Parser
|
||||
//get all remaining received exchanges
|
||||
$exchange_nr = 1;
|
||||
$startindex = ($rcvd_59_pos + ($serial_number_present ? 2 : 1));
|
||||
$endindex = (count($line));
|
||||
$endindex = count($line) - ($trx_number_present ? 1 : 0);
|
||||
for ($i = $startindex; $i < $endindex; $i++) {
|
||||
$qso_line["RCVD_EXCH_" . $exchange_nr] = $line[$i];
|
||||
$exchange_nr++;
|
||||
@@ -200,12 +241,15 @@ class CBR_Parser
|
||||
case '144':
|
||||
$band = '2m';
|
||||
break;
|
||||
case '220':
|
||||
case '222':
|
||||
$band = '1.25m';
|
||||
break;
|
||||
case '430':
|
||||
case '432':
|
||||
$band = '70cm';
|
||||
break;
|
||||
case '900':
|
||||
case '902':
|
||||
$band = '33cm';
|
||||
break;
|
||||
@@ -292,7 +336,7 @@ class CBR_Parser
|
||||
$result["SENT_59_POS"] = $sent_59_pos;
|
||||
$result["RCVD_59_POS"] = $rcvd_59_pos;
|
||||
$result["SENT_EXCHANGE_COUNT"] = $rcvd_59_pos - $sent_59_pos - ($serial_number_present ? 3 : 2);
|
||||
$result["RCVD_EXCHANGE_COUNT"] = $max_qso_fields - 1 - $rcvd_59_pos - ($serial_number_present ? 1 : 0);
|
||||
$result["RCVD_EXCHANGE_COUNT"] = $max_qso_fields - 1 - $rcvd_59_pos - ($serial_number_present ? 1 : 0) - ($trx_number_present ? 1 : 0);
|
||||
|
||||
//return result
|
||||
return $result;
|
||||
|
||||
@@ -410,6 +410,10 @@
|
||||
echo '<option value="' . $contest['adifname'] . '">' . $contest['name'] . '</option>';
|
||||
} ?>
|
||||
</select>
|
||||
<div class="form-check-inline">
|
||||
<input class="form-check-input" type="checkbox" name="trx_number_present" value="1" id="serial_number_present" unchecked>
|
||||
<label class="form-check-label" for="trx_number_present"><?= __("The CBR file contains a TRX number at the end of each QSO line (for multi-op stations)") ?></label>
|
||||
</div>
|
||||
<div class="form-check-inline">
|
||||
<input class="form-check-input" type="checkbox" name="serial_number_present" value="1" id="serial_number_present" unchecked>
|
||||
<label class="form-check-label" for="serial_number_present"><?= __("A serial number is ALWAYS part of the exchange for both parties in this contest.") ?></label>
|
||||
|
||||
Reference in New Issue
Block a user