feat: restore Xiaohongshu read-only collection

This commit is contained in:
2026-09-14 20:05:32 +08:00
parent 44a28954cf
commit 4c37d0c9bf
13 changed files with 1539 additions and 39 deletions
+15 -5
View File
@@ -20,7 +20,7 @@ type creatorMaterialDownloader struct {
}
func (downloader creatorMaterialDownloader) Download(ctx context.Context, work creator.Work, destination string) error {
if work.Platform != creator.PlatformDouyin || downloader.store == nil || downloader.phaseAStore == nil || downloader.hubStore == nil {
if (work.Platform != creator.PlatformDouyin && work.Platform != creator.PlatformXiaohongshu) || downloader.store == nil || downloader.phaseAStore == nil || downloader.hubStore == nil {
return fmt.Errorf("%w: creator media gateway is unavailable", creator.ErrUnavailable)
}
accountID := work.SourceID
@@ -39,7 +39,7 @@ func (downloader creatorMaterialDownloader) Download(ctx context.Context, work c
if err != nil {
return err
}
if account.Platform != creator.PlatformDouyin || profile.Platform != creator.PlatformDouyin || account.AuthorizationStatus != "authorized" || profile.LoginStatus != "logged_in" || account.PlatformAccountKey != profile.PlatformAccountKey {
if account.Platform != work.Platform || profile.Platform != work.Platform || account.AuthorizationStatus != "authorized" || profile.LoginStatus != "logged_in" || account.PlatformAccountKey != profile.PlatformAccountKey {
return fmt.Errorf("%w: media account identity is not verified", creator.ErrConflict)
}
environment, err := downloader.hubStore.GetEnvironmentContextForAccount(ctx, accountID)
@@ -50,11 +50,21 @@ func (downloader creatorMaterialDownloader) Download(ctx context.Context, work c
if err != nil {
return fmt.Errorf("%w: media gateway unavailable: %v", creator.ErrUnavailable, err)
}
browser := creatorGatewayBrowser{gateway: gateway, environment: environment}
if _, err := browser.Identity(ctx, profile.PlatformAccountKey); err != nil {
if _, err := verifyCreatorPlatformIdentity(ctx, work.Platform, gateway, environment, profile.PlatformAccountKey); err != nil {
return fmt.Errorf("%w: media browser identity verification failed: %v", creator.ErrConflict, err)
}
return browser.Media(ctx, work.OriginalURL, destination)
if work.Platform == creator.PlatformDouyin {
return (creatorGatewayBrowser{gateway: gateway, environment: environment}).Media(ctx, work.OriginalURL, destination)
}
data, contentType, err := (xiaohongshuGatewayBrowser{gateway: gateway, environment: environment}).Media(ctx, work.OriginalURL)
if err != nil {
return err
}
contentType = strings.ToLower(strings.TrimSpace(strings.SplitN(contentType, ";", 2)[0]))
if !strings.HasPrefix(contentType, "video/") && contentType != "application/octet-stream" {
return fmt.Errorf("xiaohongshu media response is not a video")
}
return writeCreatorMedia(destination, data)
}
func processCreatorMaterial(ctx context.Context, store *creator.Store, phaseAStore *phasea.Store, hubStore *hub.Store, workID string) (creator.MaterialJob, error) {