Skip to content

Commit

Permalink
支持下载完成后自动校验文件
Browse files Browse the repository at this point in the history
  • Loading branch information
iikira committed Aug 31, 2018
1 parent 8340bb7 commit df82928
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 31 deletions.
89 changes: 68 additions & 21 deletions internal/pcscommand/download.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package pcscommand

import (
"encoding/hex"
"errors"
"fmt"
"github.com/iikira/BaiduPCS-Go/baidupcs"
"github.com/iikira/BaiduPCS-Go/internal/pcsconfig"
"github.com/iikira/BaiduPCS-Go/pcstable"
"github.com/iikira/BaiduPCS-Go/pcsutil/checksum"
"github.com/iikira/BaiduPCS-Go/pcsutil/converter"
"github.com/iikira/BaiduPCS-Go/pcsutil/waitgroup"
"github.com/iikira/BaiduPCS-Go/requester"
Expand All @@ -29,28 +31,38 @@ const (
StrDownloadInitError = "初始化下载发生错误"
)

// dtask 下载任务
type dtask struct {
ListTask
path string // 下载的路径
savePath string // 保存的路径
downloadInfo *baidupcs.FileDirectory // 文件或目录详情
}
var (
// ErrNotSupportChecksum 文件不支持校验
ErrNotSupportChecksum = errors.New("该文件不支持校验")
// ErrChecksumFailed 文件校验失败
ErrChecksumFailed = errors.New("该文件校验失败, 文件md5值与服务器记录的不匹配")
)

//DownloadOptions 下载可选参数
type DownloadOptions struct {
IsTest bool
IsPrintStatus bool
IsExecutedPermission bool
IsOverwrite bool
IsShareDownload bool
IsLocateDownload bool
IsStreaming bool
SaveTo string
Parallel int
Load int
Out io.Writer
}
type (
// dtask 下载任务
dtask struct {
ListTask
path string // 下载的路径
savePath string // 保存的路径
downloadInfo *baidupcs.FileDirectory // 文件或目录详情
}

//DownloadOptions 下载可选参数
DownloadOptions struct {
IsTest bool
IsPrintStatus bool
IsExecutedPermission bool
IsOverwrite bool
IsShareDownload bool
IsLocateDownload bool
IsStreaming bool
SaveTo string
Parallel int
Load int
NoCheck bool
Out io.Writer
}
)

func downloadPrintFormat(load int) string {
if load <= 1 {
Expand Down Expand Up @@ -184,6 +196,27 @@ func download(id int, downloadURL, savePath string, loadBalansers []string, clie
return nil
}

// checkFileValid 检测文件有效性
func checkFileValid(filePath string, fileInfo *baidupcs.FileDirectory) error {
if len(fileInfo.BlockList) != 1 {
return ErrNotSupportChecksum
}

f := checksum.NewLocalFileInfo(filePath, int(256*converter.KB))
err := f.OpenPath()
if err != nil {
return err
}

defer f.Close()

f.Md5Sum()
if strings.Compare(hex.EncodeToString(f.MD5), fileInfo.MD5) != 0 {
return ErrChecksumFailed
}
return nil
}

// RunDownload 执行下载网盘内文件
func RunDownload(paths []string, options *DownloadOptions) {
if options == nil {
Expand Down Expand Up @@ -258,6 +291,8 @@ func RunDownload(paths []string, options *DownloadOptions) {

// 不重试的情况
switch {
case err == ErrNotSupportChecksum:
fallthrough
case strings.Compare(errManifest, "下载文件错误") == 0 && strings.Contains(err.Error(), StrDownloadInitError):
fmt.Fprintf(options.Out, "[%d] %s, %s\n", task.ID, errManifest, err)
return
Expand Down Expand Up @@ -420,6 +455,18 @@ func RunDownload(paths []string, options *DownloadOptions) {
return
}

if !cfg.IsTest && !options.NoCheck {
if task.downloadInfo.Size >= 128*converter.MB {
fmt.Fprintf(options.Out, "[%d] 开始检验文件有效性, 稍后...\n", task.ID)
}
err = checkFileValid(task.savePath, task.downloadInfo)
if err != nil {
handleTaskErr(task, "检验文件有效性出错", err)
} else {
fmt.Fprintf(options.Out, "[%d] 检验文件有效性成功\n", task.ID)
}
}

atomic.AddInt64(&totalSize, task.downloadInfo.Size)
}()
}
Expand Down
4 changes: 1 addition & 3 deletions internal/pcscommand/share.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"github.com/iikira/BaiduPCS-Go/baidupcs"
"github.com/iikira/BaiduPCS-Go/internal/pcsconfig"
"github.com/iikira/BaiduPCS-Go/pcstable"
"github.com/iikira/BaiduPCS-Go/requester"
"github.com/iikira/baidu-tools/pan"
"net/url"
"os"
Expand Down Expand Up @@ -125,8 +124,7 @@ func getShareDLink(pcspath string) (dlink string) {

func getLink(shareID int64, shareLink, passwd, rootSharePath, filePath string) (dlink string) {
sInfo := pan.NewSharedInfo(shareLink)
sInfo.Client = requester.NewHTTPClient()
sInfo.Client.SetHTTPSecure(pcsconfig.Config.EnableHTTPS())
sInfo.Client = pcsconfig.Config.HTTPClient()

if passwd != "" {
err := sInfo.Auth(passwd)
Expand Down
6 changes: 3 additions & 3 deletions internal/pcscommand/upload.go
Original file line number Diff line number Diff line change
Expand Up @@ -237,15 +237,15 @@ func RunUpload(localPaths []string, savePath string, opt *UploadOptions) {
func() {
fmt.Printf("[%d] 准备上传: %s\n", task.ID, task.uploadInfo.Path)

if !task.uploadInfo.OpenPath() {
fmt.Printf("[%d] 文件不可读, 跳过...\n", task.ID)
err = task.uploadInfo.OpenPath()
if err != nil {
fmt.Printf("[%d] 文件不可读, 错误信息: %s, 跳过...\n", task.ID, err)
return
}
defer task.uploadInfo.Close() // 关闭文件

// 步骤控制
var (
err error
panDir, panFile = path.Split(task.savePath)
)

Expand Down
6 changes: 6 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -954,6 +954,7 @@ func main() {
通过 BaiduPCS-Go config set -savedir <savedir>, 自定义保存的目录.
已支持目录下载.
已支持多个文件或目录下载.
已支持下载完成后自动校验文件, 但并不是所有的文件都支持校验!
自动跳过下载重名的文件!
示例:
Expand Down Expand Up @@ -1002,6 +1003,7 @@ func main() {
IsStreaming: c.Bool("stream"),
SaveTo: saveTo,
Parallel: c.Int("p"),
NoCheck: c.Bool("nocheck"),
Load: c.Int("l"),
}

Expand Down Expand Up @@ -1058,6 +1060,10 @@ func main() {
Name: "l",
Usage: "指定同时进行下载文件的数量",
},
cli.BoolFlag{
Name: "nocheck",
Usage: "下载文件完成后不检测文件的有效性",
},
cli.BoolFlag{
Name: "bg",
Usage: "加入后台下载",
Expand Down
12 changes: 8 additions & 4 deletions pcsutil/checksum/checksum.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,21 +53,25 @@ func NewLocalFileInfo(localPath string, bufSize int) *LocalFile {
}

// OpenPath 检查文件状态并获取文件的大小 (Length)
func (lf *LocalFile) OpenPath() bool {
func (lf *LocalFile) OpenPath() error {
if lf.File != nil {
lf.File.Close()
}

var err error
lf.File, err = os.Open(lf.Path)
if err != nil {
return false
return err
}

info, err := lf.File.Stat()
if err != nil {
return err
}

info, _ := lf.File.Stat()
lf.Length = info.Size()
lf.ModTime = info.ModTime().Unix()
return true
return nil
}

// Close 关闭文件
Expand Down

0 comments on commit df82928

Please sign in to comment.