必要性にかられてGoogleのファイル共有サービス「Google Drive」に 自分のサーバからファイルを自動アップロードしたくなった。 やりたいことは、ぱぱサーバでケータイメールを受信して、そこから MIMEパートの添付JPEGファイルを取り出し、これをGoogle Driveに追加する、 という一連の行程である。これができればPCを持っていない人たちからも、 とりあえず写真を収集することができるから。
メールを受信して添付を取り出すところまでは簡単なのだが、問題はサーバからユーザの手動操作やアカウント入力を経ずGoogleへバッチアップロードする部分。当初は簡単にできると思っていた。
最初に試したのはgoogle-docs-uploadというそのまんまなソフト。動作にはSun Javaランタイムが必要で、Debian squeezeの場合はaptリポジトリのnon-freeを開放しないと動かない。 さらに、動かしてみると「Uploading without conversion is only available to Google Apps for Business accounts」とのメッセージが出てアップロードできない。 --protocol httpsをつけてもダメだった。
次に試したのはGD Pythonクライアントのラッパーである gdatacopier。これには gcp.pyというのが含まれており、SSH(scp)ライクのコマンドラインで バッチアップロードできる。求めていたのはこれだ!.... 確かにちゃんと動いたけど....どうしても JPEGファイルだけがアップロードできない....
しげしげとhttp://code.google.com/p/gdatacopier/wiki/gcpを眺めていたら (思えば最初から読めばよかったのだが) Google Docs時代のドキュメントにしか対応してない! ということにようやく気づく。Google Driveは他のファイル共有サービスと異なり、前身がMicrosoft Office対抗のGoogle Docsだから、ExcelやWordファイルはアップロードできても、JPEGはアップロードできないというキテレツなことになっているのであった。いや正確にはクライアントがDocs時代のまま進化してないと言うのが正しいか。ともかく前記2つのコマンドではサーバにJPEGやMP3やMP4をアップロードすることはできないようだ....どうしよう。
Google DriveにCURLでアップロードするには?という素晴らしいページに全て書いてあったのでありがたく拝借する。
Google API ConsoleからGoogle Drive APIをEnableにしてClientIDとClient secretを取得して、さらにブラウザでOAuth認証をして認証コードを取得し、gd.confに設定ファイルとして書き込んでおく。今回は設定ファイルも含めて全部/home/papanda/binを使うちう杜撰さ。chmod a+rwx binしてます。実行に必要な他のコマンドはfile, curl, awk, perl(use JSON)。
----------------gd.conf------------- CLIENT_ID=XXXXXXXXXXX.apps.googleusercontent.com CLIENT_SECRET=YYYYYYYYYYYYYYYYYYYYYYYY CODE=ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ ACFILE=/home/papanda/bin/actoken.conf TKFILE=/home/papanda/bin/token.conf ----------------gd.conf-------------
OAuth認証の手順では、ブラウザリクエストとサーバリダイレクトを伴う関係上、 単体アプリ/コマンドでの完全自動化が難しい。Twitterでも専用クライアントにはxAuthが 存在したように、Googleでは"For Device"の審査に通ればできるらしいのだが、 こんなしょぼいコマンドにデバイス認証が通るわけもなく、かといって、 個別ユーザごとにブラウザ通したら、ガラケーからアップロードできるメリットも半減なので、 得られた認証コードをファイルに書くという暴挙に出た。
もちろん認証コードにも「寿命」があるらしいのだが...リフレッシュトークンを保存しておいて、 1時間に1回更新することでしのぐことにした。切れたら認証コードの取得だけやり直しってこと。 gdupdate.shを crontab -eして
40 * * * * sh /home/papanda/bin/gd2.sh >>/var/tmp/gd2.log 2>/dev/null
こんな風にして1時間に1回動かすことにした。
上記のスクリプトにはヘルパーとして gdval.plが必要なので 同一binディレクトリに突っ込んでchmod a+xしてください。 シェルスクリプトはGoogle APIから返ってくるJSONを解釈できないから、1段めの オブジェクトだけ解析してシェル変数に展開することが必要です。
うまく更新できれば/home/papanda/binにactoken.confとtoken.confができます。 ここにシェル変数でアクセストークンとリフレッシュトークンが入っているので、 Google Drive API経由で各種操作が(やっと)できるようになります。 /home/papanda/binのライトパーミッションが気になる場合は、適当なディレクトリを掘って gd.confのACFILE,TKFILE変数を書き換えてください。
gdls.plと gdls.shを binに突っ込んでchmod a+x。うまくアクセストークンがとれていればgdls.shを実行すれば 簡易的な閲覧ができるはずです。
0324TR [FOLDER], WWWWWWWWWWWWWWWWWWWWWWWWWWW mail_0330_152401.jpg , 565528 ,0324TR mail_0329_162300.jpg , 802816 ,0324TR DSC05098.JPG , 1215679 ,0324TR DSC05112.JPG , 550623 ,0324TR image.jpg , 2198746 ,0324TR mail_0328_120412.jpg , 885597 ,0324TR
最初に紹介したgdatacopierのgls.pyなどでは 完全無視 されていたJPEGファイルの 一覧も出せるようになりました。[FOLDER]とついている行はGoogle Drive上のフォルダで、 この最後についているWWW...の部分はIDです。アップロード時フォルダ指定をしたいときに使います。
gdupload.shを binに突っ込んでchmod a+x。Google Driveに必要なメタデータをシェルスクリプト上で 作ってcurlでアップロードします。
フォルダ指定をしたい場合は、gdls.shで閲覧したフォルダIDで、 以下のJSONのparents行の部分を書き換えてください。もしユーザフォルダ直下に アップロードしたい場合はparents行自体を消してください。
{ "title": "$BASE", "mimeType": "$MIME", "description": "$FROM", "parents": [{ "id": "WWWWWWWWWWWWWWWWWWWWWWWWWWW" }] }