package main import ( "context" "fmt" "log/slog" "net/http" "os" "os/signal" "time" "github.com/nmoniz/any2anexoj/internal" "github.com/nmoniz/any2anexoj/internal/trading212" "github.com/spf13/pflag" "golang.org/x/sync/errgroup" "golang.org/x/text/language" ) var ( // TODO: once we support more brokers or exchanges we should make this parameter required and // remove/change default platform = pflag.StringP("platform", "p", "trading212", "One of the supported platforms") lang = pflag.StringP("language", "l", language.Portuguese.String(), "The 2 letter language code") ofAPIKey = pflag.String("open-figi-api-key", "", "An OpenFIGI API key for faster report generation (better rate api rate limits)") // TODO: improve documentation on selectors selectors = pflag.StringSlice("selectors", nil, "Only process entries that conform to all the selectors:") ) func main() { pflag.Parse() err := run(context.Background()) if err != nil { slog.Error("found a fatal issue", slog.Any("err", err)) os.Exit(1) } } func run(ctx context.Context) error { ctx, cancel := signal.NotifyContext(ctx, os.Kill, os.Interrupt) defer cancel() eg, ctx := errgroup.WithContext(ctx) slog.SetDefault(slog.New(slog.NewTextHandler(os.Stderr, nil))) if platform == nil || len(*platform) == 0 { slog.Error("--platform flag is required") os.Exit(1) } if lang == nil || len(*lang) == 0 { slog.Error("--language flag is required") os.Exit(1) } reader, err := getReader(*platform, *ofAPIKey) if err != nil { return fmt.Errorf("getting reader: %w", err) } writer := internal.NewAggregatorWriter() selector, err := internal.ParseSelectors(*selectors) if err != nil { return fmt.Errorf("parsing selectors: %w", err) } eg.Go(func() error { return internal.BuildReport(ctx, reader, writer, selector) }) err = eg.Wait() if err != nil { return err } loc, err := NewLocalizer(*lang) if err != nil { return fmt.Errorf("create localizer: %w", err) } printer := NewPrettyPrinter(os.Stdout, loc) printer.Render(writer) return nil } func getReader(platform string, ofAPIKey string) (internal.RecordReader, error) { switch platform { case "trading212": return trading212.NewRecordReader(os.Stdin, internal.NewOpenFIGI(&http.Client{Timeout: 5 * time.Second}, ofAPIKey)), nil default: return nil, fmt.Errorf("unsupported platform: %s", platform) } }