Skip to content

Commit

Permalink
id/fileId command implemented
Browse files Browse the repository at this point in the history
Fixes #533.

Adds a command for just listing of fileId
"id" alias "file-id"
  • Loading branch information
odeke-em committed Dec 27, 2015
1 parent 797190c commit 6992e27
Show file tree
Hide file tree
Showing 4 changed files with 152 additions and 0 deletions.
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
- [Stating Files](#stating-files)
- [Retrieving md5 checksums](#retrieving-md5-checksums)
- [Editing Description](#editing-description)
- [FileId Retrieval](#fileid-retrieval)
- [New File](#new-file)
- [Quota](#quota)
- [Features](#features)
Expand Down Expand Up @@ -765,6 +766,29 @@ Even more conveniently by piping content
$ cat fileDescriptions | drive edit-desc --piped targetFile influx/1.txt
```
### FileId Retrieval
You can retrieve just the fileId for specified paths
```shell
$ drive id [--depth n] [paths...]
$ drive file-id [--depth n] [paths...]
```
For example:
```shell
$ drive file-id --depth 2 dup-tests bug-reproductions
$ # drive file-id --depth 2 dup-tests bug-reproductions
FileId Relative Path
"0By5qKlgRJeV2NB1OTlpmSkg8TFU" "/dup-tests"
"0Bz5wQlgRJeP2QkRSenBTaUowU3c" "/dup-tests/influx_0"
"0Cu5wQlgRJeV2d2VmY29HV217TFE" "/dup-tests/a"
"0Cy5wQlgRJeX2WXVFMnQyQ2NDRTQ" "/dup-tests/influx"
"0Cy5wQlgRJeP2YGMiOC15OEpUZnM" "/bug-reproductions"
"0Cy5wQlgRJeV2MzFtTm50NVV5NW8" "/bug-reproductions/drive-406"
"1xmXPziMPEgq2dK-JqaUytKz_By8S_7_RVY79ceRoZwv" "info-bulletins"
```
### Quota
The `quota` command prints information about your drive, such as the account type, bytes used/free, and the total amount of storage available.
Expand Down
35 changes: 35 additions & 0 deletions cmd/drive/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ func main() {
bindCommandWithAliases(drive.StarKey, drive.DescStar, &starCmd{}, []string{})
bindCommandWithAliases(drive.UnStarKey, drive.DescUnStar, &unstarCmd{}, []string{})
bindCommandWithAliases(drive.ClashesKey, drive.DescFixClashes, &clashesCmd{}, []string{})
bindCommandWithAliases(drive.IdKey, drive.DescId, &idCmd{}, []string{})

command.DefineHelp(&helpCmd{})
command.ParseAndRun()
Expand Down Expand Up @@ -1529,6 +1530,40 @@ func (cmd *unstarCmd) Run(args []string, definedFlags map[string]*flag.Flag) {
exitWithError(drive.New(context, opts).UnStar(*cmd.ById))
}

type idCmd struct {
Depth *int `json:"depth"`
Hidden *bool `json:"hidden"`
}

func (cmd *idCmd) Flags(fs *flag.FlagSet) *flag.FlagSet {
cmd.Depth = fs.Int(drive.DepthKey, 1, "maximum recursion depth")
cmd.Hidden = fs.Bool(drive.HiddenKey, true, "allows operation on hidden paths")
return fs
}

func (icmd *idCmd) Run(args []string, definedFlags map[string]*flag.Flag) {
sources, context, path := preprocessArgs(args)
cmd := idCmd{}
df := defaultsFiller{
from: *icmd, to: &cmd,
rcSourcePath: context.AbsPathOf(path),
definedFlags: definedFlags,
}

if err := fillWithDefaults(df); err != nil {
exitWithError(err)
}

opts := &drive.Options{
Path: path,
Sources: sources,
Depth: *cmd.Depth,
Hidden: *cmd.Hidden,
}

exitWithError(drive.New(context, opts).Id())
}

type clashesCmd struct {
Fix *bool `json:"fix"`
List *bool `json:"list"`
Expand Down
3 changes: 3 additions & 0 deletions src/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ const (
EmailMessageKey = "emailMessage"
ForceKey = "force"
QuietKey = "quiet"
IdKey = "id"
QuitShortKey = "q"
YesShortKey = "Y"
QuitLongKey = "quit"
Expand Down Expand Up @@ -179,6 +180,7 @@ const (
DescUnifiedDiff = "unified diff"
DescDiffBaseLocal = "when set uses local as the base other remote will be used as the base"
DescClashesOpById = "operate on clashes by id instead of by path"
DescId = "retrieve the fileId for the specified paths"
)

const (
Expand Down Expand Up @@ -350,6 +352,7 @@ func createAndRegisterAliases() map[string][]string {
MoveKey: []string{"mv"},
DeleteKey: []string{"del"},
EditDescriptionKey: []string{EditDescriptionShortKey},
IdKey: []string{"file-id"},
}

for originalKey, aliasList := range aliases {
Expand Down
90 changes: 90 additions & 0 deletions src/id.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// Copyright 2016 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package drive

import (
"fmt"
)

const (
fileIdWidth = -48
)

func idPrintAndRecurse(g *Commands, parentId, relToRootPath string, depth int) (err error) {
if depth == 0 {
return
}

// Paths vary greatly in length but fileIds don't vary that much
g.log.Logf("%*s %s\n", int(fileIdWidth), customQuote(parentId), customQuote(relToRootPath))

decrementedDepth := decrementTraversalDepth(depth)
if decrementedDepth == 0 { // No need to recurse if depth is already 0
return
}

children := g.rem.FindByParentId(parentId, g.opts.Hidden)

separatorPrefix := relToRootPath
if rootLike(separatorPrefix) {
// Avoid a situation where you have Join("/", "/", "a") -> "//a"
separatorPrefix = ""
}

for child := range children {
if child == nil {
continue
}
childRelToRootPath := sepJoin(RemoteSeparator, separatorPrefix, child.Name)
cErr := idPrintAndRecurse(g, child.Id, childRelToRootPath, decrementedDepth)
if cErr != nil {
err = reComposeError(err, cErr.Error())
}
}

return err
}

func (g *Commands) Id() (err error) {
header := fmt.Sprintf("%*s %s", int(fileIdWidth), "FileId", "Relative Path")
headerPrinted := false

for _, relToRootPath := range g.opts.Sources {
remotes := g.rem.FindByPathM(relToRootPath)
iterCount := uint64(0)
for rem := range remotes {
if rem == nil {
continue
}

if !headerPrinted {
g.log.Logln(header)
headerPrinted = true
}

iterCount++
cErr := idPrintAndRecurse(g, rem.Id, relToRootPath, g.opts.Depth)
if cErr != nil {
err = reComposeError(err, cErr.Error())
}
}

if iterCount < 1 {
err = reComposeError(err, fmt.Sprintf("%s not matched", customQuote(relToRootPath)))
}
}

return err
}

0 comments on commit 6992e27

Please sign in to comment.