2013年4月18日木曜日

PythonでGoogleドライブのSpreadsheet

Windowsのpythonを使って、GoogleドライブのSpreadsheetをテキストデータベースとしてアクセスしてみました。Web上に情報がたくさんあるのですが、いくつかつまづいたので、覚え書き。

まず、pythonで利用するモジュールですが、
http://code.google.com/p/gdata-python-client/
からダウンロードします。左側のフレームにあるDownloadsから、gdata-2.0.17.zipをダウンロードしました。
展開して、Windowsのコマンドプロンプトを起動します。
展開してできたフォルダに移動して、インストールを実行します。

> python setup.py install

使用するモジュールは、gdata.spreadsheet.text_dbです。
これを用いると、スプレッドシートの一行目を要素名(Field名)の記述として、それ以降の各行を1つずつのレコードとしてアクセスすることができます。

import gdata.spereadsheet.text_db

としたらOKです。
googleドライブにアクセスするのには、アカウント名とパスワードが必要です。とりあえずコンソールで動かすのでパスワードをgetpassモジュールで取得します。このモジュールを利用すると、エコーバックなしに、文字を受け取ることができるようです。

import getpass
pw = getpass.getpass('password >')

pwに入力文字列が入ります。
さて、emailにgmailアドレスをいれて、アクセスしましょう。

client = gdata.spreadsheet.text_db.DatabaseClient(username=email, password=pw)

つぎにスプレッドシートを選択します。
dblist = client.GetDatabases(name='sheetname')
さて、sheetnameの名前のスプレッドシートがdblistに入ります。nameで指定すると一つとは限りません。目的のスプレッドシートのみを指定できるわけではないので、注意が必要です。スプレッドシートのkeyで指定する方法であれば一つに決まるようですが、keyを知らないといけません。

name='sheetname'で選ばれる最初のスプレッドシートはdblist[0]です。
そのkeyは、dblist[0].spreadsheet_keyに入っています。

さて、スプレッドシートを選んだら、次はその中のシートを選びます。text_dbでは、それがtableになります。

tablelist = db.GetTables(name='sheet1')
こちらもname='sheet1'で選ばれるのは一つとは限らないので注意が必要ですね。とりあえず、最初のシートを開きましょう。似たような名前の複数のシートを作らなければ大丈夫でしょう。
table = tablelist[0]
そのテーブルに含まれるField名を得るには、

table.LookupFields()

を呼びます。すると、table.fieldsにリストされます。

さてレコードを順番にアクセスしていくには、table.GetRecords()でレコードのリストを得ます。

for rec in table.GetRecords(1, 100):
    #write process for each record.
    pass

で1番から100番までのレコードを順に処理していけます。

特定の条件のレコードを得たいなら、table.FindRecords()を使うことができます。たとえば、nameというFieldに'net walker'が入っているレコードを得たければ、recs = table.FindRecords('name == "net walker"')
とするとよいでしょう。

特定の行のレコードを得体なら、table.GetRecord()を使います。10行目のレコードなら、
rec = table.getRecord(row_number=10)
でよいでしょう。ここで、10行目といいますが、Field行が0行目として考えています。

さて、最初利用してみたとき、このレコードがうまく取得できませんでした。大切なのは、第1カラム(最初のField)が空のレコード(行)を作らないことのようです。空があると、レコードの終わりと認識するようですね。

レコード(rec)内の各フィールド内の文字は、contentという辞書として保存されています。たとえば、'name'というフィールドに入っている文字を得たければ、rec.content['name']として得られます。python2.7で扱うときは、unicodeに変換して利用するとよいでしょう。

str = unicode(rec.content['name'])

とすると、いろいろと処理が便利になると思います。

さて、text_dbモジュールのいろいろは、"gdata text_db"で検索をかけてみると見つかると思います。制限がありますが、割り切って使うと便利なこともあるかもしれません。

○スプレッドシートやテーブルを選択するときに、名前で引くと意図したもの一つだけが選択されるわけではない。
○第1カラムが空の行(レコード)は作らない
○そうそう、Field名は、半角英数小文字を使うとよいそうです。
○テーブル(ファイル内のシート)を削除するときは、シートがすべて無くならないようにする。

以上、つまづいたので、覚え書きしておきます。

2013年4月17日水曜日

MacでEPSファイルを作る

最近また必要になったので、メモとして残しておきます。
私は普段Windowsを使っているのですが、Mac OSを使っている人からEPSファイルを作るのはどうしたらよいか聞かれた。ファイルに印刷することで図をPDFファイルに出力することはできたようなのですが、LaTeXに張り込むときのBoundingBoxの調整をするのに、EPSファイルでやりたいということらしい。

PDFファイルをEPSファイルに変換するツールxpdfを使えば解決するようです。Googleでxpdf-tools-3.dmgを検索するとダウンロードページが見つかります。通常通りにパッケージをインストールするとpdftopsという変換ツールが使えるようになります。

MacOS10.5.8で試したときには/opt/local/binの中にツールがインストールされました。ターミナルから、

$ pdftops -eps filename.pdf

とすると変換できます。しかし、pdfファイルをアイコンにドロップするとEPSファイルに変換されるようなツールがほしいようです。pdftopsというツールにドロップされたファイルの処理機能を追加するだけなので、Apple Scriptで書いてみたのが以下のもの。スクリプトエディタで書いてコンパイル、保存すれば完成です。

on open itemList
    tell application "Finder"
        repeat with aItem in itemList
            do shell script "/opt/local/bin/pdftops -eps " & POSIX path of aItem
        end repeat
    end tell
end open

さて、できあがったアイコンにEPSファイルを投げ込めば、pdftopsが起動して、変換されます。複数ファイルを投げ込めば、一つ一つ変換処理します。Apple Scriptも便利ですね。自分は使わないので分かりませんが、ドックに登録しておけば、作業も楽々でしょうか。最近、Mac OS 10.8の環境に移行したということで、同じ質問を受け、同じ作業が必要になったので覚え書きしときます。

AppleスクリプトはSystem 7の頃からあるらしいですね。私は、MacOS8.6時代にちょっと使うことがありましたが、懐かしい感じです。当時はHyper Cardなんて楽しいものもありましたね。