diff options
| author | Petter Rasmussen | 2016-02-06 13:08:33 +0100 |
|---|---|---|
| committer | Petter Rasmussen | 2016-02-06 13:08:33 +0100 |
| commit | ce32c7536cf40afae065b09018c05da6ba221c55 (patch) | |
| tree | e08b55be1974ba9c05df59d2a8cb10fb64d42dfe /drive | |
| parent | 77d8e36d48c73fe1d0dc86b6736c32e5fd1f744a (diff) | |
| download | gdrive-ce32c7536cf40afae065b09018c05da6ba221c55.tar.bz2 | |
Give FileComparer as argument
Diffstat (limited to 'drive')
| -rw-r--r-- | drive/sync.go | 114 | ||||
| -rw-r--r-- | drive/sync_download.go | 3 | ||||
| -rw-r--r-- | drive/sync_upload.go | 11 | ||||
| -rw-r--r-- | drive/util.go | 14 |
4 files changed, 81 insertions, 61 deletions
diff --git a/drive/sync.go b/drive/sync.go index c8396c1..cfd5acb 100644 --- a/drive/sync.go +++ b/drive/sync.go @@ -1,6 +1,7 @@ package drive import ( + "time" "fmt" "os" "path/filepath" @@ -13,18 +14,18 @@ import ( const DefaultIgnoreFile = ".gdriveignore" -func (self *Drive) prepareSyncFiles(localPath string, root *drive.File) (*syncFiles, error) { - localCh := make(chan struct{files []*localFile; err error}) - remoteCh := make(chan struct{files []*remoteFile; err error}) +func (self *Drive) prepareSyncFiles(localPath string, root *drive.File, cmp FileComparer) (*syncFiles, error) { + localCh := make(chan struct{files []*LocalFile; err error}) + remoteCh := make(chan struct{files []*RemoteFile; err error}) go func() { files, err := prepareLocalFiles(localPath) - localCh <- struct{files []*localFile; err error}{files, err} + localCh <- struct{files []*LocalFile; err error}{files, err} }() go func() { files, err := self.prepareRemoteFiles(root) - remoteCh <- struct{files []*remoteFile; err error}{files, err} + remoteCh <- struct{files []*RemoteFile; err error}{files, err} }() local := <-localCh @@ -38,14 +39,15 @@ func (self *Drive) prepareSyncFiles(localPath string, root *drive.File) (*syncFi } return &syncFiles{ - root: &remoteFile{file: root}, + root: &RemoteFile{file: root}, local: local.files, remote: remote.files, + compare: cmp, }, nil } -func prepareLocalFiles(root string) ([]*localFile, error) { - var files []*localFile +func prepareLocalFiles(root string) ([]*LocalFile, error) { + var files []*LocalFile // Get absolute root path absRootPath, err := filepath.Abs(root) @@ -85,7 +87,7 @@ func prepareLocalFiles(root string) ([]*localFile, error) { return nil } - files = append(files, &localFile{ + files = append(files, &LocalFile{ absPath: absPath, relPath: relPath, info: info, @@ -112,7 +114,7 @@ func (self *Drive) listAllFiles(q string, fields []googleapi.Field) ([]*drive.Fi return files, err } -func (self *Drive) prepareRemoteFiles(rootDir *drive.File) ([]*remoteFile, error) { +func (self *Drive) prepareRemoteFiles(rootDir *drive.File) ([]*RemoteFile, error) { // Find all files which has rootDir as root query := fmt.Sprintf("appProperties has {key='syncRootId' and value='%s'}", rootDir.Id) fields := []googleapi.Field{"nextPageToken", "files(id,name,parents,md5Checksum,mimeType)"} @@ -130,13 +132,13 @@ func (self *Drive) prepareRemoteFiles(rootDir *drive.File) ([]*remoteFile, error return nil, err } - var remoteFiles []*remoteFile + var remoteFiles []*RemoteFile for _, f := range files { relPath, ok := relPaths[f.Id] if !ok { return nil, fmt.Errorf("File %s does not have a valid parent", f.Id) } - remoteFiles = append(remoteFiles, &remoteFile{ + remoteFiles = append(remoteFiles, &RemoteFile{ relPath: relPath, file: f, }) @@ -230,30 +232,60 @@ func checkFiles(files []*drive.File) error { return nil } -type localFile struct { +type LocalFile struct { absPath string relPath string info os.FileInfo } -type remoteFile struct { +type RemoteFile struct { relPath string file *drive.File } type changedFile struct { - local *localFile - remote *remoteFile + local *LocalFile + remote *RemoteFile } type syncFiles struct { - root *remoteFile - local []*localFile - remote []*remoteFile + root *RemoteFile + local []*LocalFile + remote []*RemoteFile + compare FileComparer } -func (self *syncFiles) filterMissingRemoteDirs() []*localFile { - var files []*localFile +type FileComparer interface { + Changed(*LocalFile, *RemoteFile) bool +} + +func (self LocalFile) AbsPath() string { + return self.absPath +} + +func (self LocalFile) Size() int64 { + return self.info.Size() +} + +func (self LocalFile) Modified() time.Time { + return self.info.ModTime() +} + +func (self RemoteFile) Md5() string { + return self.file.Md5Checksum +} + +func (self RemoteFile) Size() int64 { + return self.file.Size +} + +func (self RemoteFile) Modified() time.Time { + t, _ := time.Parse(time.RFC3339, self.file.ModifiedTime) + return t +} + +func (self *syncFiles) filterMissingRemoteDirs() []*LocalFile { + var files []*LocalFile for _, lf := range self.local { if lf.info.IsDir() && !self.existsRemote(lf) { @@ -264,8 +296,8 @@ func (self *syncFiles) filterMissingRemoteDirs() []*localFile { return files } -func (self *syncFiles) filterMissingLocalDirs() []*remoteFile { - var files []*remoteFile +func (self *syncFiles) filterMissingLocalDirs() []*RemoteFile { + var files []*RemoteFile for _, rf := range self.remote { if isDir(rf.file) && !self.existsLocal(rf) { @@ -276,8 +308,8 @@ func (self *syncFiles) filterMissingLocalDirs() []*remoteFile { return files } -func (self *syncFiles) filterMissingRemoteFiles() []*localFile { - var files []*localFile +func (self *syncFiles) filterMissingRemoteFiles() []*LocalFile { + var files []*LocalFile for _, lf := range self.local { if !lf.info.IsDir() && !self.existsRemote(lf) { @@ -288,8 +320,8 @@ func (self *syncFiles) filterMissingRemoteFiles() []*localFile { return files } -func (self *syncFiles) filterMissingLocalFiles() []*remoteFile { - var files []*remoteFile +func (self *syncFiles) filterMissingLocalFiles() []*RemoteFile { + var files []*RemoteFile for _, rf := range self.remote { if !isDir(rf.file) && !self.existsLocal(rf) { @@ -315,8 +347,8 @@ func (self *syncFiles) filterChangedLocalFiles() []*changedFile { continue } - // Add files where remote md5 sum does not match local - if rf.file.Md5Checksum != md5sum(lf.absPath) { + // Check if file has changed + if self.compare.Changed(lf, rf) { files = append(files, &changedFile{ local: lf, remote: rf, @@ -342,8 +374,8 @@ func (self *syncFiles) filterChangedRemoteFiles() []*changedFile { continue } - // Add files where remote md5 sum does not match local - if rf.file.Md5Checksum != md5sum(lf.absPath) { + // Check if file has changed + if self.compare.Changed(lf, rf) { files = append(files, &changedFile{ local: lf, remote: rf, @@ -354,8 +386,8 @@ func (self *syncFiles) filterChangedRemoteFiles() []*changedFile { return files } -func (self *syncFiles) filterExtraneousRemoteFiles() []*remoteFile { - var files []*remoteFile +func (self *syncFiles) filterExtraneousRemoteFiles() []*RemoteFile { + var files []*RemoteFile for _, rf := range self.remote { if !self.existsLocal(rf) { @@ -366,8 +398,8 @@ func (self *syncFiles) filterExtraneousRemoteFiles() []*remoteFile { return files } -func (self *syncFiles) filterExtraneousLocalFiles() []*localFile { - var files []*localFile +func (self *syncFiles) filterExtraneousLocalFiles() []*LocalFile { + var files []*LocalFile for _, lf := range self.local { if !self.existsRemote(lf) { @@ -378,17 +410,17 @@ func (self *syncFiles) filterExtraneousLocalFiles() []*localFile { return files } -func (self *syncFiles) existsRemote(lf *localFile) bool { +func (self *syncFiles) existsRemote(lf *LocalFile) bool { _, found := self.findRemoteByPath(lf.relPath) return found } -func (self *syncFiles) existsLocal(rf *remoteFile) bool { +func (self *syncFiles) existsLocal(rf *RemoteFile) bool { _, found := self.findLocalByPath(rf.relPath) return found } -func (self *syncFiles) findRemoteByPath(relPath string) (*remoteFile, bool) { +func (self *syncFiles) findRemoteByPath(relPath string) (*RemoteFile, bool) { if relPath == "." { return self.root, true } @@ -402,7 +434,7 @@ func (self *syncFiles) findRemoteByPath(relPath string) (*remoteFile, bool) { return nil, false } -func (self *syncFiles) findLocalByPath(relPath string) (*localFile, bool) { +func (self *syncFiles) findLocalByPath(relPath string) (*LocalFile, bool) { for _, lf := range self.local { if relPath == lf.relPath { return lf, true @@ -412,7 +444,7 @@ func (self *syncFiles) findLocalByPath(relPath string) (*localFile, bool) { return nil, false } -type byLocalPathLength []*localFile +type byLocalPathLength []*LocalFile func (self byLocalPathLength) Len() int { return len(self) @@ -426,7 +458,7 @@ func (self byLocalPathLength) Less(i, j int) bool { return pathLength(self[i].relPath) < pathLength(self[j].relPath) } -type byRemotePathLength []*remoteFile +type byRemotePathLength []*RemoteFile func (self byRemotePathLength) Len() int { return len(self) diff --git a/drive/sync_download.go b/drive/sync_download.go index 7da16bd..f18cb18 100644 --- a/drive/sync_download.go +++ b/drive/sync_download.go @@ -18,6 +18,7 @@ type DownloadSyncArgs struct { Path string DryRun bool DeleteExtraneous bool + Comparer FileComparer } func (self *Drive) DownloadSync(args DownloadSyncArgs) error { @@ -31,7 +32,7 @@ func (self *Drive) DownloadSync(args DownloadSyncArgs) error { } fmt.Fprintln(args.Out, "Collecting local and remote file information...") - files, err := self.prepareSyncFiles(args.Path, rootDir) + files, err := self.prepareSyncFiles(args.Path, rootDir, args.Comparer) if err != nil { return err } diff --git a/drive/sync_upload.go b/drive/sync_upload.go index 151a9f8..445ed42 100644 --- a/drive/sync_upload.go +++ b/drive/sync_upload.go @@ -19,6 +19,7 @@ type UploadSyncArgs struct { DryRun bool DeleteExtraneous bool ChunkSize int64 + Comparer FileComparer } func (self *Drive) UploadSync(args UploadSyncArgs) error { @@ -36,7 +37,7 @@ func (self *Drive) UploadSync(args UploadSyncArgs) error { } fmt.Fprintln(args.Out, "Collecting local and remote file information...") - files, err := self.prepareSyncFiles(args.Path, rootDir) + files, err := self.prepareSyncFiles(args.Path, rootDir, args.Comparer) if err != nil { return err } @@ -143,7 +144,7 @@ func (self *Drive) createMissingRemoteDirs(files *syncFiles, args UploadSyncArgs fmt.Fprintf(args.Out, "[%04d/%04d] Creating directory: %s\n", i + 1, missingCount, filepath.Join(files.root.file.Name, lf.relPath)) if args.DryRun { - files.remote = append(files.remote, &remoteFile{ + files.remote = append(files.remote, &RemoteFile{ relPath: lf.relPath, file: dstFile, }) @@ -153,7 +154,7 @@ func (self *Drive) createMissingRemoteDirs(files *syncFiles, args UploadSyncArgs return nil, fmt.Errorf("Failed to create directory: %s", err) } - files.remote = append(files.remote, &remoteFile{ + files.remote = append(files.remote, &RemoteFile{ relPath: lf.relPath, file: f, }) @@ -244,7 +245,7 @@ func (self *Drive) deleteExtraneousRemoteFiles(files *syncFiles, args UploadSync return nil } -func (self *Drive) uploadMissingFile(parentId string, lf *localFile, args UploadSyncArgs) error { +func (self *Drive) uploadMissingFile(parentId string, lf *LocalFile, args UploadSyncArgs) error { srcFile, err := os.Open(lf.absPath) if err != nil { return fmt.Errorf("Failed to open file: %s", err) @@ -300,7 +301,7 @@ func (self *Drive) updateChangedFile(cf *changedFile, args UploadSyncArgs) error return nil } -func (self *Drive) deleteRemoteFile(rf *remoteFile, args UploadSyncArgs) error { +func (self *Drive) deleteRemoteFile(rf *RemoteFile, args UploadSyncArgs) error { err := self.service.Files.Delete(rf.file.Id).Do() if err != nil { return fmt.Errorf("Failed to delete file: %s", err) diff --git a/drive/util.go b/drive/util.go index 1c43009..2116f9b 100644 --- a/drive/util.go +++ b/drive/util.go @@ -9,8 +9,6 @@ import ( "unicode/utf8" "math" "time" - "crypto/md5" - "io" ) type kv struct { @@ -137,18 +135,6 @@ func intMax() int64 { return 1 << (strconv.IntSize - 1) - 1 } -func md5sum(path string) string { - h := md5.New() - f, err := os.Open(path) - if err != nil { - return "" - } - defer f.Close() - - io.Copy(h, f) - return fmt.Sprintf("%x", h.Sum(nil)) -} - func pathLength(path string) int { return strings.Count(path, string(os.PathSeparator)) } |
