mirror of
https://github.com/GopeedLab/gopeed.git
synced 2026-11-04 07:45:30 +00:00
151 lines
3.9 KiB
Go
151 lines
3.9 KiB
Go
package download
|
|
|
|
import (
|
|
"github.com/GopeedLab/gopeed/internal/controller"
|
|
"github.com/GopeedLab/gopeed/internal/fetcher"
|
|
"github.com/GopeedLab/gopeed/internal/protocol/bt"
|
|
"github.com/GopeedLab/gopeed/internal/protocol/http"
|
|
"github.com/GopeedLab/gopeed/pkg/base"
|
|
"github.com/GopeedLab/gopeed/pkg/util"
|
|
|
|
gonanoid "github.com/matoous/go-nanoid/v2"
|
|
"net/url"
|
|
"sync"
|
|
"time"
|
|
)
|
|
|
|
type ResolveResult struct {
|
|
ID string `json:"id"`
|
|
Res *base.Resource `json:"res"`
|
|
}
|
|
|
|
type Task struct {
|
|
ID string `json:"id"`
|
|
Meta *fetcher.FetcherMeta `json:"meta"`
|
|
Status base.Status `json:"status"`
|
|
Protocol string `json:"protocol"`
|
|
Progress *Progress `json:"progress"`
|
|
CreatedAt time.Time `json:"createdAt"`
|
|
UpdatedAt time.Time `json:"updatedAt"`
|
|
|
|
fetcherBuilder fetcher.FetcherBuilder
|
|
fetcher fetcher.Fetcher
|
|
timer *util.Timer
|
|
statusLock *sync.Mutex
|
|
lock *sync.Mutex
|
|
speedArr []int64
|
|
}
|
|
|
|
func NewTask() *Task {
|
|
id, err := gonanoid.New()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return &Task{
|
|
ID: id,
|
|
Status: base.DownloadStatusReady,
|
|
CreatedAt: time.Now(),
|
|
UpdatedAt: time.Now(),
|
|
}
|
|
}
|
|
|
|
func (t *Task) updateStatus(status base.Status) {
|
|
t.UpdatedAt = time.Now()
|
|
t.Status = status
|
|
}
|
|
|
|
func (t *Task) clone() *Task {
|
|
return &Task{
|
|
ID: t.ID,
|
|
Meta: t.Meta,
|
|
Status: t.Status,
|
|
Progress: t.Progress,
|
|
CreatedAt: t.CreatedAt,
|
|
UpdatedAt: t.UpdatedAt,
|
|
}
|
|
}
|
|
|
|
func (t *Task) calcSpeed(downloaded int64, usedTime float64) int64 {
|
|
t.speedArr = append(t.speedArr, downloaded)
|
|
if len(t.speedArr) > 6 {
|
|
t.speedArr = t.speedArr[1:]
|
|
}
|
|
var total int64
|
|
for _, v := range t.speedArr {
|
|
total += v
|
|
}
|
|
return int64(float64(total) / float64(len(t.speedArr)) / usedTime)
|
|
}
|
|
|
|
type DownloaderConfig struct {
|
|
Controller *controller.Controller
|
|
FetchBuilders []fetcher.FetcherBuilder
|
|
|
|
RefreshInterval int `json:"refreshInterval"` // RefreshInterval time duration to refresh task progress(ms)
|
|
Storage Storage
|
|
StorageDir string
|
|
|
|
ProductionMode bool
|
|
|
|
*DownloaderStoreConfig
|
|
}
|
|
|
|
func (cfg *DownloaderConfig) Init() *DownloaderConfig {
|
|
if cfg.Controller == nil {
|
|
cfg.Controller = controller.NewController()
|
|
}
|
|
if len(cfg.FetchBuilders) == 0 {
|
|
cfg.FetchBuilders = []fetcher.FetcherBuilder{
|
|
new(http.FetcherBuilder),
|
|
new(bt.FetcherBuilder),
|
|
}
|
|
}
|
|
if cfg.RefreshInterval == 0 {
|
|
cfg.RefreshInterval = 350
|
|
}
|
|
if cfg.Storage == nil {
|
|
cfg.Storage = NewMemStorage()
|
|
}
|
|
return cfg
|
|
}
|
|
|
|
// DownloaderStoreConfig is the config that can restore the downloader.
|
|
type DownloaderStoreConfig struct {
|
|
FirstLoad bool `json:"-"` // FirstLoad is the flag that the config is first time init and not from store
|
|
|
|
DownloadDir string `json:"downloadDir"` // DownloadDir is the default directory to save the downloaded files
|
|
MaxRunning int `json:"maxRunning"` // MaxRunning is the max running download count
|
|
ProtocolConfig map[string]any `json:"protocolConfig"` // ProtocolConfig is special config for each protocol
|
|
Extra map[string]any `json:"extra"`
|
|
Proxy *DownloaderProxyConfig `json:"proxy"`
|
|
}
|
|
|
|
func (cfg *DownloaderStoreConfig) Init() *DownloaderStoreConfig {
|
|
if cfg.MaxRunning == 0 {
|
|
cfg.MaxRunning = 5
|
|
}
|
|
if cfg.Proxy == nil {
|
|
cfg.Proxy = &DownloaderProxyConfig{}
|
|
}
|
|
return cfg
|
|
}
|
|
|
|
func (cfg *DownloaderStoreConfig) ProxyUrl() *url.URL {
|
|
if cfg.Proxy == nil {
|
|
return nil
|
|
}
|
|
if cfg.Proxy.Enable == false || cfg.Proxy.Scheme == "" || cfg.Proxy.Host == "" {
|
|
return nil
|
|
}
|
|
return util.BuildProxyUrl(cfg.Proxy.Scheme, cfg.Proxy.Host, cfg.Proxy.Usr, cfg.Proxy.Pwd)
|
|
}
|
|
|
|
type DownloaderProxyConfig struct {
|
|
Enable bool `json:"enable"`
|
|
// Scheme is the proxy scheme, e.g. http, https, socks5, but there is a special scheme "system" that means use system proxy
|
|
Scheme string `json:"scheme"`
|
|
Host string `json:"host"`
|
|
Usr string `json:"usr"`
|
|
Pwd string `json:"pwd"`
|
|
}
|