この記事では、シェルスクリプトを介してGoogle Photosへ画像をアップロードする方法を紹介します。
Google Photosをアプリケーションから使おう
Google Photosは、写真や動画をアップロードして保管できるクラウドサービスです。無料プランで15GB、月額250円で100GBのストレージが利用できます1。また、最近では写真をスキャンしてGoogle Photosへアップロードするフォトスキャンというモバイルアプリケーションが話題になりました。
Google Photosの無料プランの容量を有効活用するために、cURLを使ったアップロードの方法について紹介していきます
Google PhotosのAPIはPicasa Web Albums Data APIで代用できる
残念なことに、APIはGoogle Photos APIという名前では提供されていません。しかし、PicasaとGoogle Photosが統合された関係か、Picasa Web Albums Data API
が代用できます2。
cURLで簡単!Picasa Web Albums Data APIを使うための認可手順
Picasa Web Albums Data APIを使って画像をアップロードするためには、アクセストークンと呼ばれるトークンが必要になります。
アクセストークンの取得手順
アクセストークンを取得するには、以下の手順が必要です。本記事では、cURLを使ったコードも載せているため、10分くらいで終わります。
- クライアントIDとクライアントシークレットを取得
- クライアントの認可コード(Authorization Code)を取得
- 認可コードからアクセストークンを取得
(1)クライアントIDとクライアントシークレットを取得
まず、Google APIs Consoleから認証情報を追加します。
以下の手順で、クライアントIDとクライアントシークレットを取得します。あとで利用するのでメモを残しておいてください。
-
認証情報を作成
から、OAuthクライアントID
を選択 -
その他
を選択し、作成 -
クライアントID
とクライアントシークレット
を控えておく
(2)認可コードの取得
続いて、クライアントIDを利用して、認可コードを(Authorization Code)を取得します。認可コードを取得するためのスクリプトを用意しました。YOUR_CLIENT_ID
には、さきほどメモしておいたクライアントIDを入れてください。
以下のスクリプトを実行すると、URIが表示されます。これは認可ページへのリンクです。ブラウザでアクセスして認可をすすめます。
認可ボタンを押すと、ページが変わって、ブラウザ上に認可コードが表示されます。認可コードはアクセストークン取得に必要なものです。このあとすぐ使うのでメモしておいてください。
CLIENT_ID="YOUR_CLIENT_ID"
REDIRECT_URI="urn:ietf:wg:oauth:2.0:oob" # HTTPサーバを起動しなくてもAuthorization_Codeを取得できる
SCOPE="https://picasaweb.google.com/data/" # Google Photos APIの代わりにPicasa APIを使う
echo "https://accounts.google.com/o/oauth2/v2/auth?response_type=code&client_id=$CLIENT_ID&redirect_uri=$REDIRECT_URI&scope=$SCOPE&access_type=offline"
余談
REDIRECT_URI
の指定は、urn:ietf:wg:oauth:2.0:oob
とします。これは、なんらかの事情でHTTPでListenできない状態のときに使われます3。
(3)認可コードから、アクセストークンを取得する
手に入れた認可コードを使って、アクセストークンを取得します。クライアントIDやクライアントシークレット、認可コードは控えていたメモにあるものを差し替えて使ってください。
CLIENT_ID="YOUR_CLIENT_ID" # クライアントID
CLIENT_SECRET="YOUR_CLIENT_SECRET" # クライアントシークレット
AUTHORIZATION_CODE="YOUR_CODE" # 認可コード
REDIRECT_URI="urn:ietf:wg:oauth:2.0:oob" # HTTPサーバを起動しなくてもAuthorization_Codeを取得できる
curl --data "code=${AUTHORIZATION_CODE}" --data "client_id=${CLIENT_ID}" --data "client_secret=${CLIENT_SECRET}" --data "redirect_uri=${REDIRECT_URI}" --data "grant_type=authorization_code" --data "access_type=offline" https://www.googleapis.com/oauth2/v4/token
スクリプトを実行すると、アクセストークンとリフレッシュトークンがJSON形式で取得できます。返ってきたJSONにも書いてありますが、アクセストークンは3600秒経つと期限切れになります。アクセストークンが期限切れになった場合は、リフレッシュトークンによってアクセストークンを再取得できるので、メモしておいてください。リフレッシュトークンによる再取得の方法は記事の付録として添付してあります。
これでアップロードする準備は整いました。
アクセストークンを使って、アップロードしてみる
画像をアップロードするシェルスクリプトを書きました。以下のスクリプトを実行すると、画像をアップロードできます。ただし、USER_ID
やACCESS_TOKEN
は自分のものを入れておいてください。
#! /bin/bash
USER_ID="USER_ID"
ACCESS_TOKEN="YOUR_ACCESS_TOKEN"
ENDPOINT="https://picasaweb.google.com/data/feed/api/user/${USER_ID}"
TYPE="image/jpeg"
FILE="sample.jpg"
LENGTH=`ls -l "${FILE}" | tail -n1 | sed -E 's/ +/ /g' | cut -d' ' -f5`
curl -XPOST -H "Content-Type:${TYPE}" -H "Content-Length:${LENGTH}" -H "Slug:${FILE}" "${ENDPOINT}?access_token=${ACCESS_TOKEN}" --data-binary "@${FILE}"
特定のアルバムにアップロードしてみる
アップロードしたいアルバムIDを自分のアルバム一覧から見つける
画像をアップロードするには、アルバムを指定するための、アルバムIDが必要です。Picasaでは、特定ユーザのアルバム一覧を取得するAPIが存在します。
以下のURIへアクセスすると、hogehoge
さんの公開アルバム一覧が取得できます。すでにhogehogeさんとしてログインしている場合には、非公開を含むすべてのアルバム一覧が取得できます。
https://picasaweb.google.com/data/feed/api/user/hogehoge
自分のアルバム一覧をみたいときは、hogehoge
の箇所を自分のユーザIDに差し替えてください。
アップロードするアルバムIDの見つけ方
アルバム一覧のXMLから、目的のアルバムIDを探します。
アルバムの情報は以下のような形式で保存されています。目的のアルバムを見つけるには、まずアルバムタイトルで検索をかけるといいでしょう。そのあと該当したエントリーの<id></id>
を見るか、<gphoto:id></gphoto:id>
を見ます。これもまたあとで利用するのでメモをとっておいてください。
<entry>
<id>https://picasaweb.google.com/data/entry/api/user/:USERID/albumid/:ALBUMID</id>
...
<title type='text'>:ALBUMTITLE</title>
...
<gphoto:id>:ALBUMID</gphoto:id>
<gphoto:user>:USERID</gphoto:user>
...
</entry>
アクセストークンを使ってcURLからアップロード
さいごに、取得したアクセストークンやアルバムIDを利用して、スクリプトからGoogle Photosへアップロードを行います。もし、アクセストークンを取得してから1時間以上経過していたら、リフレッシュトークンを使って再発行しておいてください。
試しにfoodというアルバムに画像をアップロードしてみます。
以下のスクリプトを画像ファイル(JPEG)のある場所で作成してください。アップロードしたいファイル名は、sample.jpg
という名前としておきます。USER_ID
やALBUM_ID
、ACCESS_TOKEN
を個人のものにしておけば、あとは実行するだけです。
USER_ID="USER_ID"
ALBUM_ID="YOUR_ALBUM_ID"
ENDPOINT="https://picasaweb.google.com/data/feed/api/user/${USER_ID}/albumid/${ALBUM_ID}"
ACCESS_TOKEN="YOUR_ACCESS_TOKEN"
TYPE="image/jpeg"
FILE="sample.jpg"
LENGTH=`ls -l "${FILE}" | tail -n1 | sed -E 's/ +/ /g' | cut -d' ' -f5`
curl -XPOST -H "Content-Type:${TYPE}" -H "Content-Length:${LENGTH}" -H "Slug:${FILE}" "${ENDPOINT}?access_token=${ACCESS_TOKEN}" --data-binary "@${FILE}"
スクリプトを実行すると、XMLが返ってきます。アップロードした画像の詳細情報がそこには記載されています。特に保存しておく必要はありません。Google Photosへアクセスしてアップロードされていることを確認します。
ディレクトリ内の画像を全部アップロードするスクリプト
ディレクトリ内部の画像ファイルをすべてアップロードするスクリプトを書きました。
#! /bin/bash
USER_ID="USER_ID"
ALBUM_ID="YOUR_ALBUM_ID"
ACCESS_TOKEN="YOUR_ACCESS_TOKEN"
ENDPOINT="https://picasaweb.google.com/data/feed/api/user/${USER_ID}/albumid/${ALBUM_ID}?access_token=${ACCESS_TOKEN}"
DIR="${HOME}/Downloads/images" # 任意のディレクトリを指定
IFS_BAK=${IFS}
IFS="
"
FILES=`ls -1 ${DIR}`
for FILE in ${FILES}
do
if [ "${FILE}" != "" ]; then
TYPE="UNKNOWN"
case "${FILE}" in
*\.bmp) TYPE="image/bmp";;
*\.jpeg | *\.jpg) TYPE="image/jpeg";;
*\.png) TYPE="image/png";;
*) TYPE="UNKNOWN";;
esac
echo "$TYPE $FILE $LENGTH"
if [ "${TYPE}" = "UNKNOWN" ]; then
continue;
fi
LENGTH=`ls -l "${DIR}/${FILE}" | tail -n1 | sed -E 's/ +/ /g' | cut -d' ' -f5`
curl -XPOST "${ENDPOINT}" \
-H "Content-Type:${TYPE}" \
-H "Content-Length:${LENGTH}" \
-H "Slug:${FILE}" \
--data-binary "@${DIR}/${FILE}" > /dev/null
sleep 2s
fi
done
IFS=$IFS_BAK
参考リンク
おわりに
本記事では、Google Photosへスクリプトを介してアップロードする方法を紹介しました。cURL
を使っているため、ほかのプログラミング言語にも簡単に応用できます。
記事中で利用した、Picasa Web Album APIに興味のある方は、リファレンスを参照してみてください。
https://developers.google.com/picasa-web/docs/2.0/developers_guide_protocol
付録
リフレッシュトークンからアクセストークンを取得する
アクセストークンが期限切れになった場合は、リフレッシュトークンによってアクセストークンを再取得できます。
CLIENT_ID="YOUR_CLIENT_ID"
CLIENT_SECRET="YOUR_CLIENT_SECRET"
REFRESH_TOKEN="YOUR_REFRESH_TOKEN"
curl --data "refresh_token=${REFRESH_TOKEN}" --data "client_id=${CLIENT_ID}" --data "client_secret=${CLIENT_SECRET}" --data "grant_type=refresh_token" https://www.googleapis.com/oauth2/v4/token
おまけ
xmllint
で見づらいXMLを整形して表示する
ブラウザでxmlを表示するとだいぶ読みづらく、目的のアルバムが見つけづらいです。xmllint
を利用して、見づらいXMLを整形できます。xmllint
が入っている環境4では以下のようにすると、整形されたxmlがターミナルから確認できます。
Vimを使っている人は、結果をVimに流し込むと、ハイライトがついてより見やすくなります。
#! /bin/bash
USER_ID="YOUR_USER_ID"
RES=`curl https://picasaweb.google.com/data/feed/api/user/${USER_ID}`
echo "${RES}" | xmllint --format -
#echo "${RES}" | xmllint --format - | vim -R - # Vimを使っている人はこうすると便利
-
https://developers.google.com/api-client-library/python/auth/installed-app ↩
-
xmllint
が入っているかどうかは、which xmllint
で確認できます ↩