214 lines
5.4 KiB
Go
214 lines
5.4 KiB
Go
package main
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"log/slog"
|
|
"strconv"
|
|
"strings"
|
|
|
|
"git.loyso.art/frx/kurious/internal/common/client/sravni"
|
|
"git.loyso.art/frx/kurious/internal/common/errors"
|
|
|
|
"github.com/teris-io/cli"
|
|
)
|
|
|
|
const (
|
|
learningTypeOptName = "learning-type"
|
|
courseThematicOptName = "course-thematic"
|
|
learningTypeSelectionOptName = "learning-selection"
|
|
)
|
|
|
|
func setupAPICommand(ctx context.Context) cli.Command {
|
|
learningTypeOpt := cli.NewOption(learningTypeOptName, "Specify learning type").
|
|
WithType(cli.TypeString)
|
|
courseThematic := cli.NewOption(courseThematicOptName, "Specify course thematic").
|
|
WithType(cli.TypeString)
|
|
learningSelectionOpt := cli.NewOption(learningTypeSelectionOptName, "Specify learning type selection").
|
|
WithType(cli.TypeString)
|
|
|
|
apiEducationListProducts := buildCLICommand(func() cli.Command {
|
|
return cli.NewCommand("list_products", "List products by some filters").
|
|
WithOption(learningTypeOpt).
|
|
WithOption(courseThematic).
|
|
WithOption(learningSelectionOpt).
|
|
WithOption(limitOption).
|
|
WithOption(offsetOption).
|
|
WithAction(newListProductAction(ctx))
|
|
})
|
|
apiEducationFilterCount := buildCLICommand(func() cli.Command {
|
|
return cli.NewCommand("filter_count", "Loads counts of returned entities").
|
|
WithOption(learningTypeOpt).
|
|
WithOption(courseThematic).
|
|
WithOption(learningSelectionOpt).
|
|
WithAction(newProductsFilterCountAction(ctx))
|
|
})
|
|
|
|
apiEducation := cli.NewCommand("education", "Education related category").
|
|
WithCommand(apiEducationListProducts).
|
|
WithCommand(apiEducationFilterCount)
|
|
|
|
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 listProductsActionParams struct {
|
|
learningType string
|
|
courseThematic string
|
|
learningSelectionType string
|
|
limit int
|
|
offset int
|
|
}
|
|
|
|
type listProductsAction struct {
|
|
*baseAction
|
|
|
|
client sravni.Client
|
|
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 errors.SimpleError(learningTypeOptName + " is empty")
|
|
}
|
|
|
|
a.params.courseThematic = options[courseThematicOptName]
|
|
a.params.learningSelectionType = options[learningTypeSelectionOptName]
|
|
|
|
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)
|
|
}
|
|
|
|
client, err := makeSravniClient(a.ctx, a.log, options)
|
|
if err != nil {
|
|
return fmt.Errorf("making sravni client: %w", err)
|
|
}
|
|
|
|
a.client = client
|
|
|
|
return nil
|
|
}
|
|
|
|
func (a *listProductsAction) handle() error {
|
|
params := sravni.ListEducationProductsParams{
|
|
LearningType: a.params.learningType,
|
|
CoursesThematics: []string{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
|
|
}
|
|
|
|
type productsFilterCountActionParams struct {
|
|
learningType string
|
|
courseThematic []string
|
|
learningSelectionType string
|
|
}
|
|
|
|
type productsFilterCountAction struct {
|
|
*baseAction
|
|
|
|
client sravni.Client
|
|
params productsFilterCountActionParams
|
|
}
|
|
|
|
func newProductsFilterCountAction(ctx context.Context) cli.Action {
|
|
action := &productsFilterCountAction{
|
|
baseAction: newBaseAction(ctx),
|
|
}
|
|
|
|
return asCLIAction(action)
|
|
}
|
|
|
|
func (a *productsFilterCountAction) 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 errors.SimpleError(learningTypeOptName + " is empty")
|
|
}
|
|
|
|
a.params.courseThematic = strings.Split(options[courseThematicOptName], ",")
|
|
a.params.learningSelectionType = options[learningTypeSelectionOptName]
|
|
|
|
client, err := makeSravniClient(a.ctx, a.log, options)
|
|
if err != nil {
|
|
return fmt.Errorf("making sravni client: %w", err)
|
|
}
|
|
|
|
a.client = client
|
|
|
|
return nil
|
|
}
|
|
|
|
func (a *productsFilterCountAction) handle() error {
|
|
params := sravni.ListEducationProductsParams{
|
|
LearningType: a.params.learningType,
|
|
CoursesThematics: a.params.courseThematic,
|
|
}
|
|
result, err := a.client.ListEducationalProductsFilterCount(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
|
|
}
|