2024-11-21 13:23:21 -05:00
|
|
|
package radioref
|
2024-11-12 19:20:03 -05:00
|
|
|
|
|
|
|
import (
|
|
|
|
"bufio"
|
2024-11-13 09:24:11 -05:00
|
|
|
"context"
|
2024-11-12 19:20:03 -05:00
|
|
|
"io"
|
|
|
|
"regexp"
|
|
|
|
"strconv"
|
|
|
|
"strings"
|
|
|
|
|
2024-11-13 09:24:11 -05:00
|
|
|
"dynatron.me/x/stillbox/internal/jsontypes"
|
2024-11-12 19:20:03 -05:00
|
|
|
"dynatron.me/x/stillbox/pkg/database"
|
2024-11-15 11:15:12 -05:00
|
|
|
"dynatron.me/x/stillbox/pkg/talkgroups"
|
2024-11-20 19:59:24 -05:00
|
|
|
"dynatron.me/x/stillbox/pkg/talkgroups/tgstore"
|
2024-11-12 19:20:03 -05:00
|
|
|
)
|
|
|
|
|
2024-11-21 13:23:21 -05:00
|
|
|
type Driver struct{}
|
2024-11-12 19:20:03 -05:00
|
|
|
|
2024-11-21 13:23:21 -05:00
|
|
|
func New() *Driver {
|
|
|
|
return new(Driver)
|
2024-11-12 19:20:03 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
type rrState int
|
2024-11-13 09:24:11 -05:00
|
|
|
|
2024-11-12 19:20:03 -05:00
|
|
|
const (
|
|
|
|
rrsInitial rrState = iota
|
|
|
|
rrsGroupDesc
|
|
|
|
rrsTG
|
|
|
|
)
|
|
|
|
|
|
|
|
var rrRE = regexp.MustCompile(`DEC\s+HEX\s+Mode\s+Alpha Tag\s+Description\s+Tag`)
|
|
|
|
|
2024-11-21 13:23:21 -05:00
|
|
|
func (rr *Driver) ImportTalkgroups(ctx context.Context, sys int, r io.Reader) ([]talkgroups.Talkgroup, error) {
|
2024-11-12 19:20:03 -05:00
|
|
|
sc := bufio.NewScanner(r)
|
2024-11-15 11:15:12 -05:00
|
|
|
tgs := make([]talkgroups.Talkgroup, 0, 8)
|
2024-11-21 07:44:08 -05:00
|
|
|
sysn, has := tgstore.FromCtx(ctx).SystemName(ctx, sys)
|
2024-11-13 09:24:11 -05:00
|
|
|
if !has {
|
2024-11-20 19:59:24 -05:00
|
|
|
return nil, tgstore.ErrNoSuchSystem
|
2024-11-13 09:24:11 -05:00
|
|
|
}
|
2024-11-12 19:20:03 -05:00
|
|
|
|
|
|
|
var groupName string
|
|
|
|
state := rrsInitial
|
|
|
|
for sc.Scan() {
|
2024-11-13 09:24:11 -05:00
|
|
|
if err := ctx.Err(); err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
2024-11-12 19:20:03 -05:00
|
|
|
ln := strings.Trim(sc.Text(), " \t\r\n")
|
|
|
|
|
|
|
|
switch state {
|
|
|
|
case rrsInitial:
|
|
|
|
groupName = ln
|
|
|
|
state++
|
|
|
|
case rrsGroupDesc:
|
|
|
|
if rrRE.MatchString(ln) {
|
|
|
|
state++
|
|
|
|
}
|
|
|
|
case rrsTG:
|
|
|
|
fields := strings.Split(ln, "\t")
|
2024-11-13 18:50:26 -05:00
|
|
|
if len(fields) != 6 {
|
2024-11-12 19:20:03 -05:00
|
|
|
state = rrsGroupDesc
|
|
|
|
groupName = ln
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
tgid, err := strconv.Atoi(fields[0])
|
|
|
|
if err != nil {
|
|
|
|
continue
|
|
|
|
}
|
2024-11-15 13:06:37 -05:00
|
|
|
var metadata jsontypes.Metadata
|
2024-11-15 11:15:12 -05:00
|
|
|
tgt := talkgroups.TG(sys, tgid)
|
2024-11-12 19:20:03 -05:00
|
|
|
mode := fields[2]
|
|
|
|
if strings.Contains(mode, "E") {
|
2024-11-15 13:06:37 -05:00
|
|
|
metadata = make(jsontypes.Metadata)
|
2024-11-13 18:50:26 -05:00
|
|
|
metadata["encrypted"] = true
|
2024-11-12 19:20:03 -05:00
|
|
|
}
|
|
|
|
tags := []string{fields[5]}
|
2024-11-13 09:24:11 -05:00
|
|
|
gn := groupName // must take a copy
|
2024-11-15 11:15:12 -05:00
|
|
|
tgs = append(tgs, talkgroups.Talkgroup{
|
2024-11-12 19:20:03 -05:00
|
|
|
Talkgroup: database.Talkgroup{
|
2024-11-20 07:26:59 -05:00
|
|
|
ID: len(tgs), // need unique ID for the UI to track
|
2024-11-15 11:34:54 -05:00
|
|
|
TGID: int32(tgt.Talkgroup),
|
2024-11-12 19:20:03 -05:00
|
|
|
SystemID: int32(tgt.System),
|
2024-11-13 09:24:11 -05:00
|
|
|
Name: &fields[4],
|
2024-11-12 19:20:03 -05:00
|
|
|
AlphaTag: &fields[3],
|
2024-11-17 21:46:10 -05:00
|
|
|
TGGroup: &gn,
|
2024-11-12 19:20:03 -05:00
|
|
|
Metadata: metadata,
|
2024-11-13 09:24:11 -05:00
|
|
|
Tags: tags,
|
|
|
|
Weight: 1.0,
|
2024-11-20 16:45:41 -05:00
|
|
|
Alert: true,
|
2024-11-12 19:20:03 -05:00
|
|
|
},
|
|
|
|
System: database.System{
|
2024-11-13 09:24:11 -05:00
|
|
|
ID: sys,
|
|
|
|
Name: sysn,
|
2024-11-12 19:20:03 -05:00
|
|
|
},
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := sc.Err(); err != nil {
|
|
|
|
return tgs, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return tgs, nil
|
|
|
|
}
|