handle dimension

This commit is contained in:
2024-02-11 15:50:43 +03:00
parent 0c7e94c834
commit e072fcbef5
13 changed files with 479 additions and 27 deletions

View File

@ -0,0 +1,71 @@
package main
import (
"context"
"strings"
"git.loyso.art/frx/eway/internal/entity"
"git.loyso.art/frx/eway/internal/matcher"
"github.com/rs/zerolog"
)
type dimensionDispatcher struct {
heigth matcher.Unit
width matcher.Unit
length matcher.Unit
}
func (d dimensionDispatcher) isDimensionParam(value string) bool {
return d.heigth.Match(value) || d.width.Match(value) || d.length.Match(value)
}
func (d dimensionDispatcher) dispatch(ctx context.Context, value, key string, in *entity.GoodsItemSize) {
if !d.isDimensionParam(value) {
return
}
if strings.Contains(value, "/") {
dimensionValues := strings.Split(value, "/")
for _, dv := range dimensionValues {
d.dispatch(ctx, dv, key, in)
}
} else {
out, err := entity.ParseDimention(key, entity.DimensionLocalRU)
if err != nil {
zerolog.Ctx(ctx).Warn().Err(err).Msg("unable to parse key, skipping")
return
}
out = out.AdjustTo(entity.DimensionKindCentimeter)
switch {
case d.heigth.Match(value):
in.Height = out
case d.width.Match(value):
in.Width = out
case d.width.Match(value):
in.Length = out
default:
zerolog.Ctx(ctx).Error().Str("key", key).Msg("unable to find proper matcher")
}
}
}
func makeDefaultDimensionDispatcher() dimensionDispatcher {
h := matcher.NewRadix(matcher.RadixCaseInsensitive())
h.Register("Высота")
h.Register("Высота/*")
w := matcher.NewRadix(matcher.RadixCaseInsensitive())
w.Register("Ширина")
w.Register("Ширина/*")
l := matcher.NewRadix(matcher.RadixCaseInsensitive())
l.Register("Длина")
l.Register("Длина/*")
l.Register("Общ. длина")
return dimensionDispatcher{
heigth: h,
width: w,
length: l,
}
}

View File

@ -34,6 +34,8 @@ import (
"github.com/urfave/cli/v3"
)
type empty entity.Empty
func main() {
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer func() {
@ -506,14 +508,14 @@ func viewItemsUniqueParamsAction(ctx context.Context, c *cli.Command) error {
return fmt.Errorf("getting repository: %w", err)
}
knownParams := map[string]struct{}{}
knownParams := map[string]empty{}
iter, err := repository.GoodsItem().ListIter(ctx, 1)
if err != nil {
return fmt.Errorf("getting list iter: %w", err)
}
for item := range iter {
for k := range item.Parameters {
knownParams[k] = struct{}{}
knownParams[k] = empty{}
}
}
@ -595,8 +597,8 @@ func viewItemsParamsKnownValuesAction(ctx context.Context, c *cli.Command) error
m.RegisterRegexp(regexp)
}
requestedValues := make(map[string]map[string]struct{}, len(params))
requestedValuesByPattern := make(map[string]map[string]struct{}, len(params))
requestedValues := make(map[string]map[string]empty, len(params))
requestedValuesByPattern := make(map[string]map[string]empty, len(params))
iter := getItemsIter(ctx, repository.GoodsItem())
for iter.Next() {
item := iter.Get()
@ -608,16 +610,16 @@ func viewItemsParamsKnownValuesAction(ctx context.Context, c *cli.Command) error
values, ok := requestedValues[k]
if !ok {
values = make(map[string]struct{})
values = make(map[string]empty)
}
values[v] = struct{}{}
values[v] = empty{}
requestedValues[k] = values
values, ok = requestedValuesByPattern[matchedPattern]
if !ok {
values = map[string]struct{}{}
values = map[string]empty{}
}
values[v] = struct{}{}
values[v] = empty{}
requestedValuesByPattern[matchedPattern] = values
}
}
@ -657,7 +659,7 @@ func viewItemsCountAction(ctx context.Context, c *cli.Command) error {
filters := c.StringSlice("param-key-match")
m := matcher.NewRadix()
patternMapped := make(map[string]struct{}, len(filters))
patternMapped := make(map[string]empty, len(filters))
if len(filters) == 0 {
m.Register("*")
} else {
@ -665,7 +667,7 @@ func viewItemsCountAction(ctx context.Context, c *cli.Command) error {
m.Register(f)
}
for _, pattern := range m.Patterns() {
patternMapped[pattern] = struct{}{}
patternMapped[pattern] = empty{}
}
}
@ -675,7 +677,7 @@ func viewItemsCountAction(ctx context.Context, c *cli.Command) error {
return fmt.Errorf("getting items: %w", err)
}
for _, item := range items {
seenPatterns := map[string]struct{}{}
seenPatterns := map[string]empty{}
for k := range item.Parameters {
pattern := m.MatchByPattern(k)
@ -685,7 +687,7 @@ func viewItemsCountAction(ctx context.Context, c *cli.Command) error {
if _, ok := seenPatterns[pattern]; ok {
continue
}
seenPatterns[pattern] = struct{}{}
seenPatterns[pattern] = empty{}
}
if len(seenPatterns) == len(patternMapped) {
@ -794,14 +796,14 @@ func importFromFileAction(ctx context.Context, c *cli.Command) error {
failedToInsert int
)
seenCategories := make(map[string]struct{})
seenCategories := make(map[string]empty)
categories, err := r.Category().List(ctx)
if err != nil {
return fmt.Errorf("listing categories: %w", err)
}
for _, category := range categories {
seenCategories[category.Name] = struct{}{}
seenCategories[category.Name] = empty{}
}
bfile := bufio.NewReader(productsFile)
@ -841,7 +843,7 @@ func importFromFileAction(ctx context.Context, c *cli.Command) error {
return fmt.Errorf("unable to create new category: %w", err)
}
log.Debug().Any("category", goodsItem.Type).Msg("inserted new category")
seenCategories[goodsItem.Type] = struct{}{}
seenCategories[goodsItem.Type] = empty{}
}
log.Debug().Int("count", len(goodsItems)).Int("failed", failedToInsert).Msg("preparing to upload")
@ -1137,16 +1139,16 @@ func parseEwayDumpAction(ctx context.Context, cmd *cli.Command) error {
goodsItems := make([]entity.GoodsItem, 0, batchSize)
productIDs := make([]int, 0, batchSize)
knownCategories := make(map[string]struct{})
knownCategories := make(map[string]empty)
err = entity.IterWithErr(repository.Category().List(ctx)).Do(func(c entity.Category) error {
knownCategories[c.Name] = struct{}{}
knownCategories[c.Name] = empty{}
return nil
})
if err != nil {
return fmt.Errorf("filling known categories: %w", err)
}
itemsUpdated := make(map[string]struct{}, len(seenItems))
itemsUpdated := make(map[string]empty, len(seenItems))
stats := struct {
fetchedInfo int
handledAll int
@ -1154,6 +1156,8 @@ func parseEwayDumpAction(ctx context.Context, cmd *cli.Command) error {
skippedItem int
}{}
dimensionDispatcher := makeDefaultDimensionDispatcher()
startFrom := time.Now()
for {
select {
@ -1190,7 +1194,7 @@ func parseEwayDumpAction(ctx context.Context, cmd *cli.Command) error {
if time.Since(seenItem.CreatedAt) < time.Hour*24 {
logger.Debug().Str("sku", item.SKU).Msg("skipping item because it's too fresh")
stats.skippedItem++
itemsUpdated[item.SKU] = struct{}{}
itemsUpdated[item.SKU] = empty{}
continue
}
@ -1213,7 +1217,11 @@ func parseEwayDumpAction(ctx context.Context, cmd *cli.Command) error {
continue
}
itemsUpdated[goodsItem.Articul] = struct{}{}
for key, value := range goodsItem.Parameters {
dimensionDispatcher.dispatch(ctx, key, value, &goodsItem.Sizes)
}
itemsUpdated[goodsItem.Articul] = empty{}
stats.handledAll++
goodsItems = append(goodsItems, goodsItem)
@ -1235,7 +1243,7 @@ func parseEwayDumpAction(ctx context.Context, cmd *cli.Command) error {
Int64("id", category.ID).
Msg("created new category")
knownCategories[goodsItem.Type] = struct{}{}
knownCategories[goodsItem.Type] = empty{}
}
_, err = repository.GoodsItem().UpsertMany(ctx, goodsItems...)