func upload_file(localFilePath string, dirId int64, fileInfo *alicloud.FileInfo) { var offset int64 for _, chunk := range fileInfo.Chunks { r, e := c.UploadChunk(chunk.Id, localFilePath, offset, chunk.Size) if !r || e != nil { log.Error(e) panic(e) } offset += chunk.Size } fileInfo, err := c.CommitUpload(fileInfo.Id, fileInfo.UpdateVersion) panic_if_error(err) //update local file's last modified time, so we don't need sync next time newModTime := fileInfo.ModifyTime / 1000 fs.ChangeModTime(localFilePath, newModTime) log.Info("Upload:", fileInfo.GetFullName(), fileInfo.Version, newModTime, fileInfo.ModifyTime/1000) }
func (c *Client) DownloadFile(fileInfo *FileInfo, file_path string) error { if file_path == "" { panic("file path can't be empty, it should be .../" + fileInfo.GetFullName()) } perm := fileInfo.FileAttribute if perm < 1 { perm = 0755 } f, err := os.OpenFile(file_path+".tmp", os.O_RDWR|os.O_CREATE|os.O_TRUNC, os.FileMode(perm)) if err != nil { panic(err) } defer f.Close() w := bufio.NewWriterSize(f, 1024*8) for _, chunk := range fileInfo.Chunks { bytes, err2 := c.DownloadChunk(chunk.Id) if err2 != nil { return err } s := string(bytes[1 : len(bytes)-1]) bytes, _ = base64.StdEncoding.DecodeString(s) n, err := w.Write(bytes) if err != nil || n != len(bytes) { panic(err) } err = w.Flush() } if fileInfo.ModifyTime > 0 { os.Rename(file_path+".tmp", file_path) fs.ChangeModTime(file_path, fileInfo.ModifyTime/1000) } return err }
func SyncFolder(dirId int64, dirPath string, dirModTime int64) { ok, err := fs.Exists(dirPath) panic_if_error(err) if !ok { os.Mkdir(dirPath, 0755) } fileList, err := c.FolderList(dirId) panic_if_error(err) cloudFiles := make(map[string]*alicloud.File) cloudFolders := make(map[string]*alicloud.Folder) for _, remoteFile := range fileList.Files { localFilePath := filepath.Join(dirPath, remoteFile.GetFullName()) modTime2 := remoteFile.ModifyTime / 1000 fileInfo1, err := os.Stat(localFilePath) var modTime1 int64 if err != nil && !os.IsNotExist(err) { panic_if_error(err) } if fileInfo1 != nil { modTime1 = fileInfo1.ModTime().Unix() } log.Debugf("+ %s local timestamp: %d remote: %d", localFilePath, modTime1, modTime2) if modTime2 > modTime1 { fileInfo2, err := c.FileInfo(remoteFile.Id, "", 3) panic_if_error(err) log.Info("Download:", localFilePath) fileInfo2.ModifyTime = remoteFile.ModifyTime c.DownloadFile(fileInfo2, localFilePath) } else if modTime1 > modTime2 { fileInfo2, err := c.FileInfo(remoteFile.Id, "", 3) panic_if_error(err) fileInfo2, err = c.ModifyFile(remoteFile.Id, dirId, localFilePath, fileInfo2) panic_if_error(err) upload_file(localFilePath, dirId, fileInfo2) } cloudFiles[localFilePath] = remoteFile } for _, d := range fileList.Dirs { p := filepath.Join(dirPath, d.Name) SyncFolder(d.Id, p, d.ModifyTime) cloudFolders[p] = d } //upload new files from local to cloud myFiles, myFolders, _ := fs.ListFiles(dirPath, accept_filter) for _, f := range myFiles { localFilePath := filepath.Join(dirPath, f.Name()) if cloudFiles[localFilePath] == nil { //upload to cloud fileInfo, err := c.CreateFile(dirId, localFilePath) panic_if_error(err) upload_file(localFilePath, dirId, fileInfo) } } for _, f := range myFolders { localFilePath := filepath.Join(dirPath, f.Name()) if cloudFolders[localFilePath] == nil { //upload to cloud newFolder, err := c.MakeFolder(dirId, f.Name()) panic_if_error(err) upload_folder(localFilePath, newFolder.Id) } } if dirModTime > 0 { err := fs.ChangeModTime(dirPath, dirModTime/1000) panic_if_error(err) } }