stillbox/pkg/calls/filter.go

91 lines
1.9 KiB
Go
Raw Normal View History

2024-08-06 11:19:30 -04:00
package calls
2024-08-06 13:54:15 -04:00
import (
2024-08-06 19:46:01 -04:00
"context"
"dynatron.me/x/stillbox/pkg/gordio/database"
2024-08-06 13:54:15 -04:00
)
type FilterQuery struct {
2024-08-06 11:19:30 -04:00
Query string
Params []interface{}
}
type Talkgroup struct {
System uint32
Talkgroup uint32
}
func (t Talkgroup) Pack() int64 {
// P25 system IDs are 12 bits, so we can fit them in a signed 8 byte int (int64, pg INT8)
return int64((int64(t.System) << 32) | int64(t.Talkgroup))
}
type Filter struct {
2024-08-06 13:54:15 -04:00
Talkgroups []Talkgroup `json:"talkgroups,omitempty"`
TalkgroupsNot []Talkgroup `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-08-06 19:46:01 -04:00
talkgroups map[Talkgroup]bool
2024-08-06 11:19:30 -04:00
}
2024-08-06 13:54:15 -04:00
func PackedTGs(tg []Talkgroup) []int64 {
s := make([]int64, len(tg))
2024-08-06 11:19:30 -04:00
for i, v := range tg {
s[i] = v.Pack()
}
return s
}
2024-08-06 19:46:01 -04:00
func (f *Filter) hasTags() bool {
return len(f.TalkgroupTagsAny) > 0 || len(f.TalkgroupTagsAll) > 0 || len(f.TalkgroupTagsNot) > 0
}
func (f *Filter) GetFinalTalkgroups() map[Talkgroup]bool {
return f.talkgroups
}
func (f *Filter) compile(ctx context.Context) error {
2024-08-06 11:19:30 -04:00
f.talkgroups = make(map[Talkgroup]bool)
for _, tg := range f.Talkgroups {
f.talkgroups[tg] = true
}
2024-08-06 19:46:01 -04:00
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 nil, err
}
2024-08-06 11:19:30 -04:00
2024-08-06 19:46:01 -04:00
for _, tg := range tagTGs {
f.talkgroups[Talkgroup{System: uint32(tg.SystemID), Talkgroup: uint32(tg.Tgid)}] = true
}
2024-08-06 11:19:30 -04:00
}
2024-08-06 19:46:01 -04:00
for _, tg := range f.TalkgroupsNot {
f.talkgroups[tg] = false
2024-08-06 11:19:30 -04:00
}
2024-08-06 19:46:01 -04:00
return nil
2024-08-06 11:19:30 -04:00
}
2024-08-06 19:46:01 -04:00
func (f *Filter) Test(ctx context.Context, call *Call) bool {
if f == nil { // no filter means all calls
return true
2024-08-06 13:54:15 -04:00
}
2024-08-06 19:46:01 -04:00
if f.talkgroups == nil {
err := f.compile(ctx)
if err != nil {
panic(err)
}
2024-08-06 13:54:15 -04:00
}
return false
}