package radioref import ( "bufio" "context" "io" "regexp" "strconv" "strings" "dynatron.me/x/stillbox/internal/jsontypes" "dynatron.me/x/stillbox/pkg/database" "dynatron.me/x/stillbox/pkg/talkgroups" "dynatron.me/x/stillbox/pkg/talkgroups/tgstore" ) type Driver struct{} func New() *Driver { return new(Driver) } type rrState int const ( rrsInitial rrState = iota rrsGroupDesc rrsTG ) var rrRE = regexp.MustCompile(`DEC\s+HEX\s+Mode\s+Alpha Tag\s+Description\s+Tag`) func (rr *Driver) ImportTalkgroups(ctx context.Context, sys int, r io.Reader) ([]talkgroups.Talkgroup, error) { sc := bufio.NewScanner(r) tgs := make([]talkgroups.Talkgroup, 0, 8) sysn, has := tgstore.FromCtx(ctx).SystemName(ctx, sys) if !has { return nil, tgstore.ErrNoSuchSystem } var groupName string state := rrsInitial for sc.Scan() { if err := ctx.Err(); err != nil { return nil, err } 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") if len(fields) != 6 { state = rrsGroupDesc groupName = ln continue } tgid, err := strconv.Atoi(fields[0]) if err != nil { continue } var metadata jsontypes.Metadata tgt := talkgroups.TG(sys, tgid) mode := fields[2] if strings.Contains(mode, "E") { metadata = make(jsontypes.Metadata) metadata["encrypted"] = true } tags := []string{fields[5]} gn := groupName // must take a copy tgs = append(tgs, talkgroups.Talkgroup{ Talkgroup: database.Talkgroup{ ID: len(tgs), // need unique ID for the UI to track TGID: int32(tgt.Talkgroup), SystemID: int32(tgt.System), Name: &fields[4], AlphaTag: &fields[3], TGGroup: &gn, Metadata: metadata, Tags: tags, Weight: 1.0, Alert: true, }, System: database.System{ ID: sys, Name: sysn, }, }) } } if err := sc.Err(); err != nil { return tgs, err } return tgs, nil }