diff --git a/filter.go b/filter.go new file mode 100644 index 0000000..b8edc16 --- /dev/null +++ b/filter.go @@ -0,0 +1,96 @@ +package main + +import ( + "context" + "fmt" + + "fiatjaf.com/nostr" + "github.com/mailru/easyjson" + "github.com/urfave/cli/v3" +) + +var filter = &cli.Command{ + Name: "filter", + Usage: "applies an event filter to an event to see if it matches.", + Description: ` +example: + echo '{"kind": 1, "content": "hello"}' | nak filter -k 1 + nak filter '{"kind": 1, "content": "hello"}' -k 1 + nak filter '{"kind": 1, "content": "hello"}' '{"kinds": [1]}' -k 0 +`, + DisableSliceFlagSeparator: true, + Flags: reqFilterFlags, + ArgsUsage: "[event_json] [base_filter_json]", + Action: func(ctx context.Context, c *cli.Command) error { + args := c.Args().Slice() + + var baseFilter nostr.Filter + var baseEvent nostr.Event + + if len(args) == 2 { + // two arguments: first is event, second is base filter + if err := easyjson.Unmarshal([]byte(args[0]), &baseEvent); err != nil { + return fmt.Errorf("invalid base event: %w", err) + } + if err := easyjson.Unmarshal([]byte(args[1]), &baseFilter); err != nil { + return fmt.Errorf("invalid base filter: %w", err) + } + } else if len(args) == 1 { + if isPiped() { + // one argument + stdin: argument is base filter + if err := easyjson.Unmarshal([]byte(args[0]), &baseFilter); err != nil { + return fmt.Errorf("invalid base filter: %w", err) + } + } else { + // one argument, no stdin: argument is event + if err := easyjson.Unmarshal([]byte(args[0]), &baseEvent); err != nil { + return fmt.Errorf("invalid base event: %w", err) + } + } + } + + // apply flags to filter + if err := applyFlagsToFilter(c, &baseFilter); err != nil { + return err + } + + // if there is no stdin we'll still get an empty object here + for evtj := range getJsonsOrBlank() { + var evt nostr.Event + if err := easyjson.Unmarshal([]byte(evtj), &evt); err != nil { + ctx = lineProcessingError(ctx, "invalid event: %s", err) + continue + } + + // merge that with the base event + if evt.ID == nostr.ZeroID { + evt.ID = baseEvent.ID + } + if evt.PubKey == nostr.ZeroPK { + evt.PubKey = baseEvent.PubKey + } + if evt.Sig == [64]byte{} { + evt.Sig = baseEvent.Sig + } + if evt.Content == "" { + evt.Content = baseEvent.Content + } + if len(evt.Tags) == 0 { + evt.Tags = baseEvent.Tags + } + if evt.CreatedAt == 0 { + evt.CreatedAt = baseEvent.CreatedAt + } + + if baseFilter.Matches(evt) { + stdout(evt) + } else { + fmt.Println(baseFilter.LimitZero) + logverbose("event %s didn't match %s", evt, baseFilter) + } + } + + exitIfLineProcessingError(ctx) + return nil + }, +} diff --git a/main.go b/main.go index 5f5e04b..9545804 100644 --- a/main.go +++ b/main.go @@ -27,6 +27,7 @@ var app = &cli.Command{ Commands: []*cli.Command{ event, req, + filter, fetch, count, decode,