|
| 1 | +package main |
| 2 | + |
| 3 | +import ( |
| 4 | + "log" |
| 5 | + "net/http" |
| 6 | + "net/url" |
| 7 | + "strings" |
| 8 | + "time" |
| 9 | +) |
| 10 | + |
| 11 | +// submitLogbookAsync は非同期でADIFを各オンラインログサービスに送信します |
| 12 | +func submitLogbookAsync(adif string) { |
| 13 | + configLock.RLock() |
| 14 | + qrzEnabled := config.LogbookQRZEnabled |
| 15 | + qrzAPIKey := config.LogbookQRZAPIKey |
| 16 | + hamqthEnabled := config.LogbookHamQTHEnabled |
| 17 | + hamqthCallsign := config.LogbookHamQTHCallsign |
| 18 | + hamqthUser := config.LogbookHamQTHUser |
| 19 | + hamqthPass := config.LogbookHamQTHPass |
| 20 | + eqslEnabled := config.LogbookEQSLEnabled |
| 21 | + eqslUser := config.LogbookEQSLUser |
| 22 | + eqslPass := config.LogbookEQSLPass |
| 23 | + hrdlogEnabled := config.LogbookHRDLogEnabled |
| 24 | + hrdlogCall := config.LogbookHRDLogCallsign |
| 25 | + hrdlogCode := config.LogbookHRDLogCode |
| 26 | + // clublogEnabled := config.LogbookClubLogEnabled |
| 27 | + // clublogEmail := config.LogbookClubLogEmail |
| 28 | + // clublogPass := config.LogbookClubLogPass |
| 29 | + // clublogCall := config.LogbookClubLogCall |
| 30 | + // clublogAPI := config.LogbookClubLogAPI |
| 31 | + configLock.RUnlock() |
| 32 | + |
| 33 | + // QRZ Logbook |
| 34 | + if qrzEnabled && qrzAPIKey != "" { |
| 35 | + go submitQRZLogbook(adif, qrzAPIKey) |
| 36 | + } |
| 37 | + |
| 38 | + // HamQTH |
| 39 | + if hamqthEnabled && hamqthCallsign != "" && hamqthUser != "" && hamqthPass != "" { |
| 40 | + go submitHamQTH(adif, hamqthCallsign, hamqthUser, hamqthPass) |
| 41 | + } |
| 42 | + |
| 43 | + // eQSL |
| 44 | + if eqslEnabled && eqslUser != "" && eqslPass != "" { |
| 45 | + go submitEQSL(adif, eqslUser, eqslPass) |
| 46 | + } |
| 47 | + |
| 48 | + // HRDLog |
| 49 | + if hrdlogEnabled && hrdlogCall != "" && hrdlogCode != "" { |
| 50 | + go submitHRDLog(adif, hrdlogCall, hrdlogCode) |
| 51 | + } |
| 52 | + |
| 53 | + // ClubLog (430ssb.net中継経由で実装予定 - ペンディング) |
| 54 | + // if clublogEnabled && clublogEmail != "" && clublogPass != "" && clublogCall != "" { |
| 55 | + // go submitClubLog(adif, clublogEmail, clublogPass, clublogCall, clublogAPI) |
| 56 | + // } |
| 57 | +} |
| 58 | + |
| 59 | +// submitQRZLogbook はQRZ.com Logbookへ送信します |
| 60 | +func submitQRZLogbook(adif, apikey string) { |
| 61 | + defer func() { |
| 62 | + if r := recover(); r != nil { |
| 63 | + log.Println("[LOGBOOK] QRZ panic:", r) |
| 64 | + } |
| 65 | + }() |
| 66 | + |
| 67 | + log.Println("[LOGBOOK] QRZ: sending...") |
| 68 | + log.Printf("[LOGBOOK] QRZ: KEY=%s", apikey) |
| 69 | + log.Printf("[LOGBOOK] QRZ: ADIF=%s", adif) |
| 70 | + |
| 71 | + client := &http.Client{Timeout: 10 * time.Second} |
| 72 | + resp, err := client.PostForm("https://logbook.qrz.com/api", url.Values{ |
| 73 | + "KEY": {apikey}, |
| 74 | + "ACTION": {"INSERT"}, |
| 75 | + "ADIF": {adif}, |
| 76 | + }) |
| 77 | + if err != nil { |
| 78 | + log.Println("[LOGBOOK] QRZ error:", err) |
| 79 | + return |
| 80 | + } |
| 81 | + defer resp.Body.Close() |
| 82 | + |
| 83 | + // レスポンスボディを読み取る |
| 84 | + body := make([]byte, 1024) |
| 85 | + n, _ := resp.Body.Read(body) |
| 86 | + responseText := string(body[:n]) |
| 87 | + |
| 88 | + if resp.StatusCode == 200 { |
| 89 | + log.Printf("[LOGBOOK] QRZ: success - response: %s", responseText) |
| 90 | + } else { |
| 91 | + log.Printf("[LOGBOOK] QRZ: failed, status: %d, response: %s", resp.StatusCode, responseText) |
| 92 | + } |
| 93 | +} |
| 94 | + |
| 95 | +// submitHamQTH はHamQTHへ送信します |
| 96 | +func submitHamQTH(adif, callsign, user, pass string) { |
| 97 | + defer func() { |
| 98 | + if r := recover(); r != nil { |
| 99 | + log.Println("[LOGBOOK] HamQTH panic:", r) |
| 100 | + } |
| 101 | + }() |
| 102 | + |
| 103 | + log.Println("[LOGBOOK] HamQTH: sending...") |
| 104 | + |
| 105 | + client := &http.Client{Timeout: 10 * time.Second} |
| 106 | + resp, err := client.PostForm("https://www.hamqth.com/qso_realtime.php", url.Values{ |
| 107 | + "c": {callsign}, |
| 108 | + "u": {user}, |
| 109 | + "p": {pass}, |
| 110 | + "adif": {adif}, |
| 111 | + "prg": {"hamlab-bridge"}, |
| 112 | + "cmd": {"insert"}, |
| 113 | + }) |
| 114 | + if err != nil { |
| 115 | + log.Println("[LOGBOOK] HamQTH error:", err) |
| 116 | + return |
| 117 | + } |
| 118 | + defer resp.Body.Close() |
| 119 | + |
| 120 | + // レスポンスボディを読み取る |
| 121 | + body := make([]byte, 1024) |
| 122 | + n, _ := resp.Body.Read(body) |
| 123 | + responseText := string(body[:n]) |
| 124 | + |
| 125 | + if resp.StatusCode == 200 { |
| 126 | + log.Printf("[LOGBOOK] HamQTH: success (response: %s)", responseText) |
| 127 | + } else { |
| 128 | + log.Printf("[LOGBOOK] HamQTH: failed, status: %d, response: %s", resp.StatusCode, responseText) |
| 129 | + } |
| 130 | +} |
| 131 | + |
| 132 | +// submitEQSL はeQSL.ccへ送信します |
| 133 | +func submitEQSL(adif, user, pass string) { |
| 134 | + defer func() { |
| 135 | + if r := recover(); r != nil { |
| 136 | + log.Println("[LOGBOOK] eQSL panic:", r) |
| 137 | + } |
| 138 | + }() |
| 139 | + |
| 140 | + log.Println("[LOGBOOK] eQSL: sending...") |
| 141 | + |
| 142 | + // GETリクエストのURLを構築 |
| 143 | + params := url.Values{} |
| 144 | + params.Set("ADIFData", adif) |
| 145 | + params.Set("EQSL_USER", user) |
| 146 | + params.Set("EQSL_PSWD", pass) |
| 147 | + |
| 148 | + reqURL := "https://www.eqsl.cc/qslcard/importADIF.cfm?" + params.Encode() |
| 149 | + |
| 150 | + client := &http.Client{Timeout: 10 * time.Second} |
| 151 | + resp, err := client.Get(reqURL) |
| 152 | + if err != nil { |
| 153 | + log.Println("[LOGBOOK] eQSL error:", err) |
| 154 | + return |
| 155 | + } |
| 156 | + defer resp.Body.Close() |
| 157 | + |
| 158 | + // レスポンスボディを読み取る |
| 159 | + body := make([]byte, 1024) |
| 160 | + n, _ := resp.Body.Read(body) |
| 161 | + responseText := string(body[:n]) |
| 162 | + |
| 163 | + if resp.StatusCode == 200 { |
| 164 | + log.Printf("[LOGBOOK] eQSL: success (response: %s)", responseText) |
| 165 | + } else { |
| 166 | + log.Printf("[LOGBOOK] eQSL: failed, status: %d, response: %s", resp.StatusCode, responseText) |
| 167 | + } |
| 168 | +} |
| 169 | + |
| 170 | +// submitHRDLog はHRDLog.netへ送信します |
| 171 | +func submitHRDLog(adif, callsign, uploadCode string) { |
| 172 | + defer func() { |
| 173 | + if r := recover(); r != nil { |
| 174 | + log.Println("[LOGBOOK] HRDLog panic:", r) |
| 175 | + } |
| 176 | + }() |
| 177 | + |
| 178 | + log.Println("[LOGBOOK] HRDLog: sending...") |
| 179 | + log.Printf("[LOGBOOK] HRDLog: Callsign=%s, UploadCode=%s", callsign, uploadCode) |
| 180 | + log.Printf("[LOGBOOK] HRDLog: ADIF=%s", adif) |
| 181 | + |
| 182 | + client := &http.Client{Timeout: 10 * time.Second} |
| 183 | + resp, err := client.PostForm("https://robot.hrdlog.net/NewEntry.aspx", url.Values{ |
| 184 | + "Callsign": {callsign}, |
| 185 | + "UploadCode": {uploadCode}, |
| 186 | + "ADIF": {adif}, |
| 187 | + }) |
| 188 | + if err != nil { |
| 189 | + log.Println("[LOGBOOK] HRDLog error:", err) |
| 190 | + return |
| 191 | + } |
| 192 | + defer resp.Body.Close() |
| 193 | + |
| 194 | + // レスポンスボディを読み取る |
| 195 | + body := make([]byte, 1024) |
| 196 | + n, _ := resp.Body.Read(body) |
| 197 | + responseText := string(body[:n]) |
| 198 | + |
| 199 | + if resp.StatusCode == 200 { |
| 200 | + log.Printf("[LOGBOOK] HRDLog: success - response: %s", responseText) |
| 201 | + } else { |
| 202 | + log.Printf("[LOGBOOK] HRDLog: failed, status: %d, response: %s", resp.StatusCode, responseText) |
| 203 | + } |
| 204 | +} |
| 205 | + |
| 206 | +// submitClubLog はClubLogへ送信します |
| 207 | +func submitClubLog(adif, email, password, callsign, apikey string) { |
| 208 | + defer func() { |
| 209 | + if r := recover(); r != nil { |
| 210 | + log.Println("[LOGBOOK] ClubLog panic:", r) |
| 211 | + } |
| 212 | + }() |
| 213 | + |
| 214 | + log.Println("[LOGBOOK] ClubLog: sending...") |
| 215 | + |
| 216 | + client := &http.Client{Timeout: 10 * time.Second} |
| 217 | + |
| 218 | + values := url.Values{ |
| 219 | + "email": {email}, |
| 220 | + "password": {password}, |
| 221 | + "callsign": {callsign}, |
| 222 | + "adif": {adif}, |
| 223 | + } |
| 224 | + |
| 225 | + // APIキーが設定されている場合のみ追加 |
| 226 | + if strings.TrimSpace(apikey) != "" { |
| 227 | + values.Set("api", apikey) |
| 228 | + } |
| 229 | + |
| 230 | + resp, err := client.PostForm("https://secure.clublog.org/realtime.php", values) |
| 231 | + if err != nil { |
| 232 | + log.Println("[LOGBOOK] ClubLog error:", err) |
| 233 | + return |
| 234 | + } |
| 235 | + defer resp.Body.Close() |
| 236 | + |
| 237 | + if resp.StatusCode == 200 { |
| 238 | + log.Println("[LOGBOOK] ClubLog: success") |
| 239 | + } else { |
| 240 | + log.Println("[LOGBOOK] ClubLog: failed, status:", resp.StatusCode) |
| 241 | + } |
| 242 | +} |
0 commit comments