package main import ( "fmt" "os" "github.com/spf13/cobra" "git.leaktechnologies.dev/Leak_Technologies/Skyfeed/internal/config" "git.leaktechnologies.dev/Leak_Technologies/Skyfeed/internal/geo" "git.leaktechnologies.dev/Leak_Technologies/Skyfeed/internal/output" "git.leaktechnologies.dev/Leak_Technologies/Skyfeed/internal/weather" ) var rootCmd = &cobra.Command{ Use: "skyfeed", Short: "Skyfeed - Open Weather Engine for Telefact and Terminal", Long: `Skyfeed fetches and normalizes weather data from Environment Canada, using automatic IP-based geolocation. It supports both CLI and API modes.`, Run: func(cmd *cobra.Command, args []string) { cmd.Help() }, } func main() { // Initialize configuration and ensure data directories exist config.Init() // Register subcommands rootCmd.AddCommand(fetchCmd) rootCmd.AddCommand(showCmd) rootCmd.AddCommand(updateTownCmd) rootCmd.AddCommand(debugLogoCmd) if err := rootCmd.Execute(); err != nil { fmt.Println("Error:", err) os.Exit(1) } } // ---------------------------------------------------- // Subcommands // ---------------------------------------------------- var fetchCmd = &cobra.Command{ Use: "fetch", Short: "Fetch the latest weather data for your current location", Run: func(cmd *cobra.Command, args []string) { // Ensure town index is present and current output.LogInfo("Skyfeed: Checking town index…") if err := geo.EnsureTownIndexUpToDate(); err != nil { output.LogError(fmt.Sprintf("Failed to update town index: %v", err)) return } // Detect location via new IP method output.LogInfo("Skyfeed: Detecting location…") city, lat, lon, err := geo.GetUserLocation() if err != nil { output.LogError(fmt.Sprintf("Could not determine location: %v", err)) return } output.LogInfo(fmt.Sprintf("Detected: %s (%.4f, %.4f)", city, lat, lon)) // Find nearest EC station output.LogInfo("Finding nearest Environment Canada station…") station, err := geo.FindNearestStation(lat, lon) if err != nil { output.LogError(fmt.Sprintf("Station lookup failed: %v", err)) return } output.LogInfo(fmt.Sprintf("Nearest station: %s [%s]", station.Name, station.Code)) // Fetch weather output.LogInfo("Fetching latest weather data…") province := station.Province data, err := weather.FetchCurrent(station.Code, province) if err != nil { output.LogError(fmt.Sprintf("Weather fetch failed: %v", err)) return } // Render dynamic header/logo output.PrintLogo(data.Condition) fmt.Println() // Main output fmt.Println(output.FormatWeatherCLI(data, true)) }, } var showCmd = &cobra.Command{ Use: "show", Short: "Show cached weather data from disk", Run: func(cmd *cobra.Command, args []string) { data, err := weather.LoadCached() if err != nil { output.LogError(fmt.Sprintf("Failed to load cache: %v", err)) return } output.PrintLogo(data.Condition) fmt.Println() fmt.Println(output.FormatWeatherCLI(data, true)) }, } var updateTownCmd = &cobra.Command{ Use: "update-towns", Short: "Manually update the Canadian towns geolocation index", Run: func(cmd *cobra.Command, args []string) { output.LogInfo("Forcing town index update…") if err := geo.ForceUpdateTownIndex(); err != nil { output.LogError(fmt.Sprintf("Update failed: %v", err)) return } output.LogSuccess("Town index updated successfully.") }, } // ---------------------------------------------------- // Debug-only ASCII logo renderer // ---------------------------------------------------- var debugLogoCmd = &cobra.Command{ Use: "debug-logo [condition]", Hidden: true, Short: "Render the dynamic ASCII Skyfeed logo for a given condition", Long: `This command renders the Skyfeed ASCII logo using a simulated weather condition. It is intended strictly for development and testing. Example: skyfeed debug-logo "Light Snow"`, Run: func(cmd *cobra.Command, args []string) { if len(args) == 0 { fmt.Println("Usage: skyfeed debug-logo \"Weather Condition\"") fmt.Println("Example: skyfeed debug-logo \"Sunny\"") return } condition := args[0] fmt.Printf("Rendering logo for condition: %s\n\n", condition) output.PrintLogo(condition) }, }