Google Driveをコマンドラインから扱う(Gdrive使用)

# Gdriveとは？

https://github.com/prasmussen/gdrive

Google Drive API v3 をコマンドラインから使用可能にする。
Go言語によって書かれている。


# 目的

* Google Driveに対し、コマンドラインから操作を行いたい。


# 手順

## 1. Gdriveのインストール

GitリポジトリをCloneして自前でコンパイルする方法もあるが、コンパイル済みのバイナリを用意してくれているのでそれを利用する。

(GitHubのREADMEを読み、使用する環境に応じてバイナリを選択する)

以下は`Linux 64-bit`を取得して、パスの通っている`/usr/local/bin/`以下に配置し実行できるようにした例。

```bash
$ curl -JLO https://docs.google.com/uc?id=0B3X9GlR6EmbnQ0FtZmJJUXEyRTA&export=download
$ ls -l
合計 7624
-rw-rw-r--. 1 kumasun kumasun 7805504  2月 25 12:58 gdrive-linux-x64

$ mv gdrive-linux-x64 gdrive
$ chmod +x gdrive
$ sudo cp gdrive /usr/local/bin/

$ gdrive version
gdrive: 2.1.0
Golang: go1.6
OS/Arch: linux/amd64
$
```


## 2. 認証情報の取得と登録

まずは `gdrive list`を実行し、アクセストークンを取得する。

```bash
$ gdrive list
Authentication needed
Go to the following url in your browser:
(Googleアカウントとのリンク用URL)

Enter verification code: AAAAAAAAAAAAAAAAAAAAAAAA
Id                                                  Name                                 Type   Size      Created
1234567890_BBBBBBBBBBBBBBBBBBBBBBB                  hoge.pdf                             bin    72.1 KB   2013-01-20 19:30:16
```

`Go to the following url in your browser:` 直下に表示される、Googleアカウントとのリンク用URLにブラウザでアクセスし、GDriveにアクセスを許可する。
その後、確認コードが表示されるので、`Enter verification code:` に入力する。

正常に認証されれば、GoogleDriveに保存されているファイルが列挙される。

### 認証をやり直す/取り消すには？

* もう使わないからアクセスできないようにしよう
* 違うGoogleアカウントに切り替えたい

といったときには：

1. ブラウザでGoogleDriveにアクセスし、「設定」→「アプリの管理」内、「GDrive」の「オプション」より「ドライブから切断」を選ぶ。
2. 続いて、Linux側に保存されているアクセストークンを削除する。
`.gdrive` という隠しディレクトリに保存されているので、それを消す

```bash
$ ls -la
合計 7640
drwx------. 3 kumasun kumasun      112  2月 25 13:11 .
drwxr-xr-x. 3 root     root         22  2月 25 10:25 ..
drwx------. 2 kumasun kumasun       27  2月 25 13:11 .gdrive
$ rm -rf .gdrive
$
```

# 使い方

## ディレクトリの作成

ディレクトリやファイルは内部的に名前でなくIDで管理される。
見た目上の階層はあるが、List表示した時はすべてがフラットに表示される

### 直下にディレクトリを作る場合

```bash
$ gdrive mkdir hoge
Directory CCCCCCCCCC created
```

```text:こんなイメージ
root
└── hoge (CCCCCCCCCC)
```


### サブディレクトリを作る場合

親ディレクトリのIDを指定する。

```bash
$ gdrive mkdir -p CCCCCCCCCC  fuga
Directory DDDDDDDDDD created
```

```text:こんなイメージ
root
└── hoge (CCCCCCCCCC)
    └── fuga (DDDDDDDDDD)
```

## ファイルのアップロード

### 直下にアップロードする

```bash
$ gdrive upload test.txt 
Uploading test.txt
Uploaded EEEEEEEEEE at 10.0 B/s, total 13.0 B
```

```text:こんなイメージ
root
├── hoge (CCCCCCCCCC)
│   └── fuga (DDDDDDDDDD)
└── test.txt (EEEEEEEEEE)
```


### 特定のディレクトリの下にアップロードする

```bash
$ gdrive upload -p DDDDDDDDDD test.txt 
Uploading test.txt
Uploaded FFFFFFFFFF at 10.0 B/s, total 13.0 B
```

```text:こんなイメージ
root
├── hoge (CCCCCCCCCC)
│   └── fuga (DDDDDDDDDD)
│       └── test.txt (FFFFFFFFFF)
└── test.txt (EEEEEEEEEE)
```


## ファイルの削除

前述の通り、ファイルやディレクトリはIDによって管理されているため、階層を考えずに操作を行う。

### ファイルやディレクトリを削除する

```bash
$ gdrive delete EEEEEEEEEE
Deleted 'test.txt'
```

```text:こんなイメージ
root
├── hoge (CCCCCCCCCC)
│   └── fuga (DDDDDDDDDD)
│       └── test.txt (FFFFFFFFFF)
└── test.txt ← 削除された
```

### 再帰的に削除する

`rm -rf` に相当する。

```bash
$ gdrive delete -r CCCCCCCCCC
Deleted 'hoge'
```

```text:こんなイメージ
root
└── hoge ← 削除された
    └── fuga ← 再帰的に削除された
        └── test.txt ← 再帰的に削除された
```


## Google Driveと同期する


```bash:GoogleDriveの状態
$ gdrive list
Id           Name   Type   Size   Created
GGGGGGGGGG   sync   dir           2019-02-25 14:57:39
```

この`sync`という名前のディレクトリと同期をとる

```bash:ローカルのtree（イメージ）
$ tree
~/directory/
├── dir1
│   ├── dir2
│   │   └── test3.txt
│   └── test2.txt
├── dir3
│   └── test4.txt
└── test1.txt

3 directories, 4 files
```

### 同期の共通オプション

よく使いそうなオプションだけ抜粋

|オプション|効果|
|---------|----|
|--keep-remote|衝突した場合、Google Drive側を正とする|
|--keep-local|衝突した場合、ローカルを正とする|
|--keep-largest|衝突した場合、サイズが大きい方を正とする|
|--dry-run|何が行われるかだけ見る（実際に転送は行われない）|

### ローカルからGoogle Driveへ

```bash
$ gdrive sync upload ~/directory/ GGGGGGGGGG
Starting sync...
Collecting local and remote file information...
Found 7 local files and 0 remote files

3 remote directories are missing
[0001/0003] Creating directory sync/dir1
[0002/0003] Creating directory sync/dir3
[0003/0003] Creating directory sync/dir1/dir2

4 remote files are missing
[0001/0004] Uploading dir1/dir2/test3.txt -> sync/dir1/dir2/test3.txt
[0002/0004] Uploading dir1/test2.txt -> sync/dir1/test2.txt
[0003/0004] Uploading dir3/test4.txt -> sync/dir3/test4.txt
[0004/0004] Uploading test1.txt -> sync/test1.txt 
Sync finished in 7.290311203s                     
```

`--keep-remote` を付けないと、衝突が発生しても問答無用で上書きされてしまう？(要検証)

### Google Driveからローカルへ

```bash
$ gdrive sync download GGGGGGGGGG ~/directory/
Starting sync...
Collecting file information...
Found 0 local files and 7 remote files

3 local directories are missing
[0001/0003] Creating directory directory/dir3
[0002/0003] Creating directory directory/dir1
[0003/0003] Creating directory directory/dir1/dir2

4 local files are missing
[0001/0004] Downloading test1.txt -> directory/test1.txt
[0002/0004] Downloading dir3/test4.txt -> directory/dir3/test4.txt
[0003/0004] Downloading dir1/test2.txt -> directory/dir1/test2.txt
[0004/0004] Downloading dir1/dir2/test3.txt -> directory/dir1/dir2/test3.txt
Sync finished in 2.546029217s                 
```

`--keep-local` を付けないと、衝突が発生しても問答無用で上書きされてしまう？(要検証)



# あとがき

* Google Driveと同期をとったり、ちょっとしたファイルのバックアップなどに使えるかなと思いました
* 自分用にメモした手順です。必要に応じて読み替えてください。
* こうしたほうがいいよ的なアドバイスを頂けると大変助かります


以上