From acec39ad766e860e15d72cf330bb06b749deebc4 Mon Sep 17 00:00:00 2001 From: PhatPhuckDave Date: Fri, 10 Oct 2025 21:47:20 +0200 Subject: [PATCH] Hallucinate an esi endpoint methods --- esi/client.go | 171 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 171 insertions(+) create mode 100644 esi/client.go diff --git a/esi/client.go b/esi/client.go new file mode 100644 index 0000000..dd7812d --- /dev/null +++ b/esi/client.go @@ -0,0 +1,171 @@ +// Package esi provides EVE Online ESI API implementations for planetary interaction data. +package esi + +import ( + "context" + "encoding/json" + "fmt" + "io" + "net/http" + "time" + + logger "git.site.quack-lab.dev/dave/cylogger" +) + +const ( + ESIBaseURL = "https://esi.evetech.net" +) + +type Planet struct { + PlanetID int `json:"planet_id"` + PlanetType string `json:"planet_type"` + SolarSystemID int `json:"solar_system_id"` + UpgradeLevel int `json:"upgrade_level"` + NumPins int `json:"num_pins"` + LastUpdate string `json:"last_update"` + OwnerID int `json:"owner_id"` + PlanetName string `json:"planet_name"` + PlanetTypeID int `json:"planet_type_id"` + Position struct { + X float64 `json:"x"` + Y float64 `json:"y"` + Z float64 `json:"z"` + } `json:"position"` +} + +type PlanetDetail struct { + Links []Link `json:"links"` + Pins []Pin `json:"pins"` + Routes []Route `json:"routes"` + LastUpdate string `json:"last_update"` +} + +type Link struct { + DestinationPinID int `json:"destination_pin_id"` + LinkLevel int `json:"link_level"` + SourcePinID int `json:"source_pin_id"` +} + +type Pin struct { + Contents []StorageContent `json:"contents"` + ExpiryTime *string `json:"expiry_time"` + ExtractorDetails *ExtractorDetails `json:"extractor_details"` + FactoryDetails *FactoryDetails `json:"factory_details"` + InstallTime *string `json:"install_time"` + LastCycleStart *string `json:"last_cycle_start"` + Latitude float64 `json:"latitude"` + Longitude float64 `json:"longitude"` + PinID int `json:"pin_id"` + SchematicID *int `json:"schematic_id"` + TypeID int `json:"type_id"` +} + +type StorageContent struct { + Amount int `json:"amount"` + TypeID int `json:"type_id"` +} + +type ExtractorDetails struct { + CycleTime *int `json:"cycle_time"` + HeadRadius *float64 `json:"head_radius"` + Heads []Head `json:"heads"` + ProductTypeID *int `json:"product_type_id"` + QtyPerCycle *int `json:"qty_per_cycle"` +} + +type Head struct { + HeadID int `json:"head_id"` + Latitude float64 `json:"latitude"` + Longitude float64 `json:"longitude"` +} + +type FactoryDetails struct { + SchematicID int `json:"schematic_id"` +} + +type Route struct { + ContentTypeID int `json:"content_type_id"` + DestinationPinID int `json:"destination_pin_id"` + Quantity int `json:"quantity"` + RouteID int `json:"route_id"` + SourcePinID int `json:"source_pin_id"` + Waypoints []int `json:"waypoints"` +} + +// GetCharacterPlanets retrieves a list of planets for a character +func GetCharacterPlanets(ctx context.Context, characterID int, accessToken string) ([]Planet, error) { + logger.Debug("Fetching planets for character ID %d", characterID) + + url := fmt.Sprintf("%s/v1/characters/%d/planets/", ESIBaseURL, characterID) + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) + if err != nil { + logger.Error("Failed to create request for character planets: %v", err) + return nil, err + } + + req.Header.Set("Authorization", "Bearer "+accessToken) + req.Header.Set("Accept", "application/json") + + client := &http.Client{Timeout: 30 * time.Second} + resp, err := client.Do(req) + if err != nil { + logger.Error("Failed to fetch character planets: %v", err) + return nil, err + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + body, _ := io.ReadAll(resp.Body) + logger.Error("Character planets API returned status %d: %s", resp.StatusCode, string(body)) + return nil, fmt.Errorf("API request failed with status %d: %s", resp.StatusCode, string(body)) + } + + var planets []Planet + if err := json.NewDecoder(resp.Body).Decode(&planets); err != nil { + logger.Error("Failed to decode character planets response: %v", err) + return nil, err + } + + logger.Info("Successfully fetched %d planets for character ID %d", len(planets), characterID) + return planets, nil +} + +// GetPlanetDetails retrieves detailed information about a specific planet +func GetPlanetDetails(ctx context.Context, characterID, planetID int, accessToken string) (*PlanetDetail, error) { + logger.Debug("Fetching planet details for character ID %d, planet ID %d", characterID, planetID) + + url := fmt.Sprintf("%s/v3/characters/%d/planets/%d/", ESIBaseURL, characterID, planetID) + + req, err := http.NewRequestWithContext(ctx, http.MethodGet, url, nil) + if err != nil { + logger.Error("Failed to create request for planet details: %v", err) + return nil, err + } + + req.Header.Set("Authorization", "Bearer "+accessToken) + req.Header.Set("Accept", "application/json") + + client := &http.Client{Timeout: 30 * time.Second} + resp, err := client.Do(req) + if err != nil { + logger.Error("Failed to fetch planet details: %v", err) + return nil, err + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + body, _ := io.ReadAll(resp.Body) + logger.Error("Planet details API returned status %d: %s", resp.StatusCode, string(body)) + return nil, fmt.Errorf("API request failed with status %d: %s", resp.StatusCode, string(body)) + } + + var planetDetail PlanetDetail + if err := json.NewDecoder(resp.Body).Decode(&planetDetail); err != nil { + logger.Error("Failed to decode planet details response: %v", err) + return nil, err + } + + logger.Info("Successfully fetched planet details for character ID %d, planet ID %d", characterID, planetID) + return &planetDetail, nil +}