예제 #1
0
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)
}
예제 #2
0
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
}
예제 #3
0
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)
	}
}