Scope knowledge and image libraries by brand
This commit is contained in:
@@ -32,15 +32,15 @@ type mediaSupplyArticleImageUpload struct {
|
||||
Content []byte
|
||||
}
|
||||
|
||||
func (s *MediaSupplyService) prepareMeijiequanArticleContent(ctx context.Context, tenantID int64, content string) (string, error) {
|
||||
func (s *MediaSupplyService) prepareMeijiequanArticleContent(ctx context.Context, tenantID int64, brandID int64, content string) (string, error) {
|
||||
html := meijiequanArticleHTML(content)
|
||||
if strings.TrimSpace(html) == "" {
|
||||
return "", nil
|
||||
}
|
||||
return s.uploadMeijiequanArticleImages(ctx, tenantID, html)
|
||||
return s.uploadMeijiequanArticleImages(ctx, tenantID, brandID, html)
|
||||
}
|
||||
|
||||
func (s *MediaSupplyService) uploadMeijiequanArticleImages(ctx context.Context, tenantID int64, fragment string) (string, error) {
|
||||
func (s *MediaSupplyService) uploadMeijiequanArticleImages(ctx context.Context, tenantID int64, brandID int64, fragment string) (string, error) {
|
||||
if !strings.Contains(strings.ToLower(fragment), "<img") {
|
||||
return fragment, nil
|
||||
}
|
||||
@@ -56,7 +56,7 @@ func (s *MediaSupplyService) uploadMeijiequanArticleImages(ctx context.Context,
|
||||
|
||||
cache := make(map[string]string)
|
||||
for _, node := range nodes {
|
||||
if err := s.uploadMeijiequanArticleImageNode(ctx, tenantID, node, cache); err != nil {
|
||||
if err := s.uploadMeijiequanArticleImageNode(ctx, tenantID, brandID, node, cache); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
@@ -70,31 +70,31 @@ func (s *MediaSupplyService) uploadMeijiequanArticleImages(ctx context.Context,
|
||||
return builder.String(), nil
|
||||
}
|
||||
|
||||
func (s *MediaSupplyService) uploadMeijiequanArticleImageNode(ctx context.Context, tenantID int64, node *nethtml.Node, cache map[string]string) error {
|
||||
func (s *MediaSupplyService) uploadMeijiequanArticleImageNode(ctx context.Context, tenantID int64, brandID int64, node *nethtml.Node, cache map[string]string) error {
|
||||
if node == nil {
|
||||
return nil
|
||||
}
|
||||
if node.Type == nethtml.ElementNode && strings.EqualFold(node.Data, "img") {
|
||||
if err := s.uploadMeijiequanArticleImageAttrs(ctx, tenantID, node, cache); err != nil {
|
||||
if err := s.uploadMeijiequanArticleImageAttrs(ctx, tenantID, brandID, node, cache); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
for child := node.FirstChild; child != nil; child = child.NextSibling {
|
||||
if err := s.uploadMeijiequanArticleImageNode(ctx, tenantID, child, cache); err != nil {
|
||||
if err := s.uploadMeijiequanArticleImageNode(ctx, tenantID, brandID, child, cache); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MediaSupplyService) uploadMeijiequanArticleImageAttrs(ctx context.Context, tenantID int64, node *nethtml.Node, cache map[string]string) error {
|
||||
func (s *MediaSupplyService) uploadMeijiequanArticleImageAttrs(ctx context.Context, tenantID int64, brandID int64, node *nethtml.Node, cache map[string]string) error {
|
||||
src := mediaSupplyHTMLAttrValue(node.Attr, "src")
|
||||
originalSrc := mediaSupplyHTMLAttrValue(node.Attr, "_src")
|
||||
dataSrc := mediaSupplyHTMLAttrValue(node.Attr, "data-src")
|
||||
assetID := mediaSupplyHTMLInt64AttrValue(node.Attr, "data-asset-id")
|
||||
currentURL := firstNonEmptyText(src, originalSrc, dataSrc)
|
||||
|
||||
upload, resolved, err := s.resolveMeijiequanArticleImageUpload(ctx, tenantID, currentURL, assetID)
|
||||
upload, resolved, err := s.resolveMeijiequanArticleImageUpload(ctx, tenantID, brandID, currentURL, assetID)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -158,8 +158,8 @@ func (s *MediaSupplyService) uploadMeijiequanArticleImageAttrs(ctx context.Conte
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *MediaSupplyService) resolveMeijiequanArticleImageUpload(ctx context.Context, tenantID int64, imageURL string, assetID int64) (mediaSupplyArticleImageUpload, bool, error) {
|
||||
objectKey, internalAssetURL, ok := s.mediaSupplyObjectKeyFromPublicAssetURL(imageURL, tenantID)
|
||||
func (s *MediaSupplyService) resolveMeijiequanArticleImageUpload(ctx context.Context, tenantID int64, brandID int64, imageURL string, assetID int64) (mediaSupplyArticleImageUpload, bool, error) {
|
||||
objectKey, internalAssetURL, ok := s.mediaSupplyObjectKeyFromPublicAssetURL(ctx, imageURL, tenantID, brandID)
|
||||
if internalAssetURL {
|
||||
if !ok {
|
||||
if assetID <= 0 {
|
||||
@@ -171,7 +171,7 @@ func (s *MediaSupplyService) resolveMeijiequanArticleImageUpload(ctx context.Con
|
||||
}
|
||||
}
|
||||
if assetID > 0 {
|
||||
objectKey, err := s.loadMediaSupplyImageAssetObjectKey(ctx, tenantID, assetID)
|
||||
objectKey, err := s.loadMediaSupplyImageAssetObjectKey(ctx, tenantID, brandID, assetID)
|
||||
if err != nil {
|
||||
return mediaSupplyArticleImageUpload{}, false, err
|
||||
}
|
||||
@@ -259,7 +259,7 @@ func mediaSupplyUploadFilename(objectKey, sourceURL, ext string) string {
|
||||
return name
|
||||
}
|
||||
|
||||
func (s *MediaSupplyService) mediaSupplyObjectKeyFromPublicAssetURL(raw string, tenantID int64) (string, bool, bool) {
|
||||
func (s *MediaSupplyService) mediaSupplyObjectKeyFromPublicAssetURL(ctx context.Context, raw string, tenantID int64, brandID int64) (string, bool, bool) {
|
||||
token, ok := mediaSupplyPublicAssetTokenFromURL(raw)
|
||||
if !ok {
|
||||
return "", false, false
|
||||
@@ -268,6 +268,9 @@ func (s *MediaSupplyService) mediaSupplyObjectKeyFromPublicAssetURL(raw string,
|
||||
if !valid || !mediaSupplyObjectKeyAllowedForTenant(objectKey, tenantID) {
|
||||
return "", true, false
|
||||
}
|
||||
if !s.mediaSupplyImageObjectKeyBelongsToBrand(ctx, tenantID, brandID, objectKey) {
|
||||
return "", true, false
|
||||
}
|
||||
return objectKey, true, true
|
||||
}
|
||||
|
||||
@@ -317,16 +320,48 @@ func mediaSupplyObjectKeyAllowedForTenant(objectKey string, tenantID int64) bool
|
||||
strings.HasPrefix(objectKey, tenantPrefix+"articles/")
|
||||
}
|
||||
|
||||
func (s *MediaSupplyService) loadMediaSupplyImageAssetObjectKey(ctx context.Context, tenantID, assetID int64) (string, error) {
|
||||
func mediaSupplyObjectKeyIsImageLibraryAsset(objectKey string, tenantID int64) bool {
|
||||
if tenantID <= 0 {
|
||||
return false
|
||||
}
|
||||
tenantPrefix := "tenants/" + strconv.FormatInt(tenantID, 10) + "/"
|
||||
return strings.HasPrefix(strings.TrimSpace(objectKey), tenantPrefix+"images/")
|
||||
}
|
||||
|
||||
func (s *MediaSupplyService) mediaSupplyImageObjectKeyBelongsToBrand(ctx context.Context, tenantID, brandID int64, objectKey string) bool {
|
||||
if s == nil || s.pool == nil || !mediaSupplyObjectKeyIsImageLibraryAsset(objectKey, tenantID) {
|
||||
return true
|
||||
}
|
||||
if tenantID <= 0 || brandID <= 0 || strings.TrimSpace(objectKey) == "" {
|
||||
return false
|
||||
}
|
||||
var exists bool
|
||||
if err := s.pool.QueryRow(ctx, `
|
||||
SELECT EXISTS (
|
||||
SELECT 1
|
||||
FROM image_assets
|
||||
WHERE tenant_id = $1
|
||||
AND brand_id = $2
|
||||
AND object_key = $3
|
||||
AND status = 'active'
|
||||
AND deleted_at IS NULL
|
||||
)
|
||||
`, tenantID, brandID, objectKey).Scan(&exists); err != nil {
|
||||
return false
|
||||
}
|
||||
return exists
|
||||
}
|
||||
|
||||
func (s *MediaSupplyService) loadMediaSupplyImageAssetObjectKey(ctx context.Context, tenantID, brandID, assetID int64) (string, error) {
|
||||
if s == nil || s.pool == nil {
|
||||
return "", errMediaSupplyArticleImageUpload
|
||||
}
|
||||
var objectKey string
|
||||
if err := s.pool.QueryRow(ctx, `
|
||||
SELECT object_key
|
||||
FROM image_assets
|
||||
WHERE id = $1 AND tenant_id = $2 AND status = 'active' AND deleted_at IS NULL
|
||||
`, assetID, tenantID).Scan(&objectKey); err != nil {
|
||||
SELECT object_key
|
||||
FROM image_assets
|
||||
WHERE id = $1 AND tenant_id = $2 AND brand_id = $3 AND status = 'active' AND deleted_at IS NULL
|
||||
`, assetID, tenantID, brandID).Scan(&objectKey); err != nil {
|
||||
if errors.Is(err, pgx.ErrNoRows) {
|
||||
return "", errMediaSupplyArticleImageUpload
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user