84 lines
2.7 KiB
Go
84 lines
2.7 KiB
Go
// svxdr — live-data daemon for Reflector Dashboard (nodelist + proxy + astmeta + xlink)
|
|
// Copyright (C) 2026 SA7AUX (Björn)
|
|
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
//
|
|
// This program is free software: you can redistribute it and/or modify it under
|
|
// the terms of the GNU Affero General Public License as published by the Free
|
|
// Software Foundation, either version 3 of the License, or (at your option) any
|
|
// later version. See the LICENSE file for details.
|
|
|
|
package nodelist
|
|
|
|
// nodes.json — shared bridge map (see svx-web/nodes.README.md). nodelist takes
|
|
// the friendly reflector names (System) and the Location format strings from it,
|
|
// so the Location column ("{system} via {node} / {talker}") is driven by the
|
|
// same one file that configures astmeta and Asterisk. Merged ON TOP of the
|
|
// existing lastheard.json, so a box with only lastheard.json is unchanged.
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
type nodesFileNL struct {
|
|
Lastheard struct {
|
|
BridgeLocationFormat string `json:"bridge_location_format"`
|
|
BridgeLocationFormatNoSystem string `json:"bridge_location_format_no_system"`
|
|
} `json:"lastheard"`
|
|
Nodes []struct {
|
|
Allstar int `json:"allstar"`
|
|
System string `json:"system"`
|
|
Via string `json:"via"`
|
|
Callsign string `json:"callsign"`
|
|
Enabled *bool `json:"enabled"`
|
|
} `json:"nodes"`
|
|
}
|
|
|
|
// applyNodesRenderConfig merges nodes.json's reflector names + Location formats
|
|
// over cfg. A missing/invalid file is a no-op (cfg keeps the lastheard.json /
|
|
// default values). ReflectorNames is keyed the way bridgeIdentity looks it up:
|
|
// by the bridge label (via/callsign) and, as a fallback, the far AllStar node.
|
|
func applyNodesRenderConfig(cfg *lastheardRenderCfg, path string) {
|
|
b, err := os.ReadFile(path)
|
|
if err != nil {
|
|
return
|
|
}
|
|
var nf nodesFileNL
|
|
if json.Unmarshal(b, &nf) != nil {
|
|
return
|
|
}
|
|
if s := strings.TrimSpace(nf.Lastheard.BridgeLocationFormat); s != "" {
|
|
cfg.BridgeLocationFormat = s
|
|
}
|
|
if s := strings.TrimSpace(nf.Lastheard.BridgeLocationFormatNoSystem); s != "" {
|
|
cfg.BridgeLocationFormatNoSystem = s
|
|
}
|
|
if cfg.ReflectorNames == nil {
|
|
cfg.ReflectorNames = map[string]string{}
|
|
}
|
|
for _, e := range nf.Nodes {
|
|
if (e.Enabled != nil && !*e.Enabled) || e.System == "" {
|
|
continue
|
|
}
|
|
if e.Via != "" {
|
|
cfg.ReflectorNames[e.Via] = e.System
|
|
}
|
|
if e.Callsign != "" {
|
|
cfg.ReflectorNames[e.Callsign] = e.System
|
|
}
|
|
if e.Allstar != 0 {
|
|
cfg.ReflectorNames[strconv.Itoa(e.Allstar)] = e.System
|
|
}
|
|
}
|
|
}
|
|
|
|
// nodesJSONPath returns the nodes.json path (NODES_JSON env, default /etc/nodes.json).
|
|
func nodesJSONPath() string {
|
|
if p := os.Getenv("NODES_JSON"); p != "" {
|
|
return p
|
|
}
|
|
return "/etc/nodes.json"
|
|
}
|