Initial commit: img-infinite-canvas AI design workbench MVP
Moteva-style AI design workbench replica. Home prompt creates a project; the project page provides an infinite canvas with node drag, zoom/pan, a design chat panel, history replay, image asset upload, and project save/regenerate. - Backend: go-zero, DDD layering, sqlc/pgx, optional PostgreSQL; memory or Redis cache; asynq job queue; MinIO/S3/R2/OSS object storage; sky-valley/pi agent runtime adapter. - Frontend: Next.js App Router + Vite artifact build, TypeScript, i18n, shadcn/ui components, auth (OTP/Turnstile/Google/WeChat). - Deploy: Docker Compose and k3s manifests. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
package objectstorage
|
||||
|
||||
import (
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func objectKeyFromPublicURL(publicBase string, value string) (string, bool) {
|
||||
value = strings.TrimSpace(value)
|
||||
publicBase = strings.TrimRight(strings.TrimSpace(publicBase), "/")
|
||||
if value == "" || publicBase == "" {
|
||||
return "", false
|
||||
}
|
||||
|
||||
if strings.HasPrefix(value, publicBase+"/") {
|
||||
return unescapeObjectKey(strings.TrimPrefix(strings.Split(value, "?")[0], publicBase+"/"))
|
||||
}
|
||||
|
||||
parsedValue, err := url.Parse(value)
|
||||
if err != nil {
|
||||
return "", false
|
||||
}
|
||||
parsedBase, err := url.Parse(publicBase)
|
||||
if err != nil {
|
||||
return "", false
|
||||
}
|
||||
basePath := strings.TrimRight(parsedBase.EscapedPath(), "/")
|
||||
valuePath := parsedValue.EscapedPath()
|
||||
if basePath == "" || !strings.HasPrefix(valuePath, basePath+"/") {
|
||||
return "", false
|
||||
}
|
||||
return unescapeObjectKey(strings.TrimPrefix(valuePath, basePath+"/"))
|
||||
}
|
||||
|
||||
func unescapeObjectKey(value string) (string, bool) {
|
||||
value = strings.TrimLeft(strings.TrimSpace(value), "/")
|
||||
if value == "" {
|
||||
return "", false
|
||||
}
|
||||
objectKey, err := url.PathUnescape(value)
|
||||
if err != nil {
|
||||
return "", false
|
||||
}
|
||||
return objectKey, objectKey != ""
|
||||
}
|
||||
Reference in New Issue
Block a user