Skip to content
This repository has been archived by the owner on Sep 3, 2020. It is now read-only.

Commit

Permalink
doc export: regex support
Browse files Browse the repository at this point in the history
Allows for command like this:
`drive pull -export doc`
Equal to
`drive pull -export docx`
and any other similar formats bunched together
  • Loading branch information
Emmanuel Odeke committed Dec 27, 2014
1 parent 0c4fac7 commit 478d24e
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 38 deletions.
20 changes: 15 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,17 +59,27 @@ Background sync is not just hard, it's stupid. My technical and philosophical ra
exported to different forms e.g docx, xlsx, csv etc.
When doing a pull remember to include option `-export ext1,ext2,ext3`
where ext1, ext2, ... could be:
* docx
* jpeg
* doc, docx
* jpeg, jpg
* gif
* html
* odt
* rtf
* pdf
* png
* pptx
* ppt, pptx
* svg
* txt
* xlsx
* txt, text
* xls, xlsx

The exported files will be placed in a directory in the same path
as the source Doc but affixed with '\_exports' e.g
drive pull -export gif,jpg,svg logo
if successful will create a directory logo\_exports which will look like:
|- logo\_exports
|- logo.gif
|- logo.png
|- logo.svg

## Known issues
* Probably, it doesn't work on Windows.
Expand Down
14 changes: 12 additions & 2 deletions cmd/drive/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,15 +64,25 @@ type pullCmd struct {

func (cmd *pullCmd) Flags(fs *flag.FlagSet) *flag.FlagSet {
cmd.export = fs.String(
"export", "", "comma separated list of formats to export your docs + sheets files")
"export", "", "comma separated list of formats to export your docs + sheets files")
cmd.isRecursive = fs.Bool("r", true, "performs the pull action recursively")
cmd.isNoPrompt = fs.Bool("no-prompt", false, "shows no prompt before applying the pull action")
return fs
}

func (cmd *pullCmd) Run(args []string) {
context, path := discoverContext(args)
exports := strings.Split(*cmd.export, ",")

// Filter out empty strings.
exports := func(v []string) (splits []string) {
for _, elem := range v {
if elem != "" {
splits = append(splits, elem)
}
}
return
}(strings.Split(*cmd.export, ","))

exitWithError(drive.New(context, &drive.Options{
Path: path,
Exports: exports,
Expand Down
19 changes: 10 additions & 9 deletions pull.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,7 @@ func (g *Commands) export(f *File, destAbsPath string, exports []string) (manife

waitables := map[string]string{}
for _, ext := range exports {
mimeType, ok = docExportsMap[ext]
if !ok {
continue
}
mimeType = mimeTypeFromExt(ext)
exportURL, ok = f.ExportLinks[mimeType]
if !ok {
continue
Expand Down Expand Up @@ -206,10 +203,14 @@ func (g *Commands) export(f *File, destAbsPath string, exports []string) (manife
}

func (g *Commands) download(change *Change, exports []string) (err error) {
baseName := change.Path
destAbsPath := g.context.AbsPathOf(baseName)
var baseName, destAbsPath string

if change.Src != nil {
baseName = change.Src.Name
destAbsPath = g.context.AbsPathOf(baseName)
}

if hasExportLinks(change.Src) {
if hasExportLinks(change.Src) && len(exports) >= 1 {
// We need to touch the empty file to ensure
// consistency during a push.
emptyFilepath := g.context.AbsPathOf(baseName)
Expand All @@ -218,8 +219,8 @@ func (g *Commands) download(change *Change, exports []string) (err error) {
}
manifest, exportErr := g.export(change.Src, destAbsPath, exports)
if exportErr == nil {
for i, exportPath := range manifest {
fmt.Printf("# %d: %s\n", i+1, exportPath)
for _, exportPath := range manifest {
fmt.Printf("Exported '%s' to '%s'\n", destAbsPath, exportPath)
}
}
return exportErr
Expand Down
46 changes: 34 additions & 12 deletions remote.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
"fmt"
"io"
"net/http"
"regexp"
"strings"
"time"

Expand Down Expand Up @@ -46,25 +47,46 @@ var (
ErrPathNotExists = errors.New("remote path doesn't exist")
)

var docExportsMap = map[string]string{
"csv": "text/csv",
"html": "text/html",
"txt": "text/plain",
var regExtStrMap = map[string]string{
"csv": "text/csv",
"html?": "text/html",
"te?xt": "text/plain",

"gif": "image/gif",
"png": "image/png",
"svg": "image/svg+xml",
"jpeg": "image/jpeg",
"gif": "image/gif",
"png": "image/png",
"svg": "image/svg+xml",
"jpe?g": "image/jpeg",

"odt": "application/vnd.oasis.opendocument.text",
"rtf": "application/rtf",
"pdf": "application/pdf",

"docx": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"pptx": "application/vnd.openxmlformats-officedocument.wordprocessingml.presentation",
"docx?": "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"pptx?": "application/vnd.openxmlformats-officedocument.wordprocessingml.presentation",
"xlsx?": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
}

func compileRegExtMap() *map[*regexp.Regexp]string {
regExpMap := make(map[*regexp.Regexp]string)
for regStr, mimeType := range regExtStrMap {
regExComp, err := regexp.Compile(regStr)
if err == nil {
regExpMap[regExComp] = mimeType
}
}
return &regExpMap
}

var regExtMap = *compileRegExtMap()

"xls": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
"xlsx": "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
func mimeTypeFromExt(ext string) string {
bExt := []byte(ext)
for regEx, mimeType := range regExtMap {
if regEx != nil && regEx.Match(bExt) {
return mimeType
}
}
return ""
}

type Remote struct {
Expand Down
20 changes: 10 additions & 10 deletions types.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,30 +32,30 @@ const (
)

type File struct {
BlobAt string
ExportLinks map[string]string
Id string
Name string
IsDir bool
Md5Checksum string
MimeType string
ModTime time.Time
Name string
Size int64
BlobAt string
MimeType string
Md5Checksum string
ExportLinks map[string]string
}

func NewRemoteFile(f *drive.File) *File {
mtime, _ := time.Parse("2006-01-02T15:04:05.000Z", f.ModifiedDate)
mtime = mtime.Round(time.Second)
return &File{
BlobAt: f.DownloadUrl,
ExportLinks: f.ExportLinks,
Id: f.Id,
Name: f.Title,
IsDir: f.MimeType == "application/vnd.google-apps.folder",
Md5Checksum: f.Md5Checksum,
MimeType: f.MimeType,
ModTime: mtime,
Name: f.Title,
Size: f.FileSize,
MimeType: f.MimeType,
BlobAt: f.DownloadUrl,
Md5Checksum: f.Md5Checksum,
ExportLinks: f.ExportLinks,
}
}

Expand Down

0 comments on commit 478d24e

Please sign in to comment.