refactor: update file handling to use new downloader interface; remove unused tdler package

This commit is contained in:
krau
2025-06-29 23:00:40 +08:00
parent 75f52569a0
commit f693bd6103
11 changed files with 47 additions and 47 deletions
+1 -1
View File
@@ -149,7 +149,7 @@ func handleBatchSave(ctx *ext.Context, update *ext.Update, args []string) error
if !supported { if !supported {
continue continue
} }
file, err := tfile.FromMediaMessage(media, msg, tfile.WithNameIfEmpty(tgutil.GenFileNameFromMessage(*msg))) file, err := tfile.FromMediaMessage(media, ctx.Raw, msg, tfile.WithNameIfEmpty(tgutil.GenFileNameFromMessage(*msg)))
if err != nil { if err != nil {
log.FromContext(ctx).Errorf("获取文件失败: %s", err) log.FromContext(ctx).Errorf("获取文件失败: %s", err)
continue continue
@@ -46,7 +46,7 @@ func GetFileFromMessageWithReply(ctx *ext.Context, update *ext.Update, message *
} else { } else {
options = append(options, tfile.WithNameIfEmpty(tgutil.GenFileNameFromMessage(*message))) options = append(options, tfile.WithNameIfEmpty(tgutil.GenFileNameFromMessage(*message)))
} }
file, err = tfile.FromMediaMessage(media, message, options...) file, err = tfile.FromMediaMessage(media, ctx.Raw, message, options...)
if err != nil { if err != nil {
logger.Errorf("Failed to get file from media: %s", err) logger.Errorf("Failed to get file from media: %s", err)
ctx.Reply(update, ext.ReplyTextString("获取文件失败: "+err.Error()), nil) ctx.Reply(update, ext.ReplyTextString("获取文件失败: "+err.Error()), nil)
@@ -91,7 +91,7 @@ func GetFilesFromUpdateLinkMessageWithReplyEdit(ctx *ext.Context, update *ext.Up
logger.Debugf("message %d has no media", msg.GetID()) logger.Debugf("message %d has no media", msg.GetID())
return return
} }
file, err := tfile.FromMediaMessage(media, msg, tfile.WithNameIfEmpty(tgutil.GenFileNameFromMessage(*msg))) file, err := tfile.FromMediaMessage(media, ctx.Raw, msg, tfile.WithNameIfEmpty(tgutil.GenFileNameFromMessage(*msg)))
if err != nil { if err != nil {
logger.Errorf("failed to create file from media: %s", err) logger.Errorf("failed to create file from media: %s", err)
return return
+2 -2
View File
@@ -51,7 +51,7 @@ func CreateAndAddTGFileTaskWithEdit(ctx *ext.Context, userID int64, stor storage
storagePath := stor.JoinStoragePath(path.Join(dirPath, file.Name())) storagePath := stor.JoinStoragePath(path.Join(dirPath, file.Name()))
injectCtx := tgutil.ExtWithContext(ctx.Context, ctx) injectCtx := tgutil.ExtWithContext(ctx.Context, ctx)
taskid := xid.New().String() taskid := xid.New().String()
task, err := tftask.NewTGFileTask(taskid, injectCtx, file, ctx.Raw, stor, storagePath, task, err := tftask.NewTGFileTask(taskid, injectCtx, file, stor, storagePath,
tftask.NewProgressTrack( tftask.NewProgressTrack(
trackMsgID, trackMsgID,
userID)) userID))
@@ -134,7 +134,7 @@ func CreateAndAddBatchTGFileTaskWithEdit(ctx *ext.Context, userID int64, stor st
} }
injectCtx := tgutil.ExtWithContext(ctx.Context, ctx) injectCtx := tgutil.ExtWithContext(ctx.Context, ctx)
taskid := xid.New().String() taskid := xid.New().String()
task := batchtftask.NewBatchTGFileTask(taskid, injectCtx, elems, ctx.Raw, batchtftask.NewProgressTracker(trackMsgID, userID), true) task := batchtftask.NewBatchTGFileTask(taskid, injectCtx, elems, batchtftask.NewProgressTracker(trackMsgID, userID), true)
if err := core.AddTask(injectCtx, task); err != nil { if err := core.AddTask(injectCtx, task); err != nil {
logger.Errorf("Failed to add batch task: %s", err) logger.Errorf("Failed to add batch task: %s", err)
ctx.EditMessage(userID, &tg.MessagesEditMessageRequest{ ctx.EditMessage(userID, &tg.MessagesEditMessageRequest{
+3 -3
View File
@@ -9,11 +9,11 @@ import (
"github.com/charmbracelet/log" "github.com/charmbracelet/log"
"github.com/duke-git/lancet/v2/retry" "github.com/duke-git/lancet/v2/retry"
"github.com/krau/SaveAny-Bot/common/tdler"
"github.com/krau/SaveAny-Bot/common/utils/fsutil" "github.com/krau/SaveAny-Bot/common/utils/fsutil"
"github.com/krau/SaveAny-Bot/common/utils/ioutil" "github.com/krau/SaveAny-Bot/common/utils/ioutil"
"github.com/krau/SaveAny-Bot/config" "github.com/krau/SaveAny-Bot/config"
"github.com/krau/SaveAny-Bot/pkg/enums/ctxkey" "github.com/krau/SaveAny-Bot/pkg/enums/ctxkey"
"github.com/krau/SaveAny-Bot/pkg/tfile"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
) )
@@ -62,7 +62,7 @@ func (t *Task) processElement(ctx context.Context, elem TaskElement) error {
}) })
errg.Go(func() error { errg.Go(func() error {
logger.Info("Starting file download in stream mode") logger.Info("Starting file download in stream mode")
_, err := tdler.NewDownloader(t.client, elem.File).Stream(uploadCtx, wr) _, err := tfile.NewDownloader(elem.File).Stream(uploadCtx, wr)
if closeErr := pw.CloseWithError(err); closeErr != nil { if closeErr := pw.CloseWithError(err); closeErr != nil {
logger.Errorf("Failed to close pipe writer: %v", closeErr) logger.Errorf("Failed to close pipe writer: %v", closeErr)
} }
@@ -88,7 +88,7 @@ func (t *Task) processElement(ctx context.Context, elem TaskElement) error {
t.downloaded.Add(int64(n)) t.downloaded.Add(int64(n))
t.Progress.OnProgress(ctx, t) t.Progress.OnProgress(ctx, t)
}) })
_, err = tdler.NewDownloader(t.client, elem.File).Parallel(ctx, wrAt) _, err = tfile.NewDownloader(elem.File).Parallel(ctx, wrAt)
if err != nil { if err != nil {
return fmt.Errorf("failed to download file: %w", err) return fmt.Errorf("failed to download file: %w", err)
} }
-4
View File
@@ -6,7 +6,6 @@ import (
"path/filepath" "path/filepath"
"sync/atomic" "sync/atomic"
"github.com/krau/SaveAny-Bot/common/tdler"
"github.com/krau/SaveAny-Bot/config" "github.com/krau/SaveAny-Bot/config"
"github.com/krau/SaveAny-Bot/pkg/enums/tasktype" "github.com/krau/SaveAny-Bot/pkg/enums/tasktype"
"github.com/krau/SaveAny-Bot/pkg/tfile" "github.com/krau/SaveAny-Bot/pkg/tfile"
@@ -30,7 +29,6 @@ type Task struct {
Progress ProgressTracker Progress ProgressTracker
IgnoreErrors bool // if true, errors during processing will be ignored IgnoreErrors bool // if true, errors during processing will be ignored
downloaded atomic.Int64 downloaded atomic.Int64
client tdler.Client
totalSize int64 totalSize int64
processing map[string]TaskElementInfo processing map[string]TaskElementInfo
failed map[string]error // errors for each element failed map[string]error // errors for each element
@@ -73,14 +71,12 @@ func NewBatchTGFileTask(
id string, id string,
ctx context.Context, ctx context.Context,
files []TaskElement, files []TaskElement,
client tdler.Client,
progress ProgressTracker, progress ProgressTracker,
ignoreErrors bool, ignoreErrors bool,
) *Task { ) *Task {
task := &Task{ task := &Task{
ID: id, ID: id,
Ctx: ctx, Ctx: ctx,
client: client,
Elems: files, Elems: files,
Progress: progress, Progress: progress,
downloaded: atomic.Int64{}, downloaded: atomic.Int64{},
+2 -2
View File
@@ -8,10 +8,10 @@ import (
"time" "time"
"github.com/charmbracelet/log" "github.com/charmbracelet/log"
"github.com/krau/SaveAny-Bot/common/tdler"
"github.com/krau/SaveAny-Bot/common/utils/fsutil" "github.com/krau/SaveAny-Bot/common/utils/fsutil"
"github.com/krau/SaveAny-Bot/config" "github.com/krau/SaveAny-Bot/config"
"github.com/krau/SaveAny-Bot/pkg/enums/ctxkey" "github.com/krau/SaveAny-Bot/pkg/enums/ctxkey"
"github.com/krau/SaveAny-Bot/pkg/tfile"
) )
func (t *Task) Execute(ctx context.Context) error { func (t *Task) Execute(ctx context.Context) error {
@@ -36,7 +36,7 @@ func (t *Task) Execute(ctx context.Context) error {
defer func() { defer func() {
t.Progress.OnDone(ctx, t, err) t.Progress.OnDone(ctx, t, err)
}() }()
_, err = tdler.NewDownloader(t.client, t.File).Parallel(ctx, wrAt) _, err = tfile.NewDownloader(t.File).Parallel(ctx, wrAt)
if err != nil { if err != nil {
return fmt.Errorf("failed to download file: %w", err) return fmt.Errorf("failed to download file: %w", err)
} }
+2 -2
View File
@@ -6,7 +6,7 @@ import (
"io" "io"
"github.com/charmbracelet/log" "github.com/charmbracelet/log"
"github.com/krau/SaveAny-Bot/common/tdler" "github.com/krau/SaveAny-Bot/pkg/tfile"
"golang.org/x/sync/errgroup" "golang.org/x/sync/errgroup"
) )
@@ -22,7 +22,7 @@ func executeStream(ctx context.Context, task *Task) error {
wr := newWriter(ctx, pw, task.Progress, task) wr := newWriter(ctx, pw, task.Progress, task)
errg.Go(func() error { errg.Go(func() error {
logger.Info("Starting file download in stream mode") logger.Info("Starting file download in stream mode")
_, err := tdler.NewDownloader(task.client, task.File).Stream(uploadCtx, wr) _, err := tfile.NewDownloader(task.File).Stream(uploadCtx, wr)
if closeErr := pw.CloseWithError(err); closeErr != nil { if closeErr := pw.CloseWithError(err); closeErr != nil {
logger.Errorf("Failed to close pipe writer: %v", closeErr) logger.Errorf("Failed to close pipe writer: %v", closeErr)
} }
-5
View File
@@ -5,7 +5,6 @@ import (
"fmt" "fmt"
"path/filepath" "path/filepath"
"github.com/krau/SaveAny-Bot/common/tdler"
"github.com/krau/SaveAny-Bot/config" "github.com/krau/SaveAny-Bot/config"
"github.com/krau/SaveAny-Bot/pkg/enums/tasktype" "github.com/krau/SaveAny-Bot/pkg/enums/tasktype"
"github.com/krau/SaveAny-Bot/pkg/tfile" "github.com/krau/SaveAny-Bot/pkg/tfile"
@@ -19,7 +18,6 @@ type Task struct {
Storage storage.Storage Storage storage.Storage
Path string Path string
Progress ProgressTracker Progress ProgressTracker
client tdler.Client
stream bool // true if the file should be downloaded in stream mode stream bool // true if the file should be downloaded in stream mode
localPath string localPath string
} }
@@ -32,7 +30,6 @@ func NewTGFileTask(
id string, id string,
ctx context.Context, ctx context.Context,
file tfile.TGFile, file tfile.TGFile,
client tdler.Client,
stor storage.Storage, stor storage.Storage,
path string, path string,
progress ProgressTracker, progress ProgressTracker,
@@ -46,7 +43,6 @@ func NewTGFileTask(
tftask := &Task{ tftask := &Task{
ID: id, ID: id,
Ctx: ctx, Ctx: ctx,
client: client,
File: file, File: file,
Storage: stor, Storage: stor,
Path: path, Path: path,
@@ -58,7 +54,6 @@ func NewTGFileTask(
tfileTask := &Task{ tfileTask := &Task{
ID: id, ID: id,
Ctx: ctx, Ctx: ctx,
client: client,
File: file, File: file,
Storage: stor, Storage: stor,
Path: path, Path: path,
+4 -5
View File
@@ -1,18 +1,17 @@
package tdler package tfile
import ( import (
"github.com/gotd/td/telegram/downloader" "github.com/gotd/td/telegram/downloader"
"github.com/krau/SaveAny-Bot/common/utils/dlutil" "github.com/krau/SaveAny-Bot/common/utils/dlutil"
"github.com/krau/SaveAny-Bot/config" "github.com/krau/SaveAny-Bot/config"
"github.com/krau/SaveAny-Bot/pkg/consts/tglimit" "github.com/krau/SaveAny-Bot/pkg/consts/tglimit"
"github.com/krau/SaveAny-Bot/pkg/tfile"
) )
type Client interface { type DlerClient interface {
downloader.Client downloader.Client
} }
func NewDownloader(client Client, file tfile.TGFile) *downloader.Builder { func NewDownloader(file TGFile) *downloader.Builder {
return downloader.NewDownloader().WithPartSize(tglimit.MaxPartSize). return downloader.NewDownloader().WithPartSize(tglimit.MaxPartSize).
Download(client, file.Location()).WithThreads(dlutil.BestThreads(file.Size(), config.Cfg.Threads)) Download(file.Dler(), file.Location()).WithThreads(dlutil.BestThreads(file.Size(), config.Cfg.Threads))
} }
+30 -20
View File
@@ -10,6 +10,7 @@ import (
type TGFile interface { type TGFile interface {
Location() tg.InputFileLocationClass Location() tg.InputFileLocationClass
Dler() DlerClient // witch client to use for downloading
Size() int64 Size() int64
Name() string Name() string
} }
@@ -24,6 +25,7 @@ type tgFile struct {
size int64 size int64
name string name string
message *tg.Message message *tg.Message
dler DlerClient
} }
func (f *tgFile) Location() tg.InputFileLocationClass { func (f *tgFile) Location() tg.InputFileLocationClass {
@@ -42,11 +44,20 @@ func (f *tgFile) Message() *tg.Message {
return f.message return f.message
} }
func NewTGFile(location tg.InputFileLocationClass, size int64, name string, func (f *tgFile) Dler() DlerClient {
return f.dler
}
func NewTGFile(
location tg.InputFileLocationClass,
dler DlerClient,
size int64,
name string,
opts ...TGFileOptions, opts ...TGFileOptions,
) TGFile { ) TGFile {
f := &tgFile{ f := &tgFile{
location: location, location: location,
dler: dler,
size: size, size: size,
name: name, name: name,
} }
@@ -56,7 +67,7 @@ func NewTGFile(location tg.InputFileLocationClass, size int64, name string,
return f return f
} }
func FromMedia(media tg.MessageMediaClass, opts ...TGFileOptions) (TGFile, error) { func FromMedia(media tg.MessageMediaClass, client DlerClient, opts ...TGFileOptions) (TGFile, error) {
switch m := media.(type) { switch m := media.(type) {
case *tg.MessageMediaDocument: case *tg.MessageMediaDocument:
document, ok := m.Document.AsNotEmpty() document, ok := m.Document.AsNotEmpty()
@@ -70,14 +81,13 @@ func FromMedia(media tg.MessageMediaClass, opts ...TGFileOptions) (TGFile, error
break break
} }
} }
file := &tgFile{ file := NewTGFile(
location: document.AsInputDocumentFileLocation(), document.AsInputDocumentFileLocation(),
size: document.Size, client,
name: fileName, document.Size,
} fileName,
for _, opt := range opts { opts...,
opt(file) )
}
return file, nil return file, nil
case *tg.MessageMediaPhoto: case *tg.MessageMediaPhoto:
photo, ok := m.Photo.AsNotEmpty() photo, ok := m.Photo.AsNotEmpty()
@@ -99,26 +109,26 @@ func FromMedia(media tg.MessageMediaClass, opts ...TGFileOptions) (TGFile, error
location.FileReference = photo.GetFileReference() location.FileReference = photo.GetFileReference()
location.ThumbSize = size.GetType() location.ThumbSize = size.GetType()
fileName := fmt.Sprintf("photo_%s_%d.jpg", time.Now().Format("2006-01-02_15-04-05"), photo.GetID()) fileName := fmt.Sprintf("photo_%s_%d.jpg", time.Now().Format("2006-01-02_15-04-05"), photo.GetID())
file := &tgFile{ file := NewTGFile(
location: location, location,
size: 0, client,
name: fileName, 0, // Photo size is not available in InputPhotoFileLocation
} fileName,
for _, opt := range opts { opts...,
opt(file) )
}
return file, nil return file, nil
} }
return nil, fmt.Errorf("unsupported media type: %T", media) return nil, fmt.Errorf("unsupported media type: %T", media)
} }
func FromMediaMessage(media tg.MessageMediaClass, msg *tg.Message, opts ...TGFileOptions) (TGFileMessage, error) { func FromMediaMessage(media tg.MessageMediaClass, client DlerClient, msg *tg.Message, opts ...TGFileOptions) (TGFileMessage, error) {
file, err := FromMedia(media, opts...) file, err := FromMedia(media, client, opts...)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return &tgFile{ return &tgFile{
location: file.Location(), location: file.Location(),
dler: file.Dler(),
size: file.Size(), size: file.Size(),
name: file.Name(), name: file.Name(),
message: msg, message: msg,