113 lines
2.1 KiB
Go
113 lines
2.1 KiB
Go
package main
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"strings"
|
|
"sync"
|
|
)
|
|
|
|
type Watchlist struct {
|
|
Callsigns []string `json:"callsigns"`
|
|
mu sync.RWMutex
|
|
filename string
|
|
}
|
|
|
|
func NewWatchlist(filename string) *Watchlist {
|
|
wl := &Watchlist{
|
|
Callsigns: []string{},
|
|
filename: filename,
|
|
}
|
|
wl.Load()
|
|
return wl
|
|
}
|
|
|
|
func (wl *Watchlist) Load() error {
|
|
wl.mu.Lock()
|
|
defer wl.mu.Unlock()
|
|
|
|
data, err := os.ReadFile(wl.filename)
|
|
if err != nil {
|
|
if os.IsNotExist(err) {
|
|
// File doesn't exist, start with empty watchlist
|
|
return nil
|
|
}
|
|
return err
|
|
}
|
|
|
|
return json.Unmarshal(data, &wl.Callsigns)
|
|
}
|
|
|
|
// save est une méthode privée sans lock (appelée par Add/Remove qui ont déjà le lock)
|
|
func (wl *Watchlist) save() error {
|
|
data, err := json.Marshal(wl.Callsigns)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return os.WriteFile(wl.filename, data, 0644)
|
|
}
|
|
|
|
func (wl *Watchlist) Add(callsign string) error {
|
|
wl.mu.Lock()
|
|
defer wl.mu.Unlock()
|
|
|
|
callsign = strings.ToUpper(strings.TrimSpace(callsign))
|
|
|
|
// Check if already exists
|
|
for _, c := range wl.Callsigns {
|
|
if c == callsign {
|
|
return nil // Already in watchlist
|
|
}
|
|
}
|
|
|
|
wl.Callsigns = append(wl.Callsigns, callsign)
|
|
return wl.save() // ← Appel de save() minuscule (sans lock)
|
|
}
|
|
|
|
func (wl *Watchlist) Remove(callsign string) error {
|
|
wl.mu.Lock()
|
|
defer wl.mu.Unlock()
|
|
|
|
callsign = strings.ToUpper(strings.TrimSpace(callsign))
|
|
|
|
for i, c := range wl.Callsigns {
|
|
if c == callsign {
|
|
wl.Callsigns = append(wl.Callsigns[:i], wl.Callsigns[i+1:]...)
|
|
return wl.save() // ← Appel de save() minuscule (sans lock)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (wl *Watchlist) GetAll() []string {
|
|
wl.mu.RLock()
|
|
defer wl.mu.RUnlock()
|
|
|
|
result := make([]string, len(wl.Callsigns))
|
|
copy(result, wl.Callsigns)
|
|
return result
|
|
}
|
|
|
|
func (wl *Watchlist) Matches(callsign string) bool {
|
|
wl.mu.RLock()
|
|
defer wl.mu.RUnlock()
|
|
|
|
callsign = strings.ToUpper(callsign)
|
|
|
|
for _, pattern := range wl.Callsigns {
|
|
// Exact match
|
|
if callsign == pattern {
|
|
return true
|
|
}
|
|
|
|
// Prefix match (e.g., VK9 matches VK9XX)
|
|
if strings.HasPrefix(callsign, pattern) {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|