package main import ( "flag" "fmt" "strings" "github.com/nxadm/tail" ) // ParseChat Parses a string, returns the payload of the chat // *sigh* // This took effing forever to get right. // "Lets start with Regex, cannot go wrong". // You have this string: // ��[ 2022.02.09 10:05:43 ] Kaysee Guru > EX-GBT clr nd // Cool. Looks easy. // .*\[ (.*?) (.*?) \] (.*?) > (.*) // regex101.com says its good // And no matter what I do just does not work for some magical reason. // // Lets do this with splitting by space and compare it with that. Do a bunch of ifs, it works in test aaaaaand.... // It doesn't work. // // By now I have a somewhat reliable version, but it fails to look for the word MOTD. // I should prolly look into runes() // This is terrible func ParseChat(chatline string) (LineDate string, LineTime string, LineUser string, Payload []string) { logLine := chatline[3:] //var LineDate string //var LineTime string //var LineUser string var LinePayload string //var Payload []string var splitpos int splitpos = strings.Index(logLine, ">") LineDate = logLine[4:24] LineTime = logLine[24:42] LineUser = logLine[46 : splitpos-2] LinePayload = logLine[splitpos+4:] LinePayload = shorten(LinePayload) Payload = strings.Fields(LinePayload) //fmt.Println(logLine) //fmt.Println(LineDate) //fmt.Println(LineTime) //fmt.Println(LineUser) //fmt.Println(splitpos) //fmt.Println(LinePayload) //fmt.Println(Payload) return } func shorten(payload string) (logLine string) { runes := []rune(payload) for pos, char := range runes { if pos%2 == 0 && char != 13 { logLine = logLine + string(char) } } return } // CompareElements Compares a log msg with systems we wish to track func CompareElements(alerts []string, payload []string) bool { for _, word := range payload { for _, alert := range alerts { if strings.EqualFold(word, alert) { //fmt.Println("Found (EF): ", alert, "in", word) return true } //else { // fmt.Println(word, "!=", alert) //} // In the odd case somebody links "C-V6DQ*" if len(word) > 6 { //alert = alert[:len(word)] word = word[:6] } // In case of partials like "C-V" if len(word) < 6 && len(word) >= 3 { //word = word[:5] alert = alert[:len(word)] } if strings.EqualFold(word, alert) { //fmt.Println("Found: ", alert, "in", word) return true } } } return false } // playBeep Play a beep // Honestly, I tried to play alert.mp3, but after two executions I got a segfault and thought 0x07 it is! func playBeep() { fmt.Print("\a") } func main() { // Deal with parameters first. LogLocation := flag.String("l", "", "Location of the log-file to track.") LogSystemsRaw := flag.String("s", "jita,Perimeter,New Caldari,Sobaseki", "comma-seperated list of systems") //LogAlarm := flag.String("a", "alert.mp3", "Audio file to play when an alert needs to be triggered") flag.Parse() // Split the CSV string into different parts LogSystems := strings.Split(*LogSystemsRaw, ",") // Do the main loop and start parsing the logfiles t, err := tail.TailFile(*LogLocation, tail.Config{Follow: true}) if err != nil { panic(err) } for line := range t.Lines { // Cast a line to a text, trim the trash logLine := string(line.Text) logLine = strings.Trim(logLine, "\n") // Figure out if this is a message we want to deal with // > is critical in this regard because it is the start of the message // and everything behind it until it hits ] is the username splitpos := strings.Index(logLine, ">") if -1 == splitpos { continue } // Somehow I cannot filter out this stuff. // EVE System > Channel MOTD LineDate, LineTime, LineUser, Payload := ParseChat(logLine) if CompareElements(LogSystems, Payload) { playBeep() fmt.Println("On", LineDate, "at", LineTime, "", LineUser, "posted", Payload) } } }