mirror of
https://github.com/fiatjaf/nak.git
synced 2026-02-17 13:24:34 +00:00
count: support reading filters from stdin like req.
This commit is contained in:
89
count.go
89
count.go
@@ -9,13 +9,14 @@ import (
|
|||||||
"fiatjaf.com/nostr"
|
"fiatjaf.com/nostr"
|
||||||
"fiatjaf.com/nostr/nip45"
|
"fiatjaf.com/nostr/nip45"
|
||||||
"fiatjaf.com/nostr/nip45/hyperloglog"
|
"fiatjaf.com/nostr/nip45/hyperloglog"
|
||||||
|
"github.com/mailru/easyjson"
|
||||||
"github.com/urfave/cli/v3"
|
"github.com/urfave/cli/v3"
|
||||||
)
|
)
|
||||||
|
|
||||||
var count = &cli.Command{
|
var count = &cli.Command{
|
||||||
Name: "count",
|
Name: "count",
|
||||||
Usage: "generates encoded COUNT messages and optionally use them to talk to relays",
|
Usage: "generates encoded COUNT messages and optionally use them to talk to relays",
|
||||||
Description: `outputs a nip45 request (the flags are mostly the same as 'nak req').`,
|
Description: `like 'nak req', but does a "COUNT" call instead. Will attempt to perform HyperLogLog aggregation if more than one relay is specified.`,
|
||||||
DisableSliceFlagSeparator: true,
|
DisableSliceFlagSeparator: true,
|
||||||
Flags: reqFilterFlags,
|
Flags: reqFilterFlags,
|
||||||
ArgsUsage: "[relay...]",
|
ArgsUsage: "[relay...]",
|
||||||
@@ -37,52 +38,62 @@ var count = &cli.Command{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
filter := nostr.Filter{}
|
// go line by line from stdin or run once with input from flags
|
||||||
|
for stdinFilter := range getJsonsOrBlank() {
|
||||||
if err := applyFlagsToFilter(c, &filter); err != nil {
|
filter := nostr.Filter{}
|
||||||
return err
|
if stdinFilter != "" {
|
||||||
}
|
if err := easyjson.Unmarshal([]byte(stdinFilter), &filter); err != nil {
|
||||||
|
ctx = lineProcessingError(ctx, "invalid filter '%s' received from stdin: %s", stdinFilter, err)
|
||||||
successes := 0
|
|
||||||
if len(relayUrls) > 0 {
|
|
||||||
var hll *hyperloglog.HyperLogLog
|
|
||||||
if offset := nip45.HyperLogLogEventPubkeyOffsetForFilter(filter); offset != -1 && len(relayUrls) > 1 {
|
|
||||||
hll = hyperloglog.New(offset)
|
|
||||||
}
|
|
||||||
for _, relayUrl := range relayUrls {
|
|
||||||
relay, _ := sys.Pool.EnsureRelay(relayUrl)
|
|
||||||
count, hllRegisters, err := relay.Count(ctx, filter, nostr.SubscriptionOptions{
|
|
||||||
Label: "nak-count",
|
|
||||||
})
|
|
||||||
fmt.Fprintf(os.Stderr, "%s%s: ", strings.Repeat(" ", biggerUrlSize-len(relayUrl)), relayUrl)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "error: %s\n", err)
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var hasHLLStr string
|
if err := applyFlagsToFilter(c, &filter); err != nil {
|
||||||
if hll != nil && len(hllRegisters) == 256 {
|
return err
|
||||||
hll.MergeRegisters(hllRegisters)
|
}
|
||||||
hasHLLStr = " (hll)"
|
|
||||||
|
successes := 0
|
||||||
|
if len(relayUrls) > 0 {
|
||||||
|
var hll *hyperloglog.HyperLogLog
|
||||||
|
if offset := nip45.HyperLogLogEventPubkeyOffsetForFilter(filter); offset != -1 && len(relayUrls) > 1 {
|
||||||
|
hll = hyperloglog.New(offset)
|
||||||
}
|
}
|
||||||
|
for _, relayUrl := range relayUrls {
|
||||||
|
relay, _ := sys.Pool.EnsureRelay(relayUrl)
|
||||||
|
count, hllRegisters, err := relay.Count(ctx, filter, nostr.SubscriptionOptions{
|
||||||
|
Label: "nak-count",
|
||||||
|
})
|
||||||
|
fmt.Fprintf(os.Stderr, "%s%s: ", strings.Repeat(" ", biggerUrlSize-len(relayUrl)), relayUrl)
|
||||||
|
|
||||||
fmt.Fprintf(os.Stderr, "%d%s\n", count, hasHLLStr)
|
if err != nil {
|
||||||
successes++
|
fmt.Fprintf(os.Stderr, "error: %s\n", err)
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
var hasHLLStr string
|
||||||
|
if hll != nil && len(hllRegisters) == 256 {
|
||||||
|
hll.MergeRegisters(hllRegisters)
|
||||||
|
hasHLLStr = " (hll)"
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Fprintf(os.Stderr, "%d%s\n", count, hasHLLStr)
|
||||||
|
successes++
|
||||||
|
}
|
||||||
|
if successes == 0 {
|
||||||
|
return fmt.Errorf("all relays have failed")
|
||||||
|
} else if hll != nil {
|
||||||
|
fmt.Fprintf(os.Stderr, "HyperLogLog sum: %d\n", hll.Count())
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// no relays given, will just print the filter
|
||||||
|
var result string
|
||||||
|
j, _ := json.Marshal([]any{"COUNT", "nak", filter})
|
||||||
|
result = string(j)
|
||||||
|
stdout(result)
|
||||||
}
|
}
|
||||||
if successes == 0 {
|
|
||||||
return fmt.Errorf("all relays have failed")
|
|
||||||
} else if hll != nil {
|
|
||||||
fmt.Fprintf(os.Stderr, "HyperLogLog sum: %d\n", hll.Count())
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// no relays given, will just print the filter
|
|
||||||
var result string
|
|
||||||
j, _ := json.Marshal([]any{"COUNT", "nak", filter})
|
|
||||||
result = string(j)
|
|
||||||
stdout(result)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
exitIfLineProcessingError(ctx)
|
||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user