|
|
|
package downloader
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"net/http"
|
|
|
|
"os"
|
|
|
|
"path/filepath"
|
|
|
|
"recook/tools"
|
|
|
|
"sync"
|
|
|
|
)
|
|
|
|
|
|
|
|
type worker2 interface {
|
|
|
|
GetLocalName(raw Item) string
|
|
|
|
Download(file string, raw Item) error
|
|
|
|
}
|
|
|
|
|
|
|
|
type Item struct {
|
|
|
|
Name string
|
|
|
|
Raw string
|
|
|
|
}
|
|
|
|
|
|
|
|
type downloader2 struct {
|
|
|
|
worker worker2
|
|
|
|
workerNum int
|
|
|
|
Queue chan Item
|
|
|
|
group sync.WaitGroup
|
|
|
|
file string
|
|
|
|
}
|
|
|
|
|
|
|
|
func (o *downloader2) AddTask(raw Item) {
|
|
|
|
o.Queue <- raw
|
|
|
|
}
|
|
|
|
|
|
|
|
func (o *downloader2) Start() {
|
|
|
|
go func() {
|
|
|
|
for i := 0; i < o.workerNum; i++ {
|
|
|
|
o.group.Add(1)
|
|
|
|
go o.forever()
|
|
|
|
}
|
|
|
|
}()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (o *downloader2) GetPath(raw Item) string {
|
|
|
|
return filepath.Join(o.file, o.worker.GetLocalName(raw))
|
|
|
|
}
|
|
|
|
|
|
|
|
func (o *downloader2) forever() {
|
|
|
|
for {
|
|
|
|
if value, ok := <-o.Queue; ok {
|
|
|
|
file := filepath.Join(o.file)
|
|
|
|
o.worker.Download(file, value)
|
|
|
|
} else {
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
o.group.Done()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (o *downloader2) Wait() {
|
|
|
|
close(o.Queue)
|
|
|
|
o.group.Wait()
|
|
|
|
}
|
|
|
|
|
|
|
|
func New2(worker worker2, file string, workerNum int) *downloader2 {
|
|
|
|
if worker == nil {
|
|
|
|
worker = defaultWorker2{}
|
|
|
|
}
|
|
|
|
return &downloader2{
|
|
|
|
worker: worker,
|
|
|
|
workerNum: workerNum,
|
|
|
|
Queue: make(chan Item, 10000),
|
|
|
|
file: file,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
type defaultWorker2 struct {
|
|
|
|
}
|
|
|
|
|
|
|
|
func (o defaultWorker2) GetLocalName(raw Item) string {
|
|
|
|
if raw.Name != "" {
|
|
|
|
return raw.Name
|
|
|
|
} else {
|
|
|
|
res := filepath.Ext(raw.Raw)
|
|
|
|
return filepath.Join(tools.MD5(raw.Raw) + res)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (o defaultWorker2) Download(file string, raw Item) 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.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
|
|
|
|
}
|