mirror of
https://github.com/krau/SaveAny-Bot.git
synced 2026-08-25 02:00:59 +08:00
feat: add direct links download functionality
- Implemented a new task type for handling direct links downloads. - Added command handler for downloading multiple links via /dl command. - Introduced progress tracking for direct link downloads. - Enhanced filename parsing to support various encoding scenarios. - Updated enums to include direct links as a task type. - Refactored existing task structures to accommodate new functionality. - Improved error handling and logging throughout the download process.
This commit is contained in:
121
core/tasks/directlinks/task.go
Normal file
121
core/tasks/directlinks/task.go
Normal file
@@ -0,0 +1,121 @@
|
||||
package directlinks
|
||||
|
||||
import (
|
||||
"context"
|
||||
"net/http"
|
||||
"sync"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/krau/SaveAny-Bot/config"
|
||||
"github.com/krau/SaveAny-Bot/pkg/enums/tasktype"
|
||||
"github.com/krau/SaveAny-Bot/storage"
|
||||
)
|
||||
|
||||
type File struct {
|
||||
Name string
|
||||
URL string
|
||||
Size int64
|
||||
}
|
||||
|
||||
func (f *File) FileName() string {
|
||||
return f.Name
|
||||
}
|
||||
|
||||
func (f *File) FileSize() int64 {
|
||||
return f.Size
|
||||
}
|
||||
|
||||
type Task struct {
|
||||
ID string
|
||||
ctx context.Context
|
||||
files []*File
|
||||
Storage storage.Storage
|
||||
StorPath string
|
||||
Progress ProgressTracker
|
||||
|
||||
client *http.Client // [TODO] parallel download
|
||||
stream bool
|
||||
totalBytes int64 // total bytes to download
|
||||
downloadedBytes atomic.Int64 // downloaded bytes
|
||||
totalFiles int64 // total files to download
|
||||
downloaded atomic.Int64 // downloaded files count
|
||||
processing map[string]*File // {"url": File}
|
||||
processingMu sync.RWMutex
|
||||
failed map[string]error // [TODO] errors for each file
|
||||
}
|
||||
|
||||
// DownloadedBytes implements TaskInfo.
|
||||
func (t *Task) DownloadedBytes() int64 {
|
||||
return t.downloadedBytes.Load()
|
||||
}
|
||||
|
||||
// Processing implements TaskInfo.
|
||||
func (t *Task) Processing() []FileInfo {
|
||||
t.processingMu.RLock()
|
||||
defer t.processingMu.RUnlock()
|
||||
infos := make([]FileInfo, 0, len(t.processing))
|
||||
for _, f := range t.processing {
|
||||
infos = append(infos, f)
|
||||
}
|
||||
return infos
|
||||
}
|
||||
|
||||
// StorageName implements TaskInfo.
|
||||
func (t *Task) StorageName() string {
|
||||
return t.Storage.Name()
|
||||
}
|
||||
|
||||
// StoragePath implements TaskInfo.
|
||||
func (t *Task) StoragePath() string {
|
||||
return t.StorPath
|
||||
}
|
||||
|
||||
// TotalBytes implements TaskInfo.
|
||||
func (t *Task) TotalBytes() int64 {
|
||||
return t.totalBytes
|
||||
}
|
||||
|
||||
// TotalFiles implements TaskInfo.
|
||||
func (t *Task) TotalFiles() int {
|
||||
return int(t.totalFiles)
|
||||
}
|
||||
|
||||
func (t *Task) Type() tasktype.TaskType {
|
||||
return tasktype.TaskTypeDirectlinks
|
||||
}
|
||||
|
||||
func (t *Task) TaskID() string {
|
||||
return t.ID
|
||||
}
|
||||
|
||||
func NewTask(
|
||||
id string,
|
||||
ctx context.Context,
|
||||
links []string,
|
||||
stor storage.Storage,
|
||||
storPath string,
|
||||
progressTracker ProgressTracker,
|
||||
) *Task {
|
||||
_, ok := stor.(storage.StorageCannotStream)
|
||||
stream := config.C().Stream && !ok
|
||||
files := make([]*File, 0, len(links))
|
||||
for _, link := range links {
|
||||
files = append(files, &File{
|
||||
URL: link,
|
||||
})
|
||||
}
|
||||
return &Task{
|
||||
ID: id,
|
||||
ctx: ctx,
|
||||
files: files,
|
||||
Storage: stor,
|
||||
StorPath: storPath,
|
||||
Progress: progressTracker,
|
||||
stream: stream,
|
||||
client: http.DefaultClient,
|
||||
processing: make(map[string]*File),
|
||||
processingMu: sync.RWMutex{},
|
||||
failed: make(map[string]error),
|
||||
totalFiles: int64(len(files)),
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user