mirror of https://github.com/fiatjaf/nak.git
97 lines
2.5 KiB
Go
97 lines
2.5 KiB
Go
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
|
|
},
|
|
}
|