From 0d51c7851651fee3588bc56c6679702d31fc9d58 Mon Sep 17 00:00:00 2001
From: Andreas <6977712+AndreasK79@users.noreply.github.com>
Date: Wed, 1 Feb 2023 13:57:50 +0100
Subject: [PATCH] [DXCC id] Improved DXCC identification
---
 application/controllers/Calltester.php | 491 +++++++++++++++++++++++++
 application/models/Logbook_model.php   |  78 +++-
 2 files changed, 553 insertions(+), 16 deletions(-)
 create mode 100644 application/controllers/Calltester.php
diff --git a/application/controllers/Calltester.php b/application/controllers/Calltester.php
new file mode 100644
index 00000000..b8c99114
--- /dev/null
+++ b/application/controllers/Calltester.php
@@ -0,0 +1,491 @@
+load->model('logbook_model');
+
+        $sql = 'select distinct col_country, col_call, col_dxcc, date(col_time_on) date from ' . $this->config->item('table_name');
+        $query = $this->db->query($sql);
+
+        $callarray = $query->result();
+
+        $result = array();
+        
+        $i = 0;
+
+        foreach ($callarray as $call) {
+            $i++;
+            $dxcc = $this->logbook_model->dxcc_lookup($call->col_call, $call->date);
+
+            $dxcc['adif'] = (isset($dxcc['adif'])) ? $dxcc['adif'] : 0;
+            $dxcc['entity'] = (isset($dxcc['entity'])) ? $dxcc['entity'] : 0;
+            
+            if ($call->col_dxcc != $dxcc['adif']) {
+                $result[] = array(
+                                'Callsign'          => $call->col_call, 
+                                'Expected country'  => $call->col_country, 
+                                'Expected adif'     => $call->col_dxcc, 
+                                'Result country'    => ucwords(strtolower($dxcc['entity']), "- (/"),
+                                'Result adif'       => $dxcc['adif'],
+                            );
+            }
+        }
+        
+        // End clock time in seconds
+        $end_time = microtime(true);
+
+        // Calculate script execution time
+        $execution_time = ($end_time - $start_time);
+        
+        echo " Execution time of script = ".$execution_time." sec 
";
+        echo $i . " calls tested. 
";
+        $count = 0;
+
+        if ($result) {
+            $this->array_to_table($result);
+        }
+        
+	}
+
+    
+    function array_to_table($table) {  
+        echo ' ';
+
+       echo '
';
+    
+       // Table header
+        foreach ($table[0] as $key=>$value) {
+            echo "| ".$key."";
+        }
+    
+        // Table body
+        foreach ($table as $value) {
+            echo " | ";
+            foreach ($value as $val) {
+                    echo "| ".$val."";
+            } 
+            echo " | 
";
+        } 
+       echo "
";
+    }
+
+    function csv() {
+        set_time_limit(3600);
+
+        // Starting clock time in seconds
+        $start_time = microtime(true);
+        
+		$this->load->model('logbook_model');
+
+        $file = 'uploads/calls.csv';
+        $handle = fopen($file,"r");
+    
+        $data = fgetcsv($handle,1000,","); // Skips firsts line, usually that is the header
+        $data = fgetcsv($handle,1000,",");
+    
+        $result = array();
+        
+        $i = 0;
+
+        do {
+            if ($data[0]) {
+                // COL_CALL,COL_DXCC,COL_TIME_ON
+                $i++;
+
+                $dxcc = $this->logbook_model->dxcc_lookup($data[0], $data[2]);
+
+                $dxcc['adif'] = (isset($dxcc['adif'])) ? $dxcc['adif'] : 0;
+                $dxcc['entity'] = (isset($dxcc['entity'])) ? $dxcc['entity'] : 0;
+
+                $data[1] = $data[1] == "NULL" ? 0 : $data[1];
+                
+                if ($data[1] != $dxcc['adif']) {
+                    $result[] = array(
+                                    'Callsign'          => $data[0], 
+                                    'Expected country'  => '', 
+                                    'Expected adif'     => $data[1], 
+                                    'Result country'    => ucwords(strtolower($dxcc['entity']), "- (/"),
+                                    'Result adif'       => $dxcc['adif'],
+                                );
+                }
+            }
+        } while ($data = fgetcsv($handle,1000,","));
+
+        // End clock time in seconds
+        $end_time = microtime(true);
+
+        // Calculate script execution time
+        $execution_time = ($end_time - $start_time);
+        
+        echo " Execution time of script = ".$execution_time." sec 
";
+        echo $i . " calls tested. 
";
+        $count = 0;
+
+        if ($result) {
+            $this->array_to_table($result);
+        }
+    }
+
+    /*
+     * Uses check_dxcc_table - written to check if that function works
+     */
+    function csv2() {
+        set_time_limit(3600);
+
+        // Starting clock time in seconds
+        $start_time = microtime(true);
+        
+		$this->load->model('logbook_model');
+
+        $file = 'uploads/calls.csv';
+        $handle = fopen($file,"r");
+    
+        $data = fgetcsv($handle,1000,","); // Skips firsts line, usually that is the header
+        $data = fgetcsv($handle,1000,",");
+    
+        $result = array();
+        
+        $i = 0;
+
+        do {
+            if ($data[0]) {
+                // COL_CALL,COL_DXCC,COL_TIME_ON
+                $i++;
+
+                $dxcc = $this->logbook_model->check_dxcc_table($data[0], $data[2]);
+
+                $data[1] = $data[1] == "NULL" ? 0 : $data[1];
+                
+                if ($data[1] != $dxcc[0]) {
+                    $result[] = array(
+                                    'Callsign'          => $data[0], 
+                                    'Expected country'  => '', 
+                                    'Expected adif'     => $data[1], 
+                                    'Result country'    => ucwords(strtolower($dxcc[1]), "- (/"),
+                                    'Result adif'       => $dxcc[0],
+                                );
+                }
+            }
+        } while ($data = fgetcsv($handle,1000,","));
+
+        // End clock time in seconds
+        $end_time = microtime(true);
+
+        // Calculate script execution time
+        $execution_time = ($end_time - $start_time);
+        
+        echo " Execution time of script = ".$execution_time." sec 
";
+        echo $i . " calls tested. 
";
+        $count = 0;
+
+        if ($result) {
+            $this->array_to_table($result);
+        }
+    }
+
+    function call() {
+        $testarray = array();
+
+        $testarray[] = array(
+            'Callsign'  => 'VE3EY/VP9',
+            'Country'   => 'Bermuda', 
+            'Adif'      => 64, 
+            'Date'      => $date = date('Ymd', time())
+        );
+
+        $testarray[] = array(
+            'Callsign'  => 'VP2MDG',
+            'Country'   => 'Montserrat', 
+            'Adif'      => 96, 
+            'Date'      => $date = date('Ymd', time())
+        );
+
+        $testarray[] = array(
+            'Callsign'  => 'VP2EY',
+            'Country'   => 'Anguilla', 
+            'Adif'      => 12, 
+            'Date'      => $date = date('Ymd', time())
+        );
+
+        $testarray[] = array(
+            'Callsign'  => 'VP2VI',
+            'Country'   => 'British Virgin Islands.', 
+            'Adif'      => 65, 
+            'Date'      => $date = date('Ymd', time())
+        );
+
+        $testarray[] = array(
+            'Callsign'  => 'VP2V/AA7V',
+            'Country'   => 'British Virgin Islands', 
+            'Adif'      => 65, 
+            'Date'      => $date = date('Ymd', time())
+        );
+
+        $testarray[] = array(
+            'Callsign'  => 'W8LR/R',
+            'Country'   => 'United States Of America', 
+            'Adif'      => 291, 
+            'Date'      => $date = date('Ymd', time())
+        );
+
+        $testarray[] = array(
+            'Callsign'  => 'SO1FH',
+            'Country'   => 'Poland', 
+            'Adif'      => 269, 
+            'Date'      => $date = date('Ymd', time())
+        );
+
+        $testarray[] = array(
+            'Callsign'  => 'KZ1H/PP',
+            'Country'   => 'Brazil', 
+            'Adif'      => 108, 
+            'Date'      => $date = date('Ymd', time())
+        );
+
+        $testarray[] = array(
+            'Callsign'  => 'K1KW/AM',
+            'Country'   => 'None', 
+            'Adif'      => 0, 
+            'Date'      => $date = date('Ymd', time())
+        );
+
+        $testarray[] = array(
+            'Callsign'  => 'K1KW/MM',
+            'Country'   => 'None', 
+            'Adif'      => 0, 
+            'Date'      => $date = date('Ymd', time())
+        );
+
+        $testarray[] = array(
+            'Callsign'  => 'TF/DL2NWK/P',
+            'Country'   => 'Iceland', 
+            'Adif'      => 242, 
+            'Date'      => $date = date('Ymd', time())
+        );
+
+        $testarray[] = array(
+            'Callsign'  => 'OZ1ALS/A',
+            'Country'   => 'Denmark', 
+            'Adif'      => 221, 
+            'Date'      => $date = date('Ymd', time())
+        );
+
+        $testarray[] = array(
+            'Callsign'  => 'LA1K',
+            'Country'   => 'Norway', 
+            'Adif'      => 266, 
+            'Date'      => $date = date('Ymd', time())
+        );
+
+        $testarray[] = array(
+            'Callsign'  => 'K1KW/M',
+            'Country'   => 'United States Of America', 
+            'Adif'      => 291, 
+            'Date'      => $date = date('Ymd', time())
+        );
+
+        $testarray[] = array(
+            'Callsign'  => 'TF/DL2NWK/M',
+            'Country'   => 'Iceland', 
+            'Adif'      => 242, 
+            'Date'      => $date = date('Ymd', time())
+        );
+
+        $testarray[] = array(
+            'Callsign'  => 'TF/DL2NWK/MM',
+            'Country'   => 'None', 
+            'Adif'      => 0, 
+            'Date'      => $date = date('Ymd', time())
+        );
+
+        $testarray[] = array(
+            'Callsign'  => 'TF/DL2NWK/P',
+            'Country'   => 'Iceland', 
+            'Adif'      => 242, 
+            'Date'      => $date = date('Ymd', time())
+        );
+
+        $testarray[] = array(
+            'Callsign'  => '2M0SQL/P',
+            'Country'   => 'Scotland', 
+            'Adif'      => 279, 
+            'Date'      => $date = date('Ymd', time())
+        );
+
+        $testarray[] = array(
+            'Callsign'  => 'FT8WW',
+            'Country'   => 'Crozet Island', 
+            'Adif'      => 41, 
+            'Date'      => $date = date('Ymd', time())
+        );
+
+        $testarray[] = array(
+            'Callsign'  => 'RV0AL/0/P',
+            'Country'   => 'Asiatic Russia', 
+            'Adif'      => 15, 
+            'Date'      => $date = date('Ymd', time())
+        );
+
+        $testarray[] = array(
+            'Callsign'  => 'OH/DJ1YFK',
+            'Country'   => 'Finland', 
+            'Adif'      => 224, 
+            'Date'      => $date = date('Ymd', time())
+        );
+
+        $testarray[] = array(
+            'Callsign'  => 'N6TR/7',
+            'Country'   => 'United States Of America', 
+            'Adif'      => 291, 
+            'Date'      => $date = date('Ymd', time())
+        );
+
+        $testarray[] = array(
+            'Callsign'  => 'KH0CW',
+            'Country'   => 'United States Of America', 
+            'Adif'      => 291, 
+            'Date'      => $date = date('Ymd', time())
+        );
+
+        $testarray[] = array(
+            'Callsign'  => 'R2FM/P',
+            'Country'   => 'kaliningrad', 
+            'Adif'      => 126, 
+            'Date'      => $date = date('Ymd', time())
+        );
+
+        $testarray[] = array(
+            'Callsign'  => 'R2FM',
+            'Country'   => 'kaliningrad', 
+            'Adif'      => 126, 
+            'Date'      => $date = date('Ymd', time())
+        );
+
+        $testarray[] = array(
+            'Callsign'  => 'FT5XO',
+            'Country'   => 'Kerguelen Island', 
+            'Adif'      => 131, 
+            'Date'      => 20050320
+        );
+
+        $testarray[] = array(
+            'Callsign'  => 'VP8CTR',
+            'Country'   => 'Antarctica', 
+            'Adif'      => 13, 
+            'Date'      => 19970207
+        );
+
+        $testarray[] = array(
+            'Callsign'  => 'FO0AAA',
+            'Country'   => 'Clipperton', 
+            'Adif'      => 36, 
+            'Date'      => '20000302'
+        );
+        
+        $testarray[] = array(
+            'Callsign'  => 'CX/PR8KW',
+            'Country'   => 'Uruguay', 
+            'Adif'      => 144, 
+            'Date'      => $date = date('Ymd', time())
+        );
+
+        $testarray[] = array(
+            'Callsign'  => 'IQ3MV/LH',
+            'Country'   => 'Italy', 
+            'Adif'      => 248, 
+            'Date'      => $date = date('Ymd', time())
+        );
+
+        $testarray[] = array(
+            'Callsign'  => 'LA1K/QRP',
+            'Country'   => 'Norway', 
+            'Adif'      => 266, 
+            'Date'      => $date = date('Ymd', time())
+        );
+
+        $testarray[] = array(
+            'Callsign'  => 'LA1K/LGT',
+            'Country'   => 'Norway', 
+            'Adif'      => 266, 
+            'Date'      => $date = date('Ymd', time())
+        );
+
+        $testarray[] = array(
+            'Callsign'  => 'SM1K/LH',
+            'Country'   => 'Sweden', 
+            'Adif'      => 284, 
+            'Date'      => $date = date('Ymd', time())
+        );
+
+        set_time_limit(3600);
+
+        // Starting clock time in seconds
+        $start_time = microtime(true);
+        
+		$this->load->model('logbook_model');
+
+        $result = array();
+        
+        $i = 0;
+
+        foreach ($testarray as $call) {
+            $i++;
+            $dxcc = $this->logbook_model->dxcc_lookup($call['Callsign'], $call['Date']);
+
+            $dxcc['adif'] = (isset($dxcc['adif'])) ? $dxcc['adif'] : 0;
+            $dxcc['entity'] = (isset($dxcc['entity'])) ? $dxcc['entity'] : 0;
+            
+            if ($call['Adif'] != $dxcc['adif']) {
+                $result[] = array(
+                                'Callsign'          => $call['Callsign'], 
+                                'Expected country'  => $call['Country'], 
+                                'Expected adif'     => $call['Adif'], 
+                                'Result country'    => ucwords(strtolower($dxcc['entity']), "- (/"),
+                                'Result adif'       => $dxcc['adif'],
+                            );
+            }
+        }
+        
+        // End clock time in seconds
+        $end_time = microtime(true);
+
+        // Calculate script execution time
+        $execution_time = ($end_time - $start_time);
+        
+        echo " Execution time of script = ".$execution_time." sec 
";
+        echo $i . " calls tested. 
";
+        $count = 0;
+
+        if ($result) {
+            $this->array_to_table($result);
+        }
+    }
+}
\ No newline at end of file
diff --git a/application/models/Logbook_model.php b/application/models/Logbook_model.php
index f6ae8ae8..258b8a12 100755
--- a/application/models/Logbook_model.php
+++ b/application/models/Logbook_model.php
@@ -2907,6 +2907,8 @@ class Logbook_model extends CI_Model {
      */
     public function check_dxcc_table($call, $date){
 
+    $csadditions = '/^P$|^R$|^A$|^M$/';
+
 		$dxcc_exceptions = $this->db->select('`entity`, `adif`, `cqz`')
              ->where('call', $call)
              ->where('(start <= ', $date)
@@ -2923,6 +2925,8 @@ class Logbook_model extends CI_Model {
       $call = "K";
     } elseif (preg_match('/(^OH\/)|(\/OH[1-9]?$)/', $call)) {   # non-Aland prefix!
       $call = "OH";                                             # make callsign OH = finland
+    } elseif (preg_match('/(^CX\/)|(\/CX[1-9]?$)/', $call)) {   # non-Antarctica prefix!
+      $call = "CX";                                             # make callsign CX = Uruguay
     } elseif (preg_match('/(^3D2R)|(^3D2.+\/R)/', $call)) {     # seems to be from Rotuma
       $call = "3D2/R";                                          # will match with Rotuma
     } elseif (preg_match('/^3D2C/', $call)) {                   # seems to be from Conway Reef
@@ -2934,6 +2938,23 @@ class Logbook_model extends CI_Model {
     } elseif (preg_match('/(^KG4)[A-Z09]{1}/', $call)) {
       $call = "K";
 		} elseif (preg_match('/\w\/\w/', $call)) {
+      if (preg_match_all('/^((\d|[A-Z])+\/)?((\d|[A-Z]){3,})(\/(\d|[A-Z])+)?(\/(\d|[A-Z])+)?$/', $call, $matches)) {
+        $prefix = $matches[1][0];
+        $callsign = $matches[3][0];
+        $suffix = $matches[5][0];
+      if ($prefix) {
+          $prefix = substr($prefix, 0, -1); # Remove the / at the end 
+      }
+      if ($suffix) {
+          $suffix = substr($suffix, 1); # Remove the / at the beginning
+      };
+      if (preg_match($csadditions, $suffix)) {
+        if ($prefix) {
+          $call = $prefix;  
+        } else {
+          $call = $callsign;
+        }
+      } else {
         $result = $this->wpx($call, 1);                       # use the wpx prefix instead
         if ($result == '') {
           $row['adif'] = 0;
@@ -2943,7 +2964,9 @@ class Logbook_model extends CI_Model {
         } else {
           $call = $result . "AA";
         }
+      }
     }
+  }
 
 		$len = strlen($call);
 
@@ -2968,19 +2991,21 @@ class Logbook_model extends CI_Model {
         }
 
         return array("Not Found", "Not Found");
-    }
+
+  }
 
     public function dxcc_lookup($call, $date){
 
+    $csadditions = '/^P$|^R$|^A$|^M$/';
+
 		$dxcc_exceptions = $this->db->select('`entity`, `adif`, `cqz`')
 				->where('call', $call)
-				->where('(start <= CURDATE()')
+				->where('(start <= ', $date)
 				->or_where('start is null)', NULL, false)
-				->where('(end >= CURDATE()')
+				->where('(end >= ', $date)
 				->or_where('end is null)', NULL, false)
 				->get('dxcc_exceptions');
 
-
 			if ($dxcc_exceptions->num_rows() > 0){
 				$row = $dxcc_exceptions->row_array();
 				return $row;
@@ -2990,6 +3015,8 @@ class Logbook_model extends CI_Model {
           $call = "K";
         } elseif (preg_match('/(^OH\/)|(\/OH[1-9]?$)/', $call)) {   # non-Aland prefix!
           $call = "OH";                                             # make callsign OH = finland
+        } elseif (preg_match('/(^CX\/)|(\/CX[1-9]?$)/', $call)) {   # non-Antarctica prefix!
+          $call = "CX";                                             # make callsign CX = Uruguay
         } elseif (preg_match('/(^3D2R)|(^3D2.+\/R)/', $call)) {     # seems to be from Rotuma
           $call = "3D2/R";                                          # will match with Rotuma
         } elseif (preg_match('/^3D2C/', $call)) {                   # seems to be from Conway Reef
@@ -3001,18 +3028,37 @@ class Logbook_model extends CI_Model {
         } elseif (preg_match('/(^KG4)[A-Z09]{1}/', $call)) {
           $call = "K";
         } elseif (preg_match('/\w\/\w/', $call)) {
-            $result = $this->wpx($call, 1);                       # use the wpx prefix instead
-            if ($result == '') {
-              $row['adif'] = 0;
-              $row['entity'] = 'None';
-              $row['cqz'] = 0;
-              $row['long'] = '0';
-              $row['lat'] = '0';
-              return $row;
-            } else {
-              $call = $result . "AA";
+          if (preg_match_all('/^((\d|[A-Z])+\/)?((\d|[A-Z]){3,})(\/(\d|[A-Z])+)?(\/(\d|[A-Z])+)?$/', $call, $matches)) {
+              $prefix = $matches[1][0];
+              $callsign = $matches[3][0];
+              $suffix = $matches[5][0];
+            if ($prefix) {
+                $prefix = substr($prefix, 0, -1); # Remove the / at the end 
             }
+            if ($suffix) {
+                $suffix = substr($suffix, 1); # Remove the / at the beginning
+            };
+            if (preg_match($csadditions, $suffix)) {
+              if ($prefix) {
+                $call = $prefix;  
+              } else {
+                $call = $callsign;
+              }
+            } else {
+              $result = $this->wpx($call, 1);                       # use the wpx prefix instead
+              if ($result == '') {
+                $row['adif'] = 0;
+                $row['entity'] = 'None';
+                $row['cqz'] = 0;
+                $row['long'] = '0';
+                $row['lat'] = '0';
+                return $row;
+              } else {
+                $call = $result . "AA";
+              }
+          }
     		}
+      }
 
 				$len = strlen($call);
 
@@ -3046,8 +3092,8 @@ class Logbook_model extends CI_Model {
       $b = '';
       $c = '';
   
-      $lidadditions = '/^QRP|^LGT/';
-      $csadditions = '/^P$|^R$|^A$|^M$/';
+      $lidadditions = '/^QRP$|^LGT$/';
+      $csadditions = '/^P$|^R$|^A$|^M$|^LH$/';
       $noneadditions = '/^MM$|^AM$/';
   
       # First check if the call is in the proper format, A/B/C where A and C