38
35

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Google Photosの無料容量15GBを有効活用!cURLでGoogle Photosへ画像アップロードするには?

Last updated at Posted at 2016-11-20

この記事では、シェルスクリプトを介してGoogle Photosへ画像をアップロードする方法を紹介します。

スクリーンショット 2016-11-20 4.40.46.png

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
スクリーンショット 2016-11-20 4.42.14.png

cURLで簡単!Picasa Web Albums Data APIを使うための認可手順

Picasa Web Albums Data APIを使って画像をアップロードするためには、アクセストークンと呼ばれるトークンが必要になります。

アクセストークンの取得手順

アクセストークンを取得するには、以下の手順が必要です。本記事では、cURLを使ったコードも載せているため、10分くらいで終わります。

  1. クライアントIDとクライアントシークレットを取得
  2. クライアントの認可コード(Authorization Code)を取得
  3. 認可コードからアクセストークンを取得

(1)クライアントIDとクライアントシークレットを取得

まず、Google APIs Consoleから認証情報を追加します。

スクリーンショット 2016-11-20 2.11.34.png

以下の手順で、クライアントIDとクライアントシークレットを取得します。あとで利用するのでメモを残しておいてください。

  • 認証情報を作成から、OAuthクライアントIDを選択
  • その他を選択し、作成
  • クライアントIDクライアントシークレットを控えておく

(2)認可コードの取得

続いて、クライアントIDを利用して、認可コードを(Authorization Code)を取得します。認可コードを取得するためのスクリプトを用意しました。YOUR_CLIENT_IDには、さきほどメモしておいたクライアントIDを入れてください。

以下のスクリプトを実行すると、URIが表示されます。これは認可ページへのリンクです。ブラウザでアクセスして認可をすすめます。
認可ボタンを押すと、ページが変わって、ブラウザ上に認可コードが表示されます。認可コードはアクセストークン取得に必要なものです。このあとすぐ使うのでメモしておいてください。

get_authorization_code.sh
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やクライアントシークレット、認可コードは控えていたメモにあるものを差し替えて使ってください。

get_access_token_and_refresh_token.sh
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_IDACCESS_TOKENは自分のものを入れておいてください。

upload.sh
#! /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>を見ます。これもまたあとで利用するのでメモをとっておいてください。

各アルバムの形式.xml
<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というアルバムに画像をアップロードしてみます。
スクリーンショット 2016-11-20 5.55.45.png

以下のスクリプトを画像ファイル(JPEG)のある場所で作成してください。アップロードしたいファイル名は、sample.jpgという名前としておきます。USER_IDALBUM_IDACCESS_TOKENを個人のものにしておけば、あとは実行するだけです。

upload.sh
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へアクセスしてアップロードされていることを確認します。

スクリーンショット 2016-11-20 5.58.12.png

ディレクトリ内の画像を全部アップロードするスクリプト

ディレクトリ内部の画像ファイルをすべてアップロードするスクリプトを書きました。

upload_images_in_dir.sh
#! /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

付録

リフレッシュトークンからアクセストークンを取得する

アクセストークンが期限切れになった場合は、リフレッシュトークンによってアクセストークンを再取得できます。

get_access_token_by_refresh_token.sh
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に流し込むと、ハイライトがついてより見やすくなります。

pretty_formatted_xml.sh
#! /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を使っている人はこうすると便利
  1. https://www.google.com/settings/storage?hl=ja

  2. Picasa Web Albums Data APIリファレンス

  3. https://developers.google.com/api-client-library/python/auth/installed-app

  4. xmllintが入っているかどうかは、which xmllintで確認できます

38
35
3

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
38
35

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?