style: Apply code formatting with go fmt

- Run 'make format' to ensure all Go code follows standard formatting
- Maintains consistent code style across the entire codebase
- No functional changes, only whitespace and formatting improvements
This commit is contained in:
Ole-Morten Duesund 2025-09-01 10:05:29 +02:00
commit 2bffa2c418
19 changed files with 543 additions and 527 deletions

View file

@ -13,12 +13,12 @@ import (
type ExternalAPIClient struct {
httpClient *http.Client
mutex sync.RWMutex
// Configuration
timeout time.Duration
maxRetries int
userAgent string
// Rate limiting
lastRequest time.Time
minInterval time.Duration
@ -32,28 +32,28 @@ type APIClientConfig struct {
}
type OpenSkyFlightInfo struct {
ICAO string `json:"icao"`
Callsign string `json:"callsign"`
Origin string `json:"origin"`
Destination string `json:"destination"`
FirstSeen time.Time `json:"first_seen"`
LastSeen time.Time `json:"last_seen"`
AircraftType string `json:"aircraft_type"`
Registration string `json:"registration"`
FlightNumber string `json:"flight_number"`
Airline string `json:"airline"`
ICAO string `json:"icao"`
Callsign string `json:"callsign"`
Origin string `json:"origin"`
Destination string `json:"destination"`
FirstSeen time.Time `json:"first_seen"`
LastSeen time.Time `json:"last_seen"`
AircraftType string `json:"aircraft_type"`
Registration string `json:"registration"`
FlightNumber string `json:"flight_number"`
Airline string `json:"airline"`
}
type APIError struct {
Operation string
StatusCode int
Message string
Retryable bool
RetryAfter time.Duration
Operation string
StatusCode int
Message string
Retryable bool
RetryAfter time.Duration
}
func (e *APIError) Error() string {
return fmt.Sprintf("API error in %s: %s (status: %d, retryable: %v)",
return fmt.Sprintf("API error in %s: %s (status: %d, retryable: %v)",
e.Operation, e.Message, e.StatusCode, e.Retryable)
}
@ -70,7 +70,7 @@ func NewExternalAPIClient(config APIClientConfig) *ExternalAPIClient {
if config.MinInterval == 0 {
config.MinInterval = 1 * time.Second // Default rate limit
}
return &ExternalAPIClient{
httpClient: &http.Client{
Timeout: config.Timeout,
@ -85,7 +85,7 @@ func NewExternalAPIClient(config APIClientConfig) *ExternalAPIClient {
func (c *ExternalAPIClient) enforceRateLimit() {
c.mutex.Lock()
defer c.mutex.Unlock()
elapsed := time.Since(c.lastRequest)
if elapsed < c.minInterval {
time.Sleep(c.minInterval - elapsed)
@ -95,18 +95,18 @@ func (c *ExternalAPIClient) enforceRateLimit() {
func (c *ExternalAPIClient) makeRequest(ctx context.Context, url string) (*http.Response, error) {
c.enforceRateLimit()
req, err := http.NewRequestWithContext(ctx, "GET", url, nil)
if err != nil {
return nil, err
}
req.Header.Set("User-Agent", c.userAgent)
req.Header.Set("Accept", "application/json")
var resp *http.Response
var lastErr error
for attempt := 0; attempt <= c.maxRetries; attempt++ {
if attempt > 0 {
// Exponential backoff
@ -117,16 +117,16 @@ func (c *ExternalAPIClient) makeRequest(ctx context.Context, url string) (*http.
case <-time.After(backoff):
}
}
resp, lastErr = c.httpClient.Do(req)
if lastErr != nil {
continue
}
// Check for retryable status codes
if resp.StatusCode >= 500 || resp.StatusCode == 429 {
resp.Body.Close()
// Handle rate limiting
if resp.StatusCode == 429 {
retryAfter := parseRetryAfter(resp.Header.Get("Retry-After"))
@ -140,15 +140,15 @@ func (c *ExternalAPIClient) makeRequest(ctx context.Context, url string) (*http.
}
continue
}
// Success or non-retryable error
break
}
if lastErr != nil {
return nil, lastErr
}
return resp, nil
}
@ -156,14 +156,14 @@ func (c *ExternalAPIClient) GetFlightInfoFromOpenSky(ctx context.Context, icao s
if icao == "" {
return nil, fmt.Errorf("empty ICAO code")
}
// OpenSky Network API endpoint for flight information
apiURL := fmt.Sprintf("https://opensky-network.org/api/flights/aircraft?icao24=%s&begin=%d&end=%d",
icao,
time.Now().Add(-24*time.Hour).Unix(),
time.Now().Unix(),
)
resp, err := c.makeRequest(ctx, apiURL)
if err != nil {
return nil, &APIError{
@ -173,7 +173,7 @@ func (c *ExternalAPIClient) GetFlightInfoFromOpenSky(ctx context.Context, icao s
}
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body)
return nil, &APIError{
@ -183,7 +183,7 @@ func (c *ExternalAPIClient) GetFlightInfoFromOpenSky(ctx context.Context, icao s
Retryable: resp.StatusCode >= 500 || resp.StatusCode == 429,
}
}
var flights [][]interface{}
decoder := json.NewDecoder(resp.Body)
if err := decoder.Decode(&flights); err != nil {
@ -193,11 +193,11 @@ func (c *ExternalAPIClient) GetFlightInfoFromOpenSky(ctx context.Context, icao s
Retryable: false,
}
}
if len(flights) == 0 {
return nil, nil // No flight information available
}
// Parse the most recent flight
flight := flights[0]
if len(flight) < 10 {
@ -207,11 +207,11 @@ func (c *ExternalAPIClient) GetFlightInfoFromOpenSky(ctx context.Context, icao s
Retryable: false,
}
}
info := &OpenSkyFlightInfo{
ICAO: icao,
}
// Parse fields based on OpenSky API documentation
if callsign, ok := flight[1].(string); ok {
info.Callsign = callsign
@ -228,7 +228,7 @@ func (c *ExternalAPIClient) GetFlightInfoFromOpenSky(ctx context.Context, icao s
if destination, ok := flight[5].(string); ok {
info.Destination = destination
}
return info, nil
}
@ -236,10 +236,10 @@ func (c *ExternalAPIClient) GetAircraftInfoFromOpenSky(ctx context.Context, icao
if icao == "" {
return nil, fmt.Errorf("empty ICAO code")
}
// OpenSky Network metadata API
apiURL := fmt.Sprintf("https://opensky-network.org/api/metadata/aircraft/icao/%s", icao)
resp, err := c.makeRequest(ctx, apiURL)
if err != nil {
return nil, &APIError{
@ -249,11 +249,11 @@ func (c *ExternalAPIClient) GetAircraftInfoFromOpenSky(ctx context.Context, icao
}
}
defer resp.Body.Close()
if resp.StatusCode == http.StatusNotFound {
return nil, nil // Aircraft not found
}
if resp.StatusCode != http.StatusOK {
body, _ := io.ReadAll(resp.Body)
return nil, &APIError{
@ -263,7 +263,7 @@ func (c *ExternalAPIClient) GetAircraftInfoFromOpenSky(ctx context.Context, icao
Retryable: resp.StatusCode >= 500 || resp.StatusCode == 429,
}
}
var aircraft map[string]interface{}
decoder := json.NewDecoder(resp.Body)
if err := decoder.Decode(&aircraft); err != nil {
@ -273,7 +273,7 @@ func (c *ExternalAPIClient) GetAircraftInfoFromOpenSky(ctx context.Context, icao
Retryable: false,
}
}
return aircraft, nil
}
@ -282,7 +282,7 @@ func (c *ExternalAPIClient) EnhanceCallsignWithExternalData(ctx context.Context,
enhancement["callsign"] = callsign
enhancement["icao"] = icao
enhancement["enhanced"] = false
// Try to get flight information from OpenSky
if flightInfo, err := c.GetFlightInfoFromOpenSky(ctx, icao); err == nil && flightInfo != nil {
enhancement["flight_info"] = map[string]interface{}{
@ -295,53 +295,53 @@ func (c *ExternalAPIClient) EnhanceCallsignWithExternalData(ctx context.Context,
}
enhancement["enhanced"] = true
}
// Try to get aircraft metadata
if aircraftInfo, err := c.GetAircraftInfoFromOpenSky(ctx, icao); err == nil && aircraftInfo != nil {
enhancement["aircraft_info"] = aircraftInfo
enhancement["enhanced"] = true
}
return enhancement, nil
}
func (c *ExternalAPIClient) BatchEnhanceCallsigns(ctx context.Context, callsigns map[string]string) (map[string]map[string]interface{}, error) {
results := make(map[string]map[string]interface{})
for callsign, icao := range callsigns {
select {
case <-ctx.Done():
return results, ctx.Err()
default:
}
enhanced, err := c.EnhanceCallsignWithExternalData(ctx, callsign, icao)
if err != nil {
// Log error but continue with other callsigns
fmt.Printf("Warning: failed to enhance callsign %s (ICAO: %s): %v\n", callsign, icao, err)
continue
}
results[callsign] = enhanced
}
return results, nil
}
func (c *ExternalAPIClient) TestConnection(ctx context.Context) error {
// Test with a simple API call
testURL := "https://opensky-network.org/api/states?time=0&lamin=0&lomin=0&lamax=1&lomax=1"
resp, err := c.makeRequest(ctx, testURL)
if err != nil {
return fmt.Errorf("connection test failed: %w", err)
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("connection test returned status %d", resp.StatusCode)
}
return nil
}
@ -349,24 +349,24 @@ func parseRetryAfter(header string) time.Duration {
if header == "" {
return 0
}
// Try parsing as seconds
if seconds, err := time.ParseDuration(header + "s"); err == nil {
return seconds
}
// Try parsing as HTTP date
if t, err := http.ParseTime(header); err == nil {
return time.Until(t)
}
return 0
}
// HealthCheck provides information about the client's health
func (c *ExternalAPIClient) HealthCheck(ctx context.Context) map[string]interface{} {
health := make(map[string]interface{})
// Test connection
if err := c.TestConnection(ctx); err != nil {
health["status"] = "unhealthy"
@ -374,16 +374,16 @@ func (c *ExternalAPIClient) HealthCheck(ctx context.Context) map[string]interfac
} else {
health["status"] = "healthy"
}
// Add configuration info
health["timeout"] = c.timeout.String()
health["max_retries"] = c.maxRetries
health["min_interval"] = c.minInterval.String()
health["user_agent"] = c.userAgent
c.mutex.RLock()
health["last_request"] = c.lastRequest
c.mutex.RUnlock()
return health
}
}