godrive

package module
v0.0.0-...-aa72f78 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Mar 20, 2015 License: Apache-2.0 Imports: 11 Imported by: 0

README

godrive

godrive is a Go library that allows easy access to files and directories (aka "folders") on Google Drive. Unlike most "bare bones" libraries, godrive abstracts Google Drive concepts by presenting a "path" like interface, allowing users to access their files in Google Drive using Unix-like pathnames.

Installation

To compile this program and use the godrive libraries, you need a few things:

Create a working directory for this project:

$ mkdir ~/go
$ mkdir ~/go/src

Make sure your GOPATH environment variable points to the correct location:

$ export GOPATH=~/go

Install the necessary packages:

$ go get code.google.com/p/google-api-go-client/drive/v2
$ go get code.google.com/p/goauth2/oauth

Compile with go build as usual.

Google Drive instructions

To use Google Drive with this library, you need a Client Id, a Client Secret and a one-time code. To create the Client Id and Secret, visit the Google Developers Console and create a new project. Make sure the project has the Google Drive API turned on (APIs & Auth/APIs menu on the left). Use the APIs & Auth/Credentials menu to create a new Client ID for OAuth authentication.

For more information on the entire process, consult the Google Drive Web APIs page.

Example

To run the program below, you need a "Client Id" and "Secret" (see instructions on how to obtain those in the "Google Drive instructions" section above). Run the program with the --id and --secret options, passing those values. The program will show an URL where the "code" can be obtained and exit. Use a browser to open that link and re-run the program with the --code option. From this point on, it will not be necessary to specify --id, --secret or --code.

package main

import (
        "flag"
        "fmt"
        "log"
        "os"
        "os/user"
        "path"
        "time"

        drive "code.google.com/p/google-api-go-client/drive/v2"
        "github.com/marcopaganini/godrive"
)

const (
        // Oauth cache file. Relative to the user's homedir
        authCacheFile = ".gdrive_example_auth.cache"

        // Our base directory inside Gdrive
        gdriveBaseDir = "testdir"
)

var (
        clientId     = flag.String("id", "", "Client ID")
        clientSecret = flag.String("secret", "", "Client Secret")
        requestURL   = flag.String("request_url", "https://www.googleapis.com/oauth2/v1/userinfo", "API request")
        code         = flag.String("code", "", "Authorization Code")
)
func main() {
        flag.Parse()

        usr, err := user.Current()
        if err != nil {
                log.Fatalf("Unable to get user information")
        }
        cachefile := path.Join(usr.HomeDir, authCacheFile)

        g, err := godrive.NewGoDrive(*clientId, *clientSecret, *code, drive.DriveScope, cachefile)
        if err != nil {
                log.Fatalf("Unable to initialize godrive: %v", err)
        }

        // Create a few directories for no good reason other than
        // show that we refer to files using familiar pathnames.
        dirs := [...]string{gdriveBaseDir, path.Join(gdriveBaseDir, "test1"), path.Join(gdriveBaseDir, "test2")}
        for _, d := range dirs {
                _, err := g.Mkdir(d)
                if err != nil {
                        log.Fatalf("Unable to create directory \"%s\", error %v\n", d, err)
                }
        }

        // Insert the /etc/group file into the newly created directories
        remoteFile := path.Join(gdriveBaseDir, "group")
        localFile := "/etc/group"

        r, err := os.Open(localFile)
        if err != nil {
                log.Fatalf("Unable to open", localFile)
        }
        defer r.Close()

        // Insert the file into Google Gdrive
        _, err = g.InsertInPlace(remoteFile, r)
        if err != nil {
                log.Fatalf("Error inserting \"%s\": %v", remoteFile, err)
        }

        // List the contents of the newly created directory
        dirlist, err := g.ListDir(gdriveBaseDir, "")
        if err != nil {
                log.Fatalf("Error listing directory \"%s\": %v", gdriveBaseDir, err)
        }

        for _, fileObj := range dirlist {
                filetype := "[file] "
                if godrive.IsDir(fileObj) {
                        filetype = "[dir]  "
                }
                create, _ := godrive.CreateDate(fileObj)
                modify, _ := godrive.CreateDate(fileObj)

                fmt.Printf("%s %s %s [%s]\n",
                        filetype,
                        create.Format(time.UnixDate),
                        modify.Format(time.UnixDate),
                        fileObj.Title)
        }
}

Notes

This library should be considered in BETA state. I'm actively working on it. Please keep the following in mind when using this it:

  • Google Drive allows multiple files/directories with the same name. Since we're (kinda) emulating the semantics of a Unix filesystem, the library will return an error if it finds duplicates. It's up to the user to clean the files manually. Every effort has been made to prevent this condition, but there are certainly bugs lurking around.

  • Since Google Drive was not designed to be used with "paths", the library needs to make many Google Drive native calls, even for simple operations (anything using a path needs information about every element on the path. I've added caching to the library to make things better.

Author

(C) 2014 by Marco Paganini

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func CreateDate

func CreateDate(driveFile *drive.File) (time.Time, error)

CreateDate returns the time.Time representation of the *drive.File object's creation date.

func IsDir

func IsDir(driveFile *drive.File) bool

IsDir returns true if the passed *drive.File object is a directory.

func IsObjectNotFound

func IsObjectNotFound(e error) bool

IsObjectNotFound Returns true if the passed error is of type godrive.Error and the error condition was caused by an Object Not Found.

func ModifiedDate

func ModifiedDate(driveFile *drive.File) (time.Time, error)

ModifiedDate returns the time.Time representation of the *drive.File object's modification date. Dates are rounded to the nearest second (to avoid nanosecond rounding errors when comparing dates.)

Types

type Error

type Error struct {
	ObjectNotFound bool
	// contains filtered or unexported fields
}

Error defines a custom error for godrive

func (*Error) Error

func (e *Error) Error() string

type Gdrive

type Gdrive struct {
	// contains filtered or unexported fields
}

Gdrive is the main structure representing a GoDrive object

func NewGoDrive

func NewGoDrive(clientID string, clientSecret string, code string, scope string, cacheFile string) (*Gdrive, error)

NewGoDrive creates and returns a new *Gdrive Object or (nil, error) in case of problems.

func (*Gdrive) Download

func (g *Gdrive) Download(srcPath string) (io.Reader, error)

Download a file from Gdrive. Returns an io.Reader to gdrive file pointed by srcPath. The io.Reader can be used to save the file locally by the caller.

func (*Gdrive) DownloadToFile

func (g *Gdrive) DownloadToFile(srcPath string, localFile string) (int64, error)

DownloadToFile downloads a file named 'srcPath' into 'localFile'. localFile will be overwritten if it exists. The file is first downloaded into a temporary file and then atomically moved into the destination file. Returns the number of bytes downloaded.

func (*Gdrive) GdriveChildrenList

func (g *Gdrive) GdriveChildrenList(parentID string, query string) ([]*drive.ChildReference, error)

GdriveChildrenList returns a slice of *drive.ChilReference containing all objects under 'ParentId' which satisfy the 'query' parameter.

func (*Gdrive) GdriveFilesGet

func (g *Gdrive) GdriveFilesGet(fileID string) (*drive.File, error)

GdriveFilesGet returns a *drive.File object for the object identified by 'fileId'

func (*Gdrive) GdriveFilesInsert

func (g *Gdrive) GdriveFilesInsert(reader io.Reader, title string, parentID string, mimeType string) (*drive.File, error)

GdriveFilesInsert inserts a new Object (file/dir) on Google Drive under 'parentId'. The object's contents will come from 'reader' (io.Reader). If reader is nil, an empty object will be created (this is how we create directories). The title of the object will be set to 'title' and the object's MIME Type will be set to 'mimeType', or automatically detected if mimeType is blank.

Returns a *drive.File object pointing to the file just inserted.

func (*Gdrive) GdriveFilesPatch

func (g *Gdrive) GdriveFilesPatch(fileID string, title string, modifiedDate string, addParentIds []string, removeParentIds []string) (*drive.File, error)

GdriveFilesPatch patches a Gdrive object metadata. Currently it can change the Title, modifiedDate, and the list of parent Ids. Setting values to a blank string (when of type string) or an empty slice (type slice) will cause that particular attribute to remain untouched.

Returns a *drive.File object pointing to the modified file.

func (*Gdrive) GdriveFilesTrash

func (g *Gdrive) GdriveFilesTrash(fileID string) (*drive.File, error)

GdriveFilesTrash moves the object indicated by 'fileID' to the Google Drive Trash. Returns a *drive.File object pointing to the file inside Trash.

func (*Gdrive) Insert

func (g *Gdrive) Insert(dstPath string, reader io.Reader) (*drive.File, error)

Insert inserts a file named 'dstPath' with the contents coming from 'reader'. The method calls the 'insert' method with the inplace option set to false, causing the file to be writen to a temporary location and then renamed to its final place. This method is safer (but slower) than the InsertInPlace method.

Returns *drive.File pointing to the file in its final location.

func (*Gdrive) InsertInPlace

func (g *Gdrive) InsertInPlace(dstPath string, reader io.Reader) (*drive.File, error)

InsertInPlace inserts a file named 'dstPath' with the contents coming from reader. The method calls the 'insert' method with the inplace option set to true, causing the file to be written directly to its final destination. This is faster but (theoretically) less safe than using "Insert".

Returns *drive.File: pointing to the file in its final location.

func (*Gdrive) ListDir

func (g *Gdrive) ListDir(drivePath string, query string) ([]*drive.File, error)

ListDir returns a slice of *drive.File objects under 'drivePath' matching 'query' (in Google Drive query format.) If query is blank, it defaults to 'trashed = false'.

func (*Gdrive) Mkdir

func (g *Gdrive) Mkdir(drivePath string) (*drive.File, error)

Mkdir creates the directory (folder) specified by drivePath. Returns the *drive.File pointing to the object. If the folder already exists, the *drive.File of the existing folder will be returned (this saves one Stat when creating directories.)

func (*Gdrive) Move

func (g *Gdrive) Move(srcPath string, dstPath string) (*drive.File, error)

Move renames/moves the object in 'srcPath' (file or directory) to 'dstPath' by calling patch to replace dstPath as the parent of 'srcPath'. The paths are full paths (dir/dir/dir.../file). Returns the *drive.File containing the destination object.

func (*Gdrive) SetDebugLevel

func (g *Gdrive) SetDebugLevel(n int)

SetDebugLevel sets the debug level for future uses of the log.Debug{ln,f} methods.

func (*Gdrive) SetModifiedDate

func (g *Gdrive) SetModifiedDate(drivePath string, modifiedDate time.Time) (*drive.File, error)

SetModifiedDate sets the modification date of the file/directory specified by 'drivePath' to 'modifiedDate'. Returns *drive.File pointing to the modified file/dir.

func (*Gdrive) SetVerboseLevel

func (g *Gdrive) SetVerboseLevel(n int)

SetVerboseLevel sets the verbose level for future uses of the log.Verbose{ln,f} methods.

func (*Gdrive) Stat

func (g *Gdrive) Stat(drivePath string) (*drive.File, error)

Stat returns the *drive.File object for the last element in 'drivePath'. The path must be specified as a full path (similar to unix filesystem path.)

Google Drive allows more than one object with the same name and Unix filesystems do not. Stat returns an error if a duplicate is found anywhere in the requested path (which will require human intervention, and should never happen if only this set of routines is used to create files under that path.) Stat returns an instance of godrive.Error with ObjectNotFound set if the requested object cannot be found. Use g.IsObjecNotFound(err) to test for this condition.

Returns *drive.File object of the object pointed by the full path.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL