automatic Logging
This commit is contained in:
parent
0308cf0985
commit
056fda8cff
1 changed files with 174 additions and 16 deletions
180
main.go
180
main.go
|
|
@ -10,8 +10,6 @@ import (
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"sort"
|
"sort"
|
||||||
|
|
||||||
// "strings"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
"time"
|
"time"
|
||||||
Untis "untislogger/Bot"
|
Untis "untislogger/Bot"
|
||||||
|
|
@ -51,25 +49,88 @@ func init() {
|
||||||
}
|
}
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
Untis.Main() //starting API calls function
|
//Untis.Main() //starting API calls function| happens in schedule func
|
||||||
|
//Run()
|
||||||
//checking for time
|
//Starts logging the timetable for each new Lesson and logs changes
|
||||||
|
scheduleTimetableUpdate()
|
||||||
|
|
||||||
sigChan := make(chan os.Signal, 1)
|
sigChan := make(chan os.Signal, 1)
|
||||||
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
signal.Notify(sigChan, syscall.SIGINT, syscall.SIGTERM)
|
||||||
|
|
||||||
log.Println("Program is running. Press Ctrl+C to stop.")
|
log.Println("Program is running. Press Ctrl+C to stop.")
|
||||||
//Start logging
|
//Start logging
|
||||||
Run()
|
//Run()
|
||||||
// Block until we receive a signal
|
// Block until we receive a signal
|
||||||
<-sigChan
|
<-sigChan
|
||||||
log.Println("Shutting down...")
|
log.Println("Shutting down...")
|
||||||
}
|
}
|
||||||
|
func isScheduledTime(now time.Time) bool {
|
||||||
|
scheduled := []string{"07:45", "08:35", "09:35", "10:25", "11:25", "12:15", "13:45", "14:25"}
|
||||||
|
current := now.Format("15:04")
|
||||||
|
for _, t := range scheduled {
|
||||||
|
if t == current {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
func scheduleTimetableUpdate() {
|
||||||
|
var prevData []byte
|
||||||
|
//run once
|
||||||
|
Untis.Main()
|
||||||
|
// Initial read of the file
|
||||||
|
data, err := os.ReadFile("timetableFilled.json")
|
||||||
|
if err == nil {
|
||||||
|
prevData = data
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ticker for checking timetable changes every hour
|
||||||
|
hourTicker := time.NewTicker(1 * time.Hour)
|
||||||
|
go func() {
|
||||||
|
for range hourTicker.C {
|
||||||
|
Untis.Main()
|
||||||
|
data, err := os.ReadFile("timetableFilled.json")
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error reading timetable: %v", err)
|
||||||
|
} else if !bytes.Equal(data, prevData) {
|
||||||
|
log.Println("Timetable file has changed.")
|
||||||
|
sendUpdateDiscordWebhook()
|
||||||
|
prevData = data
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
// Ticker for checking scheduled times every minute
|
||||||
|
startMinuteTicker(func() {
|
||||||
|
now := time.Now()
|
||||||
|
if isScheduledTime(now) {
|
||||||
|
log.Println("Scheduled time reached, updating and running Run()")
|
||||||
|
Untis.Main()
|
||||||
|
log.Println("Updated now running Run()")
|
||||||
|
Run()
|
||||||
|
log.Println("Finished running Run")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func startMinuteTicker(f func()) {
|
||||||
|
now := time.Now()
|
||||||
|
next := now.Truncate(time.Minute).Add(time.Minute)
|
||||||
|
time.Sleep(time.Until(next))
|
||||||
|
ticker := time.NewTicker(1 * time.Minute)
|
||||||
|
go func() {
|
||||||
|
for {
|
||||||
|
f()
|
||||||
|
<-ticker.C
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
#Main Run Function
|
#Main Run Function
|
||||||
*/
|
*/
|
||||||
func Run() {
|
func Run() {
|
||||||
|
log.Println("Sending next Lesson")
|
||||||
codeByStartTime, err := MapTimeToCode("timetableFilled.json")
|
codeByStartTime, err := MapTimeToCode("timetableFilled.json")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println(err)
|
log.Println(err)
|
||||||
|
|
@ -79,14 +140,25 @@ func Run() {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
subjectByStartTime, err := MapTimeToSubject("timetableFilled.json")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
now := time.Now().Format("15:04")
|
now := time.Now().Format("15:04")
|
||||||
nextTime, room, found := NextRoomForTime(roomByStartTime, now)
|
nextTime, room, found := NextRoomForTime(roomByStartTime, now)
|
||||||
if found {
|
if found {
|
||||||
|
log.Println("found Room")
|
||||||
|
Subject, found := NextSubjectForTime(subjectByStartTime, now)
|
||||||
|
if found {
|
||||||
|
log.Println("Found Subject")
|
||||||
Status, found := NextCodeForTime(codeByStartTime, now)
|
Status, found := NextCodeForTime(codeByStartTime, now)
|
||||||
if found {
|
if found {
|
||||||
|
log.Println("Found Status")
|
||||||
fmt.Printf("Next time: %s, Room: %s\n", nextTime, room)
|
fmt.Printf("Next time: %s, Room: %s\n", nextTime, room)
|
||||||
sendDiscordWebhook(room, nextTime, Status)
|
sendDiscordWebhook(Subject, room, nextTime, Status)
|
||||||
|
} else {
|
||||||
|
sendDiscordWebhook(Subject, room, nextTime, "")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -118,6 +190,30 @@ func NextRoomForTime(roomByStartTime map[string]string, current string) (string,
|
||||||
}
|
}
|
||||||
return "", "", false
|
return "", "", false
|
||||||
}
|
}
|
||||||
|
func NextSubjectForTime(subjectByStartTime map[string]string, current string) (string, bool) {
|
||||||
|
layout := "15:04"
|
||||||
|
now, err := time.Parse(layout, current)
|
||||||
|
if err != nil {
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
|
var times []time.Time
|
||||||
|
timeToStr := make(map[time.Time]string)
|
||||||
|
for t := range subjectByStartTime {
|
||||||
|
parsed, err := time.Parse(layout, t)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
times = append(times, parsed)
|
||||||
|
timeToStr[parsed] = t
|
||||||
|
}
|
||||||
|
sort.Slice(times, func(i, j int) bool { return times[i].Before(times[j]) })
|
||||||
|
for _, t := range times {
|
||||||
|
if t.After(now) {
|
||||||
|
return subjectByStartTime[timeToStr[t]], true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return "", false
|
||||||
|
}
|
||||||
func NextCodeForTime(codeByStartTime map[string]string, current string) (string, bool) {
|
func NextCodeForTime(codeByStartTime map[string]string, current string) (string, bool) {
|
||||||
|
|
||||||
layout := "15:04"
|
layout := "15:04"
|
||||||
|
|
@ -156,8 +252,10 @@ func MapTimeToRoom(path string) (map[string]string, error) {
|
||||||
}
|
}
|
||||||
roomByStartTime := make(map[string]string)
|
roomByStartTime := make(map[string]string)
|
||||||
for _, entry := range table {
|
for _, entry := range table {
|
||||||
|
if len(entry.Ro) > 0 {
|
||||||
roomByStartTime[entry.StartTime] = entry.Ro[0]
|
roomByStartTime[entry.StartTime] = entry.Ro[0]
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if roomByStartTime == nil {
|
if roomByStartTime == nil {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
@ -175,8 +273,12 @@ func MapTimeToCode(path string) (map[string]string, error) {
|
||||||
}
|
}
|
||||||
codeByStartTime := make(map[string]string)
|
codeByStartTime := make(map[string]string)
|
||||||
for _, entry := range table {
|
for _, entry := range table {
|
||||||
|
if len(entry.Code) > 0 {
|
||||||
|
if _, exists := codeByStartTime[entry.StartTime]; !exists {
|
||||||
codeByStartTime[entry.StartTime] = entry.Code
|
codeByStartTime[entry.StartTime] = entry.Code
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return codeByStartTime, nil
|
return codeByStartTime, nil
|
||||||
}
|
}
|
||||||
func MapTimeToSubject(path string) (map[string]string, error) {
|
func MapTimeToSubject(path string) (map[string]string, error) {
|
||||||
|
|
@ -191,8 +293,10 @@ func MapTimeToSubject(path string) (map[string]string, error) {
|
||||||
}
|
}
|
||||||
subjectByStartTime := make(map[string]string)
|
subjectByStartTime := make(map[string]string)
|
||||||
for _, entry := range table {
|
for _, entry := range table {
|
||||||
|
if len(entry.Su) > 0 {
|
||||||
subjectByStartTime[entry.StartTime] = entry.Su[0]
|
subjectByStartTime[entry.StartTime] = entry.Su[0]
|
||||||
}
|
}
|
||||||
|
}
|
||||||
return subjectByStartTime, nil
|
return subjectByStartTime, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -220,12 +324,12 @@ type Field struct {
|
||||||
Inline bool `json:"inline"`
|
Inline bool `json:"inline"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func sendDiscordWebhook(room string, nextTime string, Status string) {
|
func sendDiscordWebhook(subject string, room string, nextTime string, Status string) {
|
||||||
log.Println("Sending Discord webhook notification...")
|
log.Println("Sending Discord webhook notification...")
|
||||||
// Create a rich embed message
|
// Create a rich embed message
|
||||||
message := fmt.Sprintf(
|
message := fmt.Sprintf(
|
||||||
"Room: %s\nStart-Time: %s\nStatus: %s",
|
"Subject: %s\nRoom: %s\nStart-Time: %s\nStatus: %s",
|
||||||
room, nextTime, Status,
|
subject, room, nextTime, Status,
|
||||||
)
|
)
|
||||||
/*embed := Embed{
|
/*embed := Embed{
|
||||||
Title: "Next Lesson ",
|
Title: "Next Lesson ",
|
||||||
|
|
@ -276,3 +380,57 @@ func sendDiscordWebhook(room string, nextTime string, Status string) {
|
||||||
log.Printf("Discord webhook failed with status %d: %s", resp.StatusCode, string(body))
|
log.Printf("Discord webhook failed with status %d: %s", resp.StatusCode, string(body))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sendUpdateDiscordWebhook() {
|
||||||
|
log.Println("Sending Discord webhook notification...")
|
||||||
|
// Create a rich embed message
|
||||||
|
message := "A lesson on your timetable has changed"
|
||||||
|
/*embed := Embed{
|
||||||
|
Title: "Next Lesson ",
|
||||||
|
Description: "The next lesson is starting soon: ",
|
||||||
|
Color: 3066993, // Green color
|
||||||
|
Timestamp: time.Now().Format(time.RFC3339),
|
||||||
|
Fields: []Field{
|
||||||
|
{
|
||||||
|
Name: "New Lesson",
|
||||||
|
// Value: fmt.Sprintf("`%s`", ip),
|
||||||
|
Value: fmt.Sprintf("Room: %s", room),
|
||||||
|
Inline: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Start-Time",
|
||||||
|
Value: fmt.Sprintf("Start time: %s", nextTime),
|
||||||
|
Inline: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "Status",
|
||||||
|
Value: fmt.Sprintf("Status: %s", Status),
|
||||||
|
Inline: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
payload := DiscordWebhookPayload{
|
||||||
|
Content: message,
|
||||||
|
}
|
||||||
|
|
||||||
|
jsonData, err := json.Marshal(payload)
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error marshaling webhook payload: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := http.Post(discordWebhookURL, "application/json", bytes.NewBuffer(jsonData))
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("Error sending Discord webhook: %v", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode >= 200 && resp.StatusCode < 300 {
|
||||||
|
log.Println("Discord webhook notification sent successfully")
|
||||||
|
} else {
|
||||||
|
body, _ := ioutil.ReadAll(resp.Body)
|
||||||
|
log.Printf("Discord webhook failed with status %d: %s", resp.StatusCode, string(body))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue