93 lines
2.6 KiB
Go
93 lines
2.6 KiB
Go
package telegraph
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"path"
|
|
"path/filepath"
|
|
|
|
"github.com/charmbracelet/log"
|
|
"github.com/duke-git/lancet/v2/retry"
|
|
"github.com/krau/SaveAny-Bot/common/utils/fsutil"
|
|
"github.com/krau/SaveAny-Bot/config"
|
|
"golang.org/x/sync/errgroup"
|
|
)
|
|
|
|
func (t *Task) Execute(ctx context.Context) error {
|
|
logger := log.FromContext(ctx)
|
|
logger.Infof("Starting Telegraph task %s", t.PhPath)
|
|
t.progress.OnStart(ctx, t)
|
|
eg, gctx := errgroup.WithContext(ctx)
|
|
eg.SetLimit(config.C().Workers)
|
|
for i, pic := range t.Pics {
|
|
eg.Go(func() error {
|
|
err := t.processPic(gctx, pic, i)
|
|
if err != nil {
|
|
logger.Errorf("Error processing picture %s: %v", pic, err)
|
|
return fmt.Errorf("failed to process picture %s: %w", pic, err)
|
|
}
|
|
t.downloaded.Add(1)
|
|
t.progress.OnProgress(gctx, t)
|
|
return nil
|
|
})
|
|
}
|
|
err := eg.Wait()
|
|
if err != nil {
|
|
logger.Errorf("Error during Telegraph task execution: %v", err)
|
|
} else {
|
|
logger.Infof("Telegraph task %s completed successfully", t.PhPath)
|
|
}
|
|
t.progress.OnDone(ctx, t, err)
|
|
return err
|
|
}
|
|
|
|
func (t *Task) processPic(ctx context.Context, picUrl string, index int) error {
|
|
retryOpts := []retry.Option{
|
|
retry.Context(ctx),
|
|
retry.RetryTimes(uint(config.C().Retry)),
|
|
}
|
|
err := retry.Retry(func() error {
|
|
body, err := t.client.Download(ctx, picUrl)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to download picture %s: %w", picUrl, err)
|
|
}
|
|
defer body.Close()
|
|
filename := fmt.Sprintf("%d%s", index+1, path.Ext(picUrl))
|
|
if t.cannotStream {
|
|
cacheFile, err := fsutil.CreateFile(filepath.Join(config.C().Temp.BasePath,
|
|
fmt.Sprintf("tph_%s_%s", t.TaskID(), filename),
|
|
))
|
|
if err != nil {
|
|
return fmt.Errorf("failed to create cache file for picture %s: %w", filename, err)
|
|
}
|
|
defer func() {
|
|
if err := cacheFile.CloseAndRemove(); err != nil {
|
|
logger := log.FromContext(ctx)
|
|
logger.Errorf("Failed to close and remove cache file for picture %s: %v", filename, err)
|
|
}
|
|
}()
|
|
_, err = io.Copy(cacheFile, body)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to copy picture %s to cache file: %w", filename, err)
|
|
}
|
|
_, err = cacheFile.Seek(0, 0)
|
|
if err != nil {
|
|
return fmt.Errorf("failed to seek cache file for picture %s: %w", filename, err)
|
|
}
|
|
err = t.Stor.Save(ctx, cacheFile, path.Join(t.StorPath, filename))
|
|
if err != nil {
|
|
return fmt.Errorf("failed to save picture %s: %w", filename, err)
|
|
}
|
|
} else {
|
|
err = t.Stor.Save(ctx, body, path.Join(t.StorPath, filename))
|
|
}
|
|
|
|
if err != nil {
|
|
return fmt.Errorf("failed to save picture %s: %w", filename, err)
|
|
}
|
|
return nil
|
|
}, retryOpts...)
|
|
return err
|
|
}
|