diff --git a/package.nw/lib/adif.js b/package.nw/lib/adif.js index 6c22c66..ef4ac67 100644 --- a/package.nw/lib/adif.js +++ b/package.nw/lib/adif.js @@ -1,2963 +1,2963 @@ -// GridTracker Copyright © 2021 GridTracker.org -// All rights reserved. -// See LICENSE for more information. - -var selectStartupLink = null; - -function dragOverHandler(ev) -{ - // Prevent default behavior (Prevent file from being opened) - ev.preventDefault(); -} - -function dropHandler(ev) -{ - // Prevent default behavior (Prevent file from being opened) - ev.preventDefault(); - if (ev.dataTransfer.items) - { - // Use DataTransferItemList interface to access the file(s) - for (var i = 0; i < ev.dataTransfer.items.length; i++) - { - // If dropped items aren't files, reject them - Entry = ev.dataTransfer.items[i].webkitGetAsEntry(); - if (Entry && typeof Entry.isFile != "undefined" && Entry.isFile == true) - { - var filename = ev.dataTransfer.items[i].getAsFile().path; - var test = filename.toLowerCase(); - var valid = test.endsWith(".adi") - ? true - : test.endsWith(".adif") - ? true - : test.endsWith(".log") - ? true - : !!test.endsWith(".txt"); - if (valid && fs.existsSync(filename)) - { - onAdiLoadComplete(fs.readFileSync(filename, "UTF-8"), false); - } - } - } - } -} - -function findAdiField(row, field) -{ - var value = ""; - var regex = new RegExp("<" + field + ":", "i"); - var firstSplitArray = row.split(regex); - if (firstSplitArray && firstSplitArray.length == 2) - { - var secondSplitArray = firstSplitArray[1].split(">"); - if (secondSplitArray.length > 1) - { - var newLenSearch = secondSplitArray[0].split(":"); - var newLen = newLenSearch[0]; - value = secondSplitArray[1].slice(0, newLen); - } - } - return value; -} - -function onAdiLoadComplete(adiBuffer, saveAdifFile, adifFileName, newFile) -{ - let rawAdiBuffer = ""; - if (typeof adiBuffer == "object") rawAdiBuffer = String(adiBuffer); - else rawAdiBuffer = adiBuffer; - - let activeAdifArray = Array(); - let activeAdifLogMode = true; - let eQSLfile = false; - - if (rawAdiBuffer.indexOf("PSKReporter") > -1) activeAdifLogMode = false; - - if (rawAdiBuffer.indexOf("Received eQSLs") > -1) eQSLfile = true; - - if (rawAdiBuffer.length > 1) - { - let regex = new RegExp("", "i"); - activeAdifArray = rawAdiBuffer.split(regex); - } - - let dateTime = new Date(); - let dupes = 0; - - for (let x = 0; x < activeAdifArray.length; x++) - { - let finalMode = ""; - - if (activeAdifArray[x].length > 3) - { - if (activeAdifLogMode) - { - let confirmed = false; - let finalGrid = findAdiField( - activeAdifArray[x], - "GRIDSQUARE" - ).toUpperCase(); - let vuccGrids = findAdiField( - activeAdifArray[x], - "VUCC_GRIDS" - ).toUpperCase(); - let finalVucc = []; - let finalDXcall = findAdiField(activeAdifArray[x], "CALL").replace( - "_", - "/" - ); - let finalDEcall = findAdiField( - activeAdifArray[x], - "STATION_CALLSIGN" - ).replace("_", "/"); - - if (finalDEcall == "") finalDEcall = myDEcall; - if ( - g_appSettings.workingCallsignEnable && - !(finalDEcall in g_appSettings.workingCallsigns) - ) - { continue; } - let finalRSTsent = findAdiField(activeAdifArray[x], "RST_SENT"); - let finalRSTrecv = findAdiField(activeAdifArray[x], "RST_RCVD"); - let finalBand = findAdiField(activeAdifArray[x], "BAND").toLowerCase(); - let dateVal = findAdiField(activeAdifArray[x], "QSO_DATE"); - let timeVal = findAdiField(activeAdifArray[x], "TIME_ON"); - let finalState = findAdiField( - activeAdifArray[x], - "STATE" - ).toUpperCase(); - if (finalState.length == 0) finalState = null; - let finalPropMode = findAdiField( - activeAdifArray[x], - "PROP_MODE" - ).toUpperCase(); - let finalSatName = findAdiField( - activeAdifArray[x], - "SAT_NAME" - ).toUpperCase(); - let finalCont = findAdiField(activeAdifArray[x], "CONT").toUpperCase(); - if (finalCont.length == 0) finalCont = null; - let finalCnty = findAdiField(activeAdifArray[x], "CNTY").toUpperCase(); - if (finalCnty.length == 0) finalCnty = null; - else - { - finalCnty = finalCnty.replaceAll(" ", ""); - } - let finalMode = findAdiField(activeAdifArray[x], "MODE").toUpperCase(); - let subMode = findAdiField(activeAdifArray[x], "SUBMODE"); - if (subMode == "FT4" && (finalMode == "MFSK" || finalMode == "DATA")) - { finalMode = "FT4"; } - if (subMode == "JS8" && finalMode == "MFSK") finalMode = "JS8"; - - if (finalBand == "oob" || finalBand == "") - { - finalBand = Number( - findAdiField(activeAdifArray[x], "FREQ") - ).formatBand(); - } - - let finalMsg = findAdiField(activeAdifArray[x], "COMMENT"); - let finalQslMsg = findAdiField(activeAdifArray[x], "QSLMSG"); - let finalQslMsgIntl = findAdiField(activeAdifArray[x], "QSLMSG_INTL"); - if (finalQslMsg.length > 1) finalMsg = finalQslMsg; - if (finalQslMsgIntl.length > 1 && finalMsg == "") - { finalMsg = finalQslMsgIntl; } - - let finalDxcc = Number(findAdiField(activeAdifArray[x], "DXCC")); - if (finalDxcc == 0) finalDxcc = Number(callsignToDxcc(finalDXcall)); - - if (!(finalDxcc in g_dxccToGeoData)) - { finalDxcc = Number(callsignToDxcc(finalDXcall)); } - - // If my callsign isn't present, it must be for me anyway - - let finalCqZone = findAdiField(activeAdifArray[x], "CQZ"); - if (finalCqZone.length == 1) finalCqZone = "0" + finalCqZone; - - if (parseInt(finalCqZone) < 1 || parseInt(finalCqZone) > 40) - { finalCqZone = ""; } - finalCqZone = String(finalCqZone); - let finalItuZone = findAdiField(activeAdifArray[x], "ITUZ"); - if (finalItuZone.length == 1) finalItuZone = "0" + finalItuZone; - - if (parseInt(finalItuZone) < 1 || parseInt(finalItuZone) > 90) - { finalItuZone = ""; } - finalItuZone = String(finalItuZone); - - let finalIOTA = findAdiField(activeAdifArray[x], "IOTA").toUpperCase(); - - let qrzConfirmed = findAdiField( - activeAdifArray[x], - "APP_QRZLOG_STATUS" - ).toUpperCase(); - let lotwConfirmed1 = findAdiField( - activeAdifArray[x], - "QSL_RCVD" - ).toUpperCase(); - let lotw_qsl_rcvd = findAdiField( - activeAdifArray[x], - "LOTW_QSL_RCVD" - ).toUpperCase(); - let eqsl_qsl_rcvd = findAdiField( - activeAdifArray[x], - "EQSL_QSL_RCVD" - ).toUpperCase(); - - if ( - qrzConfirmed == "C" || - lotw_qsl_rcvd == "Y" || - lotw_qsl_rcvd == "V" || - lotwConfirmed1 == "Y" || - eqsl_qsl_rcvd == "Y" || - eqsl_qsl_rcvd == "V" || - eQSLfile == true - ) - { confirmed = true; } - - let dateTime = new Date( - Date.UTC( - dateVal.substr(0, 4), - parseInt(dateVal.substr(4, 2)) - 1, - dateVal.substr(6, 2), - timeVal.substr(0, 2), - timeVal.substr(2, 2), - timeVal.substr(4, 2) - ) - ); - - let finalTime = parseInt(dateTime.getTime() / 1000); - - if ( - g_appSettings.workingDateEnable && - finalTime < g_appSettings.workingDate - ) - { continue; } - - finalGrid = finalGrid.substr(0, 6); - if (!validateGridFromString(finalGrid)) finalGrid = ""; - if (finalGrid == "" && vuccGrids != "") - { - finalVucc = vuccGrids.split(","); - finalGrid = finalVucc[0]; - finalVucc.shift(); - } - let isDigital = false; - let isPhone = false; - if (finalMode in g_modes) - { - isDigital = g_modes[finalMode]; - } - if (finalMode in g_modes_phone) - { - isPhone = g_modes_phone[finalMode]; - } - if (finalDXcall != "") - { - addDeDx( - finalGrid, - finalDXcall, - false, - false, - false, - finalDEcall, - finalRSTsent, - finalTime, - finalMsg, - finalMode, - finalBand, - confirmed, - false, - finalRSTrecv, - finalDxcc, - finalState, - finalCont, - finalCnty, - finalCqZone, - finalItuZone, - finalVucc, - finalPropMode, - isDigital, - isPhone, - finalIOTA, - finalSatName - ); - } - } - else - { - let finalMyGrid = findAdiField( - activeAdifArray[x], - "MY_GRIDSQUARE" - ).toUpperCase(); - let finalGrid = findAdiField( - activeAdifArray[x], - "GRIDSQUARE" - ).toUpperCase(); - let finalDXcall = findAdiField(activeAdifArray[x], "CALL"); - let finalDEcall = findAdiField(activeAdifArray[x], "OPERATOR"); - let finalRSTsent = findAdiField(activeAdifArray[x], "APP_PSKREP_SNR"); - let dateVal = findAdiField(activeAdifArray[x], "QSO_DATE"); - let timeVal = findAdiField(activeAdifArray[x], "TIME_ON"); - let finalMode = findAdiField(activeAdifArray[x], "MODE"); - let finalBand = Number( - findAdiField(activeAdifArray[x], "FREQ") - ).formatBand(); - let finalMsg = "-"; - let finalDxcc = Number(findAdiField(activeAdifArray[x], "DXCC")); - if (finalDxcc == 0) - { - if (finalDXcall == myDEcall) finalDxcc = callsignToDxcc(finalDEcall); - else finalDxcc = callsignToDxcc(finalDXcall); - } - - finalGrid = finalGrid.substr(0, 6); - - let dateTime = new Date( - Date.UTC( - dateVal.substr(0, 4), - parseInt(dateVal.substr(4, 2)) - 1, - dateVal.substr(6, 2), - timeVal.substr(0, 2), - timeVal.substr(2, 2), - timeVal.substr(4, 2) - ) - ); - let finalTime = parseInt(dateTime.getTime() / 1000); - if ( - finalGrid != "" && - finalDXcall != "" && - validateGridFromString(finalGrid) - ) - { - if (finalDXcall == myDEcall) - { - addDeDx( - finalMyGrid, - finalDEcall, - false, - false, - false, - finalDXcall, - null, - finalTime, - finalMsg, - finalMode, - finalBand, - false, - true, - finalRSTsent, - finalDxcc, - null, - null, - null, - null, - null - ); - } - else if (finalDEcall == myDEcall) - { - addDeDx( - finalGrid, - finalDXcall, - false, - false, - false, - "-", - finalRSTsent, - finalTime, - finalMsg, - finalMode, - finalBand, - false, - true, - null, - finalDxcc, - null, - null, - null, - null, - null - ); - } - else - { - addDeDx( - finalGrid, - finalDXcall, - false, - false, - false, - finalDEcall, - finalRSTsent, - finalTime, - finalMsg, - finalMode, - finalBand, - false, - true, - null, - finalDxcc, - null, - null, - null, - null, - null - ); - } - } - } - } - } - - redrawGrids(); - updateCountStats(); - updateLogbook(); - - if (g_fromDirectCallNoFileDialog == false) - { - fileSelector.setAttribute("type", ""); - fileSelector.setAttribute("type", "file"); - fileSelector.setAttribute("accept", ".adi,"); - fileSelector.value = null; - } - g_fromDirectCallNoFileDialog = false; - - updateRosterWorked(); - goProcessRoster(); -} - -function clubLogCallback(buffer, flag, cookie) -{ - var rawAdiBuffer = String(buffer); - if (rawAdiBuffer.indexOf("Invalid login") > -1) - { - if (flag) clubTestResult.innerHTML = "Invalid"; - } - else if (buffer == null) - { - if (flag) clubTestResult.innerHTML = "Unknown Error"; - } - else - { - if (flag) clubTestResult.innerHTML = "Passed"; - else - { - g_fromDirectCallNoFileDialog = true; - - rawAdiBuffer = cleanAndPrepADIF("clublog.adif", rawAdiBuffer); - - tryToWriteAdifToDocFolder("clublog.adif", rawAdiBuffer); - - onAdiLoadComplete(rawAdiBuffer, true, "clublog.adif", true); - } - } -} - -var g_isGettingClub = false; -function grabClubLog(test) -{ - if (g_isGettingClub == false) - { - if (test) clubTestResult.innerHTML = "Testing"; - - var postData = { - email: clubEmail.value, - password: clubPassword.value, - call: clubCall.value - }; - getAPostBuffer( - "https://clublog.org/getadif.php", - clubLogCallback, - test, - "https", - 443, - postData, - ClubLogImg, - "g_isGettingClub" - ); - } -} - -function tryToWriteAdifToDocFolder(filename, buffer, append = false) -{ - var finalFile = g_appData + g_dirSeperator + filename; - try - { - if (append == false) - { - fs.writeFileSync(finalFile, buffer); - return buffer; - } - else - { - fs.appendFileSync(finalFile, buffer); - return fs.readFileSync(finalFile); - } - } - catch (e) - { - return false; - } -} - -function cleanAndPrepADIF(name, adiBuffer, reverse = false, noheader = false) -{ - var rawAdiBuffer = adiBuffer; - var regex = new RegExp("", "i"); - rawAdiBuffer = rawAdiBuffer.replace(regex, ""); - regex = new RegExp("", "i"); - var adiArray = rawAdiBuffer.split(regex); - var activeAdifArray = Array(); - var activeAdifLogMode = true; - var finalBuffer = ""; - - if (noheader == false) finalBuffer = name + "\r\n"; - - if (adiArray.length > 1) - { - regex = new RegExp("", "i"); - activeAdifArray = adiArray[1].split(regex); - - if (reverse == false) - { - for (var x = 0; x < activeAdifArray.length - 1; x++) - { - var row = activeAdifArray[x].replace(/[\n\r]/g, ""); - if (row.length > 0) finalBuffer += row + "\r\n"; - } - } - else - { - for (var x = activeAdifArray.length - 1; x > -1; x--) - { - var row = activeAdifArray[x].replace(/[\n\r]/g, ""); - if (row.length > 0) finalBuffer += row + "\r\n"; - } - } - } - - return finalBuffer; -} - -function addZero(i) -{ - if (i < 10) - { - i = "0" + i; - } - return i; -} - -function getUTCString(d) -{ - var Y = d.getUTCFullYear(); - var M = addZero(d.getUTCMonth() + 1); - var D = addZero(d.getUTCDate()); - var h = addZero(d.getUTCHours()); - var m = addZero(d.getUTCMinutes()); - var s = addZero(d.getUTCSeconds()); - return Y + "-" + M + "-" + D + " " + h + ":" + m + ":" + s; -} - -function lotwCallback(buffer, flag) -{ - var rawAdiBuffer = String(buffer); - if (rawAdiBuffer.indexOf("password incorrect") > -1) - { - if (flag) lotwTestResult.innerHTML = "Invalid"; - } - else - { - if (flag) lotwTestResult.innerHTML = "Passed"; - else - { - var shouldAppend = false; - g_fromDirectCallNoFileDialog = true; - - rawAdiBuffer = cleanAndPrepADIF( - "lotw.adif", - rawAdiBuffer, - true, - shouldAppend - ); - - rawAdiBuffer = tryToWriteAdifToDocFolder( - "lotw.adif", - rawAdiBuffer, - shouldAppend - ); - - onAdiLoadComplete(rawAdiBuffer, true, "lotw.adif", true); - } - } -} - -function shouldWeAppendInsteadOfCreate(filename) -{ - var finalFile = g_appData + g_dirSeperator + filename; - try - { - if (fs.existsSync(finalFile)) return true; - else return false; - } - catch (e) - { - return false; - } -} - -function tryToDeleteLog(filename) -{ - var finalFile = g_appData + g_dirSeperator + filename; - try - { - if (fs.existsSync(finalFile)) - { - fs.unlinkSync(finalFile); - } - } - catch (e) {} -} - -var g_lotwCount = 0; - -var g_isGettingLOTW = false; - -function grabLOtWLog(test) -{ - if (g_isGettingLOTW == false) - { - var lastQSLDateString = - "&qso_qsorxsince=1945-01-01&qso_qslsince=1945-01-01"; - if (test == true) - { - lotwTestResult.innerHTML = "Testing"; - lastQSLDateString = "&qso_qsosince=2100-01-01"; - } - - getABuffer( - "https://lotw.arrl.org/lotwuser/lotwreport.adi?login=" + - lotwLogin.value + - "&password=" + - encodeURIComponent(lotwPassword.value) + - "&qso_query=1&qso_qsl=no&qso_qsldetail=yes&qso_withown=yes" + - lastQSLDateString, - lotwCallback, - test, - "https", - 443, - lotwLogImg, - "g_isGettingLOTW", - 120000 - ); - } -} - -function qrzCallback(buffer, flag) -{ - if (buffer.indexOf("invalid api key") > -1) - { - if (flag) qrzTestResult.innerHTML = "Invalid"; - } - else - { - if (flag) - { - qrzTestResult.innerHTML = "Passed"; - } - else - { - g_fromDirectCallNoFileDialog = true; - var htmlString = String(buffer).replace(/</g, "<"); - htmlString = htmlString.replace(/>/g, ">"); - htmlString = htmlString.replace("ADIF=", "QRZ\r\n"); - - htmlString = cleanAndPrepADIF("qrz.adif", htmlString); - - tryToWriteAdifToDocFolder("qrz.adif", htmlString); - - onAdiLoadComplete(htmlString, true, "qrz.adif", true); - } - } -} - -var g_isGettingQRZCom = false; -function grabQrzComLog(test) -{ - if (g_isGettingQRZCom == false) - { - var action = "FETCH"; - if (test) - { - qrzTestResult.innerHTML = "Testing"; - action = "STATUS"; - } - - getABuffer( - "https://logbook.qrz.com/api?KEY=" + - qrzApiKey.value + - "&ACTION=" + - action, - qrzCallback, - test, - "https", - 443, - qrzLogImg, - "g_isGettingQRZCom", - null - ); - } -} - -function ValidateQrzApi(inputText) -{ - inputText.value = inputText.value.toUpperCase(); - if (inputText.value.length == 19) - { - var passed = false; - var dashcount = 0; - for (var i = 0; i < inputText.value.length; i++) - { - if (inputText.value[i] == "-") dashcount++; - } - if (dashcount == 3) - { - passed = true; - } - if (passed) - { - inputText.style.color = "#FF0"; - inputText.style.backgroundColor = "green"; - - return true; - } - else - { - inputText.style.color = "white"; - inputText.style.backgroundColor = "red"; - return false; - } - } - else - { - inputText.style.color = "white"; - inputText.style.backgroundColor = "red"; - - return false; - } -} - -function ValidateText(inputText) -{ - if (inputText.value.length > 0) - { - inputText.style.color = "#FF0"; - inputText.style.backgroundColor = "green"; - return true; - } - else - { - inputText.style.color = "white"; - inputText.style.backgroundColor = "red"; - return false; - } -} - -function pskCallback(buffer, flag) -{ - g_fromDirectCallNoFileDialog = true; - var rawAdiBuffer = String(buffer); - - onAdiLoadComplete(rawAdiBuffer, false); -} - -var g_isGettingPsk = false; - -function grabPsk24() -{ - if (g_isGettingPsk == true) return; - - if (myDEcall.length > 0 && myDEcall != "NOCALL") - { - var days = 1; - if (pskImg.src == 1) days = 7; - getABuffer( - "https://pskreporter.info/cgi-bin/pskdata.pl?adif=1&days=" + - days + - "&receiverCallsign=" + - myDEcall.toLowerCase(), - pskCallback, - null, - "https", - 443, - pskImg, - "g_isGettingPsk" - ); - } -} - -function adifMenuCheckBoxChanged(what) -{ - g_adifLogSettings.menu[what.id] = what.checked; - var menuItem = what.id + "Div"; - if (what.checked == true) - { - document.getElementById(menuItem).style.display = "inline-block"; - } - else - { - document.getElementById(menuItem).style.display = "none"; - } - - localStorage.adifLogSettings = JSON.stringify(g_adifLogSettings); - - if (what == buttonAdifCheckBox) setAdifStartup(loadAdifCheckBox); -} - -function adifStartupCheckBoxChanged(what) -{ - g_adifLogSettings.startup[what.id] = what.checked; - localStorage.adifLogSettings = JSON.stringify(g_adifLogSettings); - - if (what == loadAdifCheckBox) setAdifStartup(loadAdifCheckBox); -} - -function adifLogQsoCheckBoxChanged(what) -{ - g_adifLogSettings.qsolog[what.id] = what.checked; - if (what.id == "logLOTWqsoCheckBox") - { - if (what.checked == true) - { - lotwUpload.style.display = "inline-block"; - trustedTestButton.style.display = "inline-block"; - } - else - { - lotwUpload.style.display = "none"; - trustedTestButton.style.display = "none"; - } - } - localStorage.adifLogSettings = JSON.stringify(g_adifLogSettings); -} - -function adifNicknameCheckBoxChanged(what) -{ - g_adifLogSettings.nickname[what.id] = what.checked; - if (what.id == "nicknameeQSLCheckBox") - { - if (what.checked == true) - { - eQSLNickname.style.display = "inline-block"; - } - else - { - eQSLNickname.style.display = "none"; - } - } - localStorage.adifLogSettings = JSON.stringify(g_adifLogSettings); -} - -function adifTextValueChange(what) -{ - what.value = what.value.trim(); - g_adifLogSettings.text[what.id] = what.value; - localStorage.adifLogSettings = JSON.stringify(g_adifLogSettings); -} - -var fileSelector = document.createElement("input"); -fileSelector.setAttribute("type", "file"); -fileSelector.setAttribute("accept", ".adi,.adif"); -fileSelector.onchange = function () -{ - if (this.files && this.files[0]) - { - let path = this.value.replace(this.files[0].name, ""); - fileSelector.setAttribute("nwworkingdir", path); - - var reader = new FileReader(); - reader.onload = function (e) - { - if (e.target.error == null) - { - onAdiLoadComplete(e.target.result, false); - } - }; - - reader.readAsText(this.files[0]); - } -}; - -function adifLoadDialog() -{ - var exists = fileSelector.getAttribute("nwworkingdir"); - - fileSelector.setAttribute("nwworkingdir", g_appData); - - fileSelector.click(); - - return false; -} - -var startupFileSelector = document.createElement("input"); -startupFileSelector.setAttribute("type", "file"); -startupFileSelector.setAttribute("accept", ".adi,.adif"); -startupFileSelector.onchange = function () -{ - if (this.files && this.files[0]) - { - for (var i in g_startupLogs) - { - if (this.value == g_startupLogs[i].file) return; - } - var newObject = Object(); - newObject.name = this.files[0].name; - newObject.file = this.value; - g_startupLogs.push(newObject); - localStorage.startupLogs = JSON.stringify(g_startupLogs); - - let path = this.value.replace(this.files[0].name, ""); - startupFileSelector.setAttribute("nwworkingdir", path); - - setAdifStartup(loadAdifCheckBox); - } -}; - -function start_and_end(str) -{ - if (str.length > 31) - { - return ( - str.substr(0, 16) + " ... " + str.substr(str.length - 15, str.length) - ); - } - return str; -} - -function setFileSelectors() -{ - selectStartupLink = document.getElementById("selectAdifButton"); - selectStartupLink.onclick = function () - { - var exists = startupFileSelector.getAttribute("nwworkingdir"); - if (exists == null) - { - if (g_workingIniPath.length > 1) - { startupFileSelector.setAttribute("nwworkingdir", g_appData); } - } - - startupFileSelector.click(); - return false; - }; - - selectTqsl = document.getElementById("selectTQSLButton"); - selectTqsl.onclick = function () - { - tqslFileSelector.click(); - return false; - }; - lotwUpload.prepend(selectTqsl); -} - -var tqslFileSelector = document.createElement("input"); -tqslFileSelector.setAttribute("type", "file"); -tqslFileSelector.setAttribute("accept", "*"); -tqslFileSelector.onchange = function () -{ - if (this.files && this.files[0]) - { - g_trustedQslSettings.binaryFile = this.files[0].path; - var fs = require("fs"); - - if ( - fs.existsSync(g_trustedQslSettings.binaryFile) && - (g_trustedQslSettings.binaryFile.endsWith("tqsl.exe") || - g_trustedQslSettings.binaryFile.endsWith("tqsl")) - ) - { - g_trustedQslSettings.binaryFileValid = true; - } - else g_trustedQslSettings.binaryFileValid = false; - - if (g_trustedQslSettings.binaryFileValid == true) - { - tqslFileDiv.style.backgroundColor = "blue"; - } - else - { - tqslFileDiv.style.backgroundColor = "red"; - } - - tqslFileDiv.innerHTML = "" + start_and_end(this.files[0].path) + ""; - localStorage.trustedQslSettings = JSON.stringify(g_trustedQslSettings); - } -}; - -function loadGtQSOLogFile() -{ - var fs = require("fs"); - - if (fs.existsSync(g_qsoLogFile)) - { - var rawAdiBuffer = fs.readFileSync(g_qsoLogFile); - - g_fromDirectCallNoFileDialog = true; - - onAdiLoadComplete(rawAdiBuffer, false); - } -} - -function loadWsjtLogFile() -{ - var fs = require("fs"); - if (fs.existsSync(g_workingIniPath + "wsjtx_log.adi")) - { - var rawAdiBuffer = fs.readFileSync(g_workingIniPath + "wsjtx_log.adi"); - g_fromDirectCallNoFileDialog = true; - onAdiLoadComplete(rawAdiBuffer, false); - } -} - -function findTrustedQSLPaths() -{ - var process = require("process"); - var base = null; - - if (g_trustedQslSettings.stationFileValid == true) - { - // double check the presence of the station_data; - if (!fs.existsSync(g_trustedQslSettings.stationFile)) - { - g_trustedQslSettings.stationFileValid = false; - } - } - if (g_trustedQslSettings.stationFileValid == false) - { - if (g_platform == "windows") - { - base = process.env.APPDATA + "\\TrustedQSL\\station_data"; - if (fs.existsSync(base)) - { - g_trustedQslSettings.stationFile = base; - g_trustedQslSettings.stationFileValid = true; - } - else - { - base = process.env.LOCALAPPDATA + "\\TrustedQSL\\station_data"; - if (fs.existsSync(base)) - { - g_trustedQslSettings.stationFile = base; - g_trustedQslSettings.stationFileValid = true; - } - } - } - else - { - base = process.env.HOME + "/.tqsl/station_data"; - if (fs.existsSync(base)) - { - g_trustedQslSettings.stationFile = base; - g_trustedQslSettings.stationFileValid = true; - } - } - } - if (g_trustedQslSettings.stationFileValid == true) - { - var validate = false; - var option = document.createElement("option"); - option.value = ""; - option.text = "Select a Station"; - lotwStation.appendChild(option); - - var buffer = fs.readFileSync(g_trustedQslSettings.stationFile, "UTF-8"); - parser = new DOMParser(); - xmlDoc = parser.parseFromString(buffer, "text/xml"); - var x = xmlDoc.getElementsByTagName("StationData"); - for (var i = 0; i < x.length; i++) - { - option = document.createElement("option"); - option.value = x[i].getAttribute("name"); - option.text = x[i].getAttribute("name"); - if (option.value == g_adifLogSettings.text.lotwStation) - { - option.selected = true; - validate = true; - } - lotwStation.appendChild(option); - } - if (validate) - { - ValidateText(lotwStation); - } - } - - if (g_trustedQslSettings.binaryFileValid == true) - { - // double check the presence of the TrustedQSL binary; - if (!fs.existsSync(g_trustedQslSettings.binaryFile)) - { - g_trustedQslSettings.binaryFileValid = false; - } - } - if (g_trustedQslSettings.binaryFileValid == false || g_platform == "mac") - { - if (g_platform == "windows") - { - base = process.env["ProgramFiles(x86)"] + "\\TrustedQSL\\tqsl.exe"; - if (fs.existsSync(base)) - { - g_trustedQslSettings.binaryFile = base; - g_trustedQslSettings.binaryFileValid = true; - } - } - else if (g_platform == "mac") - { - base = "/Applications/TrustedQSL/tqsl.app/Contents/MacOS/tqsl"; - if (fs.existsSync(base)) - { - g_trustedQslSettings.binaryFile = base; - g_trustedQslSettings.binaryFileValid = true; - } - else - { - base = - process.env.HOME + - "/Applications/TrustedQSL/tqsl.app/Contents/MacOS/tqsl"; - if (fs.existsSync(base)) - { - g_trustedQslSettings.binaryFile = base; - g_trustedQslSettings.binaryFileValid = true; - } - else - { - base = - process.env.HOME + "/Applications/tqsl.app/Contents/MacOS/tqsl"; - if (fs.existsSync(base)) - { - g_trustedQslSettings.binaryFile = base; - g_trustedQslSettings.binaryFileValid = true; - } - else - { - base = "/Applications/tqsl.app/Contents/MacOS/tqsl"; - if (fs.existsSync(base)) - { - g_trustedQslSettings.binaryFile = base; - g_trustedQslSettings.binaryFileValid = true; - } - else - { - base = - process.env.HOME + - "/Desktop/TrustedQSL/tqsl.app/Contents/MacOS/tqsl"; - if (fs.existsSync(base)) - { - g_trustedQslSettings.binaryFile = base; - g_trustedQslSettings.binaryFileValid = true; - } - else - { - base = - process.env.HOME + - "/Applications/Ham Radio/tqsl.app/Contents/MacOS/tqsl"; - if (fs.existsSync(base)) - { - g_trustedQslSettings.binaryFile = base; - g_trustedQslSettings.binaryFileValid = true; - } - } - } - } - } - } - } - else if (g_platform == "linux") - { - base = "/usr/bin/tqsl"; - if (fs.existsSync(base)) - { - g_trustedQslSettings.binaryFile = base; - g_trustedQslSettings.binaryFileValid = true; - } - else - { - base = "/usr/local/bin/tqsl"; - if (fs.existsSync(base)) - { - g_trustedQslSettings.binaryFile = base; - g_trustedQslSettings.binaryFileValid = true; - } - } - } - } - localStorage.trustedQslSettings = JSON.stringify(g_trustedQslSettings); -} - -function startupAdifLoadFunction() -{ - var fs = require("fs"); - - for (var i in g_startupLogs) - { - try - { - if (fs.existsSync(g_startupLogs[i].file)) - { - var rawAdiBuffer = fs.readFileSync(g_startupLogs[i].file); - g_fromDirectCallNoFileDialog = true; - onAdiLoadComplete(rawAdiBuffer, false); - } - } - catch (e) {} - } -} - -function setAdifStartup(checkbox) -{ - if (g_trustedQslSettings.binaryFile == null) - { g_trustedQslSettings.binaryFile = ""; } - - if ( - g_trustedQslSettings.binaryFile.endsWith("tqsl.exe") || - g_trustedQslSettings.binaryFile.endsWith("tqsl") - ) - { - g_trustedQslSettings.binaryFileValid = true; - } - else g_trustedQslSettings.binaryFileValid = false; - - if (g_trustedQslSettings.binaryFileValid == true) - { - tqslFileDiv.style.backgroundColor = "blue"; - } - else - { - tqslFileDiv.style.backgroundColor = "red"; - } - tqslFileDiv.innerHTML = - "" + start_and_end(g_trustedQslSettings.binaryFile) + ""; - - if (buttonAdifCheckBox.checked || loadAdifCheckBox.checked) - { - var worker = ""; - if (g_startupLogs.length > 0) - { - worker += ""; - for (var i in g_startupLogs) - { - worker += - ""; - } - worker += "
" + - g_startupLogs[i].name + - "
"; - } - else - { - worker = "No file(s) selected"; - } - startupLogFileDiv.innerHTML = worker; - selectFileOnStartupDiv.style.display = "block"; - } - else - { - startupLogFileDiv.innerHTML = "No file(s) selected"; - startupFileSelector.setAttribute("type", ""); - startupFileSelector.setAttribute("type", "file"); - startupFileSelector.setAttribute("accept", ".adi*"); - startupFileSelector.value = null; - selectFileOnStartupDiv.style.display = "none"; - } -} - -function removeStartupLog(i) -{ - if (i in g_startupLogs) - { - g_startupLogs.splice(i, 1); - localStorage.startupLogs = JSON.stringify(g_startupLogs); - setAdifStartup(loadAdifCheckBox); - } -} - -function startupAdifLoadCheck() -{ - logEventMedia.value = g_alertSettings.logEventMedia; - - loadWsjtLogFile(); - - if (loadGTCheckBox.checked == true) loadGtQSOLogFile(); - - if (loadAdifCheckBox.checked == true && g_startupLogs.length > 0) - { startupAdifLoadFunction(); } - - if (g_mapSettings.offlineMode == false) - { - if (g_appSettings.gtFlagImgSrc == 1) showGtFlags(); - - if (loadLOTWCheckBox.checked == true) grabLOtWLog(false); - - if (loadQRZCheckBox.checked == true) grabQrzComLog(false); - - if (loadClubCheckBox.checked == true) grabClubLog(false); - - if (loadPsk24CheckBox.checked == true) grabPsk24(); - } -} - -function getABuffer( - file_url, - callback, - flag, - mode, - port, - imgToGray, - stringOfFlag, - timeoutX -) -{ - let url = require("url"); - let http = require(mode); - let fileBuffer = null; - let options = null; - - options = { - host: url.parse(file_url).host, // eslint-disable-line node/no-deprecated-api - port: port, - path: url.parse(file_url).path, // eslint-disable-line node/no-deprecated-api - method: "get" - }; - - if (typeof stringOfFlag != "undefined") window[stringOfFlag] = true; - if (typeof imgToGray != "undefined") - { - imgToGray.parentNode.style.background = - "linear-gradient(grey 0%, black 0% 100% )"; - imgToGray.style.webkitFilter = "invert(100%) grayscale(1)"; - } - - let req = http.request(options, function (res) - { - let fsize = res.headers["content-length"]; - let cookies = null; - if (typeof res.headers["set-cookie"] != "undefined") - { cookies = res.headers["set-cookie"]; } - - res - .on("data", function (data) - { - if (fileBuffer == null) fileBuffer = data; - else fileBuffer += data; - - if (typeof imgToGray != "undefined") - { - let percent = 0; - if (fsize > 0) percent = parseInt((fileBuffer.length / fsize) * 100); - else percent = parseInt(((fileBuffer.length / 100000) * 100) % 100); - imgToGray.parentNode.style.background = - "linear-gradient(grey " + - percent + - "%, black " + - Number(percent + 10) + - "% 100% )"; - } - }) - .on("end", function () - { - if (typeof callback === "function") - { - // Call it, since we have confirmed it is callable - callback(fileBuffer, flag, cookies); - } - if (typeof stringOfFlag != "undefined") - { - window[stringOfFlag] = false; - } - if (typeof imgToGray != "undefined") - { - imgToGray.parentNode.style.background = ""; - imgToGray.style.webkitFilter = ""; - } - }) - .on("error", function () - { - if (typeof stringOfFlag != "undefined") - { - window[stringOfFlag] = false; - } - if (typeof imgToGray != "undefined") - { - imgToGray.parentNode.style.background = ""; - imgToGray.style.webkitFilter = ""; - } - }); - }); - - req.on("socket", function (socket) - { - socket.on("timeout", function () - { - req.abort(); - }); - }); - - req.on("error", function () - { - if (typeof stringOfFlag != "undefined") - { - window[stringOfFlag] = false; - } - if (typeof imgToGray != "undefined") - { - imgToGray.parentNode.style.background = ""; - imgToGray.style.webkitFilter = ""; - } - }); - - req.end(); -} - -function getAPostBuffer( - file_url, - callback, - flag, - mode, - port, - theData, - imgToGray, - stringOfFlag -) -{ - var querystring = require("querystring"); - var postData = querystring.stringify(theData); - var url = require("url"); - var http = require(mode); - var fileBuffer = null; - - var options = { - host: url.parse(file_url).host, // eslint-disable-line node/no-deprecated-api - port: port, - path: url.parse(file_url).path, // eslint-disable-line node/no-deprecated-api - method: "post", - headers: { - "Content-Type": "application/x-www-form-urlencoded", - "Content-Length": postData.length - } - }; - - window[stringOfFlag] = true; - - if (typeof imgToGray != "undefined") - { - imgToGray.parentNode.style.background = - "linear-gradient(grey 0%, black 0% 100% )"; - imgToGray.style.webkitFilter = "invert(100%) grayscale(1)"; - } - - var req = http.request(options, function (res) - { - var fsize = res.headers["content-length"]; - var cookies = null; - if (typeof res.headers["set-cookie"] != "undefined") - { cookies = res.headers["set-cookie"]; } - - res - .on("data", function (data) - { - if (fileBuffer == null) fileBuffer = data; - else fileBuffer += data; - - if (typeof imgToGray != "undefined") - { - var percent = 0; - if (fsize > 0) percent = parseInt((fileBuffer.length / fsize) * 100); - else percent = parseInt(((fileBuffer.length / 100000) * 100) % 100); - - imgToGray.parentNode.style.background = - "linear-gradient(grey " + - percent + - "%, black " + - Number(percent + 10) + - "% 100% )"; - } - }) - .on("end", function () - { - if (typeof callback === "function") - { - // Call it, since we have confirmed it is callable - callback(fileBuffer, flag, cookies); - window[stringOfFlag] = false; - if (typeof imgToGray != "undefined") - { - imgToGray.parentNode.style.background = ""; - imgToGray.style.webkitFilter = ""; - } - } - }) - .on("error", function () - { - window[stringOfFlag] = false; - if (typeof imgToGray != "undefined") - { - imgToGray.parentNode.style.background = ""; - imgToGray.style.webkitFilter = ""; - } - }); - }); - - req.on("socket", function (socket) - { - socket.on("timeout", function () - { - req.abort(); - }); - }); - - req.on("error", function (err) // eslint-disable-line node/handle-callback-err - { - window[stringOfFlag] = false; - if (typeof imgToGray != "undefined") - { - imgToGray.parentNode.style.background = ""; - imgToGray.style.webkitFilter = ""; - } - }); - - req.write(postData); - req.end(); -} - -function sendUdpMessage(msg, length, port, address) -{ - var dgram = require("dgram"); - var socket = dgram.createSocket({ type: "udp4", reuseAddr: true }); - socket.send(msg, 0, length, port, address, (err) => // eslint-disable-line node/handle-callback-err - { - socket.close(); - }); -} - -function sendTcpMessage(msg, length, port, address) -{ - var net = require("net"); - var client = new net.Socket(); - client.setTimeout(30000); - client.connect(port, address, function () - { - client.write(msg); - }); - - client.on("close", function () {}); -} - -function valueToAdiField(field, value) -{ - var adi = "<" + field + ":"; - adi += String(value).length + ">"; - adi += String(value) + " "; - return adi; -} - -function pad(value) -{ - if (value < 10) - { - return "0" + value; - } - else - { - return value; - } -} - -function HMSfromMilli(milli) -{ - var seconds = parseInt(milli / 1000); - var days = Math.floor(seconds / (3600 * 24)); - seconds -= days * 3600 * 24; - var hrs = Math.floor(seconds / 3600); - seconds -= hrs * 3600; - var mnts = Math.floor(seconds / 60); - seconds -= mnts * 60; - - val = String(pad(hrs)) + String(pad(mnts)) + String(pad(seconds)); - return String(val); -} - -function colonHMSfromMilli(milli) -{ - var seconds = parseInt(milli / 1000); - var days = Math.floor(seconds / (3600 * 24)); - seconds -= days * 3600 * 24; - var hrs = Math.floor(seconds / 3600); - seconds -= hrs * 3600; - var mnts = Math.floor(seconds / 60); - seconds -= mnts * 60; - - val = String(pad(hrs)) + ":" + String(pad(mnts)) + ":" + String(pad(seconds)); - return String(val); -} - -function colonHMSfromSeconds(secondsIn) -{ - var seconds = secondsIn; - var days = Math.floor(seconds / (3600 * 24)); - seconds -= days * 3600 * 24; - var hrs = Math.floor(seconds / 3600); - seconds -= hrs * 3600; - var mnts = Math.floor(seconds / 60); - seconds -= mnts * 60; - - val = String(pad(hrs)) + ":" + String(pad(mnts)) + ":" + String(pad(seconds)); - return String(val); -} - -function convertToDate(julian) -{ - var DAY = 86400000; - var HALF_DAY = DAY / 2; - var UNIX_EPOCH_JULIAN_DATE = 2440587.5; - var UNIX_EPOCH_JULIAN_DAY = 2440587; - return new Date((Number(julian) - UNIX_EPOCH_JULIAN_DATE) * DAY); -} - -var CLk = "25bc718451a71954cb6d0d1b50541dd45d4ba148"; - -var lastReportHash = null; - -var g_oldStyleLogMessage = null; - -function oldSendToLogger() -{ - var newMessage = Object.assign({}, g_oldStyleLogMessage); - - var band = Number(newMessage.Frequency / 1000000).formatBand(); - - if ( - newMessage.DXGrid.length == 0 && - newMessage.DXCall + band + newMessage.MO in g_liveCallsigns - ) - { - newMessage.DXGrid = g_liveCallsigns[ - newMessage.DXCall + band + newMessage.MO - ].grid.substr(0, 4); - } - - var report = ""; - - report += valueToAdiField( - "BAND", - Number(newMessage.Frequency / 1000000).formatBand() - ); - report += valueToAdiField("CALL", newMessage.DXCall.toUpperCase()); - report += valueToAdiField( - "FREQ", - Number(newMessage.Frequency / 1000000).toFixed(6) - ); - report += valueToAdiField("MODE", newMessage.MO.toUpperCase()); - var date = convertToDate(parseInt(newMessage.DateOn)); - var dataString = - date.getUTCFullYear() + - ("0" + (date.getUTCMonth() + 1)).slice(-2) + - ("0" + date.getUTCDate()).slice(-2); - report += valueToAdiField("QSO_DATE", dataString); - report += valueToAdiField("TIME_ON", HMSfromMilli(newMessage.TimeOn)); - - date = convertToDate(parseInt(newMessage.DateOff)); - dataString = - date.getUTCFullYear() + - ("0" + (date.getUTCMonth() + 1)).slice(-2) + - ("0" + date.getUTCDate()).slice(-2); - report += valueToAdiField("QSO_DATE_OFF", dataString); - report += valueToAdiField("TIME_OFF", HMSfromMilli(newMessage.TimeOff)); - - report += valueToAdiField("RST_RCVD", newMessage.ReportRecieved); - report += valueToAdiField("RST_SENT", newMessage.ReportSend); - report += valueToAdiField("TX_PWR", parseInt(newMessage.TXPower)); - report += valueToAdiField("GRIDSQUARE", newMessage.DXGrid); - - if (newMessage.Comments.length > 0) - { report += valueToAdiField("COMMENT", newMessage.Comments); } - - if (newMessage.Name.length > 0) - { report += valueToAdiField("NAME", newMessage.Name); } - - if (newMessage.Operatorcall.length > 0) - { - report += valueToAdiField("OPERATOR", newMessage.Operatorcall); - } - - if (newMessage.Mycall.length > 0) - { - report += valueToAdiField("STATION_CALLSIGN", newMessage.Mycall); - } - else if (myDEcall != "NOCALL" && myDEcall.length > 0) - { report += valueToAdiField("STATION_CALLSIGN", myDEcall); } - - if (newMessage.Mygrid.length > 0) - { - report += valueToAdiField("MY_GRIDSQUARE", newMessage.Mygrid); - } - else if (myDEGrid.length > 1) - { report += valueToAdiField("MY_GRIDSQUARE", myDEGrid); } - - report += ""; - - sendToLogger(report); -} - -var g_adifLookupMap = { - name: "NAME", - iota: "IOTA", - sota: "SOTA_REF", - continent: "CONT", - cqzone: "CQZ", - ituzone: "ITUZ", - email: "EMAIL", - county: "CNTY" -}; - -function sendToLogger(ADIF) -{ - let regex = new RegExp("", "i"); - let record = parseADIFRecord(ADIF.split(regex)[1]); - let localMode = record.MODE; - - if (localMode == "MFSK" && "SUBMODE" in record) - { - localMode = record.SUBMODE; - } - - if ( - (!("GRIDSQUARE" in record) || record.GRIDSQUARE.length == 0) && - record.CALL + record.BAND + localMode in g_liveCallsigns - ) - { - record.GRIDSQUARE = g_liveCallsigns[ - record.CALL + record.BAND + localMode - ].grid.substr(0, 4); - } - - if ("TX_PWR" in record) - { - record.TX_PWR = String(parseInt(record.TX_PWR)); - } - - if ( - (!("STATION_CALLSIGN" in record) || - record.STATION_CALLSIGN.length == 0) && - myDEcall != "NOCALL" && - myDEcall.length > 0 - ) - { - record.STATION_CALLSIGN = myDEcall; - } - - if ( - (!("MY_GRIDSQUARE" in record) || record.MY_GRIDSQUARE.length == 0) && - myDEGrid.length > 1 - ) - { - record.MY_GRIDSQUARE = myDEGrid; - } - - if (!("DXCC" in record)) - { - let dxcc = callsignToDxcc(record.CALL); - if (dxcc == -1) dxcc = 0; - record.DXCC = String(dxcc); - } - - // Tag: This is going to bite us in the butt later, but leaving it alone. - if (!("COUNTRY" in record) && Number(record.DXCC) > 0) - { - record.COUNTRY = g_dxccToADIFName[Number(record.DXCC)]; - } - - if (g_appSettings.lookupMerge == true) - { - let request = g_Idb - .transaction(["lookups"], "readwrite") - .objectStore("lookups") - .get(record.CALL); - - request.onsuccess = function (event) - { - if (request.result) - { - let lookup = request.result; - for (let key in lookup) - { - if (key in g_adifLookupMap) - { - record[g_adifLookupMap[key]] = lookup[key]; - } - } - if ("GRIDSQUARE" in record && "grid" in lookup) - { - if ( - record.GRIDSQUARE.substr(0, 4) == lookup.grid.substr(0, 4) - ) - { - record.GRIDSQUARE = lookup.grid; - } - } - if ( - g_appSettings.lookupMissingGrid && - "grid" in lookup && - (!("GRIDSQUARE" in record) || record.GRIDSQUARE.length == 0) - ) - { - record.GRIDSQUARE = lookup.grid; - } - } - finishSendingReport(record, localMode); - }; - - request.onerror = function (event) - { - finishSendingReport(record, localMode); - }; - } - else - { - finishSendingReport(record, localMode); - } -} - -function finishSendingReport(record, localMode) -{ - let report = ""; - - let reportHash = record.CALL + record.MODE + localMode; - - for (let key in record) - { - report += "<" + key + ":" + record[key].length + ">" + record[key] + " "; - } - report += ""; - - if (reportHash != lastReportHash) - { - lastReportHash = reportHash; - - if ( - g_N1MMSettings.enable == true && - g_N1MMSettings.port > 1024 && - g_N1MMSettings.ip.length > 4 - ) - { - sendUdpMessage( - report, - report.length, - parseInt(g_N1MMSettings.port), - g_N1MMSettings.ip - ); - addLastTraffic("Logged to N1MM"); - } - - if ( - g_log4OMSettings.enable == true && - g_log4OMSettings.port > 1024 && - g_log4OMSettings.ip.length > 4 - ) - { - sendUdpMessage( - "ADD " + report, - report.length + 4, - parseInt(g_log4OMSettings.port), - g_log4OMSettings.ip - ); - addLastTraffic("Logged to Log4OM"); - } - - try - { - onAdiLoadComplete("GT" + report); - } - catch (e) - { - addLastTraffic("Exception Internal Log"); - } - try - { - // Log worthy - if (logGTqsoCheckBox.checked == true) - { - var fs = require("fs"); - fs.appendFileSync(g_qsoLogFile, report + "\r\n"); - addLastTraffic( - "Logged to GridTracker backup" - ); - } - } - catch (e) - { - addLastTraffic( - "Exception GridTracker backup" - ); - } - - try - { - sendQrzLogEntry(report); - } - catch (e) - { - addLastTraffic("Exception QRZ Log"); - } - - try - { - sendClubLogEntry(report); - } - catch (e) - { - addLastTraffic("Exception ClubLog Log"); - } - - try - { - sendHrdLogEntry(report); - } - catch (e) - { - addLastTraffic("Exception HrdLog.net Log"); - } - - try - { - sendCloudlogEntry(report); - } - catch (e) - { - addLastTraffic("Exception Cloudlog Log"); - } - - if ( - g_acLogSettings.enable == true && - g_acLogSettings.port > 0 && - g_acLogSettings.ip.length > 4 - ) - { - try - { - sendACLogMessage(record, g_acLogSettings.port, g_acLogSettings.ip); - addLastTraffic("Logged to N3FJP"); - } - catch (e) - { - addLastTraffic("Exception N3FJP Log"); - } - } - - if ( - g_dxkLogSettings.enable == true && - g_dxkLogSettings.port > 0 && - g_dxkLogSettings.ip.length > 4 - ) - { - try - { - sendDXKeeperLogMessage( - report, - g_dxkLogSettings.port, - g_dxkLogSettings.ip - ); - addLastTraffic("Logged to DXKeeper"); - } - catch (e) - { - addLastTraffic("Exception DXKeeper Log"); - } - } - - if ( - g_HRDLogbookLogSettings.enable == true && - g_HRDLogbookLogSettings.port > 0 && - g_HRDLogbookLogSettings.ip.length > 4 - ) - { - try - { - sendHRDLogbookEntry( - record, - g_HRDLogbookLogSettings.port, - g_HRDLogbookLogSettings.ip - ); - addLastTraffic( - "Logged to HRD Logbook" - ); - } - catch (e) - { - addLastTraffic("Exception HRD Log"); - } - } - - try - { - sendLotwLogEntry(report); - } - catch (e) - { - addLastTraffic("Exception LoTW Log"); - } - - if ( - logeQSLQSOCheckBox.checked == true && - nicknameeQSLCheckBox.checked == true && - eQSLNickname.value.trim().length > 0 - ) - { - record.APP_EQSL_QTH_NICKNAME = eQSLNickname.value.trim(); - report = ""; - for (var key in record) - { - report += - "<" + key + ":" + record[key].length + ">" + record[key] + " "; - } - report += ""; - } - - try - { - sendeQSLEntry(report); - } - catch (e) - { - addLastTraffic("Exception LoTW Log"); - } - - try - { - alertLogMessage(); - } - catch (e) - { - addLastTraffic("Exception Alert Log"); - } - - if (lookupCloseLog.checked == true) - { - try - { - openLookupWindow(false); - } - catch (e) - { - addLastTraffic("Exception Hide Lookup"); - } - } - } - - return report; -} - -function alertLogMessage() -{ - if (logEventMedia.value != "none") - { - playAlertMediaFile(logEventMedia.value); - } -} - -function eqslCallback(buffer, flag) -{ - var result = String(buffer); - if (flag) - { - if (result.indexOf("No such Username/Password found") != -1) - { - eQSLTestResult.innerHTML = "Bad
Password
or
Nickname"; - logeQSLQSOCheckBox.checked = false; - adifLogQsoCheckBoxChanged(logeQSLQSOCheckBox); - } - else if (result.indexOf("No such Callsign found") != -1) - { - eQSLTestResult.innerHTML = "Unknown
Callsign"; - logeQSLQSOCheckBox.checked = false; - adifLogQsoCheckBoxChanged(logeQSLQSOCheckBox); - } - else if (result.indexOf("Your ADIF log file has been built") > -1 || result.indexOf("You have no log entries") > -1) - { - eQSLTestResult.innerHTML = "Passed"; - } - else if (result.indexOf("specify the desired User by using the QTHNickname") != -1) - { - eQSLTestResult.innerHTML = "QTH Nickname
Needed"; - } - else - { - eQSLTestResult.innerHTML = "Unknown
Error"; - logeQSLQSOCheckBox.checked = false; - adifLogQsoCheckBoxChanged(logeQSLQSOCheckBox); - } - } - else - { - if (result.indexOf("Error: No match on eQSL_User/eQSL_Pswd") != -1) - { - addLastTraffic( - "Fail log eQSL.cc (credentials)" - ); - } - if ( - result.indexOf("specify the desired User by using the QTHNickname") != -1 - ) - { - addLastTraffic( - "Fail log eQSL.cc (nickname)" - ); - } - else if (result.indexOf("Result: 0 out of 1 records") != -1) - { - addLastTraffic("Fail log eQSL.cc (dupe)"); - } - else if (result.indexOf("Result: 1 out of 1 records added") != -1) - { - addLastTraffic("Logged to eQSL.cc"); - } - else - { - addLastTraffic("Fail log eQSL.cc (?)"); - } - } -} - -function eQSLTest(test) -{ - if (g_mapSettings.offlineMode == true) return; - - eQSLTestResult.innerHTML = "Testing"; - - var fUrl = - "https://www.eQSL.cc/qslcard/DownloadInBox.cfm?UserName=" + - encodeURIComponent(eQSLUser.value) + - "&Password=" + - encodeURIComponent(eQSLPassword.value) + - "&RcvdSince=2020101"; - - if (nicknameeQSLCheckBox.checked == true) - { fUrl += "&QTHNickname=" + encodeURIComponent(eQSLNickname.value); } - getABuffer(fUrl, eqslCallback, true, "https", 443); -} - -function sendeQSLEntry(report) -{ - if (g_mapSettings.offlineMode == true) return; - - if (logeQSLQSOCheckBox.checked == true) - { - var pid = "GridTracker"; - var pver = String(gtVersion); - var header = "" + pid + "\r\n"; - header += "" + pver + "\r\n"; - header += "\r\n"; - var eReport = encodeURIComponent(header + report); - var fUrl = - "https://www.eQSL.cc/qslcard/importADIF.cfm?ADIFData=" + - eReport + - "&EQSL_USER=" + - encodeURIComponent(eQSLUser.value) + - "&EQSL_PSWD=" + - encodeURIComponent(eQSLPassword.value); - getABuffer(fUrl, eqslCallback, false, "https", 443); - } -} - -function testTrustedQSL(test) -{ - if (g_mapSettings.offlineMode == true) - { - lotwTestResult.innerHTML = "Currently
offline"; - return; - } - - if ( - logLOTWqsoCheckBox.checked == true && - g_trustedQslSettings.binaryFileValid == true && - g_trustedQslSettings.stationFileValid == true && - lotwStation.value.length > 0 - ) - { - lotwTestResult.innerHTML = "Testing Upload"; - - var child_process = require("child_process"); - var options = Array(); - options.push("-q"); - options.push("-v"); - - child_process.execFile( - g_trustedQslSettings.binaryFile, - options, - (error, stdout, stderr) => - { - if (error) - { - lotwTestResult.innerHTML = "Error encountered"; - } - lotwTestResult.innerHTML = stderr; - } - ); - } - else - { - var worker = ""; - if (g_trustedQslSettings.binaryFileValid == false) - { worker += "Invalid tqsl executable
"; } - if (g_trustedQslSettings.stationFileValid == false) - { worker += "TrustQSL not installed
"; } - if (!ValidateText(lotwTrusted)) worker += "TQSL Password missing
"; - if (!ValidateText(lotwStation)) worker += "Select Station
"; - lotwTestResult.innerHTML = worker; - } -} -var g_trustTempPath = ""; - -function sendLotwLogEntry(report) -{ - if (g_mapSettings.offlineMode == true) return; - - if ( - logLOTWqsoCheckBox.checked == true && - g_trustedQslSettings.binaryFileValid == true && - g_trustedQslSettings.stationFileValid == true && - lotwStation.value.length > 0 - ) - { - var header = - "Generated " + userTimeString(null) + " for " + myDEcall + "\r\n\r\n"; - var pid = "GridTracker"; - var pver = String(gtVersion); - header += "" + pid + "\r\n"; - header += "" + pver + "\r\n"; - header += "\r\n"; - var finalLog = header + report + "\r\n"; - - g_trustTempPath = os.tmpdir() + g_dirSeperator + unique(report) + ".adif"; - fs.writeFileSync(g_trustTempPath, finalLog); - - var child_process = require("child_process"); - var options = Array(); - options.push("-a"); - options.push("all"); - options.push("-l"); - options.push(lotwStation.value); - if (lotwTrusted.value.length > 0) - { - options.push("-p"); - options.push(lotwTrusted.value); - } - options.push("-q"); - options.push("-x"); - options.push("-d"); - options.push("-u"); - options.push(g_trustTempPath); - - child_process.execFile( - g_trustedQslSettings.binaryFile, - options, - (error, stdout, stderr) => // eslint-disable-line node/handle-callback-err - { - if (stderr.indexOf("Final Status: Success") < 0) - { - alert(stderr); - addLastTraffic("Fail log to TQSL"); - } - else - { - addLastTraffic("Logged to TQSL"); - } - fs.unlinkSync(g_trustTempPath); - } - ); - } -} - -function n1mmLoggerChanged() -{ - g_N1MMSettings.enable = buttonN1MMCheckBox.checked; - g_N1MMSettings.ip = N1MMIpInput.value; - g_N1MMSettings.port = N1MMPortInput.value; - - localStorage.N1MMSettings = JSON.stringify(g_N1MMSettings); -} - -function log4OMLoggerChanged() -{ - g_log4OMSettings.enable = buttonLog4OMCheckBox.checked; - g_log4OMSettings.ip = log4OMIpInput.value; - g_log4OMSettings.port = log4OMPortInput.value; - - localStorage.log4OMSettings = JSON.stringify(g_log4OMSettings); -} - -function acLogLoggerChanged() -{ - g_acLogSettings.enable = buttonacLogCheckBox.checked; - g_acLogSettings.ip = acLogIpInput.value; - g_acLogSettings.port = acLogPortInput.value; - - localStorage.acLogSettings = JSON.stringify(g_acLogSettings); -} - -function dxkLogLoggerChanged() -{ - g_dxkLogSettings.enable = buttondxkLogCheckBox.checked; - g_dxkLogSettings.ip = dxkLogIpInput.value; - g_dxkLogSettings.port = dxkLogPortInput.value; - - localStorage.dxkLogSettings = JSON.stringify(g_dxkLogSettings); -} - -function hrdLogbookLoggerChanged() -{ - g_HRDLogbookLogSettings.enable = buttonHrdLogbookCheckBox.checked; - g_HRDLogbookLogSettings.ip = hrdLogbookIpInput.value; - g_HRDLogbookLogSettings.port = hrdLogbookPortInput.value; - - localStorage.HRDLogbookLogSettings = JSON.stringify(g_HRDLogbookLogSettings); -} - -function CloudUrlErrorCallback( - file_url, - callback, - flag, - mode, - port, - theData, - timeoutMs, - timeoutCallback, - message -) -{ - CloudlogTestResult.innerHTML = message; -} - -function CloudlogSendLogResult(buffer, flag) -{ - if (flag && flag == true) - { - if (buffer) - { - if (buffer.indexOf("missing api key") > -1) - { - CloudlogTestResult.innerHTML = "API Key Invalid"; - } - else if (buffer.indexOf("created") > -1) - { - CloudlogTestResult.innerHTML = "Passed"; - } - else - { - CloudlogTestResult.innerHTML = "Invalid Response"; - } - } - else - { - CloudlogTestResult.innerHTML = "Invalid Response"; - } - } - else - { - if (buffer && buffer.indexOf("created") > -1) - { addLastTraffic("Logged to Cloudlog"); } - else addLastTraffic("Fail log to Cloudlog"); - } -} - -function qrzSendLogResult(buffer, flag) -{ - if (typeof buffer != "undefined" && buffer != null) - { - var data = String(buffer); - var kv = data.split("&"); - if (kv.length > 0) - { - var arrData = Object(); - for (var x in kv) - { - var split = kv[x].split("="); - arrData[split[0]] = split[1]; - } - if ( - typeof arrData.RESULT == "undefined" || - arrData.RESULT != "OK" - ) - { - alert( - "Error uploading QSO to QRZ.com (" + - (arrData.REASON || "Unknown error") + - ")" - ); - addLastTraffic("Fail log to QRZ.com"); - } - else - { addLastTraffic("Logged to QRZ.com"); } - } - } - else alert("Error uploading QSO to QRZ.com (No response)"); -} - -function postDialogRetryCallback( - file_url, - callback, - flag, - mode, - port, - theData, - timeoutMs, - timeoutCallback, - who -) -{ - if (window.confirm("Error sending QSO to " + who + ", retry?")) - { - getPostBuffer( - file_url, - callback, - flag, - mode, - port, - theData, - timeoutMs, - postDialogRetryCallback, - who - ); - } -} - -function postRetryErrorCallaback( - file_url, - callback, - flag, - mode, - port, - theData, - timeoutMs, - timeoutCallback, - who -) -{ - getPostBuffer( - file_url, - callback, - flag, - mode, - port, - theData, - timeoutMs, - postDialogRetryCallback, - who - ); -} - -function sendQrzLogEntry(report) -{ - if (g_mapSettings.offlineMode == true) return; - - if (logQRZqsoCheckBox.checked == true && ValidateQrzApi(qrzApiKey)) - { - if (typeof nw != "undefined") - { - var postData = { - KEY: qrzApiKey.value, - ACTION: "INSERT", - ADIF: report - }; - getPostBuffer( - "https://logbook.qrz.com/api", - qrzSendLogResult, - null, - "https", - 443, - postData, - 30000, - postRetryErrorCallaback, - "QRZ.com" - ); - } - } -} - -function clubLogQsoResult(buffer, flag) -{ - addLastTraffic("Logged to ClubLog.org"); -} - -function sendClubLogEntry(report) -{ - if (g_mapSettings.offlineMode == true) return; - - if (logClubqsoCheckBox.checked == true) - { - if (typeof nw != "undefined") - { - var postData = { - email: clubEmail.value, - password: clubPassword.value, - callsign: clubCall.value, - adif: report, - api: CLk - }; - - getPostBuffer( - "https://clublog.org/realtime.php", - clubLogQsoResult, - null, - "https", - 443, - postData, - 30000, - postRetryErrorCallaback, - "ClubLog.org" - ); - } - } -} - -function sendCloudlogEntry(report) -{ - if (g_mapSettings.offlineMode == true) return; - - if (logCloudlogQSOCheckBox.checked == true) - { - if (typeof nw != "undefined") - { - var postData = { key: CloudlogAPI.value, type: "adif", string: report }; - getPostJSONBuffer( - CloudlogURL.value, - CloudlogSendLogResult, - null, - "https", - 80, - postData, - 10000, - CloudUrlErrorCallback, - "Failed to Send" - ); - } - } -} - -function hrdSendLogResult(buffer, flag) -{ - if (flag && flag == true) - { - if (buffer.indexOf("Unknown user") > -1) - { - HRDLogTestResult.innerHTML = "Failed"; - logHRDLOGqsoCheckBox.checked = false; - adifLogQsoCheckBoxChanged(logHRDLOGqsoCheckBox); - } - else HRDLogTestResult.innerHTML = "Passed"; - } - else - { - if (buffer.indexOf("Unknown user") == -1) - { addLastTraffic("Logged to HRDLOG.net"); } - else - { addLastTraffic("Fail log to HRDLOG.net"); } - } -} - -function sendHrdLogEntry(report) -{ - if (g_mapSettings.offlineMode == true) return; - - if (logHRDLOGqsoCheckBox.checked == true) - { - if (typeof nw != "undefined") - { - var postData = { - Callsign: HRDLOGCallsign.value, - Code: HRDLOGUploadCode.value, - App: "GridTracker " + gtVersion, - ADIFData: report - }; - getPostBuffer( - "https://www.hrdlog.net/NewEntry.aspx", - hrdSendLogResult, - null, - "https", - 443, - postData, - 30000, - postRetryErrorCallaback, - "HRDLog.net" - ); - } - } -} - -function hrdCredentialTest(test) -{ - if (test && test == true) - { - HRDLogTestResult.innerHTML = "Testing"; - - if (typeof nw != "undefined") - { - var postData = { - Callsign: HRDLOGCallsign.value, - Code: HRDLOGUploadCode.value - }; - getPostBuffer( - "https://www.hrdlog.net/NewEntry.aspx", - hrdSendLogResult, - test, - "https", - 443, - postData - ); - } - } -} - -function ClublogTest(test) -{ - if (test && test == true) - { - CloudlogTestResult.innerHTML = "Testing"; - - if (typeof nw != "undefined") - { - var postData = { key: CloudlogAPI.value, type: "adif", string: "" }; - getPostJSONBuffer( - CloudlogURL.value, - CloudlogSendLogResult, - test, - "https", - 80, - postData, - 10000, - CloudUrlErrorCallback, - "No Response
or
Timeout" - ); - } - } -} - -function getPostJSONBuffer( - file_url, - callback, - flag, - mode, - port, - theData, - timeoutMs, - timeoutCallback, - who -) -{ - try - { - var postData = JSON.stringify(theData); - var url = require("url"); - var protocol = url.parse(file_url).protocol; // eslint-disable-line node/no-deprecated-api - var http = require(protocol.replace(":", "")); - var fileBuffer = null; - var options = { - host: url.parse(file_url).hostname, // eslint-disable-line node/no-deprecated-api - port: url.parse(file_url).port, // eslint-disable-line node/no-deprecated-api - path: url.parse(file_url).path, // eslint-disable-line node/no-deprecated-api - method: "post", - headers: { - "Content-Type": "application/json", - "Content-Length": postData.length - } - }; - var req = http.request(options, function (res) - { - var fsize = res.headers["content-length"]; - var cookies = null; - if (typeof res.headers["set-cookie"] != "undefined") - { cookies = res.headers["set-cookie"]; } - res - .on("data", function (data) - { - if (fileBuffer == null) fileBuffer = data; - else fileBuffer += data; - }) - .on("end", function () - { - if (typeof callback === "function") - { - // Call it, since we have confirmed it is callable - callback(fileBuffer, flag, cookies); - } - }) - .on("error", function () {}); - }); - if (typeof timeoutMs == "number" && timeoutMs > 0) - { - req.on("socket", function (socket) - { - socket.setTimeout(timeoutMs); - socket.on("timeout", function () - { - req.abort(); - }); - }); - req.on("error", function (err) // eslint-disable-line node/handle-callback-err - { - if (typeof timeoutCallback != "undefined") - { - timeoutCallback( - file_url, - callback, - flag, - mode, - 80, - theData, - timeoutMs, - timeoutCallback, - who - ); - } - }); - } - req.write(postData); - req.end(); - } - catch (e) - { - if (typeof timeoutCallback != "undefined") - { - timeoutCallback( - file_url, - callback, - flag, - mode, - 80, - theData, - timeoutMs, - timeoutCallback, - "Invalid Url" - ); - } - } -} - -function valueToXmlField(field, value) -{ - var adi = "<" + field + ">"; - adi += String(value); - adi += ""; - return adi; -} - -function aclUpdateControlValue(control, value) -{ - return ( - valueToXmlField( - "CMD", - "" + - valueToXmlField("CONTROL", control) + - valueToXmlField("VALUE", value) - ) + "\r\n" - ); -} - -function aclAction(action) -{ - return ( - valueToXmlField("CMD", "" + valueToXmlField("VALUE", action)) + - "\r\n" - ); -} - -function adifField(record, key) -{ - if (key in record) return record[key]; - else return ""; -} -function sendACLogMessage(record, port, address) -{ - var report = ""; - - report += aclAction("CLEAR"); - report += aclUpdateControlValue("TXTENTRYBAND", adifField(record, "BAND")); - report += aclUpdateControlValue("TXTENTRYCALL", adifField(record, "CALL")); - report += aclAction("CALLTAB"); - report += aclUpdateControlValue( - "TXTENTRYFREQUENCY", - adifField(record, "FREQ") - ); - if (adifField(record, "SUBMODE").length > 0) - { - report += aclUpdateControlValue( - "TXTENTRYMODE", - adifField(record, "SUBMODE") - ); - } - else - { report += aclUpdateControlValue("TXTENTRYMODE", adifField(record, "MODE")); } - - var date = adifField(record, "QSO_DATE"); - var dataString = - date.substr(0, 4) + "/" + date.substr(4, 2) + "/" + date.substr(6); - - report += aclUpdateControlValue("TXTENTRYDATE", dataString); - - var timeVal = adifField(record, "TIME_ON"); - var whenString = - timeVal.substr(0, 2) + - ":" + - timeVal.substr(2, 2) + - ":" + - timeVal.substr(4, 2); - report += aclUpdateControlValue("TXTENTRYTIMEON", whenString); - - timeVal = adifField(record, "TIME_OFF"); - whenString = - timeVal.substr(0, 2) + - ":" + - timeVal.substr(2, 2) + - ":" + - timeVal.substr(4, 2); - report += aclUpdateControlValue("TXTENTRYTIMEOFF", whenString); - - report += aclUpdateControlValue( - "TXTENTRYRSTR", - adifField(record, "RST_RCVD") - ); - report += aclUpdateControlValue( - "TXTENTRYRSTS", - adifField(record, "RST_SENT") - ); - report += aclUpdateControlValue("TXTENTRYPOWER", adifField(record, "TX_PWR")); - report += aclUpdateControlValue( - "TXTENTRYGRID", - adifField(record, "GRIDSQUARE") - ); - report += aclUpdateControlValue( - "TXTENTRYCOMMENTS", - adifField(record, "COMMENT") - ); - report += aclUpdateControlValue("TXTENTRYNAMER", adifField(record, "NAME")); - report += aclUpdateControlValue("TXTENTRYIOTA", adifField(record, "IOTA")); - report += aclUpdateControlValue( - "TXTENTRYCONTINENT", - adifField(record, "CONT") - ); - report += aclUpdateControlValue("TXTENTRYITUZ", adifField(record, "ITUZ")); - report += aclUpdateControlValue("TXTENTRYCQZONE", adifField(record, "CQZ")); - report += aclUpdateControlValue("TXTENTRYCOUNTYR", adifField(record, "CNTY")); - - var sentSpcNum = false; - if (adifField(record, "SRX").length > 0) - { - report += aclUpdateControlValue( - "TXTENTRYSERIALNOR", - adifField(record, "SRX") - ); - } - else if (adifField(record, "CONTEST_ID").length > 0) - { - report += aclUpdateControlValue( - "TXTENTRYSPCNUM", - adifField(record, "SRX_STRING") - ); - sentSpcNum = true; - report += aclUpdateControlValue( - "TXTENTRYCLASS", - adifField(record, "CLASS") - ); - report += aclUpdateControlValue( - "TXTENTRYSECTION", - adifField(record, "ARRL_SECT") - ); - } - - if (adifField(record, "STATE").length > 0) - { - report += aclUpdateControlValue( - "TXTENTRYSTATE", - adifField(record, "STATE") - ); - if (sentSpcNum == false) - { - report += aclUpdateControlValue( - "TXTENTRYSPCNUM", - adifField(record, "STATE") - ); - } - } - - report += aclAction("ENTER"); - - sendTcpMessage(report, report.length, port, address); -} - -function sendDXKeeperLogMessage(newMessage, port, address) -{ - var report = ""; - - report += valueToAdiField("command", "log"); - report += valueToAdiField("parameters", newMessage); - report += "\r\n"; - - sendTcpMessage(report, report.length, Number(port) + 1, address); -} - -function parseADIFRecord(adif) -{ - var regex = new RegExp("", "i"); - var newLine = adif.split(regex); - var line = newLine[0].trim(); // Catch the naughty case of someone sending two records at the same time - var record = {}; - - // because strings are not escaped for adif.. ie: :'s and <'s .. we have to walk from left to right - // cheesy, but damn i'm tired of parsing things - var x = 0; - while (line.length > 0) - { - while (line.charAt(0) != "<" && line.length > 0) - { - line = line.substr(1); - } - if (line.length > 0) - { - line = line.substr(1); - var where = line.indexOf(":"); - if (where != -1) - { - var fieldName = line.substr(0, where).toUpperCase(); - line = line.substr(fieldName.length + 1); - var fieldLength = parseInt(line); - var end = line.indexOf(">"); - if (end > 0) - { - line = line.substr(end + 1); - var fieldValue = line.substr(0, fieldLength); - line = line.substr(fieldLength); - record[fieldName] = fieldValue; - } - } - } - } - - return record; -} - -function sendHRDLogbookEntry(report, port, address) -{ - var command = "ver\rdb add {"; - var items = Object.assign({}, report); - - items.FREQ = items.FREQ.split(".").join(""); - - for (var item in items) - { - command += item + "=\"" + items[item] + "\" "; - } - - command += "}\rexit\r"; - - sendTcpMessage(command, command.length, Number(port), address); -} +// GridTracker Copyright © 2021 GridTracker.org +// All rights reserved. +// See LICENSE for more information. + +var selectStartupLink = null; + +function dragOverHandler(ev) +{ + // Prevent default behavior (Prevent file from being opened) + ev.preventDefault(); +} + +function dropHandler(ev) +{ + // Prevent default behavior (Prevent file from being opened) + ev.preventDefault(); + if (ev.dataTransfer.items) + { + // Use DataTransferItemList interface to access the file(s) + for (var i = 0; i < ev.dataTransfer.items.length; i++) + { + // If dropped items aren't files, reject them + Entry = ev.dataTransfer.items[i].webkitGetAsEntry(); + if (Entry && typeof Entry.isFile != "undefined" && Entry.isFile == true) + { + var filename = ev.dataTransfer.items[i].getAsFile().path; + var test = filename.toLowerCase(); + var valid = test.endsWith(".adi") + ? true + : test.endsWith(".adif") + ? true + : test.endsWith(".log") + ? true + : !!test.endsWith(".txt"); + if (valid && fs.existsSync(filename)) + { + onAdiLoadComplete(fs.readFileSync(filename, "UTF-8"), false); + } + } + } + } +} + +function findAdiField(row, field) +{ + var value = ""; + var regex = new RegExp("<" + field + ":", "i"); + var firstSplitArray = row.split(regex); + if (firstSplitArray && firstSplitArray.length == 2) + { + var secondSplitArray = firstSplitArray[1].split(">"); + if (secondSplitArray.length > 1) + { + var newLenSearch = secondSplitArray[0].split(":"); + var newLen = newLenSearch[0]; + value = secondSplitArray[1].slice(0, newLen); + } + } + return value; +} + +function onAdiLoadComplete(adiBuffer, saveAdifFile, adifFileName, newFile) +{ + let rawAdiBuffer = ""; + if (typeof adiBuffer == "object") rawAdiBuffer = String(adiBuffer); + else rawAdiBuffer = adiBuffer; + + let activeAdifArray = Array(); + let activeAdifLogMode = true; + let eQSLfile = false; + + if (rawAdiBuffer.indexOf("PSKReporter") > -1) activeAdifLogMode = false; + + if (rawAdiBuffer.indexOf("Received eQSLs") > -1) eQSLfile = true; + + if (rawAdiBuffer.length > 1) + { + let regex = new RegExp("", "i"); + activeAdifArray = rawAdiBuffer.split(regex); + } + + let dateTime = new Date(); + let dupes = 0; + + for (let x = 0; x < activeAdifArray.length; x++) + { + let finalMode = ""; + + if (activeAdifArray[x].length > 3) + { + if (activeAdifLogMode) + { + let confirmed = false; + let finalGrid = findAdiField( + activeAdifArray[x], + "GRIDSQUARE" + ).toUpperCase(); + let vuccGrids = findAdiField( + activeAdifArray[x], + "VUCC_GRIDS" + ).toUpperCase(); + let finalVucc = []; + let finalDXcall = findAdiField(activeAdifArray[x], "CALL").replace( + "_", + "/" + ); + let finalDEcall = findAdiField( + activeAdifArray[x], + "STATION_CALLSIGN" + ).replace("_", "/"); + + if (finalDEcall == "") finalDEcall = myDEcall; + if ( + g_appSettings.workingCallsignEnable && + !(finalDEcall in g_appSettings.workingCallsigns) + ) + { continue; } + let finalRSTsent = findAdiField(activeAdifArray[x], "RST_SENT"); + let finalRSTrecv = findAdiField(activeAdifArray[x], "RST_RCVD"); + let finalBand = findAdiField(activeAdifArray[x], "BAND").toLowerCase(); + let dateVal = findAdiField(activeAdifArray[x], "QSO_DATE"); + let timeVal = findAdiField(activeAdifArray[x], "TIME_ON"); + let finalState = findAdiField( + activeAdifArray[x], + "STATE" + ).toUpperCase(); + if (finalState.length == 0) finalState = null; + let finalPropMode = findAdiField( + activeAdifArray[x], + "PROP_MODE" + ).toUpperCase(); + let finalSatName = findAdiField( + activeAdifArray[x], + "SAT_NAME" + ).toUpperCase(); + let finalCont = findAdiField(activeAdifArray[x], "CONT").toUpperCase(); + if (finalCont.length == 0) finalCont = null; + let finalCnty = findAdiField(activeAdifArray[x], "CNTY").toUpperCase(); + if (finalCnty.length == 0) finalCnty = null; + else + { + finalCnty = finalCnty.replaceAll(" ", ""); + } + let finalMode = findAdiField(activeAdifArray[x], "MODE").toUpperCase(); + let subMode = findAdiField(activeAdifArray[x], "SUBMODE"); + if (subMode == "FT4" && (finalMode == "MFSK" || finalMode == "DATA")) + { finalMode = "FT4"; } + if (subMode == "JS8" && finalMode == "MFSK") finalMode = "JS8"; + + if (finalBand == "oob" || finalBand == "") + { + finalBand = Number( + findAdiField(activeAdifArray[x], "FREQ") + ).formatBand(); + } + + let finalMsg = findAdiField(activeAdifArray[x], "COMMENT"); + let finalQslMsg = findAdiField(activeAdifArray[x], "QSLMSG"); + let finalQslMsgIntl = findAdiField(activeAdifArray[x], "QSLMSG_INTL"); + if (finalQslMsg.length > 1) finalMsg = finalQslMsg; + if (finalQslMsgIntl.length > 1 && finalMsg == "") + { finalMsg = finalQslMsgIntl; } + + let finalDxcc = Number(findAdiField(activeAdifArray[x], "DXCC")); + if (finalDxcc == 0) finalDxcc = Number(callsignToDxcc(finalDXcall)); + + if (!(finalDxcc in g_dxccToGeoData)) + { finalDxcc = Number(callsignToDxcc(finalDXcall)); } + + // If my callsign isn't present, it must be for me anyway + + let finalCqZone = findAdiField(activeAdifArray[x], "CQZ"); + if (finalCqZone.length == 1) finalCqZone = "0" + finalCqZone; + + if (parseInt(finalCqZone) < 1 || parseInt(finalCqZone) > 40) + { finalCqZone = ""; } + finalCqZone = String(finalCqZone); + let finalItuZone = findAdiField(activeAdifArray[x], "ITUZ"); + if (finalItuZone.length == 1) finalItuZone = "0" + finalItuZone; + + if (parseInt(finalItuZone) < 1 || parseInt(finalItuZone) > 90) + { finalItuZone = ""; } + finalItuZone = String(finalItuZone); + + let finalIOTA = findAdiField(activeAdifArray[x], "IOTA").toUpperCase(); + + let qrzConfirmed = findAdiField( + activeAdifArray[x], + "APP_QRZLOG_STATUS" + ).toUpperCase(); + let lotwConfirmed1 = findAdiField( + activeAdifArray[x], + "QSL_RCVD" + ).toUpperCase(); + let lotw_qsl_rcvd = findAdiField( + activeAdifArray[x], + "LOTW_QSL_RCVD" + ).toUpperCase(); + let eqsl_qsl_rcvd = findAdiField( + activeAdifArray[x], + "EQSL_QSL_RCVD" + ).toUpperCase(); + + if ( + qrzConfirmed == "C" || + lotw_qsl_rcvd == "Y" || + lotw_qsl_rcvd == "V" || + lotwConfirmed1 == "Y" || + eqsl_qsl_rcvd == "Y" || + eqsl_qsl_rcvd == "V" || + eQSLfile == true + ) + { confirmed = true; } + + let dateTime = new Date( + Date.UTC( + dateVal.substr(0, 4), + parseInt(dateVal.substr(4, 2)) - 1, + dateVal.substr(6, 2), + timeVal.substr(0, 2), + timeVal.substr(2, 2), + timeVal.substr(4, 2) + ) + ); + + let finalTime = parseInt(dateTime.getTime() / 1000); + + if ( + g_appSettings.workingDateEnable && + finalTime < g_appSettings.workingDate + ) + { continue; } + + finalGrid = finalGrid.substr(0, 6); + if (!validateGridFromString(finalGrid)) finalGrid = ""; + if (finalGrid == "" && vuccGrids != "") + { + finalVucc = vuccGrids.split(","); + finalGrid = finalVucc[0]; + finalVucc.shift(); + } + let isDigital = false; + let isPhone = false; + if (finalMode in g_modes) + { + isDigital = g_modes[finalMode]; + } + if (finalMode in g_modes_phone) + { + isPhone = g_modes_phone[finalMode]; + } + if (finalDXcall != "") + { + addDeDx( + finalGrid, + finalDXcall, + false, + false, + false, + finalDEcall, + finalRSTsent, + finalTime, + finalMsg, + finalMode, + finalBand, + confirmed, + false, + finalRSTrecv, + finalDxcc, + finalState, + finalCont, + finalCnty, + finalCqZone, + finalItuZone, + finalVucc, + finalPropMode, + isDigital, + isPhone, + finalIOTA, + finalSatName + ); + } + } + else + { + let finalMyGrid = findAdiField( + activeAdifArray[x], + "MY_GRIDSQUARE" + ).toUpperCase(); + let finalGrid = findAdiField( + activeAdifArray[x], + "GRIDSQUARE" + ).toUpperCase(); + let finalDXcall = findAdiField(activeAdifArray[x], "CALL"); + let finalDEcall = findAdiField(activeAdifArray[x], "OPERATOR"); + let finalRSTsent = findAdiField(activeAdifArray[x], "APP_PSKREP_SNR"); + let dateVal = findAdiField(activeAdifArray[x], "QSO_DATE"); + let timeVal = findAdiField(activeAdifArray[x], "TIME_ON"); + let finalMode = findAdiField(activeAdifArray[x], "MODE"); + let finalBand = Number( + findAdiField(activeAdifArray[x], "FREQ") + ).formatBand(); + let finalMsg = "-"; + let finalDxcc = Number(findAdiField(activeAdifArray[x], "DXCC")); + if (finalDxcc == 0) + { + if (finalDXcall == myDEcall) finalDxcc = callsignToDxcc(finalDEcall); + else finalDxcc = callsignToDxcc(finalDXcall); + } + + finalGrid = finalGrid.substr(0, 6); + + let dateTime = new Date( + Date.UTC( + dateVal.substr(0, 4), + parseInt(dateVal.substr(4, 2)) - 1, + dateVal.substr(6, 2), + timeVal.substr(0, 2), + timeVal.substr(2, 2), + timeVal.substr(4, 2) + ) + ); + let finalTime = parseInt(dateTime.getTime() / 1000); + if ( + finalGrid != "" && + finalDXcall != "" && + validateGridFromString(finalGrid) + ) + { + if (finalDXcall == myDEcall) + { + addDeDx( + finalMyGrid, + finalDEcall, + false, + false, + false, + finalDXcall, + null, + finalTime, + finalMsg, + finalMode, + finalBand, + false, + true, + finalRSTsent, + finalDxcc, + null, + null, + null, + null, + null + ); + } + else if (finalDEcall == myDEcall) + { + addDeDx( + finalGrid, + finalDXcall, + false, + false, + false, + "-", + finalRSTsent, + finalTime, + finalMsg, + finalMode, + finalBand, + false, + true, + null, + finalDxcc, + null, + null, + null, + null, + null + ); + } + else + { + addDeDx( + finalGrid, + finalDXcall, + false, + false, + false, + finalDEcall, + finalRSTsent, + finalTime, + finalMsg, + finalMode, + finalBand, + false, + true, + null, + finalDxcc, + null, + null, + null, + null, + null + ); + } + } + } + } + } + + redrawGrids(); + updateCountStats(); + updateLogbook(); + + if (g_fromDirectCallNoFileDialog == false) + { + fileSelector.setAttribute("type", ""); + fileSelector.setAttribute("type", "file"); + fileSelector.setAttribute("accept", ".adi,"); + fileSelector.value = null; + } + g_fromDirectCallNoFileDialog = false; + + updateRosterWorked(); + goProcessRoster(); +} + +function clubLogCallback(buffer, flag, cookie) +{ + var rawAdiBuffer = String(buffer); + if (rawAdiBuffer.indexOf("Invalid login") > -1) + { + if (flag) clubTestResult.innerHTML = "Invalid"; + } + else if (buffer == null) + { + if (flag) clubTestResult.innerHTML = "Unknown Error"; + } + else + { + if (flag) clubTestResult.innerHTML = "Passed"; + else + { + g_fromDirectCallNoFileDialog = true; + + rawAdiBuffer = cleanAndPrepADIF("clublog.adif", rawAdiBuffer); + + tryToWriteAdifToDocFolder("clublog.adif", rawAdiBuffer); + + onAdiLoadComplete(rawAdiBuffer, true, "clublog.adif", true); + } + } +} + +var g_isGettingClub = false; +function grabClubLog(test) +{ + if (g_isGettingClub == false) + { + if (test) clubTestResult.innerHTML = "Testing"; + + var postData = { + email: clubEmail.value, + password: clubPassword.value, + call: clubCall.value + }; + getAPostBuffer( + "https://clublog.org/getadif.php", + clubLogCallback, + test, + "https", + 443, + postData, + ClubLogImg, + "g_isGettingClub" + ); + } +} + +function tryToWriteAdifToDocFolder(filename, buffer, append = false) +{ + var finalFile = g_appData + g_dirSeperator + filename; + try + { + if (append == false) + { + fs.writeFileSync(finalFile, buffer); + return buffer; + } + else + { + fs.appendFileSync(finalFile, buffer); + return fs.readFileSync(finalFile); + } + } + catch (e) + { + return false; + } +} + +function cleanAndPrepADIF(name, adiBuffer, reverse = false, noheader = false) +{ + var rawAdiBuffer = adiBuffer; + var regex = new RegExp("", "i"); + rawAdiBuffer = rawAdiBuffer.replace(regex, ""); + regex = new RegExp("", "i"); + var adiArray = rawAdiBuffer.split(regex); + var activeAdifArray = Array(); + var activeAdifLogMode = true; + var finalBuffer = ""; + + if (noheader == false) finalBuffer = name + "\r\n"; + + if (adiArray.length > 1) + { + regex = new RegExp("", "i"); + activeAdifArray = adiArray[1].split(regex); + + if (reverse == false) + { + for (var x = 0; x < activeAdifArray.length - 1; x++) + { + var row = activeAdifArray[x].replace(/[\n\r]/g, ""); + if (row.length > 0) finalBuffer += row + "\r\n"; + } + } + else + { + for (var x = activeAdifArray.length - 1; x > -1; x--) + { + var row = activeAdifArray[x].replace(/[\n\r]/g, ""); + if (row.length > 0) finalBuffer += row + "\r\n"; + } + } + } + + return finalBuffer; +} + +function addZero(i) +{ + if (i < 10) + { + i = "0" + i; + } + return i; +} + +function getUTCString(d) +{ + var Y = d.getUTCFullYear(); + var M = addZero(d.getUTCMonth() + 1); + var D = addZero(d.getUTCDate()); + var h = addZero(d.getUTCHours()); + var m = addZero(d.getUTCMinutes()); + var s = addZero(d.getUTCSeconds()); + return Y + "-" + M + "-" + D + " " + h + ":" + m + ":" + s; +} + +function lotwCallback(buffer, flag) +{ + var rawAdiBuffer = String(buffer); + if (rawAdiBuffer.indexOf("password incorrect") > -1) + { + if (flag) lotwTestResult.innerHTML = "Invalid"; + } + else + { + if (flag) lotwTestResult.innerHTML = "Passed"; + else + { + var shouldAppend = false; + g_fromDirectCallNoFileDialog = true; + + rawAdiBuffer = cleanAndPrepADIF( + "lotw.adif", + rawAdiBuffer, + true, + shouldAppend + ); + + rawAdiBuffer = tryToWriteAdifToDocFolder( + "lotw.adif", + rawAdiBuffer, + shouldAppend + ); + + onAdiLoadComplete(rawAdiBuffer, true, "lotw.adif", true); + } + } +} + +function shouldWeAppendInsteadOfCreate(filename) +{ + var finalFile = g_appData + g_dirSeperator + filename; + try + { + if (fs.existsSync(finalFile)) return true; + else return false; + } + catch (e) + { + return false; + } +} + +function tryToDeleteLog(filename) +{ + var finalFile = g_appData + g_dirSeperator + filename; + try + { + if (fs.existsSync(finalFile)) + { + fs.unlinkSync(finalFile); + } + } + catch (e) {} +} + +var g_lotwCount = 0; + +var g_isGettingLOTW = false; + +function grabLOtWLog(test) +{ + if (g_isGettingLOTW == false) + { + var lastQSLDateString = + "&qso_qsorxsince=1945-01-01&qso_qslsince=1945-01-01"; + if (test == true) + { + lotwTestResult.innerHTML = "Testing"; + lastQSLDateString = "&qso_qsosince=2100-01-01"; + } + + getABuffer( + "https://lotw.arrl.org/lotwuser/lotwreport.adi?login=" + + lotwLogin.value + + "&password=" + + encodeURIComponent(lotwPassword.value) + + "&qso_query=1&qso_qsl=no&qso_qsldetail=yes&qso_withown=yes" + + lastQSLDateString, + lotwCallback, + test, + "https", + 443, + lotwLogImg, + "g_isGettingLOTW", + 120000 + ); + } +} + +function qrzCallback(buffer, flag) +{ + if (buffer.indexOf("invalid api key") > -1) + { + if (flag) qrzTestResult.innerHTML = "Invalid"; + } + else + { + if (flag) + { + qrzTestResult.innerHTML = "Passed"; + } + else + { + g_fromDirectCallNoFileDialog = true; + var htmlString = String(buffer).replace(/</g, "<"); + htmlString = htmlString.replace(/>/g, ">"); + htmlString = htmlString.replace("ADIF=", "QRZ\r\n"); + + htmlString = cleanAndPrepADIF("qrz.adif", htmlString); + + tryToWriteAdifToDocFolder("qrz.adif", htmlString); + + onAdiLoadComplete(htmlString, true, "qrz.adif", true); + } + } +} + +var g_isGettingQRZCom = false; +function grabQrzComLog(test) +{ + if (g_isGettingQRZCom == false) + { + var action = "FETCH"; + if (test) + { + qrzTestResult.innerHTML = "Testing"; + action = "STATUS"; + } + + getABuffer( + "https://logbook.qrz.com/api?KEY=" + + qrzApiKey.value + + "&ACTION=" + + action, + qrzCallback, + test, + "https", + 443, + qrzLogImg, + "g_isGettingQRZCom", + null + ); + } +} + +function ValidateQrzApi(inputText) +{ + inputText.value = inputText.value.toUpperCase(); + if (inputText.value.length == 19) + { + var passed = false; + var dashcount = 0; + for (var i = 0; i < inputText.value.length; i++) + { + if (inputText.value[i] == "-") dashcount++; + } + if (dashcount == 3) + { + passed = true; + } + if (passed) + { + inputText.style.color = "#FF0"; + inputText.style.backgroundColor = "green"; + + return true; + } + else + { + inputText.style.color = "white"; + inputText.style.backgroundColor = "red"; + return false; + } + } + else + { + inputText.style.color = "white"; + inputText.style.backgroundColor = "red"; + + return false; + } +} + +function ValidateText(inputText) +{ + if (inputText.value.length > 0) + { + inputText.style.color = "#FF0"; + inputText.style.backgroundColor = "green"; + return true; + } + else + { + inputText.style.color = "white"; + inputText.style.backgroundColor = "red"; + return false; + } +} + +function pskCallback(buffer, flag) +{ + g_fromDirectCallNoFileDialog = true; + var rawAdiBuffer = String(buffer); + + onAdiLoadComplete(rawAdiBuffer, false); +} + +var g_isGettingPsk = false; + +function grabPsk24() +{ + if (g_isGettingPsk == true) return; + + if (myDEcall.length > 0 && myDEcall != "NOCALL") + { + var days = 1; + if (pskImg.src == 1) days = 7; + getABuffer( + "https://pskreporter.info/cgi-bin/pskdata.pl?adif=1&days=" + + days + + "&receiverCallsign=" + + myDEcall.toLowerCase(), + pskCallback, + null, + "https", + 443, + pskImg, + "g_isGettingPsk" + ); + } +} + +function adifMenuCheckBoxChanged(what) +{ + g_adifLogSettings.menu[what.id] = what.checked; + var menuItem = what.id + "Div"; + if (what.checked == true) + { + document.getElementById(menuItem).style.display = "inline-block"; + } + else + { + document.getElementById(menuItem).style.display = "none"; + } + + localStorage.adifLogSettings = JSON.stringify(g_adifLogSettings); + + if (what == buttonAdifCheckBox) setAdifStartup(loadAdifCheckBox); +} + +function adifStartupCheckBoxChanged(what) +{ + g_adifLogSettings.startup[what.id] = what.checked; + localStorage.adifLogSettings = JSON.stringify(g_adifLogSettings); + + if (what == loadAdifCheckBox) setAdifStartup(loadAdifCheckBox); +} + +function adifLogQsoCheckBoxChanged(what) +{ + g_adifLogSettings.qsolog[what.id] = what.checked; + if (what.id == "logLOTWqsoCheckBox") + { + if (what.checked == true) + { + lotwUpload.style.display = "inline-block"; + trustedTestButton.style.display = "inline-block"; + } + else + { + lotwUpload.style.display = "none"; + trustedTestButton.style.display = "none"; + } + } + localStorage.adifLogSettings = JSON.stringify(g_adifLogSettings); +} + +function adifNicknameCheckBoxChanged(what) +{ + g_adifLogSettings.nickname[what.id] = what.checked; + if (what.id == "nicknameeQSLCheckBox") + { + if (what.checked == true) + { + eQSLNickname.style.display = "inline-block"; + } + else + { + eQSLNickname.style.display = "none"; + } + } + localStorage.adifLogSettings = JSON.stringify(g_adifLogSettings); +} + +function adifTextValueChange(what) +{ + what.value = what.value.trim(); + g_adifLogSettings.text[what.id] = what.value; + localStorage.adifLogSettings = JSON.stringify(g_adifLogSettings); +} + +var fileSelector = document.createElement("input"); +fileSelector.setAttribute("type", "file"); +fileSelector.setAttribute("accept", ".adi,.adif"); +fileSelector.onchange = function () +{ + if (this.files && this.files[0]) + { + let path = this.value.replace(this.files[0].name, ""); + fileSelector.setAttribute("nwworkingdir", path); + + var reader = new FileReader(); + reader.onload = function (e) + { + if (e.target.error == null) + { + onAdiLoadComplete(e.target.result, false); + } + }; + + reader.readAsText(this.files[0]); + } +}; + +function adifLoadDialog() +{ + var exists = fileSelector.getAttribute("nwworkingdir"); + + fileSelector.setAttribute("nwworkingdir", g_appData); + + fileSelector.click(); + + return false; +} + +var startupFileSelector = document.createElement("input"); +startupFileSelector.setAttribute("type", "file"); +startupFileSelector.setAttribute("accept", ".adi,.adif"); +startupFileSelector.onchange = function () +{ + if (this.files && this.files[0]) + { + for (var i in g_startupLogs) + { + if (this.value == g_startupLogs[i].file) return; + } + var newObject = Object(); + newObject.name = this.files[0].name; + newObject.file = this.value; + g_startupLogs.push(newObject); + localStorage.startupLogs = JSON.stringify(g_startupLogs); + + let path = this.value.replace(this.files[0].name, ""); + startupFileSelector.setAttribute("nwworkingdir", path); + + setAdifStartup(loadAdifCheckBox); + } +}; + +function start_and_end(str) +{ + if (str.length > 31) + { + return ( + str.substr(0, 16) + " ... " + str.substr(str.length - 15, str.length) + ); + } + return str; +} + +function setFileSelectors() +{ + selectStartupLink = document.getElementById("selectAdifButton"); + selectStartupLink.onclick = function () + { + var exists = startupFileSelector.getAttribute("nwworkingdir"); + if (exists == null) + { + if (g_workingIniPath.length > 1) + { startupFileSelector.setAttribute("nwworkingdir", g_appData); } + } + + startupFileSelector.click(); + return false; + }; + + selectTqsl = document.getElementById("selectTQSLButton"); + selectTqsl.onclick = function () + { + tqslFileSelector.click(); + return false; + }; + lotwUpload.prepend(selectTqsl); +} + +var tqslFileSelector = document.createElement("input"); +tqslFileSelector.setAttribute("type", "file"); +tqslFileSelector.setAttribute("accept", "*"); +tqslFileSelector.onchange = function () +{ + if (this.files && this.files[0]) + { + g_trustedQslSettings.binaryFile = this.files[0].path; + var fs = require("fs"); + + if ( + fs.existsSync(g_trustedQslSettings.binaryFile) && + (g_trustedQslSettings.binaryFile.endsWith("tqsl.exe") || + g_trustedQslSettings.binaryFile.endsWith("tqsl")) + ) + { + g_trustedQslSettings.binaryFileValid = true; + } + else g_trustedQslSettings.binaryFileValid = false; + + if (g_trustedQslSettings.binaryFileValid == true) + { + tqslFileDiv.style.backgroundColor = "blue"; + } + else + { + tqslFileDiv.style.backgroundColor = "red"; + } + + tqslFileDiv.innerHTML = "" + start_and_end(this.files[0].path) + ""; + localStorage.trustedQslSettings = JSON.stringify(g_trustedQslSettings); + } +}; + +function loadGtQSOLogFile() +{ + var fs = require("fs"); + + if (fs.existsSync(g_qsoLogFile)) + { + var rawAdiBuffer = fs.readFileSync(g_qsoLogFile); + + g_fromDirectCallNoFileDialog = true; + + onAdiLoadComplete(rawAdiBuffer, false); + } +} + +function loadWsjtLogFile() +{ + var fs = require("fs"); + if (fs.existsSync(g_workingIniPath + "wsjtx_log.adi")) + { + var rawAdiBuffer = fs.readFileSync(g_workingIniPath + "wsjtx_log.adi"); + g_fromDirectCallNoFileDialog = true; + onAdiLoadComplete(rawAdiBuffer, false); + } +} + +function findTrustedQSLPaths() +{ + var process = require("process"); + var base = null; + + if (g_trustedQslSettings.stationFileValid == true) + { + // double check the presence of the station_data; + if (!fs.existsSync(g_trustedQslSettings.stationFile)) + { + g_trustedQslSettings.stationFileValid = false; + } + } + if (g_trustedQslSettings.stationFileValid == false) + { + if (g_platform == "windows") + { + base = process.env.APPDATA + "\\TrustedQSL\\station_data"; + if (fs.existsSync(base)) + { + g_trustedQslSettings.stationFile = base; + g_trustedQslSettings.stationFileValid = true; + } + else + { + base = process.env.LOCALAPPDATA + "\\TrustedQSL\\station_data"; + if (fs.existsSync(base)) + { + g_trustedQslSettings.stationFile = base; + g_trustedQslSettings.stationFileValid = true; + } + } + } + else + { + base = process.env.HOME + "/.tqsl/station_data"; + if (fs.existsSync(base)) + { + g_trustedQslSettings.stationFile = base; + g_trustedQslSettings.stationFileValid = true; + } + } + } + if (g_trustedQslSettings.stationFileValid == true) + { + var validate = false; + var option = document.createElement("option"); + option.value = ""; + option.text = "Select a Station"; + lotwStation.appendChild(option); + + var buffer = fs.readFileSync(g_trustedQslSettings.stationFile, "UTF-8"); + parser = new DOMParser(); + xmlDoc = parser.parseFromString(buffer, "text/xml"); + var x = xmlDoc.getElementsByTagName("StationData"); + for (var i = 0; i < x.length; i++) + { + option = document.createElement("option"); + option.value = x[i].getAttribute("name"); + option.text = x[i].getAttribute("name"); + if (option.value == g_adifLogSettings.text.lotwStation) + { + option.selected = true; + validate = true; + } + lotwStation.appendChild(option); + } + if (validate) + { + ValidateText(lotwStation); + } + } + + if (g_trustedQslSettings.binaryFileValid == true) + { + // double check the presence of the TrustedQSL binary; + if (!fs.existsSync(g_trustedQslSettings.binaryFile)) + { + g_trustedQslSettings.binaryFileValid = false; + } + } + if (g_trustedQslSettings.binaryFileValid == false || g_platform == "mac") + { + if (g_platform == "windows") + { + base = process.env["ProgramFiles(x86)"] + "\\TrustedQSL\\tqsl.exe"; + if (fs.existsSync(base)) + { + g_trustedQslSettings.binaryFile = base; + g_trustedQslSettings.binaryFileValid = true; + } + } + else if (g_platform == "mac") + { + base = "/Applications/TrustedQSL/tqsl.app/Contents/MacOS/tqsl"; + if (fs.existsSync(base)) + { + g_trustedQslSettings.binaryFile = base; + g_trustedQslSettings.binaryFileValid = true; + } + else + { + base = + process.env.HOME + + "/Applications/TrustedQSL/tqsl.app/Contents/MacOS/tqsl"; + if (fs.existsSync(base)) + { + g_trustedQslSettings.binaryFile = base; + g_trustedQslSettings.binaryFileValid = true; + } + else + { + base = + process.env.HOME + "/Applications/tqsl.app/Contents/MacOS/tqsl"; + if (fs.existsSync(base)) + { + g_trustedQslSettings.binaryFile = base; + g_trustedQslSettings.binaryFileValid = true; + } + else + { + base = "/Applications/tqsl.app/Contents/MacOS/tqsl"; + if (fs.existsSync(base)) + { + g_trustedQslSettings.binaryFile = base; + g_trustedQslSettings.binaryFileValid = true; + } + else + { + base = + process.env.HOME + + "/Desktop/TrustedQSL/tqsl.app/Contents/MacOS/tqsl"; + if (fs.existsSync(base)) + { + g_trustedQslSettings.binaryFile = base; + g_trustedQslSettings.binaryFileValid = true; + } + else + { + base = + process.env.HOME + + "/Applications/Ham Radio/tqsl.app/Contents/MacOS/tqsl"; + if (fs.existsSync(base)) + { + g_trustedQslSettings.binaryFile = base; + g_trustedQslSettings.binaryFileValid = true; + } + } + } + } + } + } + } + else if (g_platform == "linux") + { + base = "/usr/bin/tqsl"; + if (fs.existsSync(base)) + { + g_trustedQslSettings.binaryFile = base; + g_trustedQslSettings.binaryFileValid = true; + } + else + { + base = "/usr/local/bin/tqsl"; + if (fs.existsSync(base)) + { + g_trustedQslSettings.binaryFile = base; + g_trustedQslSettings.binaryFileValid = true; + } + } + } + } + localStorage.trustedQslSettings = JSON.stringify(g_trustedQslSettings); +} + +function startupAdifLoadFunction() +{ + var fs = require("fs"); + + for (var i in g_startupLogs) + { + try + { + if (fs.existsSync(g_startupLogs[i].file)) + { + var rawAdiBuffer = fs.readFileSync(g_startupLogs[i].file); + g_fromDirectCallNoFileDialog = true; + onAdiLoadComplete(rawAdiBuffer, false); + } + } + catch (e) {} + } +} + +function setAdifStartup(checkbox) +{ + if (g_trustedQslSettings.binaryFile == null) + { g_trustedQslSettings.binaryFile = ""; } + + if ( + g_trustedQslSettings.binaryFile.endsWith("tqsl.exe") || + g_trustedQslSettings.binaryFile.endsWith("tqsl") + ) + { + g_trustedQslSettings.binaryFileValid = true; + } + else g_trustedQslSettings.binaryFileValid = false; + + if (g_trustedQslSettings.binaryFileValid == true) + { + tqslFileDiv.style.backgroundColor = "blue"; + } + else + { + tqslFileDiv.style.backgroundColor = "red"; + } + tqslFileDiv.innerHTML = + "" + start_and_end(g_trustedQslSettings.binaryFile) + ""; + + if (buttonAdifCheckBox.checked || loadAdifCheckBox.checked) + { + var worker = ""; + if (g_startupLogs.length > 0) + { + worker += ""; + for (var i in g_startupLogs) + { + worker += + ""; + } + worker += "
" + + g_startupLogs[i].name + + "
"; + } + else + { + worker = "No file(s) selected"; + } + startupLogFileDiv.innerHTML = worker; + selectFileOnStartupDiv.style.display = "block"; + } + else + { + startupLogFileDiv.innerHTML = "No file(s) selected"; + startupFileSelector.setAttribute("type", ""); + startupFileSelector.setAttribute("type", "file"); + startupFileSelector.setAttribute("accept", ".adi*"); + startupFileSelector.value = null; + selectFileOnStartupDiv.style.display = "none"; + } +} + +function removeStartupLog(i) +{ + if (i in g_startupLogs) + { + g_startupLogs.splice(i, 1); + localStorage.startupLogs = JSON.stringify(g_startupLogs); + setAdifStartup(loadAdifCheckBox); + } +} + +function startupAdifLoadCheck() +{ + logEventMedia.value = g_alertSettings.logEventMedia; + + loadWsjtLogFile(); + + if (loadGTCheckBox.checked == true) loadGtQSOLogFile(); + + if (loadAdifCheckBox.checked == true && g_startupLogs.length > 0) + { startupAdifLoadFunction(); } + + if (g_mapSettings.offlineMode == false) + { + if (g_appSettings.gtFlagImgSrc == 1) showGtFlags(); + + //if (loadLOTWCheckBox.checked == true) grabLOtWLog(false); + + if (loadQRZCheckBox.checked == true) grabQrzComLog(false); + + if (loadClubCheckBox.checked == true) grabClubLog(false); + + if (loadPsk24CheckBox.checked == true) grabPsk24(); + } +} + +function getABuffer( + file_url, + callback, + flag, + mode, + port, + imgToGray, + stringOfFlag, + timeoutX +) +{ + let url = require("url"); + let http = require(mode); + let fileBuffer = null; + let options = null; + + options = { + host: url.parse(file_url).host, // eslint-disable-line node/no-deprecated-api + port: port, + path: url.parse(file_url).path, // eslint-disable-line node/no-deprecated-api + method: "get" + }; + + if (typeof stringOfFlag != "undefined") window[stringOfFlag] = true; + if (typeof imgToGray != "undefined") + { + imgToGray.parentNode.style.background = + "linear-gradient(grey 0%, black 0% 100% )"; + imgToGray.style.webkitFilter = "invert(100%) grayscale(1)"; + } + + let req = http.request(options, function (res) + { + let fsize = res.headers["content-length"]; + let cookies = null; + if (typeof res.headers["set-cookie"] != "undefined") + { cookies = res.headers["set-cookie"]; } + + res + .on("data", function (data) + { + if (fileBuffer == null) fileBuffer = data; + else fileBuffer += data; + + if (typeof imgToGray != "undefined") + { + let percent = 0; + if (fsize > 0) percent = parseInt((fileBuffer.length / fsize) * 100); + else percent = parseInt(((fileBuffer.length / 100000) * 100) % 100); + imgToGray.parentNode.style.background = + "linear-gradient(grey " + + percent + + "%, black " + + Number(percent + 10) + + "% 100% )"; + } + }) + .on("end", function () + { + if (typeof callback === "function") + { + // Call it, since we have confirmed it is callable + callback(fileBuffer, flag, cookies); + } + if (typeof stringOfFlag != "undefined") + { + window[stringOfFlag] = false; + } + if (typeof imgToGray != "undefined") + { + imgToGray.parentNode.style.background = ""; + imgToGray.style.webkitFilter = ""; + } + }) + .on("error", function () + { + if (typeof stringOfFlag != "undefined") + { + window[stringOfFlag] = false; + } + if (typeof imgToGray != "undefined") + { + imgToGray.parentNode.style.background = ""; + imgToGray.style.webkitFilter = ""; + } + }); + }); + + req.on("socket", function (socket) + { + socket.on("timeout", function () + { + req.abort(); + }); + }); + + req.on("error", function () + { + if (typeof stringOfFlag != "undefined") + { + window[stringOfFlag] = false; + } + if (typeof imgToGray != "undefined") + { + imgToGray.parentNode.style.background = ""; + imgToGray.style.webkitFilter = ""; + } + }); + + req.end(); +} + +function getAPostBuffer( + file_url, + callback, + flag, + mode, + port, + theData, + imgToGray, + stringOfFlag +) +{ + var querystring = require("querystring"); + var postData = querystring.stringify(theData); + var url = require("url"); + var http = require(mode); + var fileBuffer = null; + + var options = { + host: url.parse(file_url).host, // eslint-disable-line node/no-deprecated-api + port: port, + path: url.parse(file_url).path, // eslint-disable-line node/no-deprecated-api + method: "post", + headers: { + "Content-Type": "application/x-www-form-urlencoded", + "Content-Length": postData.length + } + }; + + window[stringOfFlag] = true; + + if (typeof imgToGray != "undefined") + { + imgToGray.parentNode.style.background = + "linear-gradient(grey 0%, black 0% 100% )"; + imgToGray.style.webkitFilter = "invert(100%) grayscale(1)"; + } + + var req = http.request(options, function (res) + { + var fsize = res.headers["content-length"]; + var cookies = null; + if (typeof res.headers["set-cookie"] != "undefined") + { cookies = res.headers["set-cookie"]; } + + res + .on("data", function (data) + { + if (fileBuffer == null) fileBuffer = data; + else fileBuffer += data; + + if (typeof imgToGray != "undefined") + { + var percent = 0; + if (fsize > 0) percent = parseInt((fileBuffer.length / fsize) * 100); + else percent = parseInt(((fileBuffer.length / 100000) * 100) % 100); + + imgToGray.parentNode.style.background = + "linear-gradient(grey " + + percent + + "%, black " + + Number(percent + 10) + + "% 100% )"; + } + }) + .on("end", function () + { + if (typeof callback === "function") + { + // Call it, since we have confirmed it is callable + callback(fileBuffer, flag, cookies); + window[stringOfFlag] = false; + if (typeof imgToGray != "undefined") + { + imgToGray.parentNode.style.background = ""; + imgToGray.style.webkitFilter = ""; + } + } + }) + .on("error", function () + { + window[stringOfFlag] = false; + if (typeof imgToGray != "undefined") + { + imgToGray.parentNode.style.background = ""; + imgToGray.style.webkitFilter = ""; + } + }); + }); + + req.on("socket", function (socket) + { + socket.on("timeout", function () + { + req.abort(); + }); + }); + + req.on("error", function (err) // eslint-disable-line node/handle-callback-err + { + window[stringOfFlag] = false; + if (typeof imgToGray != "undefined") + { + imgToGray.parentNode.style.background = ""; + imgToGray.style.webkitFilter = ""; + } + }); + + req.write(postData); + req.end(); +} + +function sendUdpMessage(msg, length, port, address) +{ + var dgram = require("dgram"); + var socket = dgram.createSocket({ type: "udp4", reuseAddr: true }); + socket.send(msg, 0, length, port, address, (err) => // eslint-disable-line node/handle-callback-err + { + socket.close(); + }); +} + +function sendTcpMessage(msg, length, port, address) +{ + var net = require("net"); + var client = new net.Socket(); + client.setTimeout(30000); + client.connect(port, address, function () + { + client.write(msg); + }); + + client.on("close", function () {}); +} + +function valueToAdiField(field, value) +{ + var adi = "<" + field + ":"; + adi += String(value).length + ">"; + adi += String(value) + " "; + return adi; +} + +function pad(value) +{ + if (value < 10) + { + return "0" + value; + } + else + { + return value; + } +} + +function HMSfromMilli(milli) +{ + var seconds = parseInt(milli / 1000); + var days = Math.floor(seconds / (3600 * 24)); + seconds -= days * 3600 * 24; + var hrs = Math.floor(seconds / 3600); + seconds -= hrs * 3600; + var mnts = Math.floor(seconds / 60); + seconds -= mnts * 60; + + val = String(pad(hrs)) + String(pad(mnts)) + String(pad(seconds)); + return String(val); +} + +function colonHMSfromMilli(milli) +{ + var seconds = parseInt(milli / 1000); + var days = Math.floor(seconds / (3600 * 24)); + seconds -= days * 3600 * 24; + var hrs = Math.floor(seconds / 3600); + seconds -= hrs * 3600; + var mnts = Math.floor(seconds / 60); + seconds -= mnts * 60; + + val = String(pad(hrs)) + ":" + String(pad(mnts)) + ":" + String(pad(seconds)); + return String(val); +} + +function colonHMSfromSeconds(secondsIn) +{ + var seconds = secondsIn; + var days = Math.floor(seconds / (3600 * 24)); + seconds -= days * 3600 * 24; + var hrs = Math.floor(seconds / 3600); + seconds -= hrs * 3600; + var mnts = Math.floor(seconds / 60); + seconds -= mnts * 60; + + val = String(pad(hrs)) + ":" + String(pad(mnts)) + ":" + String(pad(seconds)); + return String(val); +} + +function convertToDate(julian) +{ + var DAY = 86400000; + var HALF_DAY = DAY / 2; + var UNIX_EPOCH_JULIAN_DATE = 2440587.5; + var UNIX_EPOCH_JULIAN_DAY = 2440587; + return new Date((Number(julian) - UNIX_EPOCH_JULIAN_DATE) * DAY); +} + +var CLk = "25bc718451a71954cb6d0d1b50541dd45d4ba148"; + +var lastReportHash = null; + +var g_oldStyleLogMessage = null; + +function oldSendToLogger() +{ + var newMessage = Object.assign({}, g_oldStyleLogMessage); + + var band = Number(newMessage.Frequency / 1000000).formatBand(); + + if ( + newMessage.DXGrid.length == 0 && + newMessage.DXCall + band + newMessage.MO in g_liveCallsigns + ) + { + newMessage.DXGrid = g_liveCallsigns[ + newMessage.DXCall + band + newMessage.MO + ].grid.substr(0, 4); + } + + var report = ""; + + report += valueToAdiField( + "BAND", + Number(newMessage.Frequency / 1000000).formatBand() + ); + report += valueToAdiField("CALL", newMessage.DXCall.toUpperCase()); + report += valueToAdiField( + "FREQ", + Number(newMessage.Frequency / 1000000).toFixed(6) + ); + report += valueToAdiField("MODE", newMessage.MO.toUpperCase()); + var date = convertToDate(parseInt(newMessage.DateOn)); + var dataString = + date.getUTCFullYear() + + ("0" + (date.getUTCMonth() + 1)).slice(-2) + + ("0" + date.getUTCDate()).slice(-2); + report += valueToAdiField("QSO_DATE", dataString); + report += valueToAdiField("TIME_ON", HMSfromMilli(newMessage.TimeOn)); + + date = convertToDate(parseInt(newMessage.DateOff)); + dataString = + date.getUTCFullYear() + + ("0" + (date.getUTCMonth() + 1)).slice(-2) + + ("0" + date.getUTCDate()).slice(-2); + report += valueToAdiField("QSO_DATE_OFF", dataString); + report += valueToAdiField("TIME_OFF", HMSfromMilli(newMessage.TimeOff)); + + report += valueToAdiField("RST_RCVD", newMessage.ReportRecieved); + report += valueToAdiField("RST_SENT", newMessage.ReportSend); + report += valueToAdiField("TX_PWR", parseInt(newMessage.TXPower)); + report += valueToAdiField("GRIDSQUARE", newMessage.DXGrid); + + if (newMessage.Comments.length > 0) + { report += valueToAdiField("COMMENT", newMessage.Comments); } + + if (newMessage.Name.length > 0) + { report += valueToAdiField("NAME", newMessage.Name); } + + if (newMessage.Operatorcall.length > 0) + { + report += valueToAdiField("OPERATOR", newMessage.Operatorcall); + } + + if (newMessage.Mycall.length > 0) + { + report += valueToAdiField("STATION_CALLSIGN", newMessage.Mycall); + } + else if (myDEcall != "NOCALL" && myDEcall.length > 0) + { report += valueToAdiField("STATION_CALLSIGN", myDEcall); } + + if (newMessage.Mygrid.length > 0) + { + report += valueToAdiField("MY_GRIDSQUARE", newMessage.Mygrid); + } + else if (myDEGrid.length > 1) + { report += valueToAdiField("MY_GRIDSQUARE", myDEGrid); } + + report += ""; + + sendToLogger(report); +} + +var g_adifLookupMap = { + name: "NAME", + iota: "IOTA", + sota: "SOTA_REF", + continent: "CONT", + cqzone: "CQZ", + ituzone: "ITUZ", + email: "EMAIL", + county: "CNTY" +}; + +function sendToLogger(ADIF) +{ + let regex = new RegExp("", "i"); + let record = parseADIFRecord(ADIF.split(regex)[1]); + let localMode = record.MODE; + + if (localMode == "MFSK" && "SUBMODE" in record) + { + localMode = record.SUBMODE; + } + + if ( + (!("GRIDSQUARE" in record) || record.GRIDSQUARE.length == 0) && + record.CALL + record.BAND + localMode in g_liveCallsigns + ) + { + record.GRIDSQUARE = g_liveCallsigns[ + record.CALL + record.BAND + localMode + ].grid.substr(0, 4); + } + + if ("TX_PWR" in record) + { + record.TX_PWR = String(parseInt(record.TX_PWR)); + } + + if ( + (!("STATION_CALLSIGN" in record) || + record.STATION_CALLSIGN.length == 0) && + myDEcall != "NOCALL" && + myDEcall.length > 0 + ) + { + record.STATION_CALLSIGN = myDEcall; + } + + if ( + (!("MY_GRIDSQUARE" in record) || record.MY_GRIDSQUARE.length == 0) && + myDEGrid.length > 1 + ) + { + record.MY_GRIDSQUARE = myDEGrid; + } + + if (!("DXCC" in record)) + { + let dxcc = callsignToDxcc(record.CALL); + if (dxcc == -1) dxcc = 0; + record.DXCC = String(dxcc); + } + + // Tag: This is going to bite us in the butt later, but leaving it alone. + if (!("COUNTRY" in record) && Number(record.DXCC) > 0) + { + record.COUNTRY = g_dxccToADIFName[Number(record.DXCC)]; + } + + if (g_appSettings.lookupMerge == true) + { + let request = g_Idb + .transaction(["lookups"], "readwrite") + .objectStore("lookups") + .get(record.CALL); + + request.onsuccess = function (event) + { + if (request.result) + { + let lookup = request.result; + for (let key in lookup) + { + if (key in g_adifLookupMap) + { + record[g_adifLookupMap[key]] = lookup[key]; + } + } + if ("GRIDSQUARE" in record && "grid" in lookup) + { + if ( + record.GRIDSQUARE.substr(0, 4) == lookup.grid.substr(0, 4) + ) + { + record.GRIDSQUARE = lookup.grid; + } + } + if ( + g_appSettings.lookupMissingGrid && + "grid" in lookup && + (!("GRIDSQUARE" in record) || record.GRIDSQUARE.length == 0) + ) + { + record.GRIDSQUARE = lookup.grid; + } + } + finishSendingReport(record, localMode); + }; + + request.onerror = function (event) + { + finishSendingReport(record, localMode); + }; + } + else + { + finishSendingReport(record, localMode); + } +} + +function finishSendingReport(record, localMode) +{ + let report = ""; + + let reportHash = record.CALL + record.MODE + localMode; + + for (let key in record) + { + report += "<" + key + ":" + record[key].length + ">" + record[key] + " "; + } + report += ""; + + if (reportHash != lastReportHash) + { + lastReportHash = reportHash; + + if ( + g_N1MMSettings.enable == true && + g_N1MMSettings.port > 1024 && + g_N1MMSettings.ip.length > 4 + ) + { + sendUdpMessage( + report, + report.length, + parseInt(g_N1MMSettings.port), + g_N1MMSettings.ip + ); + addLastTraffic("Logged to N1MM"); + } + + if ( + g_log4OMSettings.enable == true && + g_log4OMSettings.port > 1024 && + g_log4OMSettings.ip.length > 4 + ) + { + sendUdpMessage( + "ADD " + report, + report.length + 4, + parseInt(g_log4OMSettings.port), + g_log4OMSettings.ip + ); + addLastTraffic("Logged to Log4OM"); + } + + try + { + onAdiLoadComplete("GT" + report); + } + catch (e) + { + addLastTraffic("Exception Internal Log"); + } + try + { + // Log worthy + if (logGTqsoCheckBox.checked == true) + { + var fs = require("fs"); + fs.appendFileSync(g_qsoLogFile, report + "\r\n"); + addLastTraffic( + "Logged to GridTracker backup" + ); + } + } + catch (e) + { + addLastTraffic( + "Exception GridTracker backup" + ); + } + + try + { + sendQrzLogEntry(report); + } + catch (e) + { + addLastTraffic("Exception QRZ Log"); + } + + try + { + sendClubLogEntry(report); + } + catch (e) + { + addLastTraffic("Exception ClubLog Log"); + } + + try + { + sendHrdLogEntry(report); + } + catch (e) + { + addLastTraffic("Exception HrdLog.net Log"); + } + + try + { + sendCloudlogEntry(report); + } + catch (e) + { + addLastTraffic("Exception Cloudlog Log"); + } + + if ( + g_acLogSettings.enable == true && + g_acLogSettings.port > 0 && + g_acLogSettings.ip.length > 4 + ) + { + try + { + sendACLogMessage(record, g_acLogSettings.port, g_acLogSettings.ip); + addLastTraffic("Logged to N3FJP"); + } + catch (e) + { + addLastTraffic("Exception N3FJP Log"); + } + } + + if ( + g_dxkLogSettings.enable == true && + g_dxkLogSettings.port > 0 && + g_dxkLogSettings.ip.length > 4 + ) + { + try + { + sendDXKeeperLogMessage( + report, + g_dxkLogSettings.port, + g_dxkLogSettings.ip + ); + addLastTraffic("Logged to DXKeeper"); + } + catch (e) + { + addLastTraffic("Exception DXKeeper Log"); + } + } + + if ( + g_HRDLogbookLogSettings.enable == true && + g_HRDLogbookLogSettings.port > 0 && + g_HRDLogbookLogSettings.ip.length > 4 + ) + { + try + { + sendHRDLogbookEntry( + record, + g_HRDLogbookLogSettings.port, + g_HRDLogbookLogSettings.ip + ); + addLastTraffic( + "Logged to HRD Logbook" + ); + } + catch (e) + { + addLastTraffic("Exception HRD Log"); + } + } + + try + { + sendLotwLogEntry(report); + } + catch (e) + { + addLastTraffic("Exception LoTW Log"); + } + + if ( + logeQSLQSOCheckBox.checked == true && + nicknameeQSLCheckBox.checked == true && + eQSLNickname.value.trim().length > 0 + ) + { + record.APP_EQSL_QTH_NICKNAME = eQSLNickname.value.trim(); + report = ""; + for (var key in record) + { + report += + "<" + key + ":" + record[key].length + ">" + record[key] + " "; + } + report += ""; + } + + try + { + sendeQSLEntry(report); + } + catch (e) + { + addLastTraffic("Exception LoTW Log"); + } + + try + { + alertLogMessage(); + } + catch (e) + { + addLastTraffic("Exception Alert Log"); + } + + if (lookupCloseLog.checked == true) + { + try + { + openLookupWindow(false); + } + catch (e) + { + addLastTraffic("Exception Hide Lookup"); + } + } + } + + return report; +} + +function alertLogMessage() +{ + if (logEventMedia.value != "none") + { + playAlertMediaFile(logEventMedia.value); + } +} + +function eqslCallback(buffer, flag) +{ + var result = String(buffer); + if (flag) + { + if (result.indexOf("No such Username/Password found") != -1) + { + eQSLTestResult.innerHTML = "Bad
Password
or
Nickname"; + logeQSLQSOCheckBox.checked = false; + adifLogQsoCheckBoxChanged(logeQSLQSOCheckBox); + } + else if (result.indexOf("No such Callsign found") != -1) + { + eQSLTestResult.innerHTML = "Unknown
Callsign"; + logeQSLQSOCheckBox.checked = false; + adifLogQsoCheckBoxChanged(logeQSLQSOCheckBox); + } + else if (result.indexOf("Your ADIF log file has been built") > -1 || result.indexOf("You have no log entries") > -1) + { + eQSLTestResult.innerHTML = "Passed"; + } + else if (result.indexOf("specify the desired User by using the QTHNickname") != -1) + { + eQSLTestResult.innerHTML = "QTH Nickname
Needed"; + } + else + { + eQSLTestResult.innerHTML = "Unknown
Error"; + logeQSLQSOCheckBox.checked = false; + adifLogQsoCheckBoxChanged(logeQSLQSOCheckBox); + } + } + else + { + if (result.indexOf("Error: No match on eQSL_User/eQSL_Pswd") != -1) + { + addLastTraffic( + "Fail log eQSL.cc (credentials)" + ); + } + if ( + result.indexOf("specify the desired User by using the QTHNickname") != -1 + ) + { + addLastTraffic( + "Fail log eQSL.cc (nickname)" + ); + } + else if (result.indexOf("Result: 0 out of 1 records") != -1) + { + addLastTraffic("Fail log eQSL.cc (dupe)"); + } + else if (result.indexOf("Result: 1 out of 1 records added") != -1) + { + addLastTraffic("Logged to eQSL.cc"); + } + else + { + addLastTraffic("Fail log eQSL.cc (?)"); + } + } +} + +function eQSLTest(test) +{ + if (g_mapSettings.offlineMode == true) return; + + eQSLTestResult.innerHTML = "Testing"; + + var fUrl = + "https://www.eQSL.cc/qslcard/DownloadInBox.cfm?UserName=" + + encodeURIComponent(eQSLUser.value) + + "&Password=" + + encodeURIComponent(eQSLPassword.value) + + "&RcvdSince=2020101"; + + if (nicknameeQSLCheckBox.checked == true) + { fUrl += "&QTHNickname=" + encodeURIComponent(eQSLNickname.value); } + getABuffer(fUrl, eqslCallback, true, "https", 443); +} + +function sendeQSLEntry(report) +{ + if (g_mapSettings.offlineMode == true) return; + + if (logeQSLQSOCheckBox.checked == true) + { + var pid = "GridTracker"; + var pver = String(gtVersion); + var header = "" + pid + "\r\n"; + header += "" + pver + "\r\n"; + header += "\r\n"; + var eReport = encodeURIComponent(header + report); + var fUrl = + "https://www.eQSL.cc/qslcard/importADIF.cfm?ADIFData=" + + eReport + + "&EQSL_USER=" + + encodeURIComponent(eQSLUser.value) + + "&EQSL_PSWD=" + + encodeURIComponent(eQSLPassword.value); + getABuffer(fUrl, eqslCallback, false, "https", 443); + } +} + +function testTrustedQSL(test) +{ + if (g_mapSettings.offlineMode == true) + { + lotwTestResult.innerHTML = "Currently
offline"; + return; + } + + if ( + logLOTWqsoCheckBox.checked == true && + g_trustedQslSettings.binaryFileValid == true && + g_trustedQslSettings.stationFileValid == true && + lotwStation.value.length > 0 + ) + { + lotwTestResult.innerHTML = "Testing Upload"; + + var child_process = require("child_process"); + var options = Array(); + options.push("-q"); + options.push("-v"); + + child_process.execFile( + g_trustedQslSettings.binaryFile, + options, + (error, stdout, stderr) => + { + if (error) + { + lotwTestResult.innerHTML = "Error encountered"; + } + lotwTestResult.innerHTML = stderr; + } + ); + } + else + { + var worker = ""; + if (g_trustedQslSettings.binaryFileValid == false) + { worker += "Invalid tqsl executable
"; } + if (g_trustedQslSettings.stationFileValid == false) + { worker += "TrustQSL not installed
"; } + if (!ValidateText(lotwTrusted)) worker += "TQSL Password missing
"; + if (!ValidateText(lotwStation)) worker += "Select Station
"; + lotwTestResult.innerHTML = worker; + } +} +var g_trustTempPath = ""; + +function sendLotwLogEntry(report) +{ + if (g_mapSettings.offlineMode == true) return; + + if ( + logLOTWqsoCheckBox.checked == true && + g_trustedQslSettings.binaryFileValid == true && + g_trustedQslSettings.stationFileValid == true && + lotwStation.value.length > 0 + ) + { + var header = + "Generated " + userTimeString(null) + " for " + myDEcall + "\r\n\r\n"; + var pid = "GridTracker"; + var pver = String(gtVersion); + header += "" + pid + "\r\n"; + header += "" + pver + "\r\n"; + header += "\r\n"; + var finalLog = header + report + "\r\n"; + + g_trustTempPath = os.tmpdir() + g_dirSeperator + unique(report) + ".adif"; + fs.writeFileSync(g_trustTempPath, finalLog); + + var child_process = require("child_process"); + var options = Array(); + options.push("-a"); + options.push("all"); + options.push("-l"); + options.push(lotwStation.value); + if (lotwTrusted.value.length > 0) + { + options.push("-p"); + options.push(lotwTrusted.value); + } + options.push("-q"); + options.push("-x"); + options.push("-d"); + options.push("-u"); + options.push(g_trustTempPath); + + child_process.execFile( + g_trustedQslSettings.binaryFile, + options, + (error, stdout, stderr) => // eslint-disable-line node/handle-callback-err + { + if (stderr.indexOf("Final Status: Success") < 0) + { + alert(stderr); + addLastTraffic("Fail log to TQSL"); + } + else + { + addLastTraffic("Logged to TQSL"); + } + fs.unlinkSync(g_trustTempPath); + } + ); + } +} + +function n1mmLoggerChanged() +{ + g_N1MMSettings.enable = buttonN1MMCheckBox.checked; + g_N1MMSettings.ip = N1MMIpInput.value; + g_N1MMSettings.port = N1MMPortInput.value; + + localStorage.N1MMSettings = JSON.stringify(g_N1MMSettings); +} + +function log4OMLoggerChanged() +{ + g_log4OMSettings.enable = buttonLog4OMCheckBox.checked; + g_log4OMSettings.ip = log4OMIpInput.value; + g_log4OMSettings.port = log4OMPortInput.value; + + localStorage.log4OMSettings = JSON.stringify(g_log4OMSettings); +} + +function acLogLoggerChanged() +{ + g_acLogSettings.enable = buttonacLogCheckBox.checked; + g_acLogSettings.ip = acLogIpInput.value; + g_acLogSettings.port = acLogPortInput.value; + + localStorage.acLogSettings = JSON.stringify(g_acLogSettings); +} + +function dxkLogLoggerChanged() +{ + g_dxkLogSettings.enable = buttondxkLogCheckBox.checked; + g_dxkLogSettings.ip = dxkLogIpInput.value; + g_dxkLogSettings.port = dxkLogPortInput.value; + + localStorage.dxkLogSettings = JSON.stringify(g_dxkLogSettings); +} + +function hrdLogbookLoggerChanged() +{ + g_HRDLogbookLogSettings.enable = buttonHrdLogbookCheckBox.checked; + g_HRDLogbookLogSettings.ip = hrdLogbookIpInput.value; + g_HRDLogbookLogSettings.port = hrdLogbookPortInput.value; + + localStorage.HRDLogbookLogSettings = JSON.stringify(g_HRDLogbookLogSettings); +} + +function CloudUrlErrorCallback( + file_url, + callback, + flag, + mode, + port, + theData, + timeoutMs, + timeoutCallback, + message +) +{ + CloudlogTestResult.innerHTML = message; +} + +function CloudlogSendLogResult(buffer, flag) +{ + if (flag && flag == true) + { + if (buffer) + { + if (buffer.indexOf("missing api key") > -1) + { + CloudlogTestResult.innerHTML = "API Key Invalid"; + } + else if (buffer.indexOf("created") > -1) + { + CloudlogTestResult.innerHTML = "Passed"; + } + else + { + CloudlogTestResult.innerHTML = "Invalid Response"; + } + } + else + { + CloudlogTestResult.innerHTML = "Invalid Response"; + } + } + else + { + if (buffer && buffer.indexOf("created") > -1) + { addLastTraffic("Logged to Cloudlog"); } + else addLastTraffic("Fail log to Cloudlog"); + } +} + +function qrzSendLogResult(buffer, flag) +{ + if (typeof buffer != "undefined" && buffer != null) + { + var data = String(buffer); + var kv = data.split("&"); + if (kv.length > 0) + { + var arrData = Object(); + for (var x in kv) + { + var split = kv[x].split("="); + arrData[split[0]] = split[1]; + } + if ( + typeof arrData.RESULT == "undefined" || + arrData.RESULT != "OK" + ) + { + alert( + "Error uploading QSO to QRZ.com (" + + (arrData.REASON || "Unknown error") + + ")" + ); + addLastTraffic("Fail log to QRZ.com"); + } + else + { addLastTraffic("Logged to QRZ.com"); } + } + } + else alert("Error uploading QSO to QRZ.com (No response)"); +} + +function postDialogRetryCallback( + file_url, + callback, + flag, + mode, + port, + theData, + timeoutMs, + timeoutCallback, + who +) +{ + if (window.confirm("Error sending QSO to " + who + ", retry?")) + { + getPostBuffer( + file_url, + callback, + flag, + mode, + port, + theData, + timeoutMs, + postDialogRetryCallback, + who + ); + } +} + +function postRetryErrorCallaback( + file_url, + callback, + flag, + mode, + port, + theData, + timeoutMs, + timeoutCallback, + who +) +{ + getPostBuffer( + file_url, + callback, + flag, + mode, + port, + theData, + timeoutMs, + postDialogRetryCallback, + who + ); +} + +function sendQrzLogEntry(report) +{ + if (g_mapSettings.offlineMode == true) return; + + if (logQRZqsoCheckBox.checked == true && ValidateQrzApi(qrzApiKey)) + { + if (typeof nw != "undefined") + { + var postData = { + KEY: qrzApiKey.value, + ACTION: "INSERT", + ADIF: report + }; + getPostBuffer( + "https://logbook.qrz.com/api", + qrzSendLogResult, + null, + "https", + 443, + postData, + 30000, + postRetryErrorCallaback, + "QRZ.com" + ); + } + } +} + +function clubLogQsoResult(buffer, flag) +{ + addLastTraffic("Logged to ClubLog.org"); +} + +function sendClubLogEntry(report) +{ + if (g_mapSettings.offlineMode == true) return; + + if (logClubqsoCheckBox.checked == true) + { + if (typeof nw != "undefined") + { + var postData = { + email: clubEmail.value, + password: clubPassword.value, + callsign: clubCall.value, + adif: report, + api: CLk + }; + + getPostBuffer( + "https://clublog.org/realtime.php", + clubLogQsoResult, + null, + "https", + 443, + postData, + 30000, + postRetryErrorCallaback, + "ClubLog.org" + ); + } + } +} + +function sendCloudlogEntry(report) +{ + if (g_mapSettings.offlineMode == true) return; + + if (logCloudlogQSOCheckBox.checked == true) + { + if (typeof nw != "undefined") + { + var postData = { key: CloudlogAPI.value, type: "adif", string: report }; + getPostJSONBuffer( + CloudlogURL.value, + CloudlogSendLogResult, + null, + "https", + 80, + postData, + 10000, + CloudUrlErrorCallback, + "Failed to Send" + ); + } + } +} + +function hrdSendLogResult(buffer, flag) +{ + if (flag && flag == true) + { + if (buffer.indexOf("Unknown user") > -1) + { + HRDLogTestResult.innerHTML = "Failed"; + logHRDLOGqsoCheckBox.checked = false; + adifLogQsoCheckBoxChanged(logHRDLOGqsoCheckBox); + } + else HRDLogTestResult.innerHTML = "Passed"; + } + else + { + if (buffer.indexOf("Unknown user") == -1) + { addLastTraffic("Logged to HRDLOG.net"); } + else + { addLastTraffic("Fail log to HRDLOG.net"); } + } +} + +function sendHrdLogEntry(report) +{ + if (g_mapSettings.offlineMode == true) return; + + if (logHRDLOGqsoCheckBox.checked == true) + { + if (typeof nw != "undefined") + { + var postData = { + Callsign: HRDLOGCallsign.value, + Code: HRDLOGUploadCode.value, + App: "GridTracker " + gtVersion, + ADIFData: report + }; + getPostBuffer( + "https://www.hrdlog.net/NewEntry.aspx", + hrdSendLogResult, + null, + "https", + 443, + postData, + 30000, + postRetryErrorCallaback, + "HRDLog.net" + ); + } + } +} + +function hrdCredentialTest(test) +{ + if (test && test == true) + { + HRDLogTestResult.innerHTML = "Testing"; + + if (typeof nw != "undefined") + { + var postData = { + Callsign: HRDLOGCallsign.value, + Code: HRDLOGUploadCode.value + }; + getPostBuffer( + "https://www.hrdlog.net/NewEntry.aspx", + hrdSendLogResult, + test, + "https", + 443, + postData + ); + } + } +} + +function ClublogTest(test) +{ + if (test && test == true) + { + CloudlogTestResult.innerHTML = "Testing"; + + if (typeof nw != "undefined") + { + var postData = { key: CloudlogAPI.value, type: "adif", string: "" }; + getPostJSONBuffer( + CloudlogURL.value, + CloudlogSendLogResult, + test, + "https", + 80, + postData, + 10000, + CloudUrlErrorCallback, + "No Response
or
Timeout" + ); + } + } +} + +function getPostJSONBuffer( + file_url, + callback, + flag, + mode, + port, + theData, + timeoutMs, + timeoutCallback, + who +) +{ + try + { + var postData = JSON.stringify(theData); + var url = require("url"); + var protocol = url.parse(file_url).protocol; // eslint-disable-line node/no-deprecated-api + var http = require(protocol.replace(":", "")); + var fileBuffer = null; + var options = { + host: url.parse(file_url).hostname, // eslint-disable-line node/no-deprecated-api + port: url.parse(file_url).port, // eslint-disable-line node/no-deprecated-api + path: url.parse(file_url).path, // eslint-disable-line node/no-deprecated-api + method: "post", + headers: { + "Content-Type": "application/json", + "Content-Length": postData.length + } + }; + var req = http.request(options, function (res) + { + var fsize = res.headers["content-length"]; + var cookies = null; + if (typeof res.headers["set-cookie"] != "undefined") + { cookies = res.headers["set-cookie"]; } + res + .on("data", function (data) + { + if (fileBuffer == null) fileBuffer = data; + else fileBuffer += data; + }) + .on("end", function () + { + if (typeof callback === "function") + { + // Call it, since we have confirmed it is callable + callback(fileBuffer, flag, cookies); + } + }) + .on("error", function () {}); + }); + if (typeof timeoutMs == "number" && timeoutMs > 0) + { + req.on("socket", function (socket) + { + socket.setTimeout(timeoutMs); + socket.on("timeout", function () + { + req.abort(); + }); + }); + req.on("error", function (err) // eslint-disable-line node/handle-callback-err + { + if (typeof timeoutCallback != "undefined") + { + timeoutCallback( + file_url, + callback, + flag, + mode, + 80, + theData, + timeoutMs, + timeoutCallback, + who + ); + } + }); + } + req.write(postData); + req.end(); + } + catch (e) + { + if (typeof timeoutCallback != "undefined") + { + timeoutCallback( + file_url, + callback, + flag, + mode, + 80, + theData, + timeoutMs, + timeoutCallback, + "Invalid Url" + ); + } + } +} + +function valueToXmlField(field, value) +{ + var adi = "<" + field + ">"; + adi += String(value); + adi += ""; + return adi; +} + +function aclUpdateControlValue(control, value) +{ + return ( + valueToXmlField( + "CMD", + "" + + valueToXmlField("CONTROL", control) + + valueToXmlField("VALUE", value) + ) + "\r\n" + ); +} + +function aclAction(action) +{ + return ( + valueToXmlField("CMD", "" + valueToXmlField("VALUE", action)) + + "\r\n" + ); +} + +function adifField(record, key) +{ + if (key in record) return record[key]; + else return ""; +} +function sendACLogMessage(record, port, address) +{ + var report = ""; + + report += aclAction("CLEAR"); + report += aclUpdateControlValue("TXTENTRYBAND", adifField(record, "BAND")); + report += aclUpdateControlValue("TXTENTRYCALL", adifField(record, "CALL")); + report += aclAction("CALLTAB"); + report += aclUpdateControlValue( + "TXTENTRYFREQUENCY", + adifField(record, "FREQ") + ); + if (adifField(record, "SUBMODE").length > 0) + { + report += aclUpdateControlValue( + "TXTENTRYMODE", + adifField(record, "SUBMODE") + ); + } + else + { report += aclUpdateControlValue("TXTENTRYMODE", adifField(record, "MODE")); } + + var date = adifField(record, "QSO_DATE"); + var dataString = + date.substr(0, 4) + "/" + date.substr(4, 2) + "/" + date.substr(6); + + report += aclUpdateControlValue("TXTENTRYDATE", dataString); + + var timeVal = adifField(record, "TIME_ON"); + var whenString = + timeVal.substr(0, 2) + + ":" + + timeVal.substr(2, 2) + + ":" + + timeVal.substr(4, 2); + report += aclUpdateControlValue("TXTENTRYTIMEON", whenString); + + timeVal = adifField(record, "TIME_OFF"); + whenString = + timeVal.substr(0, 2) + + ":" + + timeVal.substr(2, 2) + + ":" + + timeVal.substr(4, 2); + report += aclUpdateControlValue("TXTENTRYTIMEOFF", whenString); + + report += aclUpdateControlValue( + "TXTENTRYRSTR", + adifField(record, "RST_RCVD") + ); + report += aclUpdateControlValue( + "TXTENTRYRSTS", + adifField(record, "RST_SENT") + ); + report += aclUpdateControlValue("TXTENTRYPOWER", adifField(record, "TX_PWR")); + report += aclUpdateControlValue( + "TXTENTRYGRID", + adifField(record, "GRIDSQUARE") + ); + report += aclUpdateControlValue( + "TXTENTRYCOMMENTS", + adifField(record, "COMMENT") + ); + report += aclUpdateControlValue("TXTENTRYNAMER", adifField(record, "NAME")); + report += aclUpdateControlValue("TXTENTRYIOTA", adifField(record, "IOTA")); + report += aclUpdateControlValue( + "TXTENTRYCONTINENT", + adifField(record, "CONT") + ); + report += aclUpdateControlValue("TXTENTRYITUZ", adifField(record, "ITUZ")); + report += aclUpdateControlValue("TXTENTRYCQZONE", adifField(record, "CQZ")); + report += aclUpdateControlValue("TXTENTRYCOUNTYR", adifField(record, "CNTY")); + + var sentSpcNum = false; + if (adifField(record, "SRX").length > 0) + { + report += aclUpdateControlValue( + "TXTENTRYSERIALNOR", + adifField(record, "SRX") + ); + } + else if (adifField(record, "CONTEST_ID").length > 0) + { + report += aclUpdateControlValue( + "TXTENTRYSPCNUM", + adifField(record, "SRX_STRING") + ); + sentSpcNum = true; + report += aclUpdateControlValue( + "TXTENTRYCLASS", + adifField(record, "CLASS") + ); + report += aclUpdateControlValue( + "TXTENTRYSECTION", + adifField(record, "ARRL_SECT") + ); + } + + if (adifField(record, "STATE").length > 0) + { + report += aclUpdateControlValue( + "TXTENTRYSTATE", + adifField(record, "STATE") + ); + if (sentSpcNum == false) + { + report += aclUpdateControlValue( + "TXTENTRYSPCNUM", + adifField(record, "STATE") + ); + } + } + + report += aclAction("ENTER"); + + sendTcpMessage(report, report.length, port, address); +} + +function sendDXKeeperLogMessage(newMessage, port, address) +{ + var report = ""; + + report += valueToAdiField("command", "log"); + report += valueToAdiField("parameters", newMessage); + report += "\r\n"; + + sendTcpMessage(report, report.length, Number(port) + 1, address); +} + +function parseADIFRecord(adif) +{ + var regex = new RegExp("", "i"); + var newLine = adif.split(regex); + var line = newLine[0].trim(); // Catch the naughty case of someone sending two records at the same time + var record = {}; + + // because strings are not escaped for adif.. ie: :'s and <'s .. we have to walk from left to right + // cheesy, but damn i'm tired of parsing things + var x = 0; + while (line.length > 0) + { + while (line.charAt(0) != "<" && line.length > 0) + { + line = line.substr(1); + } + if (line.length > 0) + { + line = line.substr(1); + var where = line.indexOf(":"); + if (where != -1) + { + var fieldName = line.substr(0, where).toUpperCase(); + line = line.substr(fieldName.length + 1); + var fieldLength = parseInt(line); + var end = line.indexOf(">"); + if (end > 0) + { + line = line.substr(end + 1); + var fieldValue = line.substr(0, fieldLength); + line = line.substr(fieldLength); + record[fieldName] = fieldValue; + } + } + } + } + + return record; +} + +function sendHRDLogbookEntry(report, port, address) +{ + var command = "ver\rdb add {"; + var items = Object.assign({}, report); + + items.FREQ = items.FREQ.split(".").join(""); + + for (var item in items) + { + command += item + "=\"" + items[item] + "\" "; + } + + command += "}\rexit\r"; + + sendTcpMessage(command, command.length, Number(port), address); +}