first commit

This commit is contained in:
Gregory Salaun 2023-11-29 11:02:30 +07:00
commit 283264a261
9 changed files with 331 additions and 0 deletions

46
CloudlogUDP.go Normal file
View File

@ -0,0 +1,46 @@
package main
import (
"fmt"
"log"
"net"
"strings"
"git.rouggy.com/CloudlogUDP/cloudlog"
"git.rouggy.com/CloudlogUDP/clublog"
"git.rouggy.com/CloudlogUDP/config"
"git.rouggy.com/CloudlogUDP/qrzcom"
"git.rouggy.com/CloudlogUDP/qso"
)
func main() {
fmt.Println("Loading config file...")
cfg := config.NewConfig()
fmt.Printf("Launching the server on port %v\n", cfg.UDP.Port)
udpServer, err := net.ListenPacket("udp", cfg.UDP.Port)
if err != nil {
log.Fatal(err)
}
defer udpServer.Close()
fmt.Printf("Server listening on port %v for incoming QSO\n", cfg.UDP.Port)
for {
buf := make([]byte, 4096)
_, _, err := udpServer.ReadFrom(buf)
if err != nil {
fmt.Println(err)
continue
}
msg := string(buf[:])
msgSplit := strings.Split(msg, "<")
qso := qso.NewQSO()
qso.ExtractQSOData(msgSplit)
cloudlog.SendCloudlogMsg(qso, cfg)
qrzcom.SendQRZcomlogMsg(qso, cfg)
clublog.SendClublogMsg(qso, cfg)
}
}

51
cloudlog/cloudlog.go Normal file
View File

@ -0,0 +1,51 @@
package cloudlog
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"git.rouggy.com/CloudlogUDP/config"
"git.rouggy.com/CloudlogUDP/qso"
)
type CloudlogAPIString struct {
Key string `json:"key"`
StationProfileID string `json:"station_profile_id"`
Type string `json:"type"`
QSOData string `json:"string"`
}
func SendCloudlogMsg(qso qso.QSO, config config.Config) {
QSODataJson := qso.Call + qso.Band + qso.Mode + qso.Freq + qso.QSODate + qso.TimeOn + qso.RSTR + qso.RSTS + qso.GridSquare
jsonStr := CloudlogAPIString{
Key: config.CloudLog.API,
StationProfileID: "1",
Type: "adif",
QSOData: QSODataJson,
}
b, err := json.Marshal(jsonStr)
if err != nil {
fmt.Println("error:", err)
}
req, err := http.NewRequest("POST", config.CloudLog.QSOUrl, bytes.NewBuffer(b))
req.Header.Set("X-Custom-Header", "myvalue")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
// body, _ := io.ReadAll(resp.Body)
// fmt.Println("response Body:", string(body))
fmt.Printf("QSO Details:\nCall: %v\nBand: %v\nFreq: %v\n", qso.Call, qso.Band, qso.Freq)
fmt.Println("QSO Uploaded to Cloudlog")
}

47
clublog/clublog.go Normal file
View File

@ -0,0 +1,47 @@
package clublog
import (
"fmt"
"net/http"
"net/url"
"strings"
"git.rouggy.com/CloudlogUDP/config"
"git.rouggy.com/CloudlogUDP/qso"
)
type ClublogAPI struct {
Email string `json:"email"`
Password string `json:"password"`
Callsign string `json:"callsign"`
ADIF string `json:"adif"`
APIKey string `json:"api"`
}
func SendClublogMsg(qso qso.QSO, config config.Config) {
QSOData := qso.Call + qso.Band + qso.Mode + qso.Freq + qso.QSODate + qso.TimeOn + qso.RSTR + qso.RSTS + qso.GridSquare + "<eor>"
apiUrl := config.Clublog.URL
data := url.Values{}
data.Set("api", config.Clublog.API)
data.Set("email", config.Clublog.EMail)
data.Set("password", config.Clublog.Password)
data.Set("callsign", config.Clublog.Callsign)
data.Set("adif", QSOData)
u, _ := url.ParseRequestURI(apiUrl)
urlStr := u.String()
client := &http.Client{}
r, _ := http.NewRequest(http.MethodPost, urlStr, strings.NewReader(data.Encode())) // URL-encoded payload
r.Header.Add("Content-Type", "application/x-www-form-urlencoded")
resp, _ := client.Do(r)
if http.StatusOK == 200 {
fmt.Println("QSO Uploaded to Clublog")
} else {
fmt.Printf("Error uploading QSO to Clublog %v", resp.Status)
}
}

49
config/config.go Normal file
View File

@ -0,0 +1,49 @@
package config
import (
"io/ioutil"
"log"
"os"
"path/filepath"
"gopkg.in/yaml.v2"
)
// Config from YAML
type Config struct {
CloudLog struct {
Server string `yaml:"server"`
QSOUrl string `yaml:"qso_url"`
API string `yaml:"api"`
} `yaml:"cloudlog"`
UDP struct {
Port string `yaml:"port"`
} `yaml:"udp"`
QRZ struct {
API string `yaml:"api"`
Callsign string `yaml:"callsign"`
}
Clublog struct {
EMail string `yaml:"email"`
Password string `yaml:"password"`
Callsign string `yaml:"callsign"`
API string `yaml:"api"`
URL string `yaml:"url"`
}
}
func NewConfig() Config {
var c Config
ex, err := os.Executable()
if err != nil {
log.Println(err)
}
configFile := filepath.Dir(ex) + "/config/config.yaml"
yamlFile, err := ioutil.ReadFile(configFile)
err = yaml.Unmarshal([]byte(yamlFile), &c)
if err != nil {
log.Fatalf("error: %v", err)
}
return c
}

20
config/config.yaml Normal file
View File

@ -0,0 +1,20 @@
# Cloudlog Setup
# Generate a Read/Write API Key cloudlog/api/help
cloudlog:
server: "https://log.rouggy.com"
qso_url: "https://log.rouggy.com/index.php/api/qso/"
api: "cl65388812a62d1"
udp:
port: ":2240"
qrz:
api: "4AEC-1886-2E4E-C3AF"
callsign: "XV9Q"
clublog:
email: "legreg002@hotmail.com"
password: "89DGgg290379"
callsign: "XV9Q"
api: "5767f19333363a9ef432ee9cd4141fe76b8adf38"
url: "https://clublog.org/realtime.php"

5
go.mod Normal file
View File

@ -0,0 +1,5 @@
module git.rouggy.com/CloudlogUDP
go 1.21.4
require gopkg.in/yaml.v2 v2.4.0

4
go.sum Normal file
View File

@ -0,0 +1,4 @@
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=

53
qrzcom/qrzcom.go Normal file
View File

@ -0,0 +1,53 @@
package qrzcom
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"net/url"
"git.rouggy.com/CloudlogUDP/config"
"git.rouggy.com/CloudlogUDP/qso"
)
type QRZComAPIString struct {
Key string `json:"KEY"`
Action string `json:"ACTION"`
Adif string `json:"ADIF"`
}
func SendQRZcomlogMsg(qso qso.QSO, config config.Config) {
QSODataJson := qso.Call + qso.Band + qso.Mode + qso.Freq + qso.QSODate + qso.TimeOn + qso.RSTR + qso.RSTS + qso.StationCallsign + "<eor>"
jsonStr := QRZComAPIString{
Key: config.QRZ.API,
Action: "INSERT",
Adif: QSODataJson,
}
b, err := json.Marshal(jsonStr)
if err != nil {
fmt.Println("error:", err)
}
params := url.Values{}
params.Add("KEY", jsonStr.Key)
params.Add("ACTION", "INSERT")
params.Add("ADIF", jsonStr.Adif)
urlQRZ := fmt.Sprint("https://logbook.qrz.com/api?" + params.Encode())
req, err := http.NewRequest("POST", urlQRZ, bytes.NewBuffer(b))
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
panic(err)
}
defer resp.Body.Close()
fmt.Println("QSO Uploaded to QRZ.com")
}

56
qso/qso.go Normal file
View File

@ -0,0 +1,56 @@
package qso
import (
"strings"
)
type QSO struct {
Call string
Band string
Mode string
Freq string
QSODate string
TimeOn string
RSTR string
RSTS string
Country string
GridSquare string
StationCallsign string
}
func NewQSO() QSO {
return *&QSO{}
}
func (q *QSO) ExtractQSOData(msg []string) {
for _, entry := range msg {
entry = strings.Trim(entry, " ")
switch {
case strings.Contains(entry, "FREQ:"):
q.Freq = "<" + entry
case strings.Contains(entry, "CALL:"):
q.Call = "<" + entry
case strings.Contains(entry, "BAND:"):
q.Band = "<" + entry
case strings.Contains(entry, "MODE:"):
q.Mode = "<" + entry
case strings.Contains(entry, "QSO_DATE:"):
if q.QSODate == "" {
q.QSODate = "<" + entry
}
case strings.Contains(entry, "TIME_ON:"):
q.TimeOn = "<" + entry
case strings.Contains(entry, "RST_RCVD:"):
q.RSTR = "<" + entry
case strings.Contains(entry, "RST_SENT:"):
q.RSTS = "<" + entry
case strings.Contains(entry, "COUNTRY:"):
q.Country = "<" + entry
case strings.Contains(entry, "GRIDSQUARE:"):
q.GridSquare = "<" + entry
case strings.Contains(entry, "STATION_CALLSIGN:"):
q.StationCallsign = "<" + entry
}
}
}