Skip to content

Instantly share code, notes, and snippets.

@rickt
Last active February 21, 2020 23:41
Show Gist options
  • Save rickt/acc12847a4330599923c4543d33faf3d to your computer and use it in GitHub Desktop.
Save rickt/acc12847a4330599923c4543d33faf3d to your computer and use it in GitHub Desktop.
gdf: Google Drive Find -- Search for a file in Google Drive using a service account and the (Golang) Google Drive API (v3)
package main
import (
"fmt"
"github.com/dustin/go-humanize"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"google.golang.org/api/drive/v3"
"io/ioutil"
"log"
"net/http"
"os"
"strings"
"time"
)
// Quick & dirty CLI tool to see if a file exists in Google Drive
//
// Usage:
// $ gdf <string or strings>
//
// Example Usage:
// $ gdf Queen Elizabeth II
// | 3.9 MB| Queen Elizabeth II (popart).png
// $ gdf foobarbaz.png
// No files found.
//
// Notes:
// 1) The service account will need to be granted 'drivescope' in the Admin Console. To grant this, go to
// 'Admin Console --> Security --> Advanced Settings --> Manage API Client Access'
// 2) Drive API will need to be enabled in the service account's GCP project
// 3) Service account will need to be granted Domain-wide Delegation authority.
// See https://developers.google.com/admin-sdk/directory/v1/guides/delegation for more info.
const (
credsfile string = "credentials.json"
drivescope string = "https://www.googleapis.com/auth/drive.readonly"
pagesize int64 = 1000
who string = "[email protected]"
)
// Get an authenticated http client
func httpclient(creds []byte) (*http.Client, error) {
conf, err := google.JWTConfigFromJSON(creds, drivescope)
if err != nil {
return nil, err
}
conf.Subject = who
return conf.Client(oauth2.NoContext), nil
}
func main() {
if len(os.Args) < 2 {
log.Fatalf("error: no search criteria specified")
}
// Load the JSON credentials
creds, err := ioutil.ReadFile(credsfile)
if err != nil {
log.Fatalf("error reading credentials file: %s", err)
}
// Get an authenticated http client
client, err := httpclient(creds)
if err != nil {
log.Fatalf("error getting authenticated http client: %s", err)
}
// Get a Drive client
dc, err := drive.New(client)
if err != nil {
log.Fatalf("Unable to get a Drive client: %v", err)
}
// Search for files with filenames containing argv[1:]
files, err := dc.Files.List().
Fields("nextPageToken, files(id, mimeType, modifiedTime, name, size)").
PageSize(pagesize).
Q("name contains '" + strings.Join(os.Args[1:], " ") + "'").
SupportsAllDrives(true).
Do()
if err != nil {
log.Fatalf("Unable to retrieve files: %v", err)
}
if len(files.Files) == 0 {
fmt.Println("No files found.")
} else {
for _, i := range files.Files {
// Get the last modified time
lmt, err := time.Parse(time.RFC3339, i.ModifiedTime)
if err != nil {
log.Fatalf("error converting last modified time: %s", err)
}
if i.MimeType == "application/vnd.google-apps.folder" {
fmt.Printf("|%8s |%14s | %s\n", "folder", humanize.Time(lmt), i.Name)
} else {
fmt.Printf("|%8s |%14s | %s\n", humanize.Bytes(uint64(i.Size)), humanize.Time(lmt), i.Name)
}
}
}
return
}
// EOF
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment