main.go
1 package main 2 3 import ( 4 "bufio" 5 "encoding/json" 6 "flag" 7 "fmt" 8 "os" 9 "path/filepath" 10 "strings" 11 12 "github.com/artur9010/HomeTUI/internal/ha" 13 "github.com/artur9010/HomeTUI/internal/tui" 14 ) 15 16 func getConfigPath() string { 17 homeDir, err := os.UserHomeDir() 18 if err != nil { 19 return "config.json" 20 } 21 return filepath.Join(homeDir, ".config", "hometui", "config.json") 22 } 23 24 func ensureConfigDir() error { 25 configPath := getConfigPath() 26 configDir := filepath.Dir(configPath) 27 return os.MkdirAll(configDir, 0755) 28 } 29 30 func promptForConfig() (*tui.Config, string, string) { 31 reader := bufio.NewReader(os.Stdin) 32 33 fmt.Println("No config file found. Please provide your Home Assistant details:") 34 fmt.Println() 35 36 fmt.Print("Home Assistant URL (e.g., http://homeassistant.local:8123): ") 37 url, _ := reader.ReadString('\n') 38 url = strings.TrimSpace(url) 39 40 fmt.Print("Long-lived access token: ") 41 token, _ := reader.ReadString('\n') 42 token = strings.TrimSpace(token) 43 44 fmt.Println() 45 46 cfg := &tui.Config{ 47 HAURL: url, 48 HAToken: token, 49 } 50 51 return cfg, url, token 52 } 53 54 func main() { 55 configPath := flag.String("config", getConfigPath(), "Path to configuration file") 56 flag.Parse() 57 58 var cfg *tui.Config 59 var url, token string 60 61 if _, err := os.Stat(*configPath); os.IsNotExist(err) { 62 cfg, url, token = promptForConfig() 63 64 fmt.Print("Save configuration to file? (y/n): ") 65 reader := bufio.NewReader(os.Stdin) 66 save, _ := reader.ReadString('\n') 67 save = strings.TrimSpace(strings.ToLower(save)) 68 69 if save == "y" || save == "yes" { 70 if err := ensureConfigDir(); err != nil { 71 fmt.Printf("Warning: failed to create config directory: %v\n", err) 72 } 73 74 appConfig := struct { 75 HomeAssistant struct { 76 URL string `json:"url"` 77 Token string `json:"token"` 78 } `json:"homeassistant"` 79 ShowOnlyFavorites bool `json:"showOnlyFavorites"` 80 }{ 81 HomeAssistant: struct { 82 URL string `json:"url"` 83 Token string `json:"token"` 84 }{ 85 URL: url, 86 Token: token, 87 }, 88 ShowOnlyFavorites: false, 89 } 90 91 data, err := json.MarshalIndent(appConfig, "", " ") 92 if err != nil { 93 fmt.Printf("Warning: failed to marshal config: %v\n", err) 94 } else if err := os.WriteFile(*configPath, data, 0600); err != nil { 95 fmt.Printf("Warning: failed to save config file: %v\n", err) 96 } else { 97 fmt.Printf("Configuration saved to %s\n", *configPath) 98 } 99 } 100 fmt.Println() 101 } else { 102 data, err := os.ReadFile(*configPath) 103 if err != nil { 104 fmt.Fprintf(os.Stderr, "Error loading config: %v\n", err) 105 os.Exit(1) 106 } 107 108 var appConfig struct { 109 HomeAssistant struct { 110 URL string `json:"url"` 111 Token string `json:"token"` 112 } `json:"homeassistant"` 113 ShowOnlyFavorites bool `json:"showOnlyFavorites"` 114 } 115 116 if err := json.Unmarshal(data, &appConfig); err != nil { 117 fmt.Fprintf(os.Stderr, "Error parsing config: %v\n", err) 118 os.Exit(1) 119 } 120 121 url = appConfig.HomeAssistant.URL 122 token = appConfig.HomeAssistant.Token 123 124 if url == "" || token == "" { 125 fmt.Println("Config file exists but credentials are missing or invalid.") 126 fmt.Println("Please re-enter your Home Assistant details:") 127 fmt.Println() 128 129 cfg, url, token = promptForConfig() 130 131 fmt.Print("Save configuration to file? (y/n): ") 132 reader := bufio.NewReader(os.Stdin) 133 save, _ := reader.ReadString('\n') 134 save = strings.TrimSpace(strings.ToLower(save)) 135 136 if save == "y" || save == "yes" { 137 if err := ensureConfigDir(); err != nil { 138 fmt.Printf("Warning: failed to create config directory: %v\n", err) 139 } 140 141 appConfig.HomeAssistant.URL = url 142 appConfig.HomeAssistant.Token = token 143 144 data, err := json.MarshalIndent(appConfig, "", " ") 145 if err != nil { 146 fmt.Printf("Warning: failed to marshal config: %v\n", err) 147 } else if err := os.WriteFile(*configPath, data, 0600); err != nil { 148 fmt.Printf("Warning: failed to save config file: %v\n", err) 149 } else { 150 fmt.Printf("Configuration saved to %s\n", *configPath) 151 } 152 } 153 fmt.Println() 154 } 155 156 cfg = &tui.Config{ 157 HAURL: url, 158 HAToken: token, 159 } 160 } 161 162 if !strings.HasPrefix(url, "http://") && !strings.HasPrefix(url, "https://") { 163 url = "http://" + url 164 } 165 166 wsURL := strings.Replace(url, "http", "ws", 1) 167 if !strings.HasSuffix(wsURL, "/api/websocket") { 168 wsURL = wsURL + "/api/websocket" 169 } 170 171 haClient := ha.NewClient(url, token) 172 wsClient := ha.NewWSClient(wsURL, token) 173 174 if err := tui.Start(cfg, haClient, wsClient); err != nil { 175 fmt.Fprintf(os.Stderr, "Error running TUI: %v\n", err) 176 os.Exit(1) 177 } 178 }