aboutsummaryrefslogtreecommitdiffstats
path: root/drive
diff options
context:
space:
mode:
authorPetter Rasmussen2016-02-06 13:08:33 +0100
committerPetter Rasmussen2016-02-06 13:08:33 +0100
commitce32c7536cf40afae065b09018c05da6ba221c55 (patch)
treee08b55be1974ba9c05df59d2a8cb10fb64d42dfe /drive
parent77d8e36d48c73fe1d0dc86b6736c32e5fd1f744a (diff)
downloadgdrive-ce32c7536cf40afae065b09018c05da6ba221c55.tar.bz2
Give FileComparer as argument
Diffstat (limited to 'drive')
-rw-r--r--drive/sync.go114
-rw-r--r--drive/sync_download.go3
-rw-r--r--drive/sync_upload.go11
-rw-r--r--drive/util.go14
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))
}