@@ -9,13 +9,14 @@ import (
99 "fiatjaf.com/nostr"
1010 "fiatjaf.com/nostr/nip45"
1111 "fiatjaf.com/nostr/nip45/hyperloglog"
12+ "github.com/mailru/easyjson"
1213 "github.com/urfave/cli/v3"
1314)
1415
1516var count = & cli.Command {
1617 Name : "count" ,
1718 Usage : "generates encoded COUNT messages and optionally use them to talk to relays" ,
18- Description : `outputs a nip45 request (the flags are mostly the same as 'nak req') .` ,
19+ Description : `like 'nak req', but does a "COUNT" call instead. Will attempt to perform HyperLogLog aggregation if more than one relay is specified .` ,
1920 DisableSliceFlagSeparator : true ,
2021 Flags : reqFilterFlags ,
2122 ArgsUsage : "[relay...]" ,
@@ -37,52 +38,62 @@ var count = &cli.Command{
3738 }
3839 }
3940
40- filter := nostr.Filter {}
41-
42- if err := applyFlagsToFilter (c , & filter ); err != nil {
43- return err
44- }
41+ // go line by line from stdin or run once with input from flags
42+ for stdinFilter := range getJsonsOrBlank () {
43+ filter := nostr.Filter {}
44+ if stdinFilter != "" {
45+ if err := easyjson .Unmarshal ([]byte (stdinFilter ), & filter ); err != nil {
46+ ctx = lineProcessingError (ctx , "invalid filter '%s' received from stdin: %s" , stdinFilter , err )
47+ continue
48+ }
49+ }
4550
46- successes := 0
47- if len (relayUrls ) > 0 {
48- var hll * hyperloglog.HyperLogLog
49- if offset := nip45 .HyperLogLogEventPubkeyOffsetForFilter (filter ); offset != - 1 && len (relayUrls ) > 1 {
50- hll = hyperloglog .New (offset )
51+ if err := applyFlagsToFilter (c , & filter ); err != nil {
52+ return err
5153 }
52- for _ , relayUrl := range relayUrls {
53- relay , _ := sys .Pool .EnsureRelay (relayUrl )
54- count , hllRegisters , err := relay .Count (ctx , filter , nostr.SubscriptionOptions {
55- Label : "nak-count" ,
56- })
57- fmt .Fprintf (os .Stderr , "%s%s: " , strings .Repeat (" " , biggerUrlSize - len (relayUrl )), relayUrl )
5854
59- if err != nil {
60- fmt .Fprintf (os .Stderr , "error: %s\n " , err )
61- continue
55+ successes := 0
56+ if len (relayUrls ) > 0 {
57+ var hll * hyperloglog.HyperLogLog
58+ if offset := nip45 .HyperLogLogEventPubkeyOffsetForFilter (filter ); offset != - 1 && len (relayUrls ) > 1 {
59+ hll = hyperloglog .New (offset )
6260 }
61+ for _ , relayUrl := range relayUrls {
62+ relay , _ := sys .Pool .EnsureRelay (relayUrl )
63+ count , hllRegisters , err := relay .Count (ctx , filter , nostr.SubscriptionOptions {
64+ Label : "nak-count" ,
65+ })
66+ fmt .Fprintf (os .Stderr , "%s%s: " , strings .Repeat (" " , biggerUrlSize - len (relayUrl )), relayUrl )
6367
64- var hasHLLStr string
65- if hll != nil && len (hllRegisters ) == 256 {
66- hll .MergeRegisters (hllRegisters )
67- hasHLLStr = " (hll)"
68- }
68+ if err != nil {
69+ fmt .Fprintf (os .Stderr , "error: %s\n " , err )
70+ continue
71+ }
6972
70- fmt .Fprintf (os .Stderr , "%d%s\n " , count , hasHLLStr )
71- successes ++
72- }
73- if successes == 0 {
74- return fmt .Errorf ("all relays have failed" )
75- } else if hll != nil {
76- fmt .Fprintf (os .Stderr , "HyperLogLog sum: %d\n " , hll .Count ())
73+ var hasHLLStr string
74+ if hll != nil && len (hllRegisters ) == 256 {
75+ hll .MergeRegisters (hllRegisters )
76+ hasHLLStr = " (hll)"
77+ }
78+
79+ fmt .Fprintf (os .Stderr , "%d%s\n " , count , hasHLLStr )
80+ successes ++
81+ }
82+ if successes == 0 {
83+ return fmt .Errorf ("all relays have failed" )
84+ } else if hll != nil {
85+ fmt .Fprintf (os .Stderr , "HyperLogLog sum: %d\n " , hll .Count ())
86+ }
87+ } else {
88+ // no relays given, will just print the filter
89+ var result string
90+ j , _ := json .Marshal ([]any {"COUNT" , "nak" , filter })
91+ result = string (j )
92+ stdout (result )
7793 }
78- } else {
79- // no relays given, will just print the filter
80- var result string
81- j , _ := json .Marshal ([]any {"COUNT" , "nak" , filter })
82- result = string (j )
83- stdout (result )
8494 }
8595
96+ exitIfLineProcessingError (ctx )
8697 return nil
8798 },
8899}
0 commit comments