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/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/migrations/123_add_lotw_users.php b/application/migrations/123_add_lotw_users.php new file mode 100644 index 00000000..84709a76 --- /dev/null +++ b/application/migrations/123_add_lotw_users.php @@ -0,0 +1,41 @@ +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' => 'timestamp', + 'unsigned' => TRUE, + ) + )); + + $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() + { + $this->dbforge->drop_table('lotw_users'); + } +} 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/interface_assets/footer.php b/application/views/interface_assets/footer.php index 4430a9c0..4e7741e2 100644 --- a/application/views/interface_assets/footer.php +++ b/application/views/interface_assets/footer.php @@ -816,6 +816,29 @@ function findduplicates(){ }); } +function findlotwunconfirmed(){ + event.preventDefault(); + $('#partial_view').load(base_url+"index.php/logbook/search_lotw_unconfirmed/"+$("#station_id").val(), function() { + $('.qsolist').DataTable({ + "pageLength": 25, + responsive: false, + ordering: false, + "scrollY": "500px", + "scrollCollapse": true, + "paging": false, + "scrollX": true, + dom: 'Bfrtip', + buttons: [ + 'csv' + ] + }); + // change color of csv-button if dark mode is chosen + if (isDarkModeTheme()) { + $(".buttons-csv").css("color", "white"); + } + }); +} + function findincorrectcqzones() { event.preventDefault(); $('#partial_view').load(base_url+"index.php/logbook/search_incorrect_cq_zones/"+$("#station_id").val(), function() { diff --git a/application/views/search/cqzones.php b/application/views/search/cqzones.php index 309d074a..ca90566a 100644 --- a/application/views/search/cqzones.php +++ b/application/views/search/cqzones.php @@ -17,9 +17,11 @@ - + diff --git a/application/views/search/duplicates.php b/application/views/search/duplicates.php index b5580ab0..714d61da 100644 --- a/application/views/search/duplicates.php +++ b/application/views/search/duplicates.php @@ -17,9 +17,11 @@ - + diff --git a/application/views/search/filter.php b/application/views/search/filter.php index cd963d06..e1a69fe2 100644 --- a/application/views/search/filter.php +++ b/application/views/search/filter.php @@ -25,9 +25,11 @@ - + diff --git a/application/views/search/lotw_unconfirmed.php b/application/views/search/lotw_unconfirmed.php new file mode 100644 index 00000000..dbeea970 --- /dev/null +++ b/application/views/search/lotw_unconfirmed.php @@ -0,0 +1,50 @@ + diff --git a/application/views/search/lotw_unconfirmed_result.php b/application/views/search/lotw_unconfirmed_result.php new file mode 100644 index 00000000..ee28cd3d --- /dev/null +++ b/application/views/search/lotw_unconfirmed_result.php @@ -0,0 +1,43 @@ +result() != NULL) { + echo ' + + + + + + + + + + '; + + // Get Date format + if($this->session->userdata('user_date_format')) { + // If Logged in and session exists + $custom_date_format = $this->session->userdata('user_date_format'); + } else { + // Get Default date format from /config/cloudlog.php + $custom_date_format = $this->config->item('qso_date_format'); + } + + $i = 0; + foreach ($qsos->result() as $qso) { + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + echo ''; + } + + echo '
'.lang('gen_hamradio_callsign').'Date / time' . lang('gen_hamradio_mode') . '' . lang('gen_hamradio_band') . 'Last LoTW upload' . lang('gen_hamradio_station') . '
' . $qso->COL_CALL . '
' . $qso->COL_TIME_ON . ''; echo $qso->COL_SUBMODE==null?$qso->COL_MODE:$qso->COL_SUBMODE; echo ''; if($qso->COL_SAT_NAME != null) { echo $qso->COL_SAT_NAME; } else { echo strtolower($qso->COL_BAND); }; echo '' . $qso->lastupload . '' . $qso->station_callsign . '
'; + ?> + + ×No duplicate QSO\'s were found.'; +} +?> \ No newline at end of file diff --git a/application/views/search/main.php b/application/views/search/main.php index fac5395c..47e2161d 100644 --- a/application/views/search/main.php +++ b/application/views/search/main.php @@ -19,6 +19,9 @@ + diff --git a/assets/js/sections/logbookadvanced.js b/assets/js/sections/logbookadvanced.js index 910148ee..4040c594 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); @@ -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..7edf070b 100644 --- a/src/QSLManager/QSO.php +++ b/src/QSLManager/QSO.php @@ -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 @@ -191,6 +194,8 @@ class QSO } else { $this->end = null; } + $this->callsign = ($data['callsign'] === null) ? '' :$data['callsign']; + $this->lastupload = ($data['lastupload'] === null) ? '' :$data['lastupload']; } /** @@ -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, ]; }