diff options
| author | Petter Rasmussen | 2013-01-01 20:48:15 +0100 | 
|---|---|---|
| committer | Petter Rasmussen | 2013-01-01 20:48:15 +0100 | 
| commit | 2f4fabf7bb74b42a7aa54c5b02538e4ca337361f (patch) | |
| tree | db087fb26d0e97ab494f8f8684dc0441630efb75 /cli | |
| download | gdrive-2f4fabf7bb74b42a7aa54c5b02538e4ca337361f.tar.bz2 | |
version 1
Diffstat (limited to 'cli')
| -rw-r--r-- | cli/cli.go | 307 | 
1 files changed, 307 insertions, 0 deletions
| diff --git a/cli/cli.go b/cli/cli.go new file mode 100644 index 0000000..d78c838 --- /dev/null +++ b/cli/cli.go @@ -0,0 +1,307 @@ +package cli + +import ( +    "fmt" +    "os" +    "io" +    "path/filepath" +    "strings" +    "code.google.com/p/google-api-go-client/drive/v2" +    "../util" +    "../gdrive" +) + +func List(d *gdrive.Drive, query, titleFilter string, maxResults int, sharedStatus bool) { +    caller := d.Files.List() + +    if maxResults > 0 { +        caller.MaxResults(int64(maxResults)) +    } + +    if titleFilter != "" { +        q := fmt.Sprintf("title contains '%s'", titleFilter) +        caller.Q(q) +    } + +    if query != "" { +        caller.Q(query) +    } + +    list, err := caller.Do() +    if err != nil { +        fmt.Println(err) +        return +    } + +    items := make([]map[string]string, 0, 0) + +    for _, f := range list.Items { +        // Skip files that dont have a download url (they are not stored on google drive) +        if f.DownloadUrl == "" { +            continue +        } + +        items = append(items, map[string]string{ +            "Id": f.Id, +            "Title": util.TruncateString(f.Title, 40), +            "Size": util.FileSizeFormat(f.FileSize), +            "Created": util.ISODateToLocal(f.CreatedDate), +        }) +    } + +    columnOrder := []string{"Id", "Title", "Size", "Created"} + +    if sharedStatus { +        addSharedStatus(d, items) +        columnOrder = append(columnOrder, "Shared") +    } + +    util.PrintColumns(items, columnOrder, 3) +} + +// Adds the key-value-pair 'Shared: True/False' to the map +func addSharedStatus(d *gdrive.Drive, items []map[string]string) { +    // Limit to 10 simultaneous requests +    active := make(chan bool, 10) +    done := make(chan bool) + +    // Closure that performs the check +    checkStatus := func(item map[string]string) { +        // Wait for an empty spot in the active queue +        active <- true + +        // Perform request +        shared := isShared(d, item["Id"]) +        item["Shared"] = util.FormatBool(shared) + +        // Decrement the active queue and notify that we are done +        <-active +        done <- true +    } + +    // Go, go, go! +    for _, item := range items { +        go checkStatus(item) +    } + +    // Wait for all goroutines to finish +    for i := 0; i < len(items); i++ { +        <-done +    } +} + +func Info(d *gdrive.Drive, fileId string) { +    info, err := d.Files.Get(fileId).Do() +    if err != nil { +        fmt.Printf("An error occurred: %v\n", err) +        return +    } +    printInfo(d, info) +} + +func printInfo(d *gdrive.Drive, f *drive.File) { +    fields := map[string]string{ +        "Id": f.Id, +        "Title": f.Title, +        "Description": f.Description, +        "Size": util.FileSizeFormat(f.FileSize), +        "Created": util.ISODateToLocal(f.CreatedDate), +        "Modified": util.ISODateToLocal(f.ModifiedDate), +        "Owner": strings.Join(f.OwnerNames, ", "), +        "Md5sum": f.Md5Checksum, +        "Shared": util.FormatBool(isShared(d, f.Id)), +    } + +    order := []string{"Id", "Title", "Description", "Size", "Created", "Modified", "Owner", "Md5sum", "Shared"} +    util.Print(fields, order) +} + +// Upload file to drive +func Upload(d *gdrive.Drive, input io.ReadCloser, title string, share bool) { +    // Use filename or 'untitled' as title if no title is specified +    if title == "" { +        if f, ok := input.(*os.File); ok && input != os.Stdin { +            title = filepath.Base(f.Name()) +        } else { +            title = "untitled" +        } +    } + +    metadata := &drive.File{Title: title} +    getRate := util.MeasureTransferRate() + +    info, err := d.Files.Insert(metadata).Media(input).Do() +    if err != nil { +        fmt.Printf("An error occurred uploading the document: %v\n", err) +        return +    } + +    // Total bytes transferred +    bytes := info.FileSize + +    // Print information about uploaded file +    printInfo(d, info) +    fmt.Printf("Uploaded '%s' at %s, total %s\n", info.Title, getRate(bytes), util.FileSizeFormat(bytes)) + +    // Share file if the share flag was provided +    if share { +        Share(d, info.Id) +    } +} + +func DownloadLatest(d *gdrive.Drive, stdout bool) { +    list, err := d.Files.List().Do() + +    if err != nil { +        fmt.Println(err) +        return +    } + +    if len(list.Items) == 0 { +        fmt.Println("No files found") +        return +    } + +    latestId := list.Items[0].Id +    Download(d, latestId, stdout, true) +} + +// Download file from drive +func Download(d *gdrive.Drive, fileId string, stdout, deleteAfterDownload bool) { +    // Get file info +    info, err := d.Files.Get(fileId).Do() +    if err != nil { +        fmt.Printf("An error occurred: %v\n", err) +        return +    } + +    if info.DownloadUrl == "" { +        // If there is no DownloadUrl, there is no body +        fmt.Println("An error occurred: File is not downloadable") +        return +    } + +    // Measure transfer rate +    getRate := util.MeasureTransferRate() + +    // GET the download url +    res, err := d.Client().Get(info.DownloadUrl) +    if err != nil { +        fmt.Printf("An error occurred: %v\n", err) +        return +    } + +    // Close body on function exit +    defer res.Body.Close() + +    if err != nil { +        fmt.Printf("An error occurred: %v\n", err) +        return +    } + +    // Write file content to stdout +    if stdout { +        io.Copy(os.Stdout, res.Body) +        return +    } + +    // Check if file exists +    if util.FileExists(info.Title) { +        fmt.Printf("An error occurred: '%s' already exists\n", info.Title) +        return +    } + +    // Create a new file +    outFile, err := os.Create(info.Title)  +    if err != nil { +        fmt.Printf("An error occurred: %v\n", err) +        return +    } + +    // Close file on function exit +    defer outFile.Close() + +    // Save file to disk +    bytes, err := io.Copy(outFile, res.Body) +    if err != nil { +        fmt.Printf("An error occurred: %v") +        return +    } + +    fmt.Printf("Downloaded '%s' at %s, total %s\n", info.Title, getRate(bytes), util.FileSizeFormat(bytes)) + +    if deleteAfterDownload { +        Delete(d, fileId) +    } +} + +// Delete file with given file id +func Delete(d *gdrive.Drive, fileId string) { +    info, err := d.Files.Get(fileId).Do() +    if err != nil { +        fmt.Printf("An error occurred: %v\n", err) +        return +    } + +    if err = d.Files.Delete(fileId).Do(); err != nil { +        fmt.Printf("An error occurred: %v\n", err) +        return +    } +     +    fmt.Printf("Removed file '%s'\n", info.Title) +} + +// Make given file id readable by anyone -- auth not required to view/download file +func Share(d *gdrive.Drive, fileId string) { +    info, err := d.Files.Get(fileId).Do() +    if err != nil { +        fmt.Printf("An error occurred: %v\n", err) +        return +    } + +    perm := &drive.Permission{ +        Value: "me", +        Type: "anyone", +        Role: "reader", +    } + +    _, err = d.Permissions.Insert(fileId, perm).Do() +    if err != nil { +        fmt.Printf("An error occurred: %v\n", err) +        return +    } + +    fmt.Printf("File '%s' is now readable by everyone @ %s\n", info.Title, util.PreviewUrl(fileId)) +} + +// Removes the 'anyone' permission -- auth will be required to view/download file +func Unshare(d *gdrive.Drive, fileId string) { +    info, err := d.Files.Get(fileId).Do() +    if err != nil { +        fmt.Printf("An error occurred: %v\n", err) +        return +    } + +    err = d.Permissions.Delete(fileId, "anyone").Do() +    if err != nil { +        fmt.Printf("An error occurred: %v\n", err) +        return +    } + +    fmt.Printf("File '%s' is now longer shared to 'anyone'\n", info.Title) +} + +func isShared(d *gdrive.Drive, fileId string) bool { +    r, err := d.Permissions.List(fileId).Do() +    if err != nil { +        fmt.Printf("An error occurred: %v\n", err) +        return false +    } + +    for _, perm := range r.Items { +        if perm.Type == "anyone" { +            return true +        } +    } +    return false +} | 
