package main import ( "flag" "fmt" "log" "net/http" "os" ) var Bold = "\033[1m" var Reset = "\033[0m" var Red = "\033[31m" var Green = "\033[32m" var Yellow = "\033[33m" var Blue = "\033[34m" var Purple = "\033[35m" var Cyan = "\033[36m" var Gray = "\033[37m" var White = "\033[97m" type WebsiteStatus struct { WebsiteURL string Description string HasIcon bool IconURL string } type Config struct { Mode string WebsiteConfFile string ListenAddress string Port int Verbose bool Color bool } var config Config func main() { config = parseFlags() if config.Verbose { fmt.Printf("Reading websites from file %s", config.WebsiteConfFile) } websites, err := readWebsitesFromFile(config.WebsiteConfFile) if err != nil { log.Fatal(err) } switch config.Mode { case "terminal": if config.Verbose { fmt.Printf("Running in terminal mode\n") } runTerminal(websites) case "server": if config.Verbose { fmt.Printf("Running in server mode\n") } runWebsite(fmt.Sprintf("%s:%d", config.ListenAddress, config.Port), websites) } } func parseFlags() Config { // Define command-line flags websiteConfFileFlag := flag.String("config", "websites.conf", "Path to the config file") verboseFlag := flag.Bool("verbose", false, "Enable verbose mode") listenAddressFlag := flag.String("address", "localhost", "The address the server will listen on") portFlag := flag.Int("port", 8080, "The port the server will listen on") modeFlag := flag.String("mode", "server", "The mode the program will run in. Options are \"terminal\" and \"server\"") colorFlag := flag.Bool("color", true, "Use terminal color") // Parse command-line flags flag.Parse() // Access the parsed values config := Config{ WebsiteConfFile: *websiteConfFileFlag, Verbose: *verboseFlag, ListenAddress: *listenAddressFlag, Port: *portFlag, Mode: *modeFlag, Color: *colorFlag, } success := true // Check if the config file exists if _, err := os.Stat(config.WebsiteConfFile); os.IsNotExist(err) { success = false fmt.Printf("File '%s' does not exist\n", config.WebsiteConfFile) } if config.Port < 0 || config.Port > 65535 { success = false fmt.Printf("Port '%d' is out of range for a port, must be between 0 and 65535\n", config.Port) } if config.Mode != "terminal" && config.Mode != "server" { success = false fmt.Printf("Mode has to be either terminal or server, but was '%s'\n", config.Mode) } if !success { fmt.Printf("Config error(s), aborting...\n") os.Exit(1) } return config } func runTerminal(websites []WebsiteStatus) { var status = make(map[string]string) for _, website := range websites { isUp := "" if config.Color { isUp = Bold + Red + "down" + Reset } else { isUp = "down" } if checkWebsite(website.WebsiteURL) == nil { if config.Color { isUp = Bold + Green + "up" + Reset } else { isUp = "up" } } status[website.WebsiteURL] = isUp } labelWidth := 0 for _, website := range websites { if len(website.Description) > labelWidth { labelWidth = len(website.Description) } } labelWidth += 1 for _, website := range websites { fmt.Printf("%-*s %s\n", labelWidth, website.Description+":", status[website.WebsiteURL]) } } func runWebsite(url string, websites []WebsiteStatus) { http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { renderTemplate(w, websites) }) http.HandleFunc("/check", handleCheck) http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("static")))) if config.Verbose { fmt.Println("Server listening on ", url) } log.Fatal(http.ListenAndServe(url, nil)) }