package main import ( "context" "encoding/json" "errors" "flag" "fmt" "io" "log/slog" "os" "codeberg.org/dijitol/trading_post/src/cardmarket" "codeberg.org/dijitol/trading_post/src/cardmarket/handlers" "codeberg.org/dijitol/trading_post/src/cli" "codeberg.org/dijitol/trading_post/src/config" "codeberg.org/dijitol/trading_post/src/oauth" ) func main() { conf, err := config.NewConfigFromEnv() if err != nil { fmt.Println(err.Error()) os.Exit(1) } if err := Run( context.Background(), os.Stdin, os.Stdout, os.Stderr, conf, os.Args, ); err != nil { fmt.Println(err.Error()) os.Exit(1) } } func Run( ctx context.Context, stdin io.Reader, stdout, stderr io.Writer, conf config.Config, args []string, ) error { flag.CommandLine.SetOutput(stderr) _ = initLogger(ctx, stderr, conf) client := initAPIClient(conf) sg := cli.NewSubcommandGroup(stderr, flag.ContinueOnError) sg.AddSubcommand( "account", "[account] outputs information about the owner of the credentials", func(_ *flag.FlagSet) error { account, err := handlers.GetAccountInformation(ctx, client) if err != nil { return err } out, err := json.Marshal(account) if err != nil { return err } _, _ = fmt.Fprintln(stdout, string(out)) return nil }, ) sg.AddSubcommand( "vacation", "[vacation] sets the vacation state", func(fs *flag.FlagSet) error { onVacation := fs.Bool("onVacation", false, "flag if the user is on vacation or not") cancelOrders := fs.Bool("cancelOrders", false, "flag to cancel open orders, resp. request cancellation for open orders") relistItems := fs.Bool("relistItems", false, "flag to relist items for cancelled orders; only applies if (cancelOrders) is also provided and set to true for all orders, that are effectively cancelled") if err := fs.Parse(args[2:]); err != nil { return err } if err := handlers.SetVacationState( ctx, client, *onVacation, cancelOrders, relistItems, ); err != nil { return err } _, _ = fmt.Fprintln(stdout, "") return nil }, ) sg.AddSubcommand( "games", "[games] outputs all the games", func(_ *flag.FlagSet) error { games, err := handlers.GetGames(ctx, client) if err != nil { return err } out, err := json.Marshal(games) if err != nil { return err } _, _ = fmt.Fprintln(stdout, string(out)) return nil }, ) if len(args) < 2 { // 1st if program name, 2nd is subcommand return fmt.Errorf("error: missing subcommand\n\nusage: `trading_post [subcommand]`\n%s", sg.Usage()) } subcmd := args[1] if subcmd == "--help" || subcmd == "-h" { return fmt.Errorf("usage: `trading_post [subcommand]`\n%s", sg.Usage()) } if err := sg.ExecSubcommand(subcmd); err != nil { return errors.Join(err, fmt.Errorf("\nusage: `trading_post [subcommand]`\n%s", sg.Usage())) } return nil } func initLogger( ctx context.Context, stderr io.Writer, conf config.Config, ) *slog.Logger { l := slog.New( slog.NewJSONHandler(stderr, &slog.HandlerOptions{Level: conf.AppLogLevel}), ) slog.SetDefault(l) slog.DebugContext(ctx, conf.String()) return l } func initAPIClient(conf config.Config) *cardmarket.ApiClient { oauthClient := oauth.NewClient( oauth.Tokens{ Consumer: oauth.ConsumerToken{ Token: string(conf.CardmarketApiAuth.AppToken), Secret: string(conf.CardmarketApiAuth.AppSecret), }, Access: oauth.AccessToken{ Token: string(conf.CardmarketApiAuth.AccessToken), Secret: string(conf.CardmarketApiAuth.AccessTokenSecret), }, }, ) client := cardmarket.NewApiClient( conf.CardmarketApiBaseURL, oauthClient, ) return client }