161 lines
3.7 KiB
Go
161 lines
3.7 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log/slog"
|
|
"strconv"
|
|
|
|
"git.loyso.art/frx/kurious/internal/domain"
|
|
"git.loyso.art/frx/kurious/internal/infrastructure/interfaceadapters/courses/sravni"
|
|
|
|
"github.com/teris-io/cli"
|
|
)
|
|
|
|
const (
|
|
learningTypeOptName = "learning_type"
|
|
courseThematicOptName = "course_thematic"
|
|
)
|
|
|
|
func setupAPICommand(ctx context.Context) cli.Command {
|
|
learningTypeOpt := cli.NewOption(learningTypeOptName, "Specify learning type").
|
|
WithChar('l').
|
|
WithType(cli.TypeString)
|
|
courseThematic := cli.NewOption(courseThematicOptName, "Specify course thematic").
|
|
WithChar('t').
|
|
WithType(cli.TypeString)
|
|
|
|
apiEducationListProducts := cli.NewCommand("list_products", "List products by some filters").
|
|
WithOption(learningTypeOpt).
|
|
WithOption(courseThematic).
|
|
WithOption(limitOption).
|
|
WithOption(offsetOption).
|
|
WithAction(newListProductAction(ctx))
|
|
|
|
apiEducation := cli.NewCommand("education", "Education related category").
|
|
WithCommand(apiEducationListProducts)
|
|
|
|
return cli.NewCommand("api", "Interaction with API").
|
|
WithCommand(apiEducation)
|
|
}
|
|
|
|
type action interface {
|
|
context() context.Context
|
|
parse(args []string, options map[string]string) error
|
|
handle() error
|
|
}
|
|
|
|
func asCLIAction(a action) cli.Action {
|
|
return func(args []string, options map[string]string) int {
|
|
ctx := a.context()
|
|
log := makeLogger(options)
|
|
err := a.parse(args, options)
|
|
if err != nil {
|
|
log.ErrorContext(ctx, "unable to parse args and opts", slog.Any("err", err))
|
|
return -1
|
|
}
|
|
err = a.handle()
|
|
if err != nil {
|
|
log.ErrorContext(ctx, "unable to handle action", slog.Any("err", err))
|
|
return -1
|
|
}
|
|
|
|
return 0
|
|
}
|
|
}
|
|
|
|
type baseAction struct {
|
|
ctx context.Context
|
|
client sravni.Client
|
|
log *slog.Logger
|
|
}
|
|
|
|
func (ba *baseAction) parse(_ []string, options map[string]string) (err error) {
|
|
ba.log = makeLogger(options).With(slog.String("component", "action"))
|
|
ba.client, err = makeSravniClient(ba.ctx, ba.log, options)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (ba *baseAction) handle() error {
|
|
return domain.ErrNotImplemented
|
|
}
|
|
|
|
func (ba baseAction) context() context.Context {
|
|
return ba.ctx
|
|
}
|
|
|
|
func newBaseAction(ctx context.Context) *baseAction {
|
|
return &baseAction{
|
|
ctx: ctx,
|
|
}
|
|
}
|
|
|
|
type listProductsActionParams struct {
|
|
learningType string
|
|
courseThematic string
|
|
limit int
|
|
offset int
|
|
}
|
|
|
|
type listProductsAction struct {
|
|
*baseAction
|
|
|
|
params listProductsActionParams
|
|
}
|
|
|
|
func newListProductAction(ctx context.Context) cli.Action {
|
|
action := &listProductsAction{
|
|
baseAction: newBaseAction(ctx),
|
|
}
|
|
|
|
return asCLIAction(action)
|
|
}
|
|
|
|
func (a *listProductsAction) parse(args []string, options map[string]string) error {
|
|
err := a.baseAction.parse(args, options)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
var ok bool
|
|
|
|
a.params.learningType, ok = options[learningTypeOptName]
|
|
if !ok {
|
|
return domain.SimpleError("learning_type is empty")
|
|
}
|
|
a.params.courseThematic, ok = options[courseThematicOptName]
|
|
if !ok {
|
|
return domain.SimpleError("course_thematic is empty")
|
|
}
|
|
|
|
if value, ok := options[limitOption.Key()]; ok {
|
|
a.params.limit, _ = strconv.Atoi(value)
|
|
}
|
|
if value, ok := options[offsetOption.Key()]; ok {
|
|
a.params.offset, _ = strconv.Atoi(value)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (a *listProductsAction) handle() error {
|
|
params := sravni.ListEducationProductsParams{
|
|
LearningType: a.params.learningType,
|
|
CoursesThematics: a.params.courseThematic,
|
|
Limit: a.params.limit,
|
|
Offset: a.params.offset,
|
|
}
|
|
result, err := a.client.ListEducationalProducts(a.ctx, params)
|
|
if err != nil {
|
|
return fmt.Errorf("listing education products: %w", err)
|
|
}
|
|
|
|
a.log.InfoContext(a.ctx, "list education products result", slog.Any("result", result))
|
|
|
|
return nil
|
|
}
|