You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
115 lines
2.0 KiB
115 lines
2.0 KiB
package downloader
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"net/http"
|
|
"os"
|
|
"path/filepath"
|
|
"recook/internal/static_path"
|
|
"recook/tools"
|
|
"sync"
|
|
)
|
|
|
|
type worker interface {
|
|
GetLocalName(raw string) string
|
|
Download(file, raw string) error
|
|
}
|
|
|
|
type downloader struct {
|
|
worker worker
|
|
workerNum int
|
|
Queue chan string
|
|
group sync.WaitGroup
|
|
file string
|
|
}
|
|
|
|
func (o *downloader) AddTask(raw string) {
|
|
o.Queue <- raw
|
|
}
|
|
|
|
func (o *downloader) Start() {
|
|
go func() {
|
|
for i := 0; i < o.workerNum; i++ {
|
|
o.group.Add(1)
|
|
go o.forever()
|
|
}
|
|
}()
|
|
}
|
|
|
|
func (o *downloader) GetPath(raw string) string {
|
|
return filepath.Join(o.file, o.worker.GetLocalName(raw))
|
|
}
|
|
|
|
func (o *downloader) forever() {
|
|
for {
|
|
if value, ok := <-o.Queue; ok {
|
|
file := filepath.Join(static_path.Dir.Root, o.file)
|
|
o.worker.Download(file, value)
|
|
} else {
|
|
break
|
|
}
|
|
}
|
|
o.group.Done()
|
|
}
|
|
|
|
func (o *downloader) Wait() {
|
|
close(o.Queue)
|
|
o.group.Wait()
|
|
}
|
|
|
|
func New(worker worker, file string, workerNum int) *downloader {
|
|
if worker == nil {
|
|
worker = defaultWorker{}
|
|
}
|
|
return &downloader{
|
|
worker: worker,
|
|
workerNum: workerNum,
|
|
Queue: make(chan string, 10000),
|
|
file: file,
|
|
}
|
|
}
|
|
|
|
type defaultWorker struct {
|
|
}
|
|
|
|
func Exists(path string) bool {
|
|
_, err := os.Stat(path) //os.Stat获取文件信息
|
|
if err != nil {
|
|
if os.IsExist(err) {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func (o defaultWorker) GetLocalName(raw string) string {
|
|
res := filepath.Ext(raw)
|
|
return filepath.Join(tools.MD5(raw) + res)
|
|
}
|
|
|
|
func (o defaultWorker) Download(file, raw string) error {
|
|
allPath := filepath.Join(file, o.GetLocalName(raw))
|
|
if !Exists(file) {
|
|
_ = os.MkdirAll(file, os.ModePerm)
|
|
}
|
|
if Exists(allPath) {
|
|
return nil
|
|
}
|
|
resp, err := http.Get(raw)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer resp.Body.Close()
|
|
data, err := io.ReadAll(resp.Body)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
err = os.WriteFile(allPath, data, os.ModePerm)
|
|
if err != nil {
|
|
fmt.Println(err.Error(), "===")
|
|
}
|
|
return err
|
|
}
|