fixes
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
package processing
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// isDescriptionFieldKey reports keys whose values should be plain text scalars
|
||||
// (not JSON arrays / nested HTML wrappers) for process + V1 poll contracts.
|
||||
func isDescriptionFieldKey(key string) bool {
|
||||
switch strings.ToLower(strings.TrimSpace(key)) {
|
||||
case "description", "desc", "body", "short_description", "shortdescription",
|
||||
"processed_description", "long_description", "longdescription":
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
// PlainDescriptionFromAny coerces legacy description shapes to a single plain
|
||||
// string: string, {#text}, or arrays of those (joined with newlines). HTML is
|
||||
// stripped via v1PlainDescription so poll/store never keep ["…"] or markup blobs.
|
||||
func PlainDescriptionFromAny(v any) string {
|
||||
if v == nil {
|
||||
return ""
|
||||
}
|
||||
switch t := v.(type) {
|
||||
case string:
|
||||
return v1PlainDescription(t)
|
||||
case []string:
|
||||
parts := make([]string, 0, len(t))
|
||||
for _, s := range t {
|
||||
if p := v1PlainDescription(s); p != "" {
|
||||
parts = append(parts, p)
|
||||
}
|
||||
}
|
||||
return strings.Join(parts, "\n")
|
||||
case []any:
|
||||
parts := make([]string, 0, len(t))
|
||||
for _, item := range t {
|
||||
if p := PlainDescriptionFromAny(item); p != "" {
|
||||
parts = append(parts, p)
|
||||
}
|
||||
}
|
||||
return strings.Join(parts, "\n")
|
||||
case map[string]any:
|
||||
for _, k := range []string{"#text", "text", "value", "description", "body"} {
|
||||
if p := PlainDescriptionFromAny(t[k]); p != "" {
|
||||
return p
|
||||
}
|
||||
}
|
||||
return ""
|
||||
default:
|
||||
s := strings.TrimSpace(fmt.Sprint(t))
|
||||
if s == "" || s == "<nil>" {
|
||||
return ""
|
||||
}
|
||||
return v1PlainDescription(s)
|
||||
}
|
||||
}
|
||||
|
||||
// coerceScalarText flattens arrays / #text wrappers into a trimmed string without
|
||||
// HTML stripping (names, brands, stock labels, …).
|
||||
func coerceScalarText(v any) string {
|
||||
if v == nil {
|
||||
return ""
|
||||
}
|
||||
switch t := v.(type) {
|
||||
case string:
|
||||
return strings.TrimSpace(t)
|
||||
case []string:
|
||||
parts := make([]string, 0, len(t))
|
||||
for _, s := range t {
|
||||
s = strings.TrimSpace(s)
|
||||
if s != "" {
|
||||
parts = append(parts, s)
|
||||
}
|
||||
}
|
||||
return strings.Join(parts, " ")
|
||||
case []any:
|
||||
parts := make([]string, 0, len(t))
|
||||
for _, item := range t {
|
||||
if s := coerceScalarText(item); s != "" {
|
||||
parts = append(parts, s)
|
||||
}
|
||||
}
|
||||
return strings.Join(parts, " ")
|
||||
case map[string]any:
|
||||
for _, k := range []string{"#text", "text", "value"} {
|
||||
if s := coerceScalarText(t[k]); s != "" {
|
||||
return s
|
||||
}
|
||||
}
|
||||
return ""
|
||||
case float64, float32, int, int64, int32, bool:
|
||||
s := strings.TrimSpace(fmt.Sprint(t))
|
||||
if s == "<nil>" {
|
||||
return ""
|
||||
}
|
||||
return s
|
||||
default:
|
||||
if n, ok := t.(jsonNumberStringer); ok {
|
||||
return strings.TrimSpace(n.String())
|
||||
}
|
||||
s := strings.TrimSpace(fmt.Sprint(t))
|
||||
if s == "" || s == "<nil>" {
|
||||
return ""
|
||||
}
|
||||
return s
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user