commit bf8a95bf2160a9b8e2f4a0757d925d58511a4605 Author: rouggy Date: Mon Jul 1 23:05:34 2024 +0700 first commit diff --git a/config.yml b/config.yml new file mode 100644 index 0000000..b1088a0 --- /dev/null +++ b/config.yml @@ -0,0 +1,7 @@ +gotify: + url: https://gotify.rouggy.com/message + token: ALaGS4MVMWTEMcP + +cluster: + host: dxc.nc7j.com:23 + call: XV9Q \ No newline at end of file diff --git a/dx.txt b/dx.txt new file mode 100644 index 0000000..7d0e799 --- /dev/null +++ b/dx.txt @@ -0,0 +1 @@ +8P9CB ZC4GW TM5FI 3A/LB3LJ VP2V/W5GI VP9/AB2E 8Q7KR FT4GL 8Q7KB 5W1SA TF2MSN FW1JG CO8BLY PZ5RA OD5KU \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100644 index 0000000..5475d55 --- /dev/null +++ b/go.mod @@ -0,0 +1,3 @@ +module gitea.rouggy.com/PushDXCluster + +go 1.21.4 diff --git a/icon.ico b/icon.ico new file mode 100644 index 0000000..562f0b9 Binary files /dev/null and b/icon.ico differ diff --git a/main.go b/main.go new file mode 100644 index 0000000..9171ed2 --- /dev/null +++ b/main.go @@ -0,0 +1,198 @@ +package main + +import ( + "bufio" + "bytes" + "encoding/json" + "fmt" + "io" + "log" + "net" + "net/http" + "os" + "regexp" + "strings" + "time" +) + +const ( + telnetAddress = "dxc.nc7j.com:23" // Remplace par l'adresse et le port de ton serveur Telnet + gotifyURL = "https://gotify.rouggy.com/message" // Remplace par l'URL de ton serveur Gotify + gotifyToken = "ALaGS4MVMWTEMcP" // Remplace par le token de ton application Gotify + identificationMessage = "XV9Q" // Message d'identification à envoyer au serveur Telnet +) + +var DX = readDXExpeFile("dx.txt") + +type ClusterMessage struct { + From string + DX string + Freq string + Mode string + Report string + Time string +} + +// Message structure for Gotify +type GotifyMessage struct { + Title string `json:"title"` + Message string `json:"message"` + Priority int `json:"priority"` +} + +func readDXExpeFile(filename string) string { + file, err := os.Open(filename) + if err != nil { + fmt.Println("Error while opening file", err) + } + defer file.Close() + + // Lire tout le contenu du fichier + content, err := io.ReadAll(file) + if err != nil { + fmt.Println("Error while reading the file", err) + } + log.Println("DX Expe file has been loaded properly") + return string(content) +} + +// Function to send message to Gotify +func sendToGotify(title string, sMess ClusterMessage, priority int) { + + message := fmt.Sprintf("DX: %s\nFrom: %s\nFreq: %s\nMode: %s\nReport: %s\nTime: %s", sMess.DX, sMess.From, sMess.Freq, sMess.Mode, sMess.Report, sMess.Time) + + gotifyMsg := GotifyMessage{ + Title: title, + Message: message, + Priority: priority, + } + + jsonData, err := json.Marshal(gotifyMsg) + if err != nil { + log.Println("Error marshaling JSON:", err) + return + } + + req, err := http.NewRequest("POST", gotifyURL, bytes.NewBuffer(jsonData)) + if err != nil { + log.Println("Error creating request:", err) + return + } + req.Header.Set("Content-Type", "application/json") + req.Header.Add("Authorization", "Bearer ALaGS4MVMWTEMcP") + + client := &http.Client{} + resp, err := client.Do(req) + if err != nil { + log.Println("Error sending request:", err) + return + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + log.Println("Gotify server returned non-OK status:", resp.Status) + } else { + log.Println("message successfully sent to Gotify") + } + +} + +func SanitizeClusterMessage(message string) ClusterMessage { + r := regexp.MustCompile(`DX\sde\s([A-Z0-9]+)[-#:]+[\s]+([0-9]+.[0-9])[\s]+([^\s]+)[\s]+([A-Z]+[0-9])\s+(.*dB).*(.{4})Z$`) + matches := r.FindStringSubmatch(message) + + mes := ClusterMessage{} + + if len(matches) > 0 { + timeLayout := "1504" + formatedTime, _ := time.Parse(timeLayout, matches[6]) + formatedTime = formatedTime.Add(time.Hour * time.Duration(7)) + newTime := formatedTime.Format("15:04") + + mes := ClusterMessage{ + From: matches[1], + Freq: matches[2], + DX: matches[3], + Mode: matches[4], + Report: matches[5], + Time: newTime, + } + + return mes + } + + return mes +} + +func main() { + fmt.Println("PushDXCluster v0.1") + for { + // Connect to the Telnet server + conn, err := net.Dial("tcp", "ve7cc.net:23") + if err != nil { + log.Printf("Failed to connect to Telnet server: %v", err) + time.Sleep(5 * time.Second) // Wait before retrying + continue + } + + log.Println("Connected to Telnet server") + time.Sleep(3 * time.Second) + + // Send identification message + _, err = conn.Write([]byte(identificationMessage + "\n")) + if err != nil { + log.Printf("Failed to send identification message: %v", err) + conn.Close() + time.Sleep(5 * time.Second) // Wait before retrying + continue + } + log.Println("Identification message sent") + + time.Sleep(3 * time.Second) + + _, err = conn.Write([]byte("set/ft8" + "\n")) + + if err != nil { + log.Printf("Failed to send FT8 message: %v", err) + conn.Close() + time.Sleep(5 * time.Second) // Wait before retrying + continue + } + log.Println("Set FT8 message sent") + + time.Sleep(3 * time.Second) + + _, err = conn.Write([]byte("SET/FILTER DOC/PASS 3W" + "\n")) + + if err != nil { + log.Printf("Failed to send Filter message: %v", err) + conn.Close() + time.Sleep(5 * time.Second) // Wait before retrying + continue + } + log.Println("Set filter Vietnam message sent") + + // Create a buffered reader to read from the Telnet server + reader := bufio.NewReader(conn) + + // Loop to read from the Telnet server + for { + message, err := reader.ReadString('\n') + if err != nil { + log.Printf("Error reading from Telnet server: %v", err) + conn.Close() + break + } + message = strings.TrimSpace(message) + sMess := SanitizeClusterMessage(message) + log.Printf("Received message: %s", message) + if sMess.DX != "" && sMess.From == "XV9Q" && strings.Contains(DX, sMess.DX) { + sendToGotify("Spot", sMess, 5) + } + + } + + log.Println("Disconnected from Telnet server, reconnecting...") + time.Sleep(5 * time.Second) // Wait before reconnecting + } +}