github.com/decred/politeia@v1.4.0/politeiawww/cmd/pictl/cmdvoteresults.go (about) 1 // Copyright (c) 2020-2021 The Decred developers 2 // Use of this source code is governed by an ISC 3 // license that can be found in the LICENSE file. 4 5 package main 6 7 import ( 8 "bufio" 9 "fmt" 10 "os" 11 "path/filepath" 12 13 tkv1 "github.com/decred/politeia/politeiawww/api/ticketvote/v1" 14 pclient "github.com/decred/politeia/politeiawww/client" 15 ) 16 17 // cmdVoteResults retreives the cast ticket votes for a record. 18 type cmdVoteResults struct { 19 Args struct { 20 Token string `positional-arg-name:"token"` 21 } `positional-args:"true" required:"true"` 22 23 // Save instructs the command to save the vote results to the 24 // current working directory as a CSV file. 25 Save bool `long:"save" optional:"true"` 26 27 // Filter can be used to instruct the command to only save a 28 // specific vote option to disk when using the --save flag. 29 // The vote option should be specified using the hex encoded 30 // vote bit. 31 // Ex: --filter=1 32 Filter string `long:"filter" optional:"true"` 33 } 34 35 // Execute executes the cmdVoteResults command. 36 // 37 // This function satisfies the go-flags Commander interface. 38 func (c *cmdVoteResults) Execute(args []string) error { 39 // Verify command options 40 switch { 41 case !c.Save && c.Filter != "": 42 return fmt.Errorf("--filter can only be used in conjunction with --save") 43 } 44 45 // Setup client 46 opts := pclient.Opts{ 47 HTTPSCert: cfg.HTTPSCert, 48 Verbose: cfg.Verbose, 49 RawJSON: cfg.RawJSON, 50 } 51 pc, err := pclient.New(cfg.Host, opts) 52 if err != nil { 53 return err 54 } 55 56 // Get vote results 57 r := tkv1.Results{ 58 Token: c.Args.Token, 59 } 60 rr, err := pc.TicketVoteResults(r) 61 if err != nil { 62 return err 63 } 64 65 // Save vote results to disk if --save flag has been provided. 66 if c.Save { 67 return saveVoteResults(r.Token, rr, c.Filter) 68 } 69 70 // Print results summary 71 printVoteResults(rr.Votes) 72 73 return nil 74 } 75 76 // saveVoteResults saves the provided vote results to disk as a csv file. The 77 // filter argument can be provided if the user wants to filter out a specific 78 // vote option and only save that vote options to disk. The filter argument 79 // should match the hex encoded vote bit. 80 func saveVoteResults(token string, rr *tkv1.ResultsReply, filter string) error { 81 // Setup the file path 82 filename := fmt.Sprintf("%v-voteresults.csv", token) 83 if filter != "" { 84 filename = fmt.Sprintf("%v-voteresults-%v.csv", token, filter) 85 } 86 wd, err := os.Getwd() 87 if err != nil { 88 return err 89 } 90 path := filepath.Join(wd, filename) 91 92 // Open the file 93 f, err := os.Create(path) 94 if err != nil { 95 return err 96 } 97 defer f.Close() 98 99 // Write votes to file buffer 100 w := bufio.NewWriter(f) 101 w.WriteString("token,ticket,votebit,address,signature,receipt,timestamp\n") 102 103 for _, v := range rr.Votes { 104 // A filter can be provided if the user only wants 105 // to save one of the vote options to disk. 106 if filter != "" && filter != v.VoteBit { 107 // This is not the specified vote option 108 continue 109 } 110 111 // Add the cast vote to the buffer 112 w.WriteString(fmt.Sprintf("%v,%v,%v,%v,%v,%v,%v\n", 113 v.Token, v.Ticket, v.VoteBit, v.Address, 114 v.Signature, v.Receipt, v.Timestamp)) 115 } 116 117 // Write the buffer to disk 118 w.Flush() 119 120 printf("File saved: %v\n", path) 121 122 return nil 123 } 124 125 // voteResultsHelpMsg is printed to stdout by the help command. 126 const voteResultsHelpMsg = `voteresults "token" 127 128 Fetch vote results for a record. 129 130 Arguments: 131 1. token (string, required) Record token. 132 133 Flags: 134 --save (bool) Save instructs the command to save the vote results to the 135 current working directory as a CSV file. 136 137 --filter (string) Filter can be used to instruct the command to only save a 138 specific vote option to disk when using the --save flag. 139 The vote option should be specified using the hex encoded 140 vote bit. 141 Ex: --filter=1 142 `