diff --git a/application/config/migration.php b/application/config/migration.php
index 372fbaf2..c4ac8962 100644
--- a/application/config/migration.php
+++ b/application/config/migration.php
@@ -21,7 +21,7 @@ $config['migration_enabled'] = TRUE;
| be upgraded / downgraded to.
|
*/
-$config['migration_version'] = 122;
+$config['migration_version'] = 123;
/*
|--------------------------------------------------------------------------
diff --git a/application/controllers/Logbook.php b/application/controllers/Logbook.php
index 548ecafd..66ae7b81 100644
--- a/application/controllers/Logbook.php
+++ b/application/controllers/Logbook.php
@@ -814,6 +814,42 @@ class Logbook extends CI_Controller {
}
+ function search_lotw_unconfirmed($station_id) {
+ $station_id = $this->security->xss_clean($station_id);
+
+ $this->load->model('user_model');
+
+ if(!$this->user_model->authorize($this->config->item('auth_mode'))) { return; }
+
+ $CI =& get_instance();
+ $CI->load->model('logbooks_model');
+ $logbooks_locations_array = $CI->logbooks_model->list_logbook_relationships($this->session->userdata('active_station_logbook'));
+
+ if (!$logbooks_locations_array) {
+ return null;
+ }
+
+ $location_list = "'".implode("','",$logbooks_locations_array)."'";
+
+ $sql = 'select COL_CALL, COL_MODE, COL_SUBMODE, station_callsign, COL_SAT_NAME, COL_BAND, COL_TIME_ON, lotw_users.lastupload from ' . $this->config->item('table_name') .
+ ' join station_profile on ' . $this->config->item('table_name') . '.station_id = station_profile.station_id
+ join lotw_users on ' . $this->config->item('table_name') . '.col_call = lotw_users.callsign
+ where ' . $this->config->item('table_name') .'.station_id in ('. $location_list . ')';
+
+ if ($station_id != 'All') {
+ $sql .= ' and station_profile.station_id = ' . $station_id;
+ }
+
+ $sql .= " and COL_LOTW_QSL_RCVD <> 'Y' and " . $this->config->item('table_name') . ".COL_TIME_ON < lotw_users.lastupload";
+
+ $query = $this->db->query($sql);
+
+ $data['qsos'] = $query;
+
+ $this->load->view('search/lotw_unconfirmed_result.php', $data);
+
+ }
+
function search_incorrect_cq_zones($station_id) {
$station_id = $this->security->xss_clean($station_id);
diff --git a/application/controllers/Logbookadvanced.php b/application/controllers/Logbookadvanced.php
index 6f054479..19daff37 100644
--- a/application/controllers/Logbookadvanced.php
+++ b/application/controllers/Logbookadvanced.php
@@ -49,11 +49,35 @@ class Logbookadvanced extends CI_Controller {
$pageData['sats'] = $this->bands->get_worked_sats();
$pageData['bands'] = $this->bands->get_worked_bands();
-
+
+ $CI =& get_instance();
+ // Get Date format
+ if($CI->session->userdata('user_date_format')) {
+ // If Logged in and session exists
+ $pageData['custom_date_format'] = $CI->session->userdata('user_date_format');
+ } else {
+ // Get Default date format from /config/cloudlog.php
+ $pageData['custom_date_format'] = $CI->config->item('qso_date_format');
+ }
+
+ switch ($pageData['custom_date_format']) {
+ case "d/m/y": $pageData['custom_date_format'] = 'DD/MM/YY'; break;
+ case "d/m/Y": $pageData['custom_date_format'] = 'DD/MM/YYYY'; break;
+ case "m/d/y": $pageData['custom_date_format'] = 'MM/DD/YY'; break;
+ case "m/d/Y": $pageData['custom_date_format'] = 'MM/DD/YYYY'; break;
+ case "d.m.Y": $pageData['custom_date_format'] = 'DD.MM.YYYY'; break;
+ case "y/m/d": $pageData['custom_date_format'] = 'YY/MM/DD'; break;
+ case "Y-m-d": $pageData['custom_date_format'] = 'YYYY-MM-DD'; break;
+ case "M d, Y": $pageData['custom_date_format'] = 'MMM DD, YYYY'; break;
+ case "M d, y": $pageData['custom_date_format'] = 'MMM DD, YY'; break;
+ default: $pageData['custom_date_format'] = 'DD/MM/YYYY';
+ }
+
$footerData = [];
$footerData['scripts'] = [
'assets/js/moment.min.js',
'assets/js/tempusdominus-bootstrap-4.min.js',
+ 'assets/js/datetime-moment.js',
'assets/js/sections/logbookadvanced.js?' . filemtime(realpath(__DIR__ . "/../../assets/js/sections/logbookadvanced.js"))
];
diff --git a/application/controllers/Search.php b/application/controllers/Search.php
index af43c511..f503d059 100644
--- a/application/controllers/Search.php
+++ b/application/controllers/Search.php
@@ -80,6 +80,18 @@ class Search extends CI_Controller {
$this->load->view('interface_assets/footer');
}
+ // Searches for unconfirmed Lotw QSOs where QSO partner has uploaded to LoTW after the QSO date
+ public function lotw_unconfirmed() {
+ $this->load->model('stations');
+
+ $data['station_profile'] = $this->stations->all_of_user();
+ $data['page_title'] = "QSOs unconfirmed on LoTW, but the callsign has uploaded to LoTW after QSO date";
+
+ $this->load->view('interface_assets/header', $data);
+ $this->load->view('search/lotw_unconfirmed');
+ $this->load->view('interface_assets/footer');
+ }
+
function json_result() {
if(isset($_POST['search'])) {
$result = $this->fetchQueryResult($_POST['search'], false);
diff --git a/application/controllers/Update.php b/application/controllers/Update.php
index 81c3f509..d6cd88c3 100644
--- a/application/controllers/Update.php
+++ b/application/controllers/Update.php
@@ -287,9 +287,6 @@ class Update extends CI_Controller {
}
public function download_lotw_users() {
-
-
-
$contents = file_get_contents('https://lotw.arrl.org/lotw-user-activity.csv', true);
if($contents === FALSE) {
@@ -306,6 +303,47 @@ class Update extends CI_Controller {
}
+ public function lotw_users() {
+ $mtime = microtime();
+ $mtime = explode(" ",$mtime);
+ $mtime = $mtime[1] + $mtime[0];
+ $starttime = $mtime;
+
+ $file = 'https://lotw.arrl.org/lotw-user-activity.csv';
+
+ $handle = fopen($file, "r");
+ if ($handle === FALSE) {
+ echo "Something went wrong with fetching the LoTW uses file";
+ return;
+ }
+ $this->db->empty_table("lotw_users");
+ $i = 0;
+ $data = fgetcsv($handle,1000,",");
+ do {
+ if ($data[0]) {
+ $lotwdata[$i]['callsign'] = $data[0];
+ $lotwdata[$i]['lastupload'] = $data[1] . ' ' . $data[2];
+ if (($i % 2000) == 0) {
+ $this->db->insert_batch('lotw_users', $lotwdata);
+ unset($lotwdata);
+ // echo 'Record ' . $i . '
';
+ }
+ $i++;
+ }
+ } while ($data = fgetcsv($handle,1000,","));
+ fclose($handle);
+
+ $this->db->insert_batch('lotw_users', $lotwdata);
+
+ $mtime = microtime();
+ $mtime = explode(" ",$mtime);
+ $mtime = $mtime[1] + $mtime[0];
+ $endtime = $mtime;
+ $totaltime = ($endtime - $starttime);
+ echo "This page was created in ".$totaltime." seconds
";
+ echo "Records inserted: " . $i . "
";
+ }
+
public function lotw_check() {
$f = fopen('./updates/lotw_users.csv', "r");
$result = false;
diff --git a/application/language/english/lotw_lang.php b/application/language/english/lotw_lang.php
index dd062ab7..26f942b0 100644
--- a/application/language/english/lotw_lang.php
+++ b/application/language/english/lotw_lang.php
@@ -57,3 +57,6 @@ $lang['lotw_confirmed'] = 'This QSO is confirmed on LoTW';
// LoTW Expiry
$lang['lotw_cert_expiring'] = 'At least one of your LoTW certificates is about to expire!';
$lang['lotw_cert_expired'] = 'At least one of your LoTW certificates is expired!';
+
+// Lotw User
+$lang['lotw_user'] = 'This station uses LoTW. The last upload was';
diff --git a/application/language/german/lotw_lang.php b/application/language/german/lotw_lang.php
index 2a2a7f58..2e01e3b0 100644
--- a/application/language/german/lotw_lang.php
+++ b/application/language/german/lotw_lang.php
@@ -57,3 +57,6 @@ $lang['lotw_confirmed'] = 'Dieses QSO wurde via LoTW bestätigt am';
// LoTW Expiry
$lang['lotw_cert_expiring'] = 'Mindestens eines deiner LoTW Zertifikate läuft bald ab!';
$lang['lotw_cert_expired'] = 'Mindestens eines deiner LoTW Zertifikate ist abgelaufen!';
+
+// Lotw User
+$lang['lotw_user'] = 'Diese Station nutzt LoTW. Der letzte Upload war am';
\ No newline at end of file
diff --git a/application/migrations/123_add_lotw_users.php b/application/migrations/123_add_lotw_users.php
new file mode 100644
index 00000000..9afa6a39
--- /dev/null
+++ b/application/migrations/123_add_lotw_users.php
@@ -0,0 +1,42 @@
+db->table_exists('lotw_users')) {
+ $this->dbforge->add_field(array(
+ 'id' => array(
+ 'type' => 'INT',
+ 'constraint' => 20,
+ 'unsigned' => TRUE,
+ 'auto_increment' => TRUE,
+ 'unique' => TRUE
+ ),
+ 'callsign' => array(
+ 'type' => 'VARCHAR',
+ 'constraint' => 32,
+ 'unsigned' => TRUE,
+ ),
+ 'lastupload' => array(
+ 'type' => 'datetime',
+ )
+ ));
+
+ $this->dbforge->add_key('id', TRUE);
+
+ $this->dbforge->create_table('lotw_users');
+
+ $this->db->query("ALTER TABLE lotw_users ADD INDEX `callsign` (`callsign`)");
+ }
+
+ }
+
+ public function down()
+ {
+ if ($this->db->table_exists('lotw_users')) {
+ $this->dbforge->drop_table('lotw_users');
+ }
+ }
+}
diff --git a/application/models/Eqsl_images.php b/application/models/Eqsl_images.php
index 31a89b37..dcd16092 100644
--- a/application/models/Eqsl_images.php
+++ b/application/models/Eqsl_images.php
@@ -27,7 +27,7 @@ class Eqsl_images extends CI_Model {
function eqsl_qso_list() {
$this->load->model('logbooks_model');
$logbooks_locations_array = $this->logbooks_model->list_logbook_relationships($this->session->userdata('active_station_logbook'));
- $this->db->select('qso_id, COL_CALL, COL_MODE, , COL_SUBMODE, COL_TIME_ON, COL_BAND, COL_SAT_NAME, image_file');
+ $this->db->select('COL_PRIMARY_KEY, qso_id, COL_CALL, COL_MODE, , COL_SUBMODE, COL_TIME_ON, COL_BAND, COL_SAT_NAME, image_file');
$this->db->join($this->config->item('table_name'), 'qso_id = COL_PRIMARY_KEY', 'left outer');
$this->db->join('station_profile', $this->config->item('table_name').'.station_id = station_profile.station_id', 'left outer');
$this->db->where_in('station_profile.station_id', $logbooks_locations_array);
diff --git a/application/models/Logbook_model.php b/application/models/Logbook_model.php
index bfed414a..bc794378 100755
--- a/application/models/Logbook_model.php
+++ b/application/models/Logbook_model.php
@@ -1295,13 +1295,13 @@ class Logbook_model extends CI_Model {
}
function get_qso($id) {
- $this->db->select($this->config->item('table_name').'.*, station_profile.*, dxcc_entities.*, dxcc_entities_2.name as station_country, dxcc_entities_2.end as station_end');
- $this->db->select($this->config->item('table_name').'.*, station_profile.*, dxcc_entities.*, coalesce(dxcc_entities_2.name, "- NONE -") as station_country, dxcc_entities_2.end as station_end, eQSL_images.image_file as eqsl_image_file');
+ $this->db->select($this->config->item('table_name').'.*, station_profile.*, dxcc_entities.*, coalesce(dxcc_entities_2.name, "- NONE -") as station_country, dxcc_entities_2.end as station_end, eQSL_images.image_file as eqsl_image_file, lotw_users.callsign as lotwuser, lotw_users.lastupload');
$this->db->from($this->config->item('table_name'));
$this->db->join('dxcc_entities', $this->config->item('table_name').'.col_dxcc = dxcc_entities.adif', 'left');
$this->db->join('station_profile', 'station_profile.station_id = '.$this->config->item('table_name').'.station_id', 'left');
$this->db->join('dxcc_entities as dxcc_entities_2', 'station_profile.station_dxcc = dxcc_entities_2.adif', 'left outer');
$this->db->join('eQSL_images', $this->config->item('table_name').'.COL_PRIMARY_KEY = eQSL_images.qso_id', 'left outer');
+ $this->db->join('lotw_users', $this->config->item('table_name').'.COL_CALL = lotw_users.callsign', 'left outer');
$this->db->where('COL_PRIMARY_KEY', $id);
return $this->db->get();
diff --git a/application/models/Logbookadvanced_model.php b/application/models/Logbookadvanced_model.php
index 437f4f7a..f0571352 100644
--- a/application/models/Logbookadvanced_model.php
+++ b/application/models/Logbookadvanced_model.php
@@ -100,6 +100,7 @@ class Logbookadvanced_model extends CI_Model {
FROM " . $this->config->item('table_name') . " qsos
INNER JOIN station_profile ON qsos.station_id=station_profile.station_id
LEFT OUTER JOIN dxcc_entities ON qsos.col_dxcc=dxcc_entities.adif
+ LEFT OUTER JOIN lotw_users ON qsos.col_call=lotw_users.callsign
WHERE station_profile.user_id = ?
$where
ORDER BY qsos.COL_TIME_ON desc, qsos.COL_PRIMARY_KEY desc
diff --git a/application/views/adif/import.php b/application/views/adif/import.php
index 779bd48d..c2c36fac 100644
--- a/application/views/adif/import.php
+++ b/application/views/adif/import.php
@@ -148,7 +148,7 @@
Export All Satellite QSOs Confirmed on LoTW
+Export All Satellite QSOs Confirmed on LoTW
diff --git a/application/views/eqslcard/index.php b/application/views/eqslcard/index.php index 979f4ee3..aaf7597e 100644 --- a/application/views/eqslcard/index.php +++ b/application/views/eqslcard/index.php @@ -34,7 +34,7 @@ foreach ($qslarray->result() as $qsl) { echo '| '.lang('gen_hamradio_callsign').' | +Date / time | +' . lang('gen_hamradio_mode') . ' | +' . lang('gen_hamradio_band') . ' | +Last LoTW upload | +' . lang('gen_hamradio_station') . ' | +
|---|---|---|---|---|---|
| '; + echo ' | ' . $qso->COL_TIME_ON . ' | '; + echo ''; echo $qso->COL_SUBMODE==null?$qso->COL_MODE:$qso->COL_SUBMODE; echo ' | '; + echo ''; if($qso->COL_SAT_NAME != null) { echo $qso->COL_SAT_NAME; } else { echo strtolower($qso->COL_BAND); }; echo ' | '; + echo '' . $qso->lastupload . ' | '; + echo '' . $qso->station_callsign . ' | '; + echo '
lastupload); echo date($custom_date_format, $timestamp); $timestamp = strtotime($row->lastupload); echo " at ".date('H:i', $timestamp);?> UTC.
+ COL_LOTW_QSL_RCVD == "Y") { ?> diff --git a/assets/js/sections/logbookadvanced.js b/assets/js/sections/logbookadvanced.js index 910148ee..58cb8482 100644 --- a/assets/js/sections/logbookadvanced.js +++ b/assets/js/sections/logbookadvanced.js @@ -26,7 +26,7 @@ function updateRow(qso) { let c = 1; cells.eq(c++).text(qso.qsoDateTime); cells.eq(c++).text(qso.de); - cells.eq(c++).html(''+qso.dx+''); + cells.eq(c++).html(''+qso.dx+'' + (qso.callsign == '' ? '' : ' L')); cells.eq(c++).text(qso.mode); cells.eq(c++).text(qso.rstS); cells.eq(c++).text(qso.rstR); @@ -58,6 +58,7 @@ function loadQSOTable(rows) { }); uninitialized.each(function() { + $.fn.dataTable.moment(custom_date_format + ' HH:mm'); $(this).DataTable({ searching: false, responsive: false, @@ -66,7 +67,6 @@ function loadQSOTable(rows) { "scrollCollapse": true, "paging": false, "scrollX": true, - "order": [ 1, 'desc' ], }); }); @@ -81,7 +81,7 @@ function loadQSOTable(rows) { data.push(''); data.push(qso.qsoDateTime); data.push(qso.de); - data.push(''+qso.dx+''); + data.push(''+qso.dx+'' + (qso.callsign == '' ? '' : ' L')); data.push(qso.mode); data.push(qso.rstS); data.push(qso.rstR); diff --git a/src/QSLManager/QSO.php b/src/QSLManager/QSO.php index 64b87501..a64bd402 100644 --- a/src/QSLManager/QSO.php +++ b/src/QSLManager/QSO.php @@ -10,7 +10,7 @@ use DomainException; class QSO { private string $qsoID; - private DateTime $qsoDateTime; + private string $qsoDateTime; private string $de; private string $dx; private string $mode; @@ -59,6 +59,9 @@ class QSO private string $qsl; private string $lotw; private string $eqsl; + /** Lotw callsign info **/ + private string $callsign; + private string $lastupload; /** * @param array $data Does no validation, it's assumed to be a row from the database in array format @@ -120,7 +123,16 @@ class QSO $this->qsoID = $data['COL_PRIMARY_KEY']; - $this->qsoDateTime = DateTime::createFromFormat("Y-m-d H:i:s", $data['COL_TIME_ON'], new DateTimeZone("UTC")); + $CI =& get_instance(); + // Get Date format + if($CI->session->userdata('user_date_format')) { + // If Logged in and session exists + $custom_date_format = $CI->session->userdata('user_date_format'); + } else { + // Get Default date format from /config/cloudlog.php + $custom_date_format = $CI->config->item('qso_date_format'); + } + $this->qsoDateTime = date($custom_date_format . " H:i", strtotime($data['COL_TIME_ON'])); $this->de = $data['COL_STATION_CALLSIGN']; $this->dx = $data['COL_CALL']; @@ -167,16 +179,6 @@ class QSO $this->QSLSent = ($data['COL_QSL_SENT'] === null) ? '' : $data['COL_QSL_SENT']; $this->QSLSentVia = ($data['COL_QSL_SENT_VIA'] === null) ? '' : $data['COL_QSL_SENT_VIA']; $this->QSLVia = ($data['COL_QSL_VIA'] === null) ? '' : $data['COL_QSL_VIA']; - - $CI =& get_instance(); - // Get Date format - if($CI->session->userdata('user_date_format')) { - // If Logged in and session exists - $custom_date_format = $CI->session->userdata('user_date_format'); - } else { - // Get Default date format from /config/cloudlog.php - $custom_date_format = $CI->config->item('qso_date_format'); - } $this->qsl = $this->getQslString($data, $custom_date_format); $this->lotw = $this->getLotwString($data, $custom_date_format); @@ -184,13 +186,16 @@ class QSO $this->cqzone = ($data['COL_CQZ'] === null) ? '' : $data['COL_CQZ']; $this->state = ($data['COL_STATE'] === null) ? '' :$data['COL_STATE']; - $this->dxcc = ($data['name'] === null) ? '- NONE -' :$data['name']; + $this->dxcc = ($data['name'] === null) ? '- NONE -' : ucwords(strtolower($data['name']), "- (/"); $this->iota = ($data['COL_IOTA'] === null) ? '' :$data['COL_IOTA']; if (array_key_exists('end', $data)) { $this->end = ($data['end'] === null) ? null : DateTime::createFromFormat("Y-m-d", $data['end'], new DateTimeZone('UTC')); } else { $this->end = null; } + $this->callsign = ($data['callsign'] === null) ? '' :$data['callsign']; + $this->lastupload = ($data['lastupload'] === null) ? '' : date($custom_date_format . " H:i", strtotime($data['lastupload'])); + } /** @@ -408,7 +413,7 @@ class QSO /** * @return DateTime */ - public function getQsoDateTime(): DateTime + public function getQsoDateTime(): string { return $this->qsoDateTime; } @@ -749,7 +754,7 @@ class QSO { return [ 'qsoID' => $this->qsoID, - 'qsoDateTime' => $this->qsoDateTime->format("Y-m-d H:i"), + 'qsoDateTime' => $this->qsoDateTime, 'de' => $this->de, 'dx' => $this->dx, 'mode' => $this->getFormattedMode(), @@ -769,6 +774,8 @@ class QSO 'cqzone' => $this->getCqzone(), 'iota' => $this->getIOTA(), 'end' => $this->end === null ? null : $this->end->format("Y-m-d"), + 'callsign' => $this->callsign, + 'lastupload' => $this->lastupload, ]; }