2024-08-06 11:19:30 -04:00
|
|
|
package calls
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
|
2024-11-03 07:19:03 -05:00
|
|
|
"dynatron.me/x/stillbox/pkg/database"
|
2024-08-06 11:19:30 -04:00
|
|
|
"dynatron.me/x/stillbox/pkg/pb"
|
2024-11-03 07:58:41 -05:00
|
|
|
|
|
|
|
tgs "dynatron.me/x/stillbox/pkg/talkgroups"
|
2024-08-06 11:19:30 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
type TalkgroupFilter struct {
|
2024-11-03 08:09:49 -05:00
|
|
|
Talkgroups []tgs.ID `json:"talkgroups,omitempty"`
|
|
|
|
TalkgroupsNot []tgs.ID `json:"talkgroupsNot,omitempty"`
|
|
|
|
TalkgroupTagsAll []string `json:"talkgroupTagsAll,omitempty"`
|
|
|
|
TalkgroupTagsAny []string `json:"talkgroupTagsAny,omitempty"`
|
|
|
|
TalkgroupTagsNot []string `json:"talkgroupTagsNot,omitempty"`
|
2024-08-06 11:19:30 -04:00
|
|
|
|
2024-11-03 08:09:49 -05:00
|
|
|
talkgroups map[tgs.ID]bool
|
2024-08-06 11:19:30 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
func TalkgroupFilterFromPB(ctx context.Context, p *pb.Filter) (*TalkgroupFilter, error) {
|
|
|
|
tgf := &TalkgroupFilter{
|
|
|
|
TalkgroupTagsAll: p.TalkgroupTagsAll,
|
|
|
|
TalkgroupTagsAny: p.TalkgroupTagsAny,
|
|
|
|
TalkgroupTagsNot: p.TalkgroupTagsNot,
|
|
|
|
}
|
|
|
|
|
|
|
|
if l := len(p.Talkgroups); l > 0 {
|
2024-11-03 08:09:49 -05:00
|
|
|
tgf.Talkgroups = make([]tgs.ID, l)
|
2024-08-06 11:19:30 -04:00
|
|
|
for i, t := range p.Talkgroups {
|
2024-11-03 08:09:49 -05:00
|
|
|
tgf.Talkgroups[i] = tgs.ID{
|
2024-08-06 11:19:30 -04:00
|
|
|
System: uint32(t.System),
|
|
|
|
Talkgroup: uint32(t.Talkgroup),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if l := len(p.TalkgroupsNot); l > 0 {
|
2024-11-03 08:09:49 -05:00
|
|
|
tgf.TalkgroupsNot = make([]tgs.ID, l)
|
2024-08-06 11:19:30 -04:00
|
|
|
for i, t := range p.TalkgroupsNot {
|
2024-11-03 08:09:49 -05:00
|
|
|
tgf.TalkgroupsNot[i] = tgs.ID{
|
2024-08-06 11:19:30 -04:00
|
|
|
System: uint32(t.System),
|
|
|
|
Talkgroup: uint32(t.Talkgroup),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return tgf, tgf.compile(ctx)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *TalkgroupFilter) hasTags() bool {
|
|
|
|
return len(f.TalkgroupTagsAny) > 0 || len(f.TalkgroupTagsAll) > 0 || len(f.TalkgroupTagsNot) > 0
|
|
|
|
}
|
|
|
|
|
2024-11-03 08:09:49 -05:00
|
|
|
func (f *TalkgroupFilter) GetFinalTalkgroups() map[tgs.ID]bool {
|
2024-08-06 11:19:30 -04:00
|
|
|
return f.talkgroups
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *TalkgroupFilter) compile(ctx context.Context) error {
|
2024-11-03 08:09:49 -05:00
|
|
|
f.talkgroups = make(map[tgs.ID]bool)
|
2024-08-06 11:19:30 -04:00
|
|
|
for _, tg := range f.Talkgroups {
|
|
|
|
f.talkgroups[tg] = true
|
|
|
|
}
|
|
|
|
|
|
|
|
if f.hasTags() { // don't bother with DB if no tags
|
|
|
|
db := database.FromCtx(ctx)
|
|
|
|
tagTGs, err := db.GetTalkgroupIDsByTags(ctx, f.TalkgroupTagsAny, f.TalkgroupTagsAll, f.TalkgroupTagsNot)
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tg := range tagTGs {
|
2024-11-03 08:09:49 -05:00
|
|
|
f.talkgroups[tgs.ID{System: uint32(tg.SystemID), Talkgroup: uint32(tg.Tgid)}] = true
|
2024-08-06 11:19:30 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tg := range f.TalkgroupsNot {
|
|
|
|
f.talkgroups[tg] = false
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *TalkgroupFilter) Test(ctx context.Context, call *Call) bool {
|
|
|
|
if f == nil { // no filter means all calls
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
if f.talkgroups == nil {
|
|
|
|
err := f.compile(ctx)
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
tg := call.TalkgroupTuple()
|
|
|
|
|
|
|
|
tgRes, have := f.talkgroups[tg]
|
|
|
|
if have {
|
|
|
|
return tgRes
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, patch := range call.Patches {
|
|
|
|
tg.Talkgroup = uint32(patch)
|
|
|
|
tgRes, have := f.talkgroups[tg]
|
|
|
|
if have {
|
|
|
|
return tgRes
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false
|
|
|
|
}
|