Advent Calendar in 信州松本(だけじゃなくてもいいよ)の18日目を担当しているthinkAmiです。
17日目はKenさんの「Highchartsを使って温度計を作ってみる」でした。
サーバーを運用していると温度・湿度は非常に気になるところなので、今すぐにでもこれを使ってサーバーの温度監視を分かりやすくしたいなぁと感じました*1。グラフ重要ですね。
さて、先月末、GoogleドライブにてWebサイト公開ができるようになったとのアナウンスがありました。
参考:Announcing Google Drive Site Publishing - Google Apps Developer Blog
そこで今回は、GoogleドライブにてWebサイト公開を行い、アルクマを追いかけてみます。
GoogleドライブでWebサイト公開するときの制限
- HTMLやCSS、画像ファイルなどは問題なく動作するものの、JavaScriptが動作しない
- URLが残念
この中のJavaScriptが動作しないというのが一番大きい制限であり、今回も使用するGoogleマップの形式はStaticMapsになりそうです。
全体の構成
アルクマのスケジュールは日々変更されるため、手動でHTMLファイルを作成・Googleドライブへアップロードするのは大きな手間です。
そこで、GoogleDriveAPIを用いてGoogleドライブ内にHTMLファイルを自動的に作成するようにします。
ただ、その場合はOAuthやDriveAPIの操作が必要になるため、その辺を簡略化できるPythonのライブラリを使用します。
参考:https://developers.google.com/api-client-library/python/reference/supported_apis
なお、アルクマのスケジュールデータについては、9日目で作成したGoogleカレンダーからデータを持ってくることにします。
本当はPythonのlxmlで解析する方が楽なのですが、GoogleAppEngineからGoogleカレンダーデータを扱いたかったため、あえてこの形式にしています。
そのため、構成図は以下の通りとなります。
Googleドライブ内の構成
www以下をWeb公開するため、wwwの共有設定で、「リンクを知っている全員が閲覧できます。」を選択しておきます。
また、cssファイルやpngファイルは、あらかじめGoogleドライブへと保存しておきます。今回、map.cssとshinanogold.pngは9日目のものを流用します。
事前準備
今回はGoogleDriveAPIとGoogleCalendarAPIを使うため、APIConsoleから両方を有効化します。
なお、似た名前にGoogleDriveSDKがありますが、APIとは別物なので、有効化は不要です。
また、APIを利用する場合、OAuthにて認証を行うため、9日目で使った「Client ID for web applications」の「Redirect URLs」に設定を行います。
今回は開発環境・本番環境の2箇所で利用するため、以下のように設定しました(URLが複数ある場合は、一行に1URLを指定します)。
http://arukumap.appspot.com/oauth2callback
http://localhost:8080/oauth2callback
なお、GoogleAppEngine用のライブラリを使う関係上、コールバックのURLは「oauth2callback」で固定となります。
app.yamlの設定
handlersに以下の設定を行います。
なお、認証後にパラメータを持ってリダイレクトされてくるため、HTML作成のハンドラは末尾を「.*」としておきます。
- url: /oauth2callback script: googledrivehandler.app login: admin - url: /cron/googledrive.* script: googledrivehandler.app login: admin
OAuth用のOAuth2Decorator設定
client_id、client_secret、scopeを指定します。
今回はGoogleドライブとGoogleカレンダーへとOAuth認証後にアクセスするため、両方のOAuth用の設定をリストとして設定しておきます。
['https://www.googleapis.com/auth/drive', 'https://www.googleapis.com/auth/calendar']
参考:Google Drive SDK — Google Developers
GoogleAppEngineでファイルを作成する
GoogleAppEngine用のライブラリにある、「apiclient.http.MediaInMemoryUpload」を使用します。
ファイルの内容はMediaInMemoryUploadの第一引数に、ファイルのメタ情報はJSON形式にてそれぞれ指定します。
メタ情報のparentsのidにはフォルダのIDを指定しますが、フォルダのIDはブラウザのアドレスに表示される値を指定します。
media_body = MediaInMemoryUpload(arukuma.create_html(), mimetype='text/plain', resumable=True) body = { 'title': HTML_FILE_NAME, 'description': 'A test document', 'mimeType': 'text/html', 'fileExtension': 'html', 'parents': [ { "id": apiKeys['folder_id'], } ], } drive_service.files().insert(body=body, media_body=media_body).execute()
GoogleDrive内のファイルを検索する
以下のような感じで、files().list()の引数qにファイル名「index.html」を指定し、対象のファイルIDを取得しています。
なお、デフォルトのままだとゴミ箱も検索対象のため、「trashed = False」とします。
query = 'title = "index.html" and trashed = False' response = drive_service.files().list(q=query).execute()
参考:Google Drive SDK — Google Developers
ソースコード
GitHubへ18日目としてコミットしています。今回のメインは「googledrivehandler.py」ファイルです。
thinkAmi/ac2012matsumoto · GitHub
なお、google-api-python-clientライブラリも含まれていますので、ご注意ください。ライブラリのファイルやディレクトリは以下のものです。
- apiclient
- httplib2
- oauth2client
- uritemplate
- gflags.py
- gflags_validators.py
お願いなど
まとめ
3回にわたってGoogleのサービスでアルクマスケジュールを扱ってみました。実用的かどうかは分かりませんが、GoogleのAPIに色々とさわったため、勉強になりました。
GoogleでWebサイトを公開する方法しては、他にはGoogleサイトがあります。こちらはよく紹介されているため、他のサイトをご確認ください。
次は
Advent Calendar in 信州松本(だけじゃなくてもいいよ)、明日はToro_Unitさんです。よろしくお願いします。
*1:先日も温度のアラートが出ました