- Go application with embedded static files for dump1090 frontend - TCP client for SBS-1/BaseStation format (port 30003) - Real-time WebSocket updates with aircraft tracking - Modern web frontend with Leaflet maps and mobile-responsive design - Aircraft table with filtering/sorting and statistics dashboard - Origin configuration for receiver location and distance calculations - Automatic config.json loading from current directory - Foreground execution by default with optional -daemon flag 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
118 lines
No EOL
2.5 KiB
Go
118 lines
No EOL
2.5 KiB
Go
package config
|
|
|
|
import (
|
|
"encoding/json"
|
|
"fmt"
|
|
"os"
|
|
"strconv"
|
|
)
|
|
|
|
type Config struct {
|
|
Server ServerConfig `json:"server"`
|
|
Dump1090 Dump1090Config `json:"dump1090"`
|
|
Origin OriginConfig `json:"origin"`
|
|
}
|
|
|
|
type ServerConfig struct {
|
|
Address string `json:"address"`
|
|
Port int `json:"port"`
|
|
}
|
|
|
|
type Dump1090Config struct {
|
|
Host string `json:"host"`
|
|
DataPort int `json:"data_port"`
|
|
}
|
|
|
|
type OriginConfig struct {
|
|
Latitude float64 `json:"latitude"`
|
|
Longitude float64 `json:"longitude"`
|
|
Name string `json:"name"`
|
|
}
|
|
|
|
func Load() (*Config, error) {
|
|
cfg := &Config{
|
|
Server: ServerConfig{
|
|
Address: ":8080",
|
|
Port: 8080,
|
|
},
|
|
Dump1090: Dump1090Config{
|
|
Host: "localhost",
|
|
DataPort: 30003,
|
|
},
|
|
Origin: OriginConfig{
|
|
Latitude: 37.7749,
|
|
Longitude: -122.4194,
|
|
Name: "Default Location",
|
|
},
|
|
}
|
|
|
|
configFile := os.Getenv("SKYVIEW_CONFIG")
|
|
if configFile == "" {
|
|
// Check for config files in common locations
|
|
candidates := []string{"config.json", "./config.json", "skyview.json"}
|
|
for _, candidate := range candidates {
|
|
if _, err := os.Stat(candidate); err == nil {
|
|
configFile = candidate
|
|
break
|
|
}
|
|
}
|
|
}
|
|
|
|
if configFile != "" {
|
|
if err := loadFromFile(cfg, configFile); err != nil {
|
|
return nil, fmt.Errorf("failed to load config file %s: %w", configFile, err)
|
|
}
|
|
}
|
|
|
|
loadFromEnv(cfg)
|
|
|
|
return cfg, nil
|
|
}
|
|
|
|
func loadFromFile(cfg *Config, filename string) error {
|
|
data, err := os.ReadFile(filename)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return json.Unmarshal(data, cfg)
|
|
}
|
|
|
|
func loadFromEnv(cfg *Config) {
|
|
if addr := os.Getenv("SKYVIEW_ADDRESS"); addr != "" {
|
|
cfg.Server.Address = addr
|
|
}
|
|
|
|
if portStr := os.Getenv("SKYVIEW_PORT"); portStr != "" {
|
|
if port, err := strconv.Atoi(portStr); err == nil {
|
|
cfg.Server.Port = port
|
|
cfg.Server.Address = fmt.Sprintf(":%d", port)
|
|
}
|
|
}
|
|
|
|
if host := os.Getenv("DUMP1090_HOST"); host != "" {
|
|
cfg.Dump1090.Host = host
|
|
}
|
|
|
|
if dataPortStr := os.Getenv("DUMP1090_DATA_PORT"); dataPortStr != "" {
|
|
if port, err := strconv.Atoi(dataPortStr); err == nil {
|
|
cfg.Dump1090.DataPort = port
|
|
}
|
|
}
|
|
|
|
if latStr := os.Getenv("ORIGIN_LATITUDE"); latStr != "" {
|
|
if lat, err := strconv.ParseFloat(latStr, 64); err == nil {
|
|
cfg.Origin.Latitude = lat
|
|
}
|
|
}
|
|
|
|
if lonStr := os.Getenv("ORIGIN_LONGITUDE"); lonStr != "" {
|
|
if lon, err := strconv.ParseFloat(lonStr, 64); err == nil {
|
|
cfg.Origin.Longitude = lon
|
|
}
|
|
}
|
|
|
|
if name := os.Getenv("ORIGIN_NAME"); name != "" {
|
|
cfg.Origin.Name = name
|
|
}
|
|
} |