diff options
| -rw-r--r-- | cli/cli.go | 37 | ||||
| -rw-r--r-- | drive.go | 6 | ||||
| -rw-r--r-- | util/drive.go | 44 |
3 files changed, 72 insertions, 15 deletions
@@ -118,6 +118,8 @@ func printInfo(d *gdrive.Drive, f *drive.File) { "Md5sum": f.Md5Checksum, "Shared": util.FormatBool(isShared(d, f.Id)), "Parents": util.ParentList(f.Parents), + "Download": f.DownloadUrl, + "Export": f.ExportLinks["text/csv"], } order := []string{ @@ -131,6 +133,8 @@ func printInfo(d *gdrive.Drive, f *drive.File) { "Md5sum", "Shared", "Parents", + "Download", + "Export", } util.Print(fields, order) } @@ -309,7 +313,7 @@ func uploadFile(d *gdrive.Drive, input *os.File, inputInfo os.FileInfo, title st return err } -func DownloadLatest(d *gdrive.Drive, stdout bool) error { +func DownloadLatest(d *gdrive.Drive, stdout bool, format string, force bool) error { list, err := d.Files.List().Do() if err != nil { return err @@ -320,29 +324,36 @@ func DownloadLatest(d *gdrive.Drive, stdout bool) error { } latestId := list.Items[0].Id - return Download(d, latestId, stdout, true) + return Download(d, latestId, stdout, true, format, force) } // Download file from drive -func Download(d *gdrive.Drive, fileId string, stdout, deleteAfterDownload bool) error { +func Download(d *gdrive.Drive, fileId string, stdout, deleteAfterDownload bool, format string, force bool) error { // Get file info info, err := d.Files.Get(fileId).Do() if err != nil { return fmt.Errorf("An error occurred: %v\n", err) } - if info.DownloadUrl == "" { - // If there is no DownloadUrl, there is no body - return fmt.Errorf("An error occurred: File is not downloadable") + downloadUrl := info.DownloadUrl + extension := "" + + if downloadUrl == "" && format == "" { + return fmt.Errorf("Document has no download url. Try to specify an export format.") + } + + downloadUrl, extension, err = util.ExportFormat(info, format) + if err != nil { + return err } // Measure transfer rate getRate := util.MeasureTransferRate() // GET the download url - res, err := d.Client().Get(info.DownloadUrl) + res, err := d.Client().Get(downloadUrl) if err != nil { - return fmt.Errorf("An error occurred: %v\n", err) + return fmt.Errorf("An error occurred: %v", err) } // Close body on function exit @@ -354,13 +365,15 @@ func Download(d *gdrive.Drive, fileId string, stdout, deleteAfterDownload bool) return nil } + fileName := fmt.Sprintf("%s%s", info.Title, extension) + // Check if file exists - if util.FileExists(info.Title) { - return fmt.Errorf("An error occurred: '%s' already exists\n", info.Title) + if !force && util.FileExists(fileName) { + return fmt.Errorf("An error occurred: '%s' already exists", fileName) } // Create a new file - outFile, err := os.Create(info.Title) + outFile, err := os.Create(fileName) if err != nil { return fmt.Errorf("An error occurred: %v\n", err) } @@ -374,7 +387,7 @@ func Download(d *gdrive.Drive, fileId string, stdout, deleteAfterDownload bool) return fmt.Errorf("An error occurred: %s", err) } - fmt.Printf("Downloaded '%s' at %s, total %s\n", info.Title, getRate(bytes), util.FileSizeFormat(bytes)) + fmt.Printf("Downloaded '%s' at %s, total %s\n", fileName, getRate(bytes), util.FileSizeFormat(bytes)) if deleteAfterDownload { err = Delete(d, fileId) @@ -53,7 +53,9 @@ type Options struct { Download struct { FileId string `goptions:"-i, --id, mutexgroup='download', obligatory, description='File Id'"` + Export string `goptions:"-e, --export, description='Export file format for google docs'"` Stdout bool `goptions:"-s, --stdout, description='Write file content to stdout'"` + Force bool `goptions:"--force, description='Overwrite existing file'"` Pop bool `goptions:"--pop, mutexgroup='download', description='Download latest file, and remove it from google drive'"` } `goptions:"download"` @@ -121,9 +123,9 @@ func main() { case "download": args := opts.Download if args.Pop { - err = cli.DownloadLatest(drive, args.Stdout) + err = cli.DownloadLatest(drive, args.Stdout, args.Export, args.Force) } else { - err = cli.Download(drive, args.FileId, args.Stdout, false) + err = cli.Download(drive, args.FileId, args.Stdout, false, args.Export, args.Force) } case "delete": diff --git a/util/drive.go b/util/drive.go index 971b7fd..c4ba137 100644 --- a/util/drive.go +++ b/util/drive.go @@ -1,8 +1,8 @@ package util import ( - "github.com/prasmussen/google-api-go-client/drive/v2" "fmt" + "github.com/prasmussen/google-api-go-client/drive/v2" "strings" ) @@ -24,3 +24,45 @@ func ParentList(parents []*drive.ParentReference) string { return strings.Join(ids, ", ") } + +func ExportFormat(info *drive.File, format string) (downloadUrl string, extension string, err error) { + // See https://developers.google.com/drive/web/manage-downloads#downloading_google_documents + switch format { + case "docx": + extension = ".docx" + downloadUrl = info.ExportLinks["application/vnd.openxmlformats-officedocument.wordprocessingml.document"] + case "xlsx": + extension = ".xlsx" + downloadUrl = info.ExportLinks["application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"] + case "pptx": + extension = ".pptx" + downloadUrl = info.ExportLinks["application/application/vnd.openxmlformats-officedocument.presentationml.presentation"] + case "odf": + extension = ".odf" + downloadUrl = info.ExportLinks["application/vnd.oasis.opendocument.text"] + case "ods": + extension = ".ods" + downloadUrl = info.ExportLinks["application/x-vnd.oasis.opendocument.spreadsheet"] + case "pdf": + extension = ".pdf" + downloadUrl = info.ExportLinks["application/pdf"] + case "rtf": + extension = ".rtf" + downloadUrl = info.ExportLinks["application/rtf"] + case "csv": + extension = ".csv" + downloadUrl = info.ExportLinks["text/csv"] + case "html": + extension = ".html" + downloadUrl = info.ExportLinks["text/html"] + case "txt": + extension = ".txt" + downloadUrl = info.ExportLinks["text/plain"] + case "json": + extension = ".json" + downloadUrl = info.ExportLinks["application/vnd.google-apps.script+json"] + default: + err = fmt.Errorf("Unknown export format: %s. Known formats: docx, xlsx, pptx, odf, ods, pdf, rtf, csv, txt, html, json", format) + } + return +} |
