WebOS Goodies

WebOS の未来を模索する、ゲームプログラマあがりの Web 開発者のブログ。

WebOS Goodies へようこそ! WebOS はインターネットの未来形。あらゆる Web サイトが繋がり、共有し、協力して創り上げる、ひとつの巨大な情報システムです。そこでは、あらゆる情報がネットワーク上に蓄積され、我々はいつでも、どこからでも、多彩なデバイスを使ってそれらにアクセスできます。 WebOS Goodies は、さまざまな情報提供やツール開発を通して、そんな世界の実現に少しでも貢献するべく活動していきます。
Subscribe       

ActiveResource で Google Spreadsheets Data API にアクセスする

先日の記事にも書きましたが、 WebOS Goodies ではコメントなどの管理に Google Spreadsheets を利用しています。それを実現するため、 Google Spreadsheet Data API にアクセスする ActiveResource のモデルクラスを作りましたので、本日はそれを公開します。

本当はきちんと gem にしようかとも思ったのですが、じゅうぶんな時間がとれそうにないので、とりあえずソースコードだけ公開です。 Rails アプリケーションはもちろん、単体で利用することも可能なので、いろいろ応用できると思います。このライブラリで、皆さんも Google Spreadsheets をデータベース代わりに活用しましょう!

ソースコード

まずはソースコードです。いつもどおりコードなにがしに投稿してあります。

ダウンロードはこちらから。

ares_google_spreadsheets.rb

このソースを、ライブラリのロードパスが通っている場所に "ares_google_spreadsheets.rb" の名前で保存してください。

下準備

それでは、使い方を説明していきます。以下は ActiveResource の基礎知識があると仮定して書いているので、はじめて使う方は README の日本語訳などをご参照ください。ちなみに、翻訳されたのは OpenSocial Expert のよういちろうさんですね。素晴らしい。

当たり前ですが、このライブラリの動作には ActiveResource と ActiveSupport が必要です。もしインストールされていなければ、 RubyGems などを使ってインストールしておいてください。

そして、ライブラリを使うスクリプトの先頭で require して、(プライベートなドキュメントにアクセスする時は) Google アカウントの E-mail アドレスとパスワードを指定すれば準備完了です。 Google Apps のアカウントも使えます。

require 'ares_google_spreadsheets'
# 公開ドキュメントにアクセスするだけなら以下は不要
GoogleSpreadsheets::Base.user     = 'E-Mailアドレス'
GoogleSpreadsheets::Base.password = 'パスワード'

Rails で使う時は、上記のコードを environment.rb の最後あたりに書けば良いでしょう。

ドキュメントの列挙

まずは、ユーザーが所有しているスプレッドシート・ドキュメントの列挙ができる Spreadsheet metafeed にアクセスしてみましょう。対応するモデルクラスは GoogleSpreadsheets::Spreadsheet です。 E-Mail アドレスとパスワードを指定していないと使えないので注意してください。

それでは、使ってみましょう。以下のようにすると自分の持っているすべてのファイルが取得できます。

docs = GoogleSpreadsheets::Spreadsheet.find(:all)

docs に格納されるオブジェクトにはフィードの値をほぼそのままぶち込んでいますが(^^;)、通常は以下のフィールドを覚えておけばじゅうぶんでしょう。

フィールド名内容
id ドキュメントID
title ファイル名
author.name 所有者の名前
author.email 所有者のメールアドレス
updated 最終更新日時(Time に変換されています)

上記のうち、 id フィールドがいわゆるプライマリ・キーになります。この値は Google Spreadsheets の編集ページ URL に含まれる key パラメータと同じです。例えば編集ページの URL が以下のようになっているとき、

http://spreadsheets.google.com/ccc?key=abcdefg

"abcdefg" がこのドキュメントの ID になります。従って、以下のコードでこのドキュメントの情報を単独で取得できます。

doc = GoogleSpreadsheets::Spreadsheet.find('abcdefg')

このあたりの感覚は ActiveRecord と同じですね。さらに、クエリーパラメータで検索条件が指定できます。例えば以下はタイトルに "WebOS Goodies" が含まれるドキュメントを検索します。

docs = GoogleSpreadsheets::Spreadsheet.find(
  :all, :params => { :title => 'WebOS Goodies' })

利用できるクエリーパラメータに関してはGoogle Spreadsheets Data API のリファレンスをご参照ください。

ワークシートの操作

次は、 Worksheet-based feed に対応する Worksheet モデルを使ってみましょう。このフィードを使うと、ワークシートの作成・削除、タイトルや行・列数の変更が行えます。

まず、ドキュメントに含まれるシートをすべて取得するには、以下のようにします。

sheets = GoogleSpreadsheets::Worksheet.find(:all, :params => {
  :document_id => 'ドキュメントID',
  :visibility  => 'private',
  :projection  => 'full'
})

ドキュメントIDは Spreadsheet クラスの id と同じもので、対象のドキュメントを指定します。残りの visibility, projection の意味は、後ほどまとめてご紹介します。また、こちらもクエリーパラメータで検索条件を指定できますので、前述のリファレンスをご参照ください。

取得できるフィールドのうち、通常使うであろうものは以下のとおりです。

フィールド名内容
id ワークシートID
title ワークシートのタイトル
rowCount 行数
colCount 列数
updated 最終更新日時

上記のうち、 title, rowCount, colCount は変更可能です。例えば、先ほど取得した sheets の先頭の要素のタイトルを "sheet1" にするには、以下のようにします。

sheet[0].title = "sheet1"
sheet[0].save

シートの削除も可能ですが、クラスメソッドの Worksheet.delete は使えません。Worksheet#destroy を使ってください。

sheet[0].destroy

新しいシートを追加するには、以下のようにします。 title などのフィールド名はシンボルではなく文字列で指定してください。

new_sheet = GoogleSpreadsheets::Worksheet.new(
  :document_id => 'ドキュメントID',
  :visibility  => 'private',
  :projection  => 'full'
  'title'      => 'タイトル',
  'rowCount'   => 行数,
  'colCount'   => 列数)
new_sheet.save
new_sheet.id # -> 追加したシートの ID が取得できます

当然ですが、認証したユーザーに編集権限がなければ更新系の処理は失敗するので、ご注意ください。

セルの内容の操作

List-based feed に対応する List モデルを使うと、行単位でセルの内容を取得・操作できます。 List-based feed では、シートの 1 行目をカラム名として扱いますので、 Web 上であらかじめ入力しておいてください。 API のみで行うには、後述の方法で Cell-based feed を直接呼び出す必要があります。

それでは、まずはすべての行の取得から。以下で実現できます。

rows = GoogleSpreadsheets::List.find(:all, :params => {
  :document_id  => 'ドキュメントID',
  :worksheet_id => 'ワークシートID',
  :visibility   => 'private',
  :projection   => 'full'
})

もはや説明の必要はないでしょう。各カラムの内容は "gsx_カラム名" というフィールドに格納されますので、例えば 1 行目(スプレッドシート上では 2 行目)の "col1" というカラムの内容は以下で取得できます。

data = rows[0].gsx_col1

もし日本語などのシンボルとして使えないカラム名の場合は、以下で取得できます。

data = rows[0].attributes['gsx_日本語カラム名']

更新や削除は Worksheet と同じなので省略。新しい行の追加もほぼ同様で、例えば "col1", "col2" という 2 つのカラムを持つ行の追加は以下のようにします。

new_row = GoogleSpreadsheets::List.new(
  :document_id  => 'ドキュメントID',
  :worksheet_id => 'ワークシートID',
  :visibility   => 'private',
  :projection   => 'full',
  'gsx_col1'    => 'col1の内容',
  'gsx_col2'    => 'col2の内容)
new_row.save
new_row.id # -> 追加された行の ID が取得できます

visibility, projection について

find メソッドなどに指定する visibility, projection パラメータの意味を書いていなかったので、ここで少し解説しておきます。

まず visibility は簡単で、ユーザー認証を行って非公開ドキュメントのデータを扱う場合は "private" 、公開ドキュメントを扱う場合は "public" を指定します。 "public" を指定した場合は更新・削除などの処理は行えないので注意してください。

projection は計算式をそのように扱うのかの指定です。 "full", "values", "basic" の 3 つがありますが、このうち "basic" は Google Spreadsheets 特有の情報が取得できないので、まず使いません。 "full", "values" の違いは計算式をどう扱うかで、 "full" の場合は計算式がそのまま取得でき、 "values" なら計算結果が取得できます。更新系の機能を使う時は "full" が必須なので注意してください。

その他の Tips

Cell-based feed の利用

Cell-based feed を使うと、行・列の番号を直接指定して値の取得や更新が行えます。このライブラリでは Cell-based feed を直接サポートしていませんが、 connection クラスのメソッドを使えば、比較的簡単にリクエストが行えます。例えば、以下の一行でワークシートの全セルの内容が取得できます。

GoogleSpreadsheets::Base.connection.get(
  '/feeds/cells/ドキュメントID/ワークシートID/private/full')

結果は Cell-based feed の XML の Entry タグ以下の部分を、 Ruby のハッシュや配列に変換した形式で返ります。詳しい Cell-based feed の使い方に関しては、 Developers Guide をご参照ください。

find などのパラメータ指定を省略する

find メソッドなどに visibility, projection などをいちいち指定するのは面倒だと思うかもしれません。そんなときは、サブクラスを作って、そこで prefix を上書きしてください。例えば Worksheet なら以下のようになります。

class MyWorksheet < GoogleSpreadsheets::Worksheet
  self.prefix = '/ドキュメントID/visibility/projection/'
end

こうしておけば、 MyWorksheet.find を読んだ際には常に指定したドキュメントID, visibility, projection が使われます。同様に List クラスは以下のようになります。

class MyWorksheet < GoogleSpreadsheets::Worksheet
  self.prefix = '/ドキュメントID/ワークシートID/visibility/projection/'
end

パラメータの一部のみを固定することも可能です。その際の書き方は・・・ ActiveResource の prefix の指定方法を勉強してください。すいません(^^ゞ

デバッグの方法

使ってみてどうもうまく動かない、というときは、ライブラリを require した直後に以下のコードを挿入してください。

class GoogleSpreadsheets::Connection
  DEBUG = true
end

こうすると、標準エラー出力にリクエストとレスポンスの内容がヘッダ込みで出力されます。とくに Google Spreadsheets 側でエラーが出ている場合は、レスポンスにけっこう詳細なエラーメッセージが含まれているので、とても役に立ちます。

ご質問・ご要望・バグ報告などは Google グループへ

このライブラリに関するご質問・ご要望・バグ報告には、以下の Google グループをご利用ください。ライブラリを更新した際もこのグループで通知しますので、実際にご利用の際は登録をお勧めします。 Google アカウントがあれば Web 上から投稿できますし、アカウントがなくてもメールで投稿できますので、お気軽にどうぞ。

Google グループ Beta
WebOS Goodiesに参加
メール アドレス:

以上、本日は ActiveResource を使って Google Spreadsheets の API を利用するライブラリをご紹介しました。 Google Spreadsheets は数ある Web API のなかで最も使いでのあるもののひとつですので、いろいろと応用できるでしょう。また、他の GData API のモデルを作成するための雛形としても使えると思います。ぜひご活用ください!

関連記事

この記事にコメントする

Recommendations
Books
「Closure Library」の入門書です。
詳しくはこちらの記事をどうぞ!
Categories
Recent Articles