pslaboが試したことの記録

はてなダイヤリーからはてなブログに引っ越してきました

この日記は現在実行中の減量記録を含む個人的なメモとして始めましたが、最近はコンピュータやガジェット、ハック、セキュリティネタのほうがメインになっております。

はてなダイヤリー時代はカテゴリ分けが適当だったのですが、これはそのうち直します。


日次バッチ処理の集計データを Google Spreadsheet に対して投げ込むインタフェースとして Google Form を使う。

日次バッチ処理で処理したデータを表計算ソフトで処理したいケースはよくあると思います。データの集計分析方法が決まっていないケースでは特にありがち。そしてそのようなケースでは Excel がそこそこお手軽です。

しかし Linux 上で実行する日次バッチ処理の結果を収集するには、Excel はイマイチ親和性がよくないです。

そういうケースでは Google Drive の Form と Spreadsheet を組み合わせれば、HTTP リクエストで Form に投げ込んだデータを自動的に Spreadsheet に記録する仕組みがカンタンにつくれます。


本来は Google Form はアンケート収集用のインタフェースであり、そのデータストアとして Spreadsheet と連携できるのですが、この機能を Spreadsheet への流し込みのインタフェースとして利用するわけです。


Google Form の作り方や、Spreadsheet との連携については以下のような記事を読みつつ手を動かしてみるのがよいです。なお、以前は Google Form を作成すると自動的に Spreadsheet 連携が作成されていましたが、2015/12 時点では Spreadsheet 連携はデフォルトで off のようですから、これは別途有効化する必要があります。
http://ascii.jp/elem/000/000/888/888853/

実際に Form と Spreadsheet が連携できるようになったら、form や input タグを調べて、投入用のURLやフィールドの name を確認します。

私のところでは以下のようなスクリプトを使ってこの作業を省力化しています。

#!/bin/sh
#
# strip_googleform.sh
#
# 指定された Google Form をダウンロードして、
# input タグの name を探す処理。
#
# また、Form の URL を、Form の送信用に変換して表示する。

curl "$1" |
        sed "s/>/>\n/g" |
        grep -e entry -e label |
        sed 's/name="entry\.[0-9]*"/\x1b[1;31;1m&\x1b[0m/gi ; s/label="\([^\s]*\)" /\x1b[1;32;1m&\x1b[0m/gi'

echo ""
echo "action=${1%/*}/formResponse"

これを実行すると、以下のような出力が得られますので、label を確認しつつ、対応する name を控えておきます。
f:id:pslabo:20151225184259p:plain

※2016/06時点ではGoogle Formのページソースが変わっているので、ブラウザのデベロッパーツールとかでリクエストの内容を追いかけるほうが早いかもしれません。



パラメータの name や登録用のURLが確認できたら、
今度は集計データを Form に投げ込むスクリプトを用意します。

以下はサンプルのスクリプトです。
スクリプト内にURLやパラメータ名を適切に記述するだけで、
標準入力から渡されたデータを Form に投げこんでくれます。

#!/bin/sh

# Google Form 経由で Google Spreadsheet に投げ込む処理のサンプル



####################################################################
# Google Form 関連設定
####################################################################

####################################################################
# Form にデータを投げ込むためのURL
#
# Google Form は URL の一番末尾の改装部分の文字列によって
# 動作モードがフォーム編集用、フォーム入力用、入力データ送信先と
# 切り替わる。
# よって、編集用ページまたは入力用ページのURLを確認しつつ、
# これを「送信先用」の formResponse に変えれば、GET メソッドの
# action の送付先として利用できる。
#
# 編集ページ:  https://docs.google.com/forms/d/[__FORM_ID__]/edit
# 入力ページ:  https://docs.google.com/forms/d/[__FORM_ID__]/viewform
# 送信先ページ: https://docs.google.com/forms/d/[__FORM_ID__]/formResponse

URL_BASE="https://docs.google.com/forms/d/[__FORM_ID__]/formResponse"


####################################################################
# クエリー名を Google Form 内の <input> の name と紐づけるための定義
#
# entry.515499214 などの文字列をそのまま使うと可読性が下がるので、
# それを回避することを意図している。

param_fqdn=entry.84966524
param_datetime=entry.1988875616
param_count=entry.85905326

# 初期設定箇所終了
####################################################################


EXEC=""
DRYRUN=""
EXEC_CMD=""

main() {

	get_args "$@" || return $?


	# 実行コマンドが不定の場合は終了
	if [ "${EXEC_CMD}" == "" ]; then
		exit 1
	fi


	#######################################################
	# データ形式が "URL 日時 件数" という情報を標準入力から
	# 受け取って、それを1件づつ Google Form に投げ込む処理。
	while read fqdn datetime count ; do


		# EXEC_CMD=bash なら wget が実行されるし、
		# EXEC_CMD=cat なら 実行すべきコマンドをそのまま標準出力に吐く

		${EXEC_CMD} <<-EOF
		wget -q -O /dev/null --no-check-certificate "${URL_BASE}?${param_fqdn}=${fqdn}&${param_datetime}=${datetime}&${param_count}=${count}"
		EOF

	done
}


show_usage() {

cat<<EOF
	--exec )
		処理を実行するかどうか

	--dryrun )
		動作テストモード

EOF
}



get_args() {
	if [ $# -eq 0 ]; then
		show_usage
		return 1
	fi

	for OPT in "$@"
	do
		case "$1" in
			--exec )
			EXEC_CMD="bash"
			shift
			;;

			--dryrun )
			EXEC_CMD="cat"
			shift
			;;

			--)
			shift
			break
			;;
		esac
	done
}

main "$@"