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

Fix bug with missing downloadURL for docs/sheets #25

Closed
wants to merge 21 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 39 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
# drive

[![Build Status](https://travis-ci.org/rakyll/drive.png?branch=master)](https://travis-ci.org/rakyll/drive)
[![Build Status](https://travis-ci.org/odeke-em/drive.png?branch=master)](https://travis-ci.org/odeke-em/drive)

`drive` is a tiny program to pull or push [Google Drive](https://drive.google.com) files. You need go1.2 installed in order to build the program.
`drive` is a tiny program to pull or push [Google Drive](https://drive.google.com) files. You need at least go1.2 installed in order to build the program.

## Installation

go get github.com/rakyll/drive/cmd/drive
go get github.com/odeke-em/drive/cmd/drive

Use `drive help` for further reference.

$ drive init [path]
$ drive pull [-r -no-prompt path] # pulls from remote
$ drive pull [-r -no-prompt -export ext1,ext2,ext3 path] # pulls from remote and exports Docs + Sheets to one of its export formats.
e.g:
$ drive pull [-r -no-prompt -export pdf,docx,rtf,html ReportII.txt] # pull ReportII.txt from remote and
export it to pdf, docx, rtf and html

$ drive push [-r -no-prompt path] # pushes to the remote
$ drive push [-r -hidden path] # pushes also hidden directories and paths to the remote
# To push from a location not on the drive:
$ drive push -m $LOCATION .
$ drive diff [path] # outputs a diff of local and remote
$ drive pub [path] # publishes a file, outputs URL
$ drive unpub [path] # revokes public access to the file
Expand Down Expand Up @@ -50,6 +57,35 @@ Background sync is not just hard, it's stupid. My technical and philosophical ra

* Possibility to support multiple accounts. Pull from or push to multiple Google Drive remotes. Possibility to support multiple backends. Why not to push to Dropbox or Box as well?

## Notes:
* Google Docs cannot be directly downloaded but only
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:
* doc, docx
* jpeg, jpg
* gif
* html
* odt
* rtf
* pdf
* png
* ppt, pptx
* svg
* 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

## [Sample usage](https://github.com/odeke-em/drive/blob/master/Sample_Usage.md):

## Known issues
* Probably, it doesn't work on Windows.
* Google Drive allows a directory to contain files/directories with the same name. Client doesn't handle these cases yet. We don't recommend you to use `drive` if you have such files/directories to avoid data loss.
Expand Down
134 changes: 134 additions & 0 deletions Sample_Usage.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
Welcome to the drive wiki!

**System pre-requisites for Drive:**
======


+ An installation of Go with version >= 1.2

To check your go version:

`$> go version`

+ Your gopath should have been set in your e.g

Sample set up:

`vi ~/.bashrc or vi ~/.bash_profile`

`export GOPATH=~/gopath`

`export PATH=$GOPATH:$GOPATH/bin:${PATH}`




**Installing drive, the program:**
=======


$> go get github.com/rakyll/drive/cmd/drive

Note: Running go install or go get github.com/rakyll/drive will not create an executable.


**Initializing a drive:**
=====


To setup/mount your Google Drive directory to path ~/GDRIVE

![drive init](https://github.com/odeke-em/wiki_content/blob/master/drive/init.png)


**Pull:**
====

+ What does a pull operation do?

A pull operation gets the manifest of content from your Google drive and tries to mirror the Google Drive's

content to your drive. This will entail downloading content from the cloud as well as deleting content that

is present on your local drive folder but not on your Google Drive.

+ How is a pull operation performed?

** Performing a pull with no arguments will pull all the respective content in from the current path

![drive pull](https://github.com/odeke-em/wiki_content/blob/master/drive/pull_all.png)

** You can also pull from a specific path
![drive pull](https://github.com/odeke-em/wiki_content/blob/master/drive/pull_specific.png)

+ Can I export documents?

Yes, by default Google Docs + Sheets cannot be downloaded raw but only exported. To export

your documents pass in: -export and a list of desired exports e.g:

* After creating a new document:

![drive newdoc](https://github.com/odeke-em/wiki_content/blob/master/drive/testDocument1.png)

* Now the exported pull:
![drive exported pull](https://github.com/odeke-em/wiki_content/blob/master/drive/export_usage.png)

**Push:**
====


+ What does "push" do?

push uploads/updates content to your Google Drive mirroring its directory structure locally.

+ How is a push operation performed?

![drive push](https://github.com/odeke-em/wiki_content/blob/master/drive/pushing.png)

**Publish "pub"**
====

+ What does pub do?

"pub" publishes a file globally so that anyone with a link to it can read the file.

+ How do I publish a file?

![drive pub](https://github.com/odeke-em/wiki_content/blob/master/drive/pub.png)

+ What happens if I publish a file that doesn't yet exist on the my Google Drive?

![drive pub non-existant](https://github.com/odeke-em/wiki_content/blob/master/drive/pub_unexistant.png)


**Unpublish "unpub"**
=========


+ What does unpub do?

"unpub" revokes public read access to a file.

+ How do I unpublish a file?

![drive unpub](https://github.com/odeke-em/wiki_content/blob/master/drive/unpub.png)


**Deleting files**
======

+ How do I delete a file on the cloud?

The options here are:

1) Using your browser login to Google Drive and delete that file.

* The next pull that you do should clean up that file off your disk.

2) Using your terminal, take that file out of its position and then perform a push on only that file.

* The moving can be performed with a rename, move or delete (rm)

![drive unpub](https://github.com/odeke-em/wiki_content/blob/master/drive/push_to_trash.png)

116 changes: 116 additions & 0 deletions changes.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,9 @@ package drive

import (
"fmt"
"os"
"path"
"path/filepath"
"strings"
"sync"
)
Expand All @@ -33,10 +35,124 @@ func (d *dirList) Name() string {
return d.local.Name
}

// Resolves the local path relative to the root directory
// Returns the path relative to the remote, the abspath on disk and an error if any
func (g *Commands) pathResolve() (relPath, absPath string, err error) {
root := g.context.AbsPathOf("")
absPath = g.context.AbsPathOf(g.opts.Path)
relPath = ""

if absPath != root {
if relPath, err = filepath.Rel(root, absPath); err != nil {
return
}
} else {
var cwd string
if cwd, err = os.Getwd(); err != nil {
return
}
if cwd == root {
relPath = ""
} else if relPath, err = filepath.Rel(root, cwd); err != nil {
return
}
}

relPath = strings.Join([]string{"", relPath}, "/")
return
}

// Resolves the local path relative to the root directory
// then performs either Push or Pull depending on 'isPush'
func (g *Commands) syncByRelativePath(isPush bool) (err error) {
defer g.clearMountPoints()
var relPath, absPath string
relPath, absPath, err = g.pathResolve()
if err != nil {
return
}
var r, l *File
if r, err = g.rem.FindByPath(relPath); err != nil {
// We cannot pull from a non-existant remote
if !isPush {
return
}
}
localinfo, _ := os.Stat(absPath)
if localinfo != nil {
l = NewLocalFile(relPath, localinfo)
}

var cl []*Change
fmt.Println("Resolving...")
cl, err = g.resolveChangeListRecv(isPush, relPath, r, l)
if err != nil {
return
}

if isPush {
cl = append(cl, clForPush(g)...)
}

if ok := printChangeList(cl, g.opts.IsNoPrompt); ok {
if isPush {
return g.playPushChangeList(cl)
}
return g.playPullChangeList(cl, g.opts.Exports)
}
return
}

func clForPush(g *Commands) (cl []*Change) {
absPath := g.context.AbsPathOf("/")
for _, indrivePath := range g.opts.Sources {
lcl, eerr := lonePush(g, indrivePath, absPath)
if eerr == nil {
cl = append(cl, lcl...)
}
}

for _, mt := range g.opts.Mounts {
ccl, cerr := lonePush(g, mt.Name, mt.MountPath)
if cerr == nil {
cl = append(cl, ccl...)
}
}

return
}

func (g *Commands) clearMountPoints() {
for _, mtpt := range g.opts.Mounts {
mtpt.Unmount()
}
}

func lonePush(g *Commands, absPath, path string) (cl []*Change, err error) {
r, err := g.rem.FindByPath(absPath)
if err != nil && err != ErrPathNotExists {
return
}

var l *File
localinfo, _ := os.Stat(path)
if localinfo != nil {
l = NewLocalFile(absPath, localinfo)
}

return g.resolveChangeListRecv(true, absPath, r, l)
}

func (g *Commands) resolveChangeListRecv(
isPush bool, p string, r *File, l *File) (cl []*Change, err error) {
var change *Change
if isPush {
// Handle the case of doc files for which we don't have a direct download
// url but have exportable links. These files should not be clobbered on the cloud
if hasExportLinks(r) {
return cl, nil
}

change = &Change{Path: p, Src: l, Dest: r}
} else {
change = &Change{Path: p, Src: r, Dest: l}
Expand Down
Loading