package main import ( "context" "log/slog" "os" "os/signal" "syscall" "time" "git.savin.nyc/alex/go-iar-notificator/bus" "git.savin.nyc/alex/go-iar-notificator/client" "git.savin.nyc/alex/go-iar-notificator/config" "git.savin.nyc/alex/go-iar-notificator/utils" "git.savin.nyc/alex/go-iar-notificator/watcher" ) func main() { // Set up slog logger with JSON handler for structured output. // By default, log to stdout. You can adjust level based on config later. logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{ Level: slog.LevelDebug, // Default to Info; will adjust if verbose. })) config, err := config.LoadConfig("config.yml") // Replace with your file path if err != nil { logger.Error("Error loading config", "error", err) os.Exit(1) } // Start watching the directory for new MP3 files if config.WatchDebounceSeconds == 0 { config.WatchDebounceSeconds = 1 } iar, err := client.New(&config.Credentials, logger) if err != nil { logger.Error("Error creating IAR client", "error", err) os.Exit(1) } eb := bus.NewCustomEventBus() // Subscribe to new MP3 event to handle uploading eb.Subscribe("new_mp3", "mp3_upload_handler", func(data any) { path, ok := data.(string) if !ok { slog.Error("Invalid data type for new MP3 event") return } mp3Enc, err := utils.Mp3ToBase64(path) if err != nil { slog.Error("Failed to encode MP3 file", "error", err, "path", path) return } if err := iar.Alert(mp3Enc); err != nil { slog.Error("Failed to upload MP3", "error", err, "path", path) } else { slog.Info("Successfully uploaded MP3", "path", path) } }) // Context for graceful shutdown ctx, cancel := context.WithCancel(context.Background()) defer cancel() // Start directory watcher in a goroutine go watcher.WatchDirectory(ctx, config.Directory, eb, logger) err = iar.KeepAlive() if err != nil { slog.Error("Initial keep-alive failed", "error", err) } // Start keep-alive sender in a goroutine go iar.ServeKeepAlive(ctx) // Handle OS signals for shutdown sigCh := make(chan os.Signal, 1) signal.Notify(sigCh, syscall.SIGINT, syscall.SIGTERM) <-sigCh slog.Info("Shutting down...") cancel() time.Sleep(1 * time.Second) // Allow goroutines to exit gracefully }