今まで、おうちで撮った写真はFlashAir W-04やPQI Air Cardによって、おうちのGentoo サーバーを経由してPicasa Webにアップロードされていました。
gentoolinux.hatenablog.comgentoolinux.hatenablog.com
gentoolinux.hatenablog.com
しかし、2019年1月の3連休中に、突如アップロードされなくなってしまいました。
当初は2段階認証を導入したせいだと思っていたのですが、アップロード後に返ってくるjson の応答を見ると、
The Picasa API is deprecated. See https://developers.google.com/picasa-web/ for more details and the migration guide.
ざっくり言うと、「Picasa API はもう使えないよ! 詳しくはこのURLとマイグレーション ガイドを見てね。」って言っています。
で、このキーワードでググる と、Picasa API からPhotos Library API に移行するそうな。
あー面倒・・・。
Google さんはすぐにいままでのことをヤメたり仕様を変えたりと、変わり身が早い企業ですよね。
で、FlashAirやPQI Air Cardから画像をサーバーに引っ張ってくるところなどは変更せず、今までPicasa にアップロードしていた"upload_images_in_dir.sh"のスクリプト を中心に変更していきます。
参考にしたのはコチラのサイト
qiita.com
ひとつひとつ丁寧に解説していただいております。大変助かります。
基本的に、今までのOAuth2の認証情報は変更せず、Photos Library API を有効化し、スコープをPhotos Libraryにします。
Google デベロッパ ーコンソールにアクセスします。
console.developers.google.com
ログインするとこんな感じだと思います。Google developer console
左の「ライブラリ」をクリックします。ライブラリリス ト
API ライブラリが膨大にあるため絞り込みます。
検索窓に"photos"とでも入れます。photosキーワードで絞り込まれた状態
このPhotos Library API をクリックします。Photos Library API の説明
"有効にする"をクリックします。Photos Library API を有効化
認証情報を作成することを勧めていますが、これはPicasa API の時に作った認証情報が流用できるのでやりません。
(実は、最初わからなくて途中まで新しい認証情報を作りかけたのですが、最後の最後で「似たような既存の認証情報があります」って出てきました。そこで作るのをやめました。紛らわしいわ。)
さて、このPhotos Library API のスコープを有効化して、新しいリフレッシュトーク ンを準備します。
ここからGentoo Linux にssh でアクセスして作業します。
まずは、Photos Libraryを読み書きする権限を有するスコープ、"https://www.googleapis.com/auth/photoslibrary "の認証情報を取得します。
認証情報をブラウザでも取得できるように、URLを生成するbash スクリプト を活用します。
CLIENT_ID =" yourClientID.apps.googleusercontent.com "
REDIRECT_URI =" urn:ietf:wg:oauth:2.0:oob "
SCOPE =" https://www.googleapis.com/auth/photoslibrary "
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 "
これを実行します。
./get_authorization_code.sh
そうすると、次のような文字列が出てきます。
https://accounts.google.com/o/oauth2/v2/auth?response_type =code&client_id =yourClientID.apps.googleusercontent.com&redirect_uri =urn:ietf:wg:oauth:2.0:oob&scope =https://www.googleapis.com/auth/photoslibrary&access_type =offline
これをブラウザにコピペすると、ログイン後に認証情報が出ます。まずはログイン画面
アカウントへのリクエス トとスコープ情報が出ます
許可します。
さらっと認証情報が表示されます
さて、この認証情報を使って、リフレッシュトーク ンを取得します。
これも過去のスクリプト を使い回しましょう。
"get_access _token_and_refresh_token.sh"というスクリプト を作成します。
CLIENT_ID =" yourClientID.apps.googleusercontent.com "
CLIENT_SECRET =" yourClientSecret "
AUTHORIZATION_CODE =" NewAuthorizationCodeFromBrowser "
REDIRECT_URI =" urn:ietf:wg:oauth:2.0:oob "
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 形式でアクセストーク ンとリフレッシュトーク ンが出力されます。
./get_access_token_and_refresh_token.sh
出力例
{
"access_token" => "NewAccessToken ",
"token_type" => "Bearer ",
"expires_in" => 3600 ,
"refresh_token " : "RefreshTokenIsPermanent "
}
Photos Library API ではこのリフレッシュトーク ンを使っていきます。
で、Photos Library API を使ってアルバムにアップロードする場合、Photos Library API を使って作成したアルバムじゃないと、アップロード出来ません。
アルバム作成のAPI 解説
developers.google.com
まずは、アルバムを作成するスクリプト として、create_album.shというスクリプト を作りました。
CLIENT_ID =" yourClientID.apps.googleusercontent.com "
CLIENT_SECRET =" yourClientSecret "
REFRESH_TOKEN =" RefreshTokenAcquiredEarlier "
curl -s --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 > token.JSON
ACCESS_TOKEN =`cat token.JSON | jq -r ' .access_token ' `
echo " Access token is " ${ACCESS_TOKEN}
ALBUMNAME =" NewAlbum "
ENDPOINT =" https://photoslibrary.googleapis.com/v1/albums "
ALBUMID =$( curl -s -X POST -H " Authorization: Bearer $ACCESS_TOKEN " \
-H " Content-type: application/json " \
-d ' { "album": { "title":"${ALBUMNAME}" } } ' ${ENDPOINT})
echo ${ALBUMID}
echo ${ALBUMID} >> albumid.txt
これを実行します。
./create_album.sh
すると、json 形式でアルバム名とアルバムIDが表示されます。
念のため、albumid.txtというファイルにも追記していくことにしました。
出力例
{ "id ": "NewAlbumIDisLongLongString ",
"title ": "${ALBUMNAME} ",
"productUrl ": "https://photos.google.com/lr/album/NewAlbumURLisAlsoLongLongString ",
"isWriteable ": true }
あらら、なぜかアルバムタイトルが${ALBUMNAME}になっちゃった。
でも、これはGoogle フォトアプリやサイト上で直せます。
大事なのはidです。
ちなみに、ここは余談ですが、既存のアルバムIDとアルバム名を取得するスクリプト get_albumid.shも作ってしまいました。
CLIENT_ID =" yourClientID.apps.googleusercontent.com "
CLIENT_SECRET =" yourClientSecret "
REFRESH_TOKEN =" RefreshTokenAcquiredEarlier "
curl -s --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 > token.JSON
ACCESS_TOKEN =`cat token.JSON | jq -r ' .access_token ' `
echo " Access token is " ${ACCESS_TOKEN}
ENDPOINT =" https://photoslibrary.googleapis.com/v1/albums?pageSize=50 "
ALBUMLIST =$( curl -s -H " Authorization: Bearer $ACCESS_TOKEN " ${ENDPOINT})
echo ${ALBUMLIST} | jq -c ' .albums[] | [.id, .title] '
jqを使ってアルバムIDとアルバム名を1行に出力するので、grep を使って目的のアルバムIDを取得できます。
が、先ほども書きましたが、Photos Library API でアップロードできるアルバム先は、Photos Library API で作成したアルバムだけです。
あんまり役にたたないですが、一応・・・。
アルバム等のリスト取得の解説
developers.google.com
さて、新たなPhotos Library API は、アルバムに写真をアップロードするのに、2段階の手順を踏みます。
写真をアップロードしupload tokenを取得
upload tokenを使ってアップロード先のアルバムを指定
アップロード先のURLはhttps://photoslibrary.googleapis.com/v1/uploads になり、ここに必要なデータをポストします。
いままでのPicasa API はURLに認証情報などを埋め込んでいましたが、今回からはヘッダーに入れるようになっています。
developers.google.com
curl を使ってfile.JPGという写真をアップロードするなら次のようなイメージになります。
curl -s -X POST \
-H " Authorization: Bearer yourAccessToken " \
-H " Content-type: application/octet-stream " \
-H " X-Goog-Upload-File-Name: $( basename file.JPG ) " \
-H " X-Goog-Upload-Protocol: raw " \
--upload-file " file.JPG " \
https://photoslibrary.googleapis.com/v1/uploads
アップロードに成功すると、upload tokenが返ってきます。そのupload tokenとアルバムIDを指定して、アルバムに移動させます。
移動を指示するURLは"https://photoslibrary.googleapis.com/v1/mediaItems:batchCreate "です。
curl -H " Content-type: application/json " \
-H " Authorization: Bearer yourAccessToken " \
-d ' {"albumId": " ' NewAlbumIDisLongLongString' ", "newMediaItems":[{"simpleMediaItem":{"uploadToken": " ' UploadTokenIsAlsoLongLongStoring' "}}]} ' \
-X POST " https://photoslibrary.googleapis.com/v1/mediaItems:batchCreate "
新しく生まれ変わったupload_images_in_dir.shは次の通りです。
これは、指定したディレクト リ上にある全ての.JPG/.jpg/.bmp /.png をGoogle Photosにアップロードします。
CLIENT_ID =" yourClientID.apps.googleusercontent.com "
CLIENT_SECRET =" yourClientSecret "
REFRESH_TOKEN =" RefreshTokenAcquiredEarlier "
ALBUM_ID =" NewAlbumIDisLongLongString "
curl -s --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 > token.JSON
ACCESS_TOKEN =`cat token.JSON | jq -r ' .access_token ' `
ENDPOINT =" https://photoslibrary.googleapis.com/v1/uploads "
MEDIAITEMS =" https://photoslibrary.googleapis.com/v1/mediaItems:batchCreate "
DIR =" ./ "
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 ";;
*\.JPG | *\.jpg) TYPE =" image/jpeg ";;
*\.png) TYPE =" image/png ";;
*) TYPE =" UNKNOWN ";;
esac
if [ " ${TYPE} " = "UNKNOWN" ] ; then
continue ;
fi
echo " Uploading to Google Photos " ${FILE}
UPLOAD_TOKEN =$( curl -s -X POST \
-H " Authorization: Bearer ${ACCESS_TOKEN} " \
-H " Content-type: application/octet-stream " \
-H " X-Goog-Upload-File-Name: $( basename $FILE) " \
-H " X-Goog-Upload-Protocol: raw " \
--upload-file " ${FILE} " \
${ENDPOINT})
echo " Move Alubums " ${FILE}
curl -H " Content-type: application/json " \
-H " Authorization: Bearer ${ACCESS_TOKEN} " \
-d ' {"albumId": " ' ${ALBUM_ID} ' ", "newMediaItems":[{"simpleMediaItem":{"uploadToken": " ' ${UPLOAD_TOKEN} ' "}}]} ' \
-s -o /dev/null \
-X POST " ${MEDIAITEMS} "
sleep 1
fi
done
IFS =$IFS_BAK
あ、もちろん、"yourClientID.apps.googleusercontent.com"、"yourClientSecret"、"RefreshTokenAcquiredEarlier"、"NewAlbumIDisLongLongString"などは、あなたがお持ちの認証情報に書き換えないと動きませんよ。