github.com/TrueBlocks/trueblocks-core/src/apps/chifra@v0.0.0-20241022031540-b362680128f7/internal/monitors/options.go (about)

     1  // Copyright 2016, 2024 The TrueBlocks Authors. All rights reserved.
     2  // Use of this source code is governed by a license that can
     3  // be found in the LICENSE file.
     4  /*
     5   * Parts of this file were auto generated. Edit only those parts of
     6   * the code inside of 'EXISTING_CODE' tags.
     7   */
     8  
     9  package monitorsPkg
    10  
    11  import (
    12  	// EXISTING_CODE
    13  	"encoding/json"
    14  	"io"
    15  	"net/http"
    16  	"net/url"
    17  	"strings"
    18  
    19  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/internal/globals"
    20  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/base"
    21  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/caps"
    22  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/logger"
    23  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/rpc"
    24  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/validate"
    25  	"github.com/TrueBlocks/trueblocks-core/src/apps/chifra/pkg/walk"
    26  	// EXISTING_CODE
    27  )
    28  
    29  // MonitorsOptions provides all command options for the chifra monitors command.
    30  type MonitorsOptions struct {
    31  	Addrs     []string              `json:"addrs,omitempty"`     // One or more addresses (0x...) to process
    32  	Delete    bool                  `json:"delete,omitempty"`    // Delete a monitor, but do not remove it
    33  	Undelete  bool                  `json:"undelete,omitempty"`  // Undelete a previously deleted monitor
    34  	Remove    bool                  `json:"remove,omitempty"`    // Remove a previously deleted monitor
    35  	Clean     bool                  `json:"clean,omitempty"`     // Clean (i.e. remove duplicate appearances) from monitors, optionally clear stage
    36  	List      bool                  `json:"list,omitempty"`      // List monitors in the cache (--verbose for more detail)
    37  	Count     bool                  `json:"count,omitempty"`     // Show the number of active monitors (included deleted but not removed monitors)
    38  	Staged    bool                  `json:"staged,omitempty"`    // For --clean, --list, and --count options only, include staged monitors
    39  	Watch     bool                  `json:"watch,omitempty"`     // Continually scan for new blocks and extract data as per the command file
    40  	Watchlist string                `json:"watchlist,omitempty"` // Available with --watch option only, a file containing the addresses to watch
    41  	Commands  string                `json:"commands,omitempty"`  // Available with --watch option only, the file containing the list of commands to apply to each watched address
    42  	BatchSize uint64                `json:"batchSize,omitempty"` // Available with --watch option only, the number of monitors to process in each batch
    43  	RunCount  uint64                `json:"runCount,omitempty"`  // Available with --watch option only, run the monitor this many times, then quit
    44  	Sleep     float64               `json:"sleep,omitempty"`     // Available with --watch option only, the number of seconds to sleep between runs
    45  	Globals   globals.GlobalOptions `json:"globals,omitempty"`   // The global options
    46  	Conn      *rpc.Connection       `json:"conn,omitempty"`      // The connection to the RPC server
    47  	BadFlag   error                 `json:"badFlag,omitempty"`   // An error flag if needed
    48  	// EXISTING_CODE
    49  	// EXISTING_CODE
    50  }
    51  
    52  var defaultMonitorsOptions = MonitorsOptions{
    53  	BatchSize: 8,
    54  	Sleep:     14,
    55  }
    56  
    57  // testLog is used only during testing to export the options for this test case.
    58  func (opts *MonitorsOptions) testLog() {
    59  	logger.TestLog(len(opts.Addrs) > 0, "Addrs: ", opts.Addrs)
    60  	logger.TestLog(opts.Delete, "Delete: ", opts.Delete)
    61  	logger.TestLog(opts.Undelete, "Undelete: ", opts.Undelete)
    62  	logger.TestLog(opts.Remove, "Remove: ", opts.Remove)
    63  	logger.TestLog(opts.Clean, "Clean: ", opts.Clean)
    64  	logger.TestLog(opts.List, "List: ", opts.List)
    65  	logger.TestLog(opts.Count, "Count: ", opts.Count)
    66  	logger.TestLog(opts.Staged, "Staged: ", opts.Staged)
    67  	logger.TestLog(opts.Watch, "Watch: ", opts.Watch)
    68  	logger.TestLog(len(opts.Watchlist) > 0, "Watchlist: ", opts.Watchlist)
    69  	logger.TestLog(len(opts.Commands) > 0, "Commands: ", opts.Commands)
    70  	logger.TestLog(opts.BatchSize != 8, "BatchSize: ", opts.BatchSize)
    71  	logger.TestLog(opts.RunCount != 0, "RunCount: ", opts.RunCount)
    72  	logger.TestLog(opts.Sleep != float64(14), "Sleep: ", opts.Sleep)
    73  	opts.Conn.TestLog(opts.getCaches())
    74  	opts.Globals.TestLog()
    75  }
    76  
    77  // String implements the Stringer interface
    78  func (opts *MonitorsOptions) String() string {
    79  	b, _ := json.MarshalIndent(opts, "", "  ")
    80  	return string(b)
    81  }
    82  
    83  // monitorsFinishParseApi finishes the parsing for server invocations. Returns a new MonitorsOptions.
    84  func monitorsFinishParseApi(w http.ResponseWriter, r *http.Request) *MonitorsOptions {
    85  	values := r.URL.Query()
    86  	if r.Header.Get("User-Agent") == "testRunner" {
    87  		values.Set("testRunner", "true")
    88  	}
    89  	return MonitorsFinishParseInternal(w, values)
    90  }
    91  
    92  func MonitorsFinishParseInternal(w io.Writer, values url.Values) *MonitorsOptions {
    93  	copy := defaultMonitorsOptions
    94  	copy.Globals.Caps = getCaps()
    95  	opts := &copy
    96  	opts.BatchSize = 8
    97  	opts.Sleep = 14
    98  	for key, value := range values {
    99  		switch key {
   100  		case "addrs":
   101  			for _, val := range value {
   102  				s := strings.Split(val, " ") // may contain space separated items
   103  				opts.Addrs = append(opts.Addrs, s...)
   104  			}
   105  		case "delete":
   106  			opts.Delete = true
   107  		case "undelete":
   108  			opts.Undelete = true
   109  		case "remove":
   110  			opts.Remove = true
   111  		case "clean":
   112  			opts.Clean = true
   113  		case "list":
   114  			opts.List = true
   115  		case "count":
   116  			opts.Count = true
   117  		case "staged":
   118  			opts.Staged = true
   119  		case "watch":
   120  			opts.Watch = true
   121  		case "watchlist":
   122  			opts.Watchlist = value[0]
   123  		case "commands":
   124  			opts.Commands = value[0]
   125  		case "batchSize":
   126  			opts.BatchSize = base.MustParseUint64(value[0])
   127  		case "runCount":
   128  			opts.RunCount = base.MustParseUint64(value[0])
   129  		case "sleep":
   130  			opts.Sleep = base.MustParseFloat64(value[0])
   131  		default:
   132  			if !copy.Globals.Caps.HasKey(key) {
   133  				err := validate.Usage("Invalid key ({0}) in {1} route.", key, "monitors")
   134  				if opts.BadFlag == nil || opts.BadFlag.Error() > err.Error() {
   135  					opts.BadFlag = err
   136  				}
   137  			}
   138  		}
   139  	}
   140  	opts.Conn = opts.Globals.FinishParseApi(w, values, opts.getCaches())
   141  
   142  	// EXISTING_CODE
   143  	// EXISTING_CODE
   144  	opts.Addrs, _ = opts.Conn.GetEnsAddresses(opts.Addrs)
   145  
   146  	return opts
   147  }
   148  
   149  // monitorsFinishParse finishes the parsing for command line invocations. Returns a new MonitorsOptions.
   150  func monitorsFinishParse(args []string) *MonitorsOptions {
   151  	// remove duplicates from args if any (not needed in api mode because the server does it).
   152  	dedup := map[string]int{}
   153  	if len(args) > 0 {
   154  		tmp := []string{}
   155  		for _, arg := range args {
   156  			if value := dedup[arg]; value == 0 {
   157  				tmp = append(tmp, arg)
   158  			}
   159  			dedup[arg]++
   160  		}
   161  		args = tmp
   162  	}
   163  
   164  	defFmt := "txt"
   165  	opts := GetOptions()
   166  	opts.Conn = opts.Globals.FinishParse(args, opts.getCaches())
   167  
   168  	// EXISTING_CODE
   169  	for _, arg := range args {
   170  		if base.IsValidAddress(arg) {
   171  			opts.Addrs = append(opts.Addrs, arg)
   172  		}
   173  	}
   174  	// EXISTING_CODE
   175  	opts.Addrs, _ = opts.Conn.GetEnsAddresses(opts.Addrs)
   176  	if len(opts.Globals.Format) == 0 || opts.Globals.Format == "none" {
   177  		opts.Globals.Format = defFmt
   178  	}
   179  
   180  	return opts
   181  }
   182  
   183  func GetOptions() *MonitorsOptions {
   184  	// EXISTING_CODE
   185  	// EXISTING_CODE
   186  	return &defaultMonitorsOptions
   187  }
   188  
   189  func getCaps() caps.Capability {
   190  	var capabilities caps.Capability // capabilities for chifra monitors
   191  	capabilities = capabilities.Add(caps.Default)
   192  	capabilities = capabilities.Add(caps.Caching)
   193  	capabilities = capabilities.Add(caps.Names)
   194  	// EXISTING_CODE
   195  	// EXISTING_CODE
   196  	return capabilities
   197  }
   198  
   199  func ResetOptions(testMode bool) {
   200  	// We want to keep writer between command file calls
   201  	w := GetOptions().Globals.Writer
   202  	opts := MonitorsOptions{}
   203  	globals.SetDefaults(&opts.Globals)
   204  	opts.Globals.TestMode = testMode
   205  	opts.Globals.Writer = w
   206  	opts.Globals.Caps = getCaps()
   207  	opts.BatchSize = 8
   208  	opts.Sleep = 14
   209  	defaultMonitorsOptions = opts
   210  }
   211  
   212  func (opts *MonitorsOptions) getCaches() (caches map[walk.CacheType]bool) {
   213  	// EXISTING_CODE
   214  	// EXISTING_CODE
   215  	return
   216  }
   217  
   218  // EXISTING_CODE
   219  // EXISTING_CODE