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

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
}