diff options
| author | Petter Rasmussen | 2016-01-31 15:37:58 +0100 |
|---|---|---|
| committer | Petter Rasmussen | 2016-01-31 15:37:58 +0100 |
| commit | 90a9a8bc58568509b5314328b721b1e7a9400a51 (patch) | |
| tree | ca0e2dbe0a4a70f6efbf7acd55f9d2aaf77a5235 | |
| parent | 893e48c864ac601fbde20f1b07331852e26358a7 (diff) | |
| download | gdrive-90a9a8bc58568509b5314328b721b1e7a9400a51.tar.bz2 | |
Require root dir id for syncing
| -rw-r--r-- | drive/upload_sync.go | 85 | ||||
| -rw-r--r-- | gdrive.go | 7 | ||||
| -rw-r--r-- | handlers_drive.go | 2 |
3 files changed, 43 insertions, 51 deletions
diff --git a/drive/upload_sync.go b/drive/upload_sync.go index 763bfcf..3e157ed 100644 --- a/drive/upload_sync.go +++ b/drive/upload_sync.go @@ -16,7 +16,7 @@ type UploadSyncArgs struct { Out io.Writer Progress io.Writer Path string - Parent string + RootId string DeleteExtraneous bool ChunkSize int64 } @@ -30,15 +30,11 @@ func (self *Drive) UploadSync(args UploadSyncArgs) error { started := time.Now() // Create root directory if it does not exist - rootDir, createdRoot, err := self.getOrCreateSyncRootDir(args) + rootDir, err := self.prepareSyncRoot(args) if err != nil { return err } - if createdRoot { - fmt.Fprintln(args.Out, "No existing files found on drive, starting from scratch") - } - fmt.Fprintln(args.Out, "Collecting local and remote file information...") files, err := self.prepareSyncFiles(args.Path, rootDir) if err != nil { @@ -108,51 +104,46 @@ func (self *Drive) prepareSyncFiles(localPath string, root *drive.File) (*syncFi }, nil } -func (self *Drive) getOrCreateSyncRootDir(args UploadSyncArgs) (*drive.File, bool, error) { - // Root dir name - name := filepath.Base(args.Path) +func (self *Drive) prepareSyncRoot(args UploadSyncArgs) (*drive.File, error) { + fields := []googleapi.Field{"id", "name", "mimeType", "appProperties"} + f, err := self.service.Files.Get(args.RootId).Fields(fields...).Do() + if err != nil { + return nil, fmt.Errorf("Failed to find root dir: %s", err) + } - // Build root dir query - query := fmt.Sprintf("name = '%s' and appProperties has {key='isSyncRoot' and value='true'}", name) - if args.Parent != "" { - query += fmt.Sprintf(" and '%s' in parents", args.Parent) + // Ensure file is a directory + if !isDir(f) { + return nil, fmt.Errorf("Provided root id is not a directory") } - // Find root dir - fileList, err := self.service.Files.List().Q(query).Fields("files(id,name,mimeType)").Do() - if err != nil { - return nil, false, fmt.Errorf("Failed listing files: %s", err) + // Return directory if syncRoot property is already set + if _, ok := f.AppProperties["isSyncRoot"]; ok { + return f, nil } - // More than one root dir found - if len(fileList.Files) > 1 { - return nil, false, fmt.Errorf("More than one root directories found, aborting...") + // This is the first time this directory have been used for sync + // Check if the directory is empty + isEmpty, err := self.dirIsEmpty(f.Id) + if err != nil { + return nil, fmt.Errorf("Failed to check if root dir is empty: %s", err) } - // Root dir found, return - if len(fileList.Files) == 1 { - return fileList.Files[0], false, nil + // Ensure that the directory is empty + if !isEmpty { + return nil, fmt.Errorf("Root directoy is not empty, the initial sync requires an empty directory") } - // Root dir not found, create new + // Update directory with syncRoot property dstFile := &drive.File{ - Name: name, - MimeType: DirectoryMimeType, AppProperties: map[string]string{"isSyncRoot": "true"}, } - // Add parent if provided - if args.Parent != "" { - dstFile.Parents = []string{args.Parent} - } - - // Create directory - f, err := self.service.Files.Create(dstFile).Do() + f, err = self.service.Files.Update(f.Id, dstFile).Fields(fields...).Do() if err != nil { - return nil, false, fmt.Errorf("Failed to create directory: %s", err) + return nil, fmt.Errorf("Failed to update root directory: %s", err) } - return f, true, nil + return f, nil } func (self *Drive) createMissingRemoteDirs(files *syncFiles, args UploadSyncArgs) (*syncFiles, error) { @@ -177,7 +168,7 @@ func (self *Drive) createMissingRemoteDirs(files *syncFiles, args UploadSyncArgs Name: lf.info.Name(), MimeType: DirectoryMimeType, Parents: []string{parent.file.Id}, - AppProperties: map[string]string{"syncRootId": files.root.file.Id}, + AppProperties: map[string]string{"syncRootId": args.RootId}, } fmt.Fprintf(args.Out, "[%04d/%04d] Creating directory: %s\n", i + 1, missingCount, filepath.Join(files.root.file.Name, lf.relPath)) @@ -211,12 +202,8 @@ func (self *Drive) uploadMissingFiles(files *syncFiles, args UploadSyncArgs) err return fmt.Errorf("Could not find remote directory with path '%s', aborting...", parentPath) } - newArgs := args - newArgs.Path = lf.absPath - newArgs.Parent = parent.file.Id - fmt.Fprintf(args.Out, "[%04d/%04d] Uploading %s -> %s\n", i + 1, missingCount, lf.absPath, filepath.Join(files.root.file.Name, lf.relPath)) - err := self.uploadMissingFile(files.root.file.Id, lf, newArgs) + err := self.uploadMissingFile(parent.file.Id, lf, args) if err != nil { return err } @@ -263,7 +250,7 @@ func (self *Drive) deleteExtraneousRemoteFiles(files *syncFiles, args UploadSync return nil } -func (self *Drive) uploadMissingFile(rootId 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) @@ -272,8 +259,8 @@ func (self *Drive) uploadMissingFile(rootId string, lf *localFile, args UploadSy // Instantiate drive file dstFile := &drive.File{ Name: lf.info.Name(), - Parents: []string{args.Parent}, - AppProperties: map[string]string{"syncRootId": rootId}, + Parents: []string{parentId}, + AppProperties: map[string]string{"syncRootId": args.RootId}, } // Chunk size option @@ -354,6 +341,16 @@ func (self *Drive) prepareRemoteFiles(rootDir *drive.File) ([]*remoteFile, error return remoteFiles, nil } +func (self *Drive) dirIsEmpty(id string) (bool, error) { + query := fmt.Sprintf("'%s' in parents", id) + fileList, err := self.service.Files.List().Q(query).Do() + if err != nil { + return false, fmt.Errorf("Empty dir check failed: ", err) + } + + return len(fileList.Files) == 0, nil +} + func checkFiles(files []*drive.File) error { uniq := map[string]string{} @@ -292,17 +292,12 @@ func main() { }, }, &cli.Handler{ - Pattern: "[global] upload sync [options] <path>", + Pattern: "[global] upload sync [options] <path> <id>", Description: "Sync local directory to drive", Callback: uploadSyncHandler, Flags: cli.Flags{ "global": globalFlags, "options": []cli.Flag{ - cli.StringFlag{ - Name: "parent", - Patterns: []string{"-p", "--parent"}, - Description: "Parent id", - }, cli.BoolFlag{ Name: "noProgress", Patterns: []string{"--no-progress"}, diff --git a/handlers_drive.go b/handlers_drive.go index e6939f2..47e5f04 100644 --- a/handlers_drive.go +++ b/handlers_drive.go @@ -105,7 +105,7 @@ func uploadSyncHandler(ctx cli.Context) { Out: os.Stdout, Progress: progressWriter(args.Bool("noProgress")), Path: args.String("path"), - Parent: args.String("parent"), + RootId: args.String("id"), DeleteExtraneous: args.Bool("deleteExtraneous"), ChunkSize: args.Int64("chunksize"), }) |
