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  `