This commit is contained in:
iikira
2018-11-04 09:56:32 +08:00
parent c217a8f1a6
commit 33857438af
2 changed files with 133 additions and 1 deletions

4
build_linux.sh Executable file
View File

@@ -0,0 +1,4 @@
#!/bin/sh
GOOS=linux GOARCH=amd64 go build -ldflags "-s -w"
upx downloader

130
main.go
View File

@@ -4,17 +4,27 @@ import (
"bufio"
"flag"
"fmt"
"github.com/iikira/BaiduPCS-Go/pcsutil/converter"
"github.com/iikira/BaiduPCS-Go/pcsverbose"
"github.com/iikira/BaiduPCS-Go/requester"
"github.com/iikira/BaiduPCS-Go/requester/downloader"
"io"
"os"
"path/filepath"
"runtime"
"time"
)
const (
//StrDownloadInitError 初始化下载发生错误
StrDownloadInitError = "初始化下载发生错误"
)
var (
parallel int
cacheSize int
test bool
isPrintStatus bool
downloadSuffix = ".downloader_downloading"
)
@@ -23,11 +33,129 @@ func init() {
flag.IntVar(&cacheSize, "c", 30000, "download cache size")
flag.BoolVar(&pcsverbose.IsVerbose, "verbose", false, "verbose")
flag.BoolVar(&test, "test", false, "test download")
flag.BoolVar(&isPrintStatus, "status", false, "print status")
flag.StringVar(&requester.UserAgent, "ua", "", "User-Agent")
flag.Parse()
}
func download(id int, downloadURL, savePath string, client *requester.HTTPClient, newCfg downloader.Config) error {
var (
file *os.File
writerAt io.WriterAt
err error
exitChan chan struct{}
)
if !newCfg.IsTest {
newCfg.InstanceStatePath = savePath + downloadSuffix
// 创建下载的目录
dir := filepath.Dir(savePath)
fileInfo, err := os.Stat(dir)
if err != nil {
err = os.MkdirAll(dir, 0777)
if err != nil {
return err
}
} else if !fileInfo.IsDir() {
return fmt.Errorf("%s, path %s: not a directory", StrDownloadInitError, dir)
}
file, err = os.OpenFile(savePath, os.O_CREATE|os.O_WRONLY, 0666)
if file != nil {
defer file.Close()
}
if err != nil {
return fmt.Errorf("%s, %s", StrDownloadInitError, err)
}
// 空指针和空接口不等价
if file != nil {
writerAt = file
}
}
download := downloader.NewDownloader(downloadURL, writerAt, &newCfg)
download.SetClient(client)
download.SetFirstCheckMethod("GET")
exitChan = make(chan struct{})
download.OnExecute(func() {
if isPrintStatus {
go func() {
for {
time.Sleep(1 * time.Second)
select {
case <-exitChan:
return
default:
download.PrintAllWorkers()
}
}
}()
}
if newCfg.IsTest {
fmt.Printf("[%d] 测试下载开始\n\n", id)
}
var (
ds = download.GetDownloadStatusChan()
format = "\r[%d] ↓ %s/%s %s/s in %s, left %s ............"
downloaded, totalSize, speeds int64
leftStr string
)
for {
select {
case <-exitChan:
return
case v, ok := <-ds:
if !ok { // channel 已经关闭
return
}
downloaded, totalSize, speeds = v.Downloaded(), v.TotalSize(), v.SpeedsPerSecond()
if speeds <= 0 {
leftStr = "-"
} else {
leftStr = (time.Duration((totalSize-downloaded)/(speeds)) * time.Second).String()
}
fmt.Printf(format, id,
converter.ConvertFileSize(v.Downloaded(), 2),
converter.ConvertFileSize(v.TotalSize(), 2),
converter.ConvertFileSize(v.SpeedsPerSecond(), 2),
v.TimeElapsed()/1e7*1e7, leftStr,
)
}
}
})
err = download.Execute()
close(exitChan)
fmt.Printf("\n")
if err != nil {
// 下载失败, 删去空文件
if info, infoErr := file.Stat(); infoErr == nil {
if info.Size() == 0 {
pcsverbose.Verbosef("[%d] remove empty file: %s\n", id, savePath)
os.Remove(savePath)
}
}
return err
}
if !newCfg.IsTest {
fmt.Printf("[%d] 下载完成, 保存位置: %s\n", id, savePath)
} else {
fmt.Printf("[%d] 测试下载结束\n", id)
}
return nil
}
func main() {
if flag.NArg() == 0 {
flag.Usage()
@@ -50,7 +178,7 @@ func main() {
return
}
}
downloader.DoDownload(flag.Arg(k), savePath, &downloader.Config{
download(k, flag.Arg(k), savePath, nil, downloader.Config{
MaxParallel: parallel,
CacheSize: cacheSize,
InstanceStatePath: savePath + downloadSuffix,