forked from prasmussen/gdrive
-
Notifications
You must be signed in to change notification settings - Fork 0
/
export.go
111 lines (89 loc) · 2.72 KB
/
export.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
package drive
import (
"fmt"
"io"
"mime"
"os"
)
var DefaultExportMime = map[string]string{
"application/vnd.google-apps.form": "application/zip",
"application/vnd.google-apps.document": "application/pdf",
"application/vnd.google-apps.drawing": "image/svg+xml",
"application/vnd.google-apps.spreadsheet": "text/csv",
"application/vnd.google-apps.script": "application/vnd.google-apps.script+json",
"application/vnd.google-apps.presentation": "application/pdf",
}
type ExportArgs struct {
Out io.Writer
Id string
PrintMimes bool
Mime string
Force bool
}
func (self *Drive) Export(args ExportArgs) error {
f, err := self.service.Files.Get(args.Id).Fields("name", "mimeType").Do()
if err != nil {
return fmt.Errorf("Failed to get file: %s", err)
}
if args.PrintMimes {
return self.printMimes(args.Out, f.MimeType)
}
exportMime, err := getExportMime(args.Mime, f.MimeType)
if err != nil {
return err
}
filename := getExportFilename(f.Name, exportMime)
res, err := self.service.Files.Export(args.Id, exportMime).Download()
if err != nil {
return fmt.Errorf("Failed to download file: %s", err)
}
// Close body on function exit
defer res.Body.Close()
// Check if file exists
if !args.Force && fileExists(filename) {
return fmt.Errorf("File '%s' already exists, use --force to overwrite", filename)
}
// Create new file
outFile, err := os.Create(filename)
if err != nil {
return fmt.Errorf("Unable to create new file '%s': %s", filename, err)
}
// Close file on function exit
defer outFile.Close()
// Save file to disk
_, err = io.Copy(outFile, res.Body)
if err != nil {
return fmt.Errorf("Failed saving file: %s", err)
}
fmt.Fprintf(args.Out, "Exported '%s' with mime type: '%s'\n", filename, exportMime)
return nil
}
func (self *Drive) printMimes(out io.Writer, mimeType string) error {
about, err := self.service.About.Get().Fields("exportFormats").Do()
if err != nil {
return fmt.Errorf("Failed to get about: %s", err)
}
mimes, ok := about.ExportFormats[mimeType]
if !ok {
return fmt.Errorf("File with type '%s' cannot be exported", mimeType)
}
fmt.Fprintf(out, "Available mime types: %s\n", formatList(mimes))
return nil
}
func getExportMime(userMime, fileMime string) (string, error) {
if userMime != "" {
return userMime, nil
}
defaultMime, ok := DefaultExportMime[fileMime]
if !ok {
return "", fmt.Errorf("File with type '%s' does not have a default export mime, and can probably not be exported", fileMime)
}
return defaultMime, nil
}
func getExportFilename(name, mimeType string) string {
extensions, err := mime.ExtensionsByType(mimeType)
if err != nil || len(extensions) == 0 {
return name
}
return name + extensions[0]
}