diff --git a/application/config/migration.php b/application/config/migration.php index b5509fd4..67ea7c6a 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'] = 126; +$config['migration_version'] = 127; /* |-------------------------------------------------------------------------- diff --git a/application/controllers/Adif.php b/application/controllers/Adif.php index 5ebe2826..605330c6 100644 --- a/application/controllers/Adif.php +++ b/application/controllers/Adif.php @@ -206,7 +206,7 @@ class adif extends CI_Controller { $custom_errors .= $this->logbook_model->import($record, $this->input->post('station_profile'), - $this->input->post('skipDuplicate'), $this->input->post('markLotw'), $this->input->post('dxccAdif'), $this->input->post('markQrz'), true, $this->input->post('operatorName')); + $this->input->post('skipDuplicate'), $this->input->post('markLotw'), $this->input->post('dxccAdif'), $this->input->post('markQrz'), $his->input->post('markHrd'), true, $this->input->post('operatorName')); }; diff --git a/application/controllers/Api.php b/application/controllers/Api.php index bd23c6ee..fc2211f8 100644 --- a/application/controllers/Api.php +++ b/application/controllers/Api.php @@ -461,9 +461,9 @@ class API extends CI_Controller { if(isset($obj['station_profile_id'])) { - $this->logbook_model->import($record, $obj['station_profile_id'], NULL, NULL, NULL, NULL, false, false, true); + $this->logbook_model->import($record, $obj['station_profile_id'], NULL, NULL, NULL, NULL, NULL, false, false, true); } else { - $this->logbook_model->import($record, 0, NULL, NULL, NULL, NULL, false, false, true); + $this->logbook_model->import($record, 0, NULL, NULL, NULL, NULL, NULL, false, false, true); } }; diff --git a/application/controllers/Lotw.php b/application/controllers/Lotw.php index 0a6ea26c..30bfb896 100644 --- a/application/controllers/Lotw.php +++ b/application/controllers/Lotw.php @@ -505,7 +505,7 @@ class Lotw extends CI_Controller { $station_id = $this->logbook_model->find_correct_station_id($record['station_callsign'], $record['my_gridsquare']); if ($station_id != NULL) { - $result = $this->logbook_model->import($record, $station_id, NULL, TRUE, NULL, NULL, true, false); // Create the Entry + $result = $this->logbook_model->import($record, $station_id, NULL, TRUE, NULL, NULL, NULL, true, false); // Create the Entry if ($result == "") { $lotw_status = 'QSO imported'; } else { diff --git a/application/language/english/menu_lang.php b/application/language/english/menu_lang.php index 30972966..b4951a41 100644 --- a/application/language/english/menu_lang.php +++ b/application/language/english/menu_lang.php @@ -75,6 +75,7 @@ $lang['menu_labels'] = 'Labels'; $lang['menu_logbook_of_the_world'] = 'Logbook of the World'; $lang['menu_eqsl_import_export'] = 'eQSL Import / Export'; $lang['menu_qrz_logbook'] = 'QRZ Logbook'; +$lang['menu_hrd_logbook'] = 'HRDLog Logbook'; $lang['menu_qo_100_dx_club_upload'] = 'QO-100 Dx Club Upload'; $lang['menu_api_keys'] = 'API Keys'; $lang['menu_hardware_interfaces'] = 'Hardware Interfaces'; diff --git a/application/language/finnish/menu_lang.php b/application/language/finnish/menu_lang.php index 8ca7b2ba..83d7321c 100644 --- a/application/language/finnish/menu_lang.php +++ b/application/language/finnish/menu_lang.php @@ -73,6 +73,7 @@ $lang['menu_print_requested_qsls'] = 'Tulosta pyydetyt QSL:t'; $lang['menu_logbook_of_the_world'] = 'Logbook of the World'; $lang['menu_eqsl_import_export'] = 'eQSL Tuonti / Vienti'; $lang['menu_qrz_logbook'] = 'QRZ Logi'; +$lang['menu_hrd_logbook'] = 'HRDLog Logi'; $lang['menu_qo_100_dx_club_upload'] = 'QO-100 Dx Club Lähetys'; $lang['menu_api_keys'] = 'API Keys'; $lang['menu_hardware_interfaces'] = 'Hardware Interfaces'; diff --git a/application/language/german/menu_lang.php b/application/language/german/menu_lang.php index ba75892b..05fbb07d 100644 --- a/application/language/german/menu_lang.php +++ b/application/language/german/menu_lang.php @@ -75,6 +75,7 @@ $lang['menu_labels'] = 'Etiketten'; $lang['menu_logbook_of_the_world'] = 'Logbook of the World'; $lang['menu_eqsl_import_export'] = 'eQSL Import / Export'; $lang['menu_qrz_logbook'] = 'QRZ Logbuch'; +$lang['menu_hrd_logbook'] = 'HRDLog Logbuch'; $lang['menu_qo_100_dx_club_upload'] = 'QO-100 Dx Club Upload'; $lang['menu_api_keys'] = 'API-Schlüssel'; $lang['menu_hardware_interfaces'] = 'Hardware-Schnittstellen'; diff --git a/application/language/russian/menu_lang.php b/application/language/russian/menu_lang.php index 2c1170d7..f4c04cb1 100644 --- a/application/language/russian/menu_lang.php +++ b/application/language/russian/menu_lang.php @@ -75,9 +75,10 @@ $lang['menu_labels'] = 'Наклейки'; $lang['menu_logbook_of_the_world'] = 'Logbook of the World'; $lang['menu_eqsl_import_export'] = 'Импорт / экспорт eQSL'; $lang['menu_qrz_logbook'] = 'QRZ Logbook'; +$lang['menu_hrd_logbook'] = 'HRDLog Logbook'; $lang['menu_qo_100_dx_club_upload'] = 'Загрузка в QO-100 Dx Club'; $lang['menu_api_keys'] = 'ключи API'; $lang['menu_hardware_interfaces'] = 'Аппаратные интерфейсы'; $lang['menu_help'] = 'Помощь'; $lang['menu_forum'] = 'Форум'; -$lang['menu_logout'] = 'Выход'; \ No newline at end of file +$lang['menu_logout'] = 'Выход'; diff --git a/application/libraries/AdifHelper.php b/application/libraries/AdifHelper.php index cc936f08..a639896c 100644 --- a/application/libraries/AdifHelper.php +++ b/application/libraries/AdifHelper.php @@ -42,7 +42,6 @@ class AdifHelper { 'FORCE_INIT', 'GRIDSQUARE', 'HEADING', - 'HRDLOG_QSO_UPLOAD_STATUS', 'IOTA', 'ITUZ', 'K_INDEX', @@ -64,6 +63,7 @@ class AdifHelper { 'PRECEDENCE', 'PROP_MODE', 'PUBLIC_KEY', + 'HRDLOG_QSO_UPLOAD_STATUS', 'QRZCOM_QSO_UPLOAD_STATUS', 'QSLMSG', 'QSL_RCVD', diff --git a/application/models/Logbook_model.php b/application/models/Logbook_model.php index 0453a240..2fe429a1 100755 --- a/application/models/Logbook_model.php +++ b/application/models/Logbook_model.php @@ -252,6 +252,10 @@ class Logbook_model extends CI_Model { $data['COL_MY_GRIDSQUARE'] = strtoupper(trim($station['station_gridsquare'])); } + if ($this->exists_hrdlog_code($station_id)) { + $data['COL_HRDLOG_QSO_UPLOAD_STATUS'] = 'N'; + } + if ($this->exists_qrz_api_key($station_id)) { $data['COL_QRZCOM_QSO_UPLOAD_STATUS'] = 'N'; } @@ -506,12 +510,26 @@ class Logbook_model extends CI_Model { $this->upload_amsat_status($data); } - // No point in fetching qrz api key and qrzrealtime setting if we're skipping the export + // No point in fetching hrdlog code or qrz api key and qrzrealtime setting if we're skipping the export if (!$skipexport) { - $result = $this->exists_qrz_api_key($data['station_id']); - // Push qso to qrz if apikey is set, and realtime upload is enabled, and we're not importing an adif-file + $result = $this->exists_hrdlog_code($data['station_id']); + // Push qso to hrdlog if code is set, and realtime upload is enabled, and we're not importing an adif-file + if (isset($result->hrdlog_code) && $result->hrdlogrealtime == 1) { + $CI =& get_instance(); + $CI->load->library('AdifHelper'); + $qso = $this->get_qso($last_id)->result(); + + $adif = $CI->adifhelper->getAdifLine($qso[0]); + $result = $this->push_qso_to_hrdlog($result->hrdlog_code, $data['COL_STATION_CALLSIGN'], $adif); + if ( ($result['status'] == 'OK') || ( ($result['status'] == 'error') || ($result['status'] == 'duplicate') || ($result['status'] == 'auth_error') )){ + $this->mark_hrdlog_qsos_sent($last_id); + } + } + $result = ''; // Empty result from previous hrdlog-attempt for safety + $result = $this->exists_qrz_api_key($data['station_id']); +// Push qso to qrz if apikey is set, and realtime upload is enabled, and we're not importing an adif-file if (isset($result->qrzapikey) && $result->qrzrealtime == 1) { $CI =& get_instance(); $CI->load->library('AdifHelper'); @@ -545,6 +563,24 @@ class Logbook_model extends CI_Model { } } + /* + * Function checks if a HRDLog Code exists in the table with the given station id + */ + function exists_hrdlog_code($station_id) { + $sql = 'select hrdlog_code, hrdlogrealtime from station_profile + where station_id = ' . $station_id; + + $query = $this->db->query($sql); + + $result = $query->row(); + + if ($result) { + return $result; + } else { + return false; + } + } + /* * Function checks if a QRZ API Key exists in the table with the given station id */ @@ -583,6 +619,59 @@ class Logbook_model extends CI_Model { } } + /* + * Function uploads a QSO to HRDLog with the API given. + * $adif contains a line with the QSO in the ADIF format. QSO ends with an + */ + function push_qso_to_hrdlog($apikey, $station_callsign, $adif, $replaceoption = false) { + $url = 'https://robot.hrdlog.net/newentry.aspx'; + + $post_data['Code'] = $apikey; + if ($replaceoption) { + $post_data['Cmd'] = 'UPDATE'; + $post_data['ADIFKey'] = $adif; + } + $post_data['ADIFData'] = $adif; + + $post_data['Callsign'] = $station_callsign; + + + $post_encoded=http_build_query($post_data); + + $ch = curl_init( $url ); + curl_setopt( $ch, CURLOPT_POST, true); + curl_setopt( $ch, CURLOPT_POSTFIELDS, $post_encoded); + curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, 1); + curl_setopt( $ch, CURLOPT_HEADER, 0); + curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt( $ch, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded')); + $content = curl_exec($ch); + if ($content){ + if (stristr($content,'1')) { + $result['status'] = 'OK'; + return $result; + } elseif (stristr($content,'0')) { + $result['status'] = 'duplicate'; + $result['message'] = $content; + return $result; + } elseif (stristr($content,'Unknown user')) { + $result['status'] = 'auth_error'; + $result['message'] = $content; + return $result; + } else { + $result['status'] = 'error'; + $result['message'] = $content; + return $result; + } + } + if(curl_errno($ch)){ + $result['status'] = 'error'; + $result['message'] = 'Curl error: '. curl_errno($ch); + return $result; + } + curl_close($ch); + } + /* * Function uploads a QSO to QRZ with the API given. * $adif contains a line with the QSO in the ADIF format. QSO ends with an @@ -655,6 +744,23 @@ class Logbook_model extends CI_Model { return $response === 200; } + /* + * Function marks QSOs as uploaded to HRDLog. + * $primarykey is the unique id for that QSO in the logbook + */ + function mark_hrdlog_qsos_sent($primarykey) { + $data = array( + 'COL_HRDLOG_QSO_UPLOAD_DATE' => date("Y-m-d H:i:s", strtotime("now")), + 'COL_HRDLOG_QSO_UPLOAD_STATUS' => 'Y', + ); + + $this->db->where('COL_PRIMARY_KEY', $primarykey); + + $this->db->update($this->config->item('table_name'), $data); + + return true; + } + /* * Function marks QSOs as uploaded to QRZ. * $primarykey is the unique id for that QSO in the logbook @@ -940,6 +1046,10 @@ class Logbook_model extends CI_Model { 'COL_CNTY' => $uscounty ); + if ($this->exists_hrdlog_code($data['station_id'])) { + $data['COL_HRDLOG_QSO_UPLOAD_STATUS'] = 'M'; + } + if ($this->exists_qrz_api_key($data['station_id'])) { $data['COL_QRZCOM_QSO_UPLOAD_STATUS'] = 'M'; } @@ -1311,6 +1421,23 @@ class Logbook_model extends CI_Model { return $this->db->get(); } + /* + * Function returns the QSOs from the logbook, which have not been either marked as uploaded to hrdlog, or has been modified with an edit + */ + function get_hrdlog_qsos($station_id){ + $sql = 'select *, dxcc_entities.name as station_country from ' . $this->config->item('table_name') . ' thcv ' . + ' left join station_profile on thcv.station_id = station_profile.station_id' . + ' left outer join dxcc_entities on thcv.col_my_dxcc = dxcc_entities.adif' . + ' where thcv.station_id = ' . $station_id . + ' and (COL_HRDLOG_QSO_UPLOAD_STATUS is NULL + or COL_HRDLOG_QSO_UPLOAD_STATUS = "" + or COL_HRDLOG_QSO_UPLOAD_STATUS = "M" + or COL_HRDLOG_QSO_UPLOAD_STATUS = "N")'; + + $query = $this->db->query($sql); + return $query; + } + /* * Function returns the QSOs from the logbook, which have not been either marked as uploaded to qrz, or has been modified with an edit */ @@ -1371,6 +1498,25 @@ class Logbook_model extends CI_Model { return $this->db->query($sql); } + /* + * Function returns all the station_id's with HRDLOG Code + */ + function get_station_id_with_hrdlog_code() { + $sql = 'select station_id, hrdlog_code from station_profile + where coalesce(hrdlog_code, "") <> ""'; + + $query = $this->db->query($sql); + + $result = $query->result(); + + if ($result) { + return $result; + } + else { + return null; + } + } + /* * Function returns all the station_id's with QRZ API Key's */ @@ -2590,9 +2736,10 @@ class Logbook_model extends CI_Model { * $markLoTW - used in ADIF import to mark QSOs as exported to LoTW when importing QSOs * $dxccAdif - used in ADIF import to determine if DXCC From ADIF is used, or if Cloudlog should try to guess * $markQrz - used in ADIF import to mark QSOs as exported to QRZ Logbook when importing QSOs + * $markHrd - used in ADIF import to mark QSOs as exported to HRDLog.net Logbook when importing QSOs * $skipexport - used in ADIF import to skip the realtime upload to QRZ Logbook when importing QSOs from ADIF */ - function import($record, $station_id = "0", $skipDuplicate = false, $markLotw = false, $dxccAdif = false, $markQrz = false, $skipexport = false, $operatorName = false, $apicall = false) { + function import($record, $station_id = "0", $skipDuplicate = false, $markLotw = false, $dxccAdif = false, $markQrz = false, $markHrd = false,$skipexport = false, $operatorName = false, $apicall = false) { // be sure that station belongs to user $CI =& get_instance(); $CI->load->model('Stations'); @@ -2931,12 +3078,19 @@ class Logbook_model extends CI_Model { $operatorName = (!empty($record['operator'])) ? $record['operator'] : ''; } - // If user checked to mark QSOs as uploaded to QRZ Logbook, or else we try to find info in ADIF import. + // If user checked to mark QSOs as uploaded to QRZ or HRDLog Logbook, or else we try to find info in ADIF import. + if ($markHrd != null) { + $input_hrdlog_qso_upload_status = 'Y'; + $input_hrdlog_qso_upload_date = $date = date("Y-m-d H:i:s", strtotime("now")); + } + if ($markQrz != null) { $input_qrzcom_qso_upload_status = 'Y'; $input_qrzcom_qso_upload_date = $date = date("Y-m-d H:i:s", strtotime("now")); } else { + $input_hrdlog_qso_upload_date = (!empty($record['hrdlog_qso_upload_date'])) ? $record['hrdlog_qso_upload_date'] : null; + $input_hrdlog_qso_upload_status = (!empty($record['hrdlog_qso_upload_status'])) ? $record['hrdlog_qso_upload_status'] : ''; $input_qrzcom_qso_upload_date = (!empty($record['qrzcom_qso_upload_date'])) ? $record['qrzcom_qso_upload_date'] : null; $input_qrzcom_qso_upload_status = (!empty($record['qrzcom_qso_upload_status'])) ? $record['qrzcom_qso_upload_status'] : ''; } @@ -3052,6 +3206,8 @@ class Logbook_model extends CI_Model { 'COL_PRECEDENCE' => (!empty($record['precedence'])) ? $record['precedence'] : '', 'COL_PROP_MODE' => (!empty($record['prop_mode'])) ? $record['prop_mode'] : '', 'COL_PUBLIC_KEY' => (!empty($record['public_key'])) ? $record['public_key'] : '', + 'COL_HRDLOG_QSO_UPLOAD_DATE' => $input_hrdlog_qso_upload_date, + 'COL_HRDLOG_QSO_UPLOAD_STATUS' => $input_hrdlog_qso_upload_status, 'COL_QRZCOM_QSO_UPLOAD_DATE' => $input_qrzcom_qso_upload_date, 'COL_QRZCOM_QSO_UPLOAD_STATUS' => $input_qrzcom_qso_upload_status, 'COL_QSL_RCVD' => $input_qsl_rcvd, diff --git a/application/models/Stations.php b/application/models/Stations.php index 17ae2008..b780b0a9 100644 --- a/application/models/Stations.php +++ b/application/models/Stations.php @@ -91,9 +91,11 @@ class Stations extends CI_Model { 'station_cq' => xss_clean($this->input->post('station_cq', true)), 'station_itu' => xss_clean($this->input->post('station_itu', true)), 'state' => $state, - 'eqslqthnickname' => xss_clean($this->input->post('eqslnickname', true)), - 'qrzapikey' => xss_clean($this->input->post('qrzapikey', true)), - 'qrzrealtime' => xss_clean($this->input->post('qrzrealtime', true)), + 'eqslqthnickname' => xss_clean($this->input->post('eqslnickname', true)), + 'hrdlog_code' => xss_clean($this->input->post('hrdlog_code', true)), + 'hrdlogrealtime' => xss_clean($this->input->post('hrdlogrealtime', true)), + 'qrzapikey' => xss_clean($this->input->post('qrzapikey', true)), + 'qrzrealtime' => xss_clean($this->input->post('qrzrealtime', true)), 'oqrs' => xss_clean($this->input->post('oqrs', true)), 'oqrs_email' => xss_clean($this->input->post('oqrsemail', true)), 'oqrs_text' => xss_clean($this->input->post('oqrstext', true)), @@ -133,8 +135,10 @@ class Stations extends CI_Model { 'station_itu' => xss_clean($this->input->post('station_itu', true)), 'state' => $state, 'eqslqthnickname' => xss_clean($this->input->post('eqslnickname', true)), - 'qrzapikey' => xss_clean($this->input->post('qrzapikey', true)), - 'qrzrealtime' => xss_clean($this->input->post('qrzrealtime', true)), + 'hrdlog_code' => xss_clean($this->input->post('hrdlog_code', true)), + 'hrdlogrealtime' => xss_clean($this->input->post('hrdlogrealtime', true)), + 'qrzapikey' => xss_clean($this->input->post('qrzapikey', true)), + 'qrzrealtime' => xss_clean($this->input->post('qrzrealtime', true)), 'oqrs' => xss_clean($this->input->post('oqrs', true)), 'oqrs_email' => xss_clean($this->input->post('oqrsemail', true)), 'oqrs_text' => xss_clean($this->input->post('oqrstext', true)), @@ -342,6 +346,35 @@ class Stations extends CI_Model { } } + function stations_with_hrdlog_code() { + $sql = "select station_profile.station_id, station_profile.station_profile_name, station_profile.station_callsign, modc.modcount, notc.notcount, totc.totcount + from station_profile + left outer join ( + select count(*) modcount, station_id + from ". $this->config->item('table_name') . + " where COL_HRDLOG_QSO_UPLOAD_STATUS = 'M' + group by station_id + ) as modc on station_profile.station_id = modc.station_id + left outer join ( + select count(*) notcount, station_id + from " . $this->config->item('table_name') . + " where (coalesce(COL_HRDLOG_QSO_UPLOAD_STATUS, '') = '' + or COL_HRDLOG_QSO_UPLOAD_STATUS = 'N') + group by station_id + ) as notc on station_profile.station_id = notc.station_id + left outer join ( + select count(*) totcount, station_id + from " . $this->config->item('table_name') . + " where COL_HRDLOG_QSO_UPLOAD_STATUS = 'Y' + group by station_id + ) as totc on station_profile.station_id = totc.station_id + where coalesce(station_profile.hrdlog_code, '') <> '' + and station_profile.user_id = " . $this->session->userdata('user_id'); + $query = $this->db->query($sql); + + return $query; + } + function stations_with_qrz_api_key() { $sql = "select station_profile.station_id, station_profile.station_profile_name, station_profile.station_callsign, modc.modcount, notc.notcount, totc.totcount from station_profile diff --git a/application/views/adif/import.php b/application/views/adif/import.php index c2c36fac..3b310065 100644 --- a/application/views/adif/import.php +++ b/application/views/adif/import.php @@ -59,6 +59,16 @@ +
+
+
+ + +
+
Select if ADIF being imported does not contain this information.
+
+
+
diff --git a/application/views/interface_assets/footer.php b/application/views/interface_assets/footer.php index df7aef74..12ad1bea 100644 --- a/application/views/interface_assets/footer.php +++ b/application/views/interface_assets/footer.php @@ -71,7 +71,7 @@ function load_was_map() { -uri->segment(1) == "adif" || $this->uri->segment(1) == "qrz" || $this->uri->segment(1) == "webadif") { ?> +uri->segment(1) == "adif" || $this->uri->segment(1) == "qrz" || $this->uri->segment(1) == "hrdlog" ||$this->uri->segment(1) == "webadif") { ?> @@ -1702,6 +1702,9 @@ $(document).ready(function(){ + uri->segment(1) == "hrdlog") { ?> + + uri->segment(1) == "qrz") { ?> diff --git a/application/views/interface_assets/header.php b/application/views/interface_assets/header.php index 2cd82483..df346f2b 100644 --- a/application/views/interface_assets/header.php +++ b/application/views/interface_assets/header.php @@ -260,6 +260,7 @@ $oqrs_requests = $CI->oqrs_model->oqrs_requests($location_list); + diff --git a/application/views/station_profile/create.php b/application/views/station_profile/create.php index 3350451e..5f6efd3e 100644 --- a/application/views/station_profile/create.php +++ b/application/views/station_profile/create.php @@ -249,6 +249,20 @@ eQSL QTH Nickname.
+ +
+
+ + Find your API key on HRDLog Userprofile +
+
+ +
+
+ diff --git a/application/views/station_profile/edit.php b/application/views/station_profile/edit.php index f2809222..d263e17d 100644 --- a/application/views/station_profile/edit.php +++ b/application/views/station_profile/edit.php @@ -371,6 +371,27 @@
+
+
+
+
HRDLog.net
+
+
+ + hrdlog_code; } ?>"> + Create your API Code on HRDLog.net Userprofile page +
+
+ + +
+
+
+
+
diff --git a/application/views/welcome/index.php b/application/views/welcome/index.php index 4bfa3b9b..6a6bd7b5 100644 --- a/application/views/welcome/index.php +++ b/application/views/welcome/index.php @@ -69,6 +69,9 @@ # Upload QSOs to LoTW if certs have been provided every hour.
0 */1 * * * curl --silent /lotw/lotw_upload &>/dev/null

+ # Upload QSOs to HRDLog.net Logbook (ignore cron job if this integration is not required)
+ 0 */6 * * * curl --silent /hrdlog/upload &>/dev/null
+
# Upload QSOs to QRZ Logbook (ignore cron job if this integration is not required)
0 */6 * * * curl --silent /qrz/upload &>/dev/null

@@ -153,4 +156,4 @@

-
\ No newline at end of file +