feat: 单场秀内的图片进度也上报(x/y 张)
一场秀几十到几百张图,按批处理要十几分钟,只报场次会让进度十几分钟不动。 media.UploadAllProgress 每批回调一次,spider 据此把「正在抓 X(32/50 张)」报给后台。
This commit is contained in:
@ -77,6 +77,15 @@ func New(client *ingest.Client, prefix string, concurrency int) *Uploader {
|
|||||||
// UploadAll 并发完成「下载 → 生成 key → 预签名 → PUT」,返回与 urls 下标一一对应的结果。
|
// UploadAll 并发完成「下载 → 生成 key → 预签名 → PUT」,返回与 urls 下标一一对应的结果。
|
||||||
// 单张失败不影响其他张:该下标 Err 非空,调用方据此对这张回退成 URL 上报。
|
// 单张失败不影响其他张:该下标 Err 非空,调用方据此对这张回退成 URL 上报。
|
||||||
func (u *Uploader) UploadAll(ctx context.Context, urls []string) []Result {
|
func (u *Uploader) UploadAll(ctx context.Context, urls []string) []Result {
|
||||||
|
return u.UploadAllProgress(ctx, urls, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
// UploadAllProgress 与 UploadAll 相同,但每完成一批回调一次 onBatch(done, total)。
|
||||||
|
//
|
||||||
|
// 用途:一场秀几十到几百张图,按批处理要跑十几分钟。
|
||||||
|
// 上层靠这个回调把「传到第几张」显示到后台,否则进度只能一场一跳,
|
||||||
|
// 中间十几分钟界面上什么都看不出。
|
||||||
|
func (u *Uploader) UploadAllProgress(ctx context.Context, urls []string, onBatch func(done, total int)) []Result {
|
||||||
results := make([]Result, len(urls))
|
results := make([]Result, len(urls))
|
||||||
if len(urls) == 0 {
|
if len(urls) == 0 {
|
||||||
return results
|
return results
|
||||||
@ -93,6 +102,9 @@ func (u *Uploader) UploadAll(ctx context.Context, urls []string) []Result {
|
|||||||
end = len(urls)
|
end = len(urls)
|
||||||
}
|
}
|
||||||
u.uploadBatch(ctx, urls, results, start, end)
|
u.uploadBatch(ctx, urls, results, start, end)
|
||||||
|
if onBatch != nil {
|
||||||
|
onBatch(end, len(urls))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return results
|
return results
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,6 +2,7 @@ package spider
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
@ -101,7 +102,7 @@ const maxShowConcurrency = 2
|
|||||||
//
|
//
|
||||||
// 返回 true 表示全部成功;false 表示有失败项 —— 失败的图仍保留原始 URL,
|
// 返回 true 表示全部成功;false 表示有失败项 —— 失败的图仍保留原始 URL,
|
||||||
// 后端见到「没有 key」就用 URL 自己下载,所以整场不会因为几张图失败而报废。
|
// 后端见到「没有 key」就用 URL 自己下载,所以整场不会因为几张图失败而报废。
|
||||||
func (s *VogueSpider) uploadLookMedia(ctx context.Context, looks []ingest.RunwayLook) bool {
|
func (s *VogueSpider) uploadLookMedia(ctx context.Context, title string, looks []ingest.RunwayLook) bool {
|
||||||
type ref struct{ look, detail int } // detail = -1 表示主图
|
type ref struct{ look, detail int } // detail = -1 表示主图
|
||||||
|
|
||||||
urls := make([]string, 0, len(looks)*2)
|
urls := make([]string, 0, len(looks)*2)
|
||||||
@ -123,7 +124,11 @@ func (s *VogueSpider) uploadLookMedia(ctx context.Context, looks []ingest.Runway
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
res := s.Media.UploadAll(ctx, urls)
|
// 每传完一批把「这场传到第几张」报给后台:一场秀按批要跑十几分钟,
|
||||||
|
// 只报场次的话界面会十几分钟不动,看着像卡死。
|
||||||
|
res := s.Media.UploadAllProgress(ctx, urls, func(done, total int) {
|
||||||
|
s.reportProgress(fmt.Sprintf("%s(%d/%d 张)", title, done, total), false)
|
||||||
|
})
|
||||||
okAll := true
|
okAll := true
|
||||||
for k, r := range res {
|
for k, r := range res {
|
||||||
if r.Err != nil || r.Key == "" {
|
if r.Err != nil || r.Key == "" {
|
||||||
@ -456,7 +461,7 @@ func (s *VogueSpider) getDetail(brandUID string, info gjson.Result) {
|
|||||||
// 任一张失败不影响整场:失败的图仍带原始 URL,由后端兜底下载。
|
// 任一张失败不影响整场:失败的图仍带原始 URL,由后端兜底下载。
|
||||||
if s.Media != nil && len(looks) > 0 {
|
if s.Media != nil && len(looks) > 0 {
|
||||||
log.Printf("[media] 开始直传 %d 个 look / %d 张图", len(looks), totalImages)
|
log.Printf("[media] 开始直传 %d 个 look / %d 张图", len(looks), totalImages)
|
||||||
okAll := s.uploadLookMedia(context.Background(), looks)
|
okAll := s.uploadLookMedia(context.Background(), hed, looks)
|
||||||
if okAll {
|
if okAll {
|
||||||
log.Printf("[media] 已直传 %d 个 look / %d 张图,后端将跳过下载", len(looks), totalImages)
|
log.Printf("[media] 已直传 %d 个 look / %d 张图,后端将跳过下载", len(looks), totalImages)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user