@@ -2,21 +2,36 @@ package task
22
33import (
44 "encoding/json"
5+ "fmt"
56 "log"
67 "os"
78 "strconv"
9+ "sync"
810
911 "../onedrive"
1012)
1113
14+ const uploadThreadNum int = 4
15+
16+ type chunkFile struct {
17+ ID int `json:"id"`
18+ User int `json:"user"`
19+ CTX string `json:"ctx"`
20+ Time string `json:"time"`
21+ ObjName string `json:"obj_name"`
22+ ChunkID int `json:"chunk_id"`
23+ Sum int `json:"sum"`
24+ }
25+
1226type oneDriveUploadAttr struct {
13- Fname string `json:"fname"`
14- Path string `json:"path"`
15- Objname string `json:"objname"`
16- SavePath string `json:"savePath"`
17- Fsize uint64 `json:"fsize"`
18- PicInfo string `json:"picInfo"`
19- PolicyID int `json:"policyId"`
27+ Fname string `json:"fname"`
28+ Path string `json:"path"`
29+ Objname string `json:"objname"`
30+ SavePath string `json:"savePath"`
31+ Fsize uint64 `json:"fsize"`
32+ PicInfo string `json:"picInfo"`
33+ PolicyID int `json:"policyId"`
34+ Chunks []chunkFile `json:"chunks"`
2035}
2136
2237//OneDriveUpload OneDrive上传类型Task
@@ -44,6 +59,14 @@ type OnedriveState struct {
4459 } `json:"token"`
4560}
4661
62+ //Chunk 文件分片
63+ type Chunk struct {
64+ Type int //分片方式,0-已切割为文件片,1-无需切割
65+ From int
66+ To int
67+ ChunkPath string
68+ }
69+
4770//Excute 执行Onedrive上传Task
4871func (task * OneDriveUpload ) Excute () {
4972 authState := OnedriveState {}
@@ -55,13 +78,103 @@ func (task *OneDriveUpload) Excute() {
5578 Tried : 0 ,
5679 }
5780 Client .Init ()
58- var filePath string
59- if task .Type == "UploadRegularRemoteDownloadFileToOnedrive" {
6081
82+ if task .Type == "uploadSingleToOnedrive" {
83+ task .uploadRegularFile (& Client )
84+ } else if task .Type == "uploadChunksToOnedrive" {
85+ task .uploadChunks (& Client )
86+ }
87+
88+ }
89+
90+ func (task * OneDriveUpload ) uploadChunks (Client * onedrive.Client ) {
91+ //获取上传URL
92+ url , err := Client .CreateUploadSession ("/me/drive/root:/" + task .Attr .SavePath + "/" + task .Attr .Objname + ":/createUploadSession" )
93+ if err != "" {
94+ task .Log ("[Error] Failed to create upload session," + err )
95+ task .Error ()
96+ return
97+ }
98+ fmt .Println (url )
99+
100+ chunkList , chunkErr := task .buildChunks ()
101+ if chunkErr != "" {
102+ task .Log ("[Error] Failed to upload chunks," + chunkErr )
103+ task .Error ()
104+ return
105+ }
106+
107+ var wg sync.WaitGroup
108+ ch := make (chan Chunk )
109+ isFailed := false
110+
111+ for index := 0 ; index < uploadThreadNum ; index ++ {
112+ wg .Add (1 )
113+ go task .uploadSingleChunk (& wg , ch , & isFailed )
114+ }
115+
116+ for _ , v := range chunkList {
117+ if isFailed {
118+ close (ch )
119+ break
120+ }
121+ ch <- v
122+ }
123+ close (ch )
124+ wg .Wait ()
125+
126+ }
127+
128+ func (task * OneDriveUpload ) uploadSingleChunk (wg * sync.WaitGroup , ch chan Chunk , isFailed * bool ) {
129+ for {
130+ chunk , opened := <- ch
131+ if ! opened {
132+ fmt .Println ("quit" )
133+ wg .Done ()
134+ return
135+ }
136+ fmt .Println (chunk .From )
137+ }
138+ }
139+
140+ func (task * OneDriveUpload ) buildChunks () ([]Chunk , string ) {
141+
142+ var chunkType int
143+ if task .Type == "uploadChunksToOnedrive" {
144+ chunkType = 0
61145 } else {
62- filePath = task . BasePath + "public/uploads/" + task . Attr . SavePath + "/" + task . Attr . Objname
146+ chunkType = 1
63147 }
64148
149+ var chunkList []Chunk
150+ var offset int
151+
152+ for _ , v := range task .Attr .Chunks {
153+
154+ chunkPath := task .BasePath + "public/uploads/chunks/" + v .ObjName + ".chunk"
155+
156+ fileInfo , err := os .Stat (chunkPath )
157+ if os .IsNotExist (err ) {
158+ return chunkList , "Chunk file " + chunkPath + " not exist"
159+ }
160+ chunkSize := int (fileInfo .Size ())
161+
162+ chunkList = append (chunkList , Chunk {
163+ Type : chunkType ,
164+ From : offset ,
165+ To : offset + chunkSize - 1 ,
166+ ChunkPath : chunkPath ,
167+ })
168+ offset += chunkSize
169+ }
170+
171+ return chunkList , ""
172+
173+ }
174+
175+ func (task * OneDriveUpload ) uploadRegularFile (Client * onedrive.Client ) {
176+ var filePath string
177+ filePath = task .BasePath + "public/uploads/" + task .Attr .SavePath + "/" + task .Attr .Objname
65178 r , err := os .Open (filePath )
66179 defer r .Close ()
67180 if err != nil {
@@ -74,14 +187,14 @@ func (task *OneDriveUpload) Excute() {
74187 if errorMsg != "" {
75188 task .Log ("[Error] Upload Failed," + errorMsg )
76189 task .Error ()
190+ return
77191 }
78192
79193 addRes := task .Info .apiInfo .SetSuccess (task .Info .sqlInfo .ID )
80194
81195 if addRes != "" {
82196 task .Log ("[Error] " + addRes )
83197 }
84-
85198}
86199
87200//Init 执行Onedrive上传Task
0 commit comments