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
|
|
|
|
}
|