From 44604e406b1a73b294af519dfa02b1fc1c7e6af0 Mon Sep 17 00:00:00 2001 From: fiatjaf Date: Sat, 1 Jan 2022 20:48:13 -0300 Subject: [PATCH] nip-01 update: everything as arrays on filters. --- filter/filter.go | 110 +++++++++-------------------------------------- filter/utils.go | 87 +++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+), 89 deletions(-) create mode 100644 filter/utils.go diff --git a/filter/filter.go b/filter/filter.go index f541f56..6f38272 100644 --- a/filter/filter.go +++ b/filter/filter.go @@ -5,13 +5,13 @@ import "github.com/fiatjaf/go-nostr/event" type EventFilters []EventFilter type EventFilter struct { - ID string `json:"id,omitempty"` - Kind *int `json:"kind,omitempty"` - Authors []string `json:"authors,omitempty"` - TagEvent string `json:"#e,omitempty"` - TagProfile string `json:"#p,omitempty"` - Since uint32 `json:"since,omitempty"` - Until uint32 `json:"until,omitempty"` + IDs []string `json:"ids,omitempty"` + Kinds []int `json:"kinds,omitempty"` + Authors []string `json:"authors,omitempty"` + Since uint32 `json:"since,omitempty"` + Until uint32 `json:"until,omitempty"` + TagE []string `json:"#e,omitempty"` + TagP []string `json:"#p,omitempty"` } func (eff EventFilters) Match(event *event.Event) bool { @@ -20,7 +20,6 @@ func (eff EventFilters) Match(event *event.Event) bool { return true } } - return false } @@ -29,82 +28,23 @@ func (ef EventFilter) Matches(event *event.Event) bool { return false } - if ef.ID != "" && ef.ID != event.ID { + if ef.IDs != nil && !stringsContain(ef.IDs, event.ID) { return false } - if ef.Authors != nil { - found := false - for _, pubkey := range ef.Authors { - if pubkey == event.PubKey { - found = true - break - } - } - if !found { - return false - } + if ef.Kinds != nil && !intsContain(ef.Kinds, event.Kind) { + return false } - if ef.TagEvent != "" { - found := false - for _, tag := range event.Tags { - if len(tag) < 2 { - continue - } - - tagType, ok := tag[0].(string) - if !ok { - continue - } - - if tagType == "e" { - taggedID, ok := tag[1].(string) - if !ok { - continue - } - - if taggedID == ef.TagEvent { - found = true - break - } - } - } - if !found { - return false - } + if ef.Authors != nil && !stringsContain(ef.Authors, event.PubKey) { + return false } - if ef.TagProfile != "" { - found := false - for _, tag := range event.Tags { - if len(tag) < 2 { - continue - } - - tagType, ok := tag[0].(string) - if !ok { - continue - } - - if tagType == "p" { - taggedID, ok := tag[1].(string) - if !ok { - continue - } - - if taggedID == ef.TagProfile { - found = true - break - } - } - } - if !found { - return false - } + if ef.TagE != nil && !containsAnyTag("e", event.Tags, ef.TagE) { + return false } - if ef.Kind != nil && *ef.Kind != event.Kind { + if ef.TagP != nil && !containsAnyTag("p", event.Tags, ef.TagP) { return false } @@ -112,7 +52,7 @@ func (ef EventFilter) Matches(event *event.Event) bool { return false } - if ef.Until != 0 && event.CreatedAt > ef.Until { + if ef.Until != 0 && event.CreatedAt >= ef.Until { return false } @@ -120,31 +60,23 @@ func (ef EventFilter) Matches(event *event.Event) bool { } func Equal(a EventFilter, b EventFilter) bool { - if a.Kind == nil && b.Kind != nil || - a.Kind != nil && b.Kind == nil || - a.Kind != b.Kind { + if !intsEqual(a.Kinds, b.Kinds) { return false } - if a.ID != b.ID { + if !stringsEqual(a.IDs, b.IDs) { return false } - if len(a.Authors) != len(b.Authors) { + if !stringsEqual(a.Authors, b.Authors) { return false } - for i, _ := range a.Authors { - if a.Authors[i] != b.Authors[i] { - return false - } - } - - if a.TagEvent != b.TagEvent { + if !stringsEqual(a.TagE, b.TagE) { return false } - if a.TagProfile != b.TagProfile { + if !stringsEqual(a.TagP, b.TagP) { return false } diff --git a/filter/utils.go b/filter/utils.go new file mode 100644 index 0000000..9bb89a3 --- /dev/null +++ b/filter/utils.go @@ -0,0 +1,87 @@ +package filter + +import "github.com/fiatjaf/go-nostr/event" + +func stringsEqual(as, bs []string) bool { + if len(as) != len(bs) { + return false + } + + for _, a := range as { + for _, b := range bs { + if b == a { + goto next + } + } + // didn't find a B that corresponded to the current A + return false + + next: + continue + } + + return true +} + +func intsEqual(as, bs []int) bool { + if len(as) != len(bs) { + return false + } + + for _, a := range as { + for _, b := range bs { + if b == a { + goto next + } + } + // didn't find a B that corresponded to the current A + return false + + next: + continue + } + + return true +} + +func stringsContain(haystack []string, needle string) bool { + for _, hay := range haystack { + if hay == needle { + return true + } + } + return false +} + +func intsContain(haystack []int, needle int) bool { + for _, hay := range haystack { + if hay == needle { + return true + } + } + return false +} + +func containsAnyTag(tagName string, tags event.Tags, values []string) bool { + for _, tag := range tags { + if len(tag) < 2 { + continue + } + + currentTagName, ok := tag[0].(string) + if !ok || currentTagName != tagName { + continue + } + + currentTagValue, ok := tag[1].(string) + if !ok { + continue + } + + if stringsContain(values, currentTagValue) { + return true + } + } + + return false +}