aboutsummaryrefslogtreecommitdiffstats
path: root/drive/sync.go
diff options
context:
space:
mode:
Diffstat (limited to 'drive/sync.go')
-rw-r--r--drive/sync.go114
1 files changed, 73 insertions, 41 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)