diff --git a/cmd/dev/sravnicli/products.go b/cmd/dev/sravnicli/products.go index 8e7eb8e..d883e6e 100644 --- a/cmd/dev/sravnicli/products.go +++ b/cmd/dev/sravnicli/products.go @@ -13,22 +13,24 @@ import ( ) const ( - learningTypeOptName = "learning-type" - courseThematicOptName = "course-thematic" + learningTypeOptName = "learning-type" + courseThematicOptName = "course-thematic" + learningTypeSelectionOptName = "learning-selection" ) 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) + 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)) @@ -67,10 +69,11 @@ func asCLIAction(a action) cli.Action { } type listProductsActionParams struct { - learningType string - courseThematic string - limit int - offset int + learningType string + courseThematic string + learningSelectionType string + limit int + offset int } type listProductsAction struct { @@ -102,6 +105,7 @@ func (a *listProductsAction) parse(args []string, options map[string]string) err } a.params.courseThematic = options[courseThematicOptName] + a.params.learningSelectionType = options[learningTypeSelectionOptName] if value, ok := options[limitOption.Key()]; ok { a.params.limit, _ = strconv.Atoi(value) diff --git a/internal/common/client/sravni/client.go b/internal/common/client/sravni/client.go index 4cc167d..a00c2bd 100644 --- a/internal/common/client/sravni/client.go +++ b/internal/common/client/sravni/client.go @@ -82,24 +82,85 @@ type ListEducationProductsParams struct { Offset int } -type ListEducationProductsRequest struct { - Fingerprint string `json:"fingerPrint,omitempty"` - ProductName string `json:"productName,omitempty"` - AdvertisingOnly bool `json:"advertisingOnly"` - Location string `json:"location"` - OfferTypes []string `json:"offerTypes"` - IsMix bool `json:"isMix"` - MixRepeated bool `json:"mixRepeated"` - Fields []string `json:"fields"` - SortProperty string `json:"sortProperty"` - SortDirection string `json:"sortDirection"` - LearningType []string `json:"learningtype"` - CoursesThematics []string `json:"coursesThematics"` - NotSubIsWebinar string `json:"not-sub-isWebinar"` - NotB2B string `json:"not-b2b"` +type stringifiedBool string - Limit int `json:"limit"` - Offset int `json:"offset"` +func AsStringifiedBool(b bool) stringifiedBool { + return stringifiedBool(strconv.FormatBool(b)) +} + +// FilterLevel is a Уровень сложности +type FilterLevel string + +const ( + FilterLevelJunior FilterLevel = "levelJuniorNew" + FilterLevelMiddle FilterLevel = "levelMiddleNew" + FilterLevelChildren FilterLevel = "levelChildNew" +) + +// FilterTime is a срок обучения +type FilterTime string + +const ( + FilterTimeLessMonth FilterTime = "1" // less than month + FilterTimeFrom1To3Month FilterTime = "2" // from month to three month + FilterTimeFrom3To6 FilterTime = "3" // from three to six months + FilterTimeFrom6To12 FilterTime = "4" // from six to twelve months + FilterTimeFrom12 FilterTime = "5" // from twelve months +) + +// FilterFormat is a Форма обучение +type FilterFormat string + +const ( + FilterFormatRecord FilterFormat = "formatRecordNew" + FilterFormatOnline FilterFormat = "formatOnlineNew" + FilterFormatOffline FilterFormat = "formatOfflineNew" +) + +// FilterGraphic is a График прохождения +type FilterGraphic string + +const ( + FilterGraphicTimeLength FilterGraphic = "courseTimeLengthNew" + FilterGraphicTerm FilterGraphic = "courseTimeTermNew" +) + +type ListEducationProductsRequest struct { + Fingerprint string `json:"fingerPrint,omitempty"` + ProductName string `json:"productName,omitempty"` + Location string `json:"location"` + OfferTypes []string `json:"offerTypes"` + IsMix bool `json:"isMix"` + MixRepeated bool `json:"mixRepeated"` + Fields []string `json:"fields"` + + // Filters + LearningType []string `json:"learningtype"` + CoursesThematics []string `json:"coursesThematics"` + Organizations []string `json:"organizations"` // list of ids + DictionatyFormatFilterNew []FilterFormat `json:"dictionaryFormatFilterNew"` + DictionaryTimeFilter []FilterTime `json:"dictionaryTimeFilter"` + DictionaryGraphicFilterNew []FilterGraphic `json:"dictionaryGraphicFilterNew"` + DictionatyLevelFilterNew []FilterLevel `json:"dictionaryLevelFilterNew"` + + // Options + SubMentor []stringifiedBool `json:"sub-mentor"` // option with mentor + SubTimeFree []stringifiedBool `json:"sub-timeFree"` // option with trial + SubJobGarantSub []stringifiedBool `json:"sub-jobGarantsub"` // option for job garantee + SubPriceFree []stringifiedBool `json:"sub-priceFree"` // only free + SubInstallment []stringifiedBool `json:"sub-installment"` // with credit + SubIsCourseProfession []stringifiedBool `json:"sub-isCourseProfession"` // освоить профессию с нуля + DevelopSkills []stringifiedBool `json:"developSkills"` // развить навыки + + NotSubIsWebinar string `json:"not-sub-isWebinar"` + NotB2B string `json:"not-b2b"` + AdvertisingOnly bool `json:"advertisingOnly"` + + // Pagination and sorting + Limit int `json:"limit"` + Offset int `json:"offset"` + SortProperty string `json:"sortProperty"` + SortDirection string `json:"sortDirection"` } type ListEducationProductsResponse struct { diff --git a/internal/kurious/domain/course.go b/internal/kurious/domain/course.go index 59d8c73..648c88d 100644 --- a/internal/kurious/domain/course.go +++ b/internal/kurious/domain/course.go @@ -27,7 +27,9 @@ type Course struct { // FullPrice is a course full price without discount. FullPrice float64 // Discount for the course. - Discount float64 + Discount float64 + Thematic string + LearningType string // Duration for the course. It will be splitted in values like: // full month / full day / full hour. diff --git a/internal/kurious/ports/background.go b/internal/kurious/ports/background.go index 806886c..c8e7faf 100644 --- a/internal/kurious/ports/background.go +++ b/internal/kurious/ports/background.go @@ -79,7 +79,8 @@ func (s NextRunStats) String() string { func (bp *BackgroundProcess) GetNextRunStats() NextRunStats { out := make(NextRunStats) if bp.syncSravniHandlerEntryID.Valid() { - sEntry := bp.scheduler.Entry(bp.syncSravniHandlerEntryID.Value()) + entryID := bp.syncSravniHandlerEntryID.Value() + sEntry := bp.scheduler.Entry(entryID) out["sravni_handler"] = sEntry.Next } @@ -118,11 +119,11 @@ func (bp *BackgroundProcess) registerHandler(ctx context.Context, spec, name str xcontext.LogInfo(jctx, bp.log, "iteration completed") })) - var out nullable.Value[cron.EntryID] if err != nil { - return out, fmt.Errorf("adding %s job: %w", name, err) + return nullable.Value[cron.EntryID]{}, fmt.Errorf("adding %s job: %w", name, err) } + var out nullable.Value[cron.EntryID] out.Set(entry) return out, nil diff --git a/internal/kurious/ports/http/server.go b/internal/kurious/ports/http/server.go new file mode 100644 index 0000000..6d0cf3b --- /dev/null +++ b/internal/kurious/ports/http/server.go @@ -0,0 +1,3 @@ +package http + +type Server struct{} diff --git a/internal/kurious/ports/services.go b/internal/kurious/ports/services.go new file mode 100644 index 0000000..03e93f2 --- /dev/null +++ b/internal/kurious/ports/services.go @@ -0,0 +1,8 @@ +package ports + +import "git.loyso.art/frx/kurious/internal/kurious/ports/http" + +type Services struct { + HTTP *http.Server + Background *BackgroundProcess +}