package main import ( "context" "errors" "fmt" "io" "log" "net/http" "os" "github.com/spf13/viper" "github.com/urfave/cli/v3" ) var ( server string token string ) func load() error { viper.SetConfigName("config") viper.SetConfigType("toml") viper.AddConfigPath("$HOME/.local/share/door-alarm") err := viper.ReadInConfig() if err != nil { return err } server = viper.GetString("server") if server == "" { return errors.New("'server' property is required") } token = viper.GetString("token") if token == "" { return errors.New("'token' property is required") } return nil } func makeReqPrint(method string, url string) error { req, err := http.NewRequest(method, url, nil) if err != nil { return err } req.Header.Set("Authorization", token) res, err := http.DefaultClient.Do(req) if err != nil { return err } if res.StatusCode != 200 { fmt.Printf("<-- %d\n", res.StatusCode) } recv, err := io.ReadAll(res.Body) if err != nil { return err } fmt.Printf("%s", recv) return nil } func makeReqRet(method string, url string) ([]byte, error) { req, err := http.NewRequest(method, url, nil) if err != nil { return nil, err } req.Header.Set("Authorization", token) res, err := http.DefaultClient.Do(req) if err != nil { return nil, err } if res.StatusCode != 200 { fmt.Printf("<-- %d\n", res.StatusCode) } return io.ReadAll(res.Body) } func main() { cmd := &cli.Command{ Name: "doorctl", Usage: "door-alarm server administration tool", Commands: []*cli.Command{ { Name: "version", Usage: "print version and exit", Action: func(context.Context, *cli.Command) error { fmt.Println("version 1.0.0") return nil }, }, { Name: "test", Usage: "test server connection", Action: test, }, { Name: "get", Usage: "get door state", Flags: []cli.Flag{ &cli.BoolFlag{ Name: "raw", Usage: "print raw server output", }, }, Action: get, }, }, } err := cmd.Run(context.Background(), os.Args) if err != nil { log.Fatal(err) } } func test(context.Context, *cli.Command) error { err := load() if err != nil { return err } url := fmt.Sprintf("%s/", server) return makeReqPrint(http.MethodGet, url) } func get(ctx context.Context, cmd *cli.Command) error { err := load() if err != nil { return err } opened, err := makeReqRet(http.MethodGet, "/read") if err != nil { return err } if cmd.Bool("raw") { fmt.Println(opened) } else { if string(opened) == "true" { fmt.Println("door is open") } else { fmt.Println("door is closed") } } return nil }