aboutsummaryrefslogtreecommitdiffstats
path: root/drive/sync.go
diff options
context:
space:
mode:
authorPetter Rasmussen2016-02-12 23:19:03 +0100
committerPetter Rasmussen2016-02-13 01:10:17 +0100
commit5eae4f159d340d257e41e75604a0fc831cb76381 (patch)
tree9e2b0f0e2de1a9dad0124bcd06c74b57eea05c1a /drive/sync.go
parentad4309f1028d165b8905a6a22be89191f787fc39 (diff)
downloadgdrive-5eae4f159d340d257e41e75604a0fc831cb76381.tar.bz2
Add conflict handling and flags for downloads
Diffstat (limited to 'drive/sync.go')
-rw-r--r--drive/sync.go88
1 files changed, 88 insertions, 0 deletions
diff --git a/drive/sync.go b/drive/sync.go
index 86ddb3b..f39c1c6 100644
--- a/drive/sync.go
+++ b/drive/sync.go
@@ -4,8 +4,10 @@ import (
"time"
"fmt"
"os"
+ "io"
"strings"
"path/filepath"
+ "text/tabwriter"
"github.com/soniakeys/graph"
"github.com/sabhiram/go-git-ignore"
"google.golang.org/api/drive/v3"
@@ -14,6 +16,31 @@ import (
const DefaultIgnoreFile = ".gdriveignore"
+type ModTime int
+
+const (
+ LocalLastModified ModTime = iota
+ RemoteLastModified
+ EqualModifiedTime
+)
+
+type LargestSize int
+
+const (
+ LocalLargestSize LargestSize = iota
+ RemoteLargestSize
+ EqualSize
+)
+
+type ConflictResolution int
+
+const (
+ NoResolution ConflictResolution = iota
+ KeepLocal
+ KeepRemote
+ KeepLargest
+)
+
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})
@@ -281,6 +308,36 @@ func (self RemoteFile) Modified() time.Time {
return t
}
+func (self *changedFile) compareModTime() ModTime {
+ localTime := self.local.Modified()
+ remoteTime := self.remote.Modified()
+
+ if localTime.After(remoteTime) {
+ return LocalLastModified
+ }
+
+ if remoteTime.After(localTime) {
+ return RemoteLastModified
+ }
+
+ return EqualModifiedTime
+}
+
+func (self *changedFile) compareSize() LargestSize {
+ localSize := self.local.Size()
+ remoteSize := self.remote.Size()
+
+ if localSize > remoteSize {
+ return LocalLargestSize
+ }
+
+ if remoteSize > localSize {
+ return RemoteLargestSize
+ }
+
+ return EqualSize
+}
+
func (self *syncFiles) filterMissingRemoteDirs() []*LocalFile {
var files []*LocalFile
@@ -441,6 +498,18 @@ func (self *syncFiles) findLocalByPath(relPath string) (*LocalFile, bool) {
return nil, false
}
+func findLocalConflicts(files []*changedFile) []*changedFile {
+ var conflicts []*changedFile
+
+ for _, cf := range files {
+ if cf.compareModTime() == LocalLastModified {
+ conflicts = append(conflicts, cf)
+ }
+ }
+
+ return conflicts
+}
+
type byLocalPathLength []*LocalFile
func (self byLocalPathLength) Len() int {
@@ -501,3 +570,22 @@ func prepareIgnorer(path string) (ignoreFunc, error) {
return ignorer.MatchesPath, nil
}
+
+func formatConflicts(conflicts []*changedFile, out io.Writer) {
+ w := new(tabwriter.Writer)
+ w.Init(out, 0, 0, 3, ' ', 0)
+
+ fmt.Fprintln(w, "Path\tSize Local\tSize Remote\tModified Local\tModified Remote")
+
+ for _, cf := range conflicts {
+ fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\n",
+ truncateString(cf.local.relPath, 60),
+ formatSize(cf.local.Size(), false),
+ formatSize(cf.remote.Size(), false),
+ cf.local.Modified().Local().Format("Jan _2 2006 15:04:05.000"),
+ cf.remote.Modified().Local().Format("Jan _2 2006 15:04:05.000"),
+ )
+ }
+
+ w.Flush()
+}