2011年3月26日

Python でコマンドラインオプションを扱う方法

コマンドライン引数の扱い方にはいくつかの方法がありますのでメモしておきます。 もちろん sys.argv を自前で解析すれば何とでもなりますが、その解析を頑張りたくはありませんね、という動機です。

  • 標準ライブラリ
  • フレームワークに特有の方法 - Django, Twisted, Tornado
  • 独立したライブラリ - gflags

2011年3月25日

東北関東大震災の記録

個人的な紙のノートに記録するような内容ですが、毎日のように余震が続いていることを記録しておきたいな、と思ったのでメモしておきます。 震災から2週間が経とうとしていますが、未だに余震が続くことに驚きを隠せません。地震酔い?と感じることもしばしば。 輪番停電は引き続き断続的に実施されていますが、都内の生活は少し落ち着いてきた印象です。 「普通」の日常を取り戻すべく社会が動いている、そんな気がします。 それにしても、社会インフラを支えてくれている人には脱帽です。

世間的には福島にある原子力発電所の放射能に関する話題が大きなトピックでした。 金町の浄水場で基準値を大幅に超えるヨウ素が検出され、「水道水を飲めないの?」という不安が広がりました。 煮沸すれば... と思ったら、余計に悪いそうです。 成人にとっては許容範囲らしいですが、乳幼児には問題があるそうで、またしても飲料水の「買い占め」騒動。 情報の断片だけが急速に広がりますので、似たようなことは今後も続きそうです。 立場に沿った情報を発信/受信できる仕組みがあると良いのですが。

復興に向けての動きも形になり始め、グルーポンのマッチングギフトが2億円に達したそうです。 企業や著名人からの寄付も続々と発表されており、日本だけでなく、外国からもたくさんの援助があります。 サッカーの欧州各国リーグからも応援メッセージがありました。 わざわざユニフォームの背番号をカタカナ表記にして試合に臨んでくれたバレンシアにはとても和みました。 日本代表と J リーグ選抜のチャリティーマッチも決まりました。 また、中止されていた J リーグも、4月下旬からの再開が決まりました。 電力消費を抑えるためにデイゲーム主体になりますが、それでも少しずつ「普通」が戻ってきています。

そんな感じのつらつらとした記録。なお、「東北関東大震災」と呼称は赤十字社より。

3/18 Fri.

  • 08:29 - 曙橋の下のガソリンスタンドから駅前まで行列ができてた。歩行者は危ないかも... と思ってたら、市ヶ谷と飯田橋の中間にあるガソリンスタンドには長蛇の列で、1車線を封鎖してた。歩行者だけでなく、車両も危ない。
  • 08:43 - 自転車のライトが盗まれてた、かも。懐中電灯の替わりだと思うけど、書置きくらいは用意して欲しい。。
  • 08:52 - 素晴らしいと思う。 "販売再開から一ヶ月間(4月15日まで)の売上から10%を東北関東大震災の義援金として日本赤十字社に寄付させていただきます。" / 東北関東大震災の復興支援プロジェクト 経過ご報告 - http://bit.ly/elI8ry
  • 08:59 - "keep sending positive messages" / MiChi Releases New Track "ONE" As Support Song http://t.co/fggocqL via @jpopasia
  • 09:57 - KML や Atom などのフィードもあるのか。 #earthquake / Latest Earthquakes: Feeds & Data - http://earthquake.usgs.gov/earthquakes/catalogs/index.php
  • 11:33 - RT @pref_iwate: 地震発生から1週間が経過する本日18日(金)14時46分、多くの尊い命をなくされた方々のご冥福を祈り、哀悼の意を表すため、1分間の黙祷を捧げます。皆さんも一緒に黙祷しましょう。#0311jisin
  • 14:56 - one week from #earthquake / Japan: Continuing crisis http://t.co/lH8xKai Japan: Hopes fade for finding more survivors http://t.co/67EivkO
  • 15:12 - 卒業式が中止された学校も多いみたいだけど、アルバイトでも卒業シーズンなんだなぁ、としみじみ。いろいろな意味で感慨深い季節になる人も多そう。
  • 17:12 - 新宿区や千代田区は震度1だけど、結構揺れた印象。 / "18日17時01分頃地震がありました。震源地は茨城県沖 ... マグニチュードは5.4" - http://www.jma.go.jp/jp/quake/00000000091.html
  • 20:57 - コンビニの宣伝文句がヒドい。。 http://t.co/WlbKFG3
  • この危機的状況にブロガーとして出来る事は何か - Life is beautiful
    "特に被災地以外に住んでいる人は、(1)できるだけ節電をする、(2)生活必需品の買い占めはしない、(3)やたらと政府や東電の批判をして回りの人の不信感・不安感を高めない、ことが大切。"
  • 第3回 浜松ハッカソン: 2011.03.19(土) - ATNDの新着イベント
    "今、起きている災害の支援に、あるいは、今後起こるであろう災害の支援に役に立つ、ソフトウェアやハードウェアについて一緒に考えてみませんか?"

3/19 Sat.

3/20 Sun.

3/21 Mon.

3/22 Tue.

3/23 Wed.

3/24 Thu.


関連:

2011年3月24日

Apache Shindig / Java を使ってみる

Apache Shindig を使えるようにしてみます。 Shindig に関しては Web サイトのトップページに簡単な説明があります。

Apache Shindig is an OpenSocial container and helps you to start hosting OpenSocial apps quickly by providing the code to render gadgets, proxy requests, and handle REST and RPC requests.

Apache Shindig's goal is to allow new sites to start hosting social apps in under an hour's worth of work.

Shindig がガジェットの表示、リクエストのプロキシ、REST と RPC リクエストの処理を担当してくれますので、 その仕様に従えばアプリケーションを素早く提供できますよ、という感じでしょうか。 ここでの「仕様」が OpenSocial と呼ばれるもので、 Google や mixi で使われている OpenSocial のコンテナが Apache Shindig だそうです。 同じ仕様のコンテナを提供することで、Google 用に作ったガジェットを mixi でも使えますし、その逆もまた然りとなります。

Shindig に関する説明は各所にありますが、2010年の10月にバージョン 2.0 がリリースされました。 メジャーバージョンアップですので、インストールするときの違いもあるでしょう。 ということで、いくつかの記事を参考にさせて頂きながら、自分でも動作させてみます。

Shindig 自体は2007年12月頃から ASF の Incubator 下で活動が開始され、2009年1月にトップレベルのプロジェクトになりました。

ローカルのマシンで動かしても構いませんが、クリーンな環境の方が失敗する要素が少ないと思いますので、Amazon EC2 を使います。 東京リージョンが追加されていますので、接続速度にこだわる場合には選択肢のひとつとして有望です。 まぁ、輪番停電が実施されている中で東京のデータセンターを選択する必要があるとは思えませんが。。

EC2 インスタンスに接続する

少し前に EC2 で Apache HTTP と Solr を使えるようにしました (Amazon EC2 を使ってみる)。 インスタンスの起動、接続方法はだいたい一緒で、標準の AMI を使います。

ファイアーウォールの設定では 20 番ポート (SSH) と 80 番ポート (HTTP) を開放しておきます。 アプリケーションサーバの動作確認用に 8080 番ポートなどを確認しても構いませんが、 ちょっと確認するだけであれば SSH トンネリングを利用すれば良いと思います。

.ssh/configHostec2shindig にしておきます。

接続例

$ ssh -L8080:localhost:8080 ec2shindig

なお、インスタンスの扱いには Amazon EC2 API Tools が便利そうです。 時間があれば設定しておきたいところです。

SSH で接続したら、Apache と Tomcat をインストールしておきます。

$ sudo yum -y install httpd tomcat6
$ sudo chkconfig httpd on
$ sudo chkconfig tomcat6 on

次に、Apache へのリクエストを Tomcat にプロキシさせるように設定し、サーバを起動しておきます。

$ cat <<'EOF' |sudo tee -a /etc/httpd/conf.d/proxy.conf
ProxyPass / http://{YOUR-INSTANCE-PUBLIC-DNS}:8080/
EOF
$ sudo service httpd start

Shindig の .war アーカイブを配置する

Apache Shindig の サイト からアーカイブをダウンロードします。 Java の実装と PHP の実装がありますが、単に配置するだけならば Java の .war アーカイブを使う方法が簡単に思えましたので、Java 版を使います。 shindig-server-2.0.0.war は予め取得しておきます。

$ sudo mv shindig-server-2.0.0.war /usr/share/tomcat6/webapps/ROOT.war
$ sudo chown tomcat /usr/share/tomcat6/webapps/ROOT.war

.war ファイルを展開し、 web.xml を編集します。 ついでに、Tomcat が 8080 番ポートで動作することを確認しておきます。

$ sudo service tomcat6 start
$ wget -SO /dev/null "http://localhost:8080/"
$ sudo service tomcat6 stop
$ sudo vim /usr/share/tomcat6/webapps/ROOT/WEB-INF/web.xml    --- (*)
$ sudo service tomcat6 start
(*) Shindig のホスト名とポート番号を設定します。
デフォルトではホスト名が localhost 、ポート番号が 8080 番になっています。 下記の NOTE 1 にあるように shindig.hostshindig.port を設定します。 Tomcat の起動設定 (/etc/tomcat6/tomcat6.conf など) でもシステムプロパティとして制御できるはずです。

これで EC2 インスタンスの Public DNS にアクセスすると、次の画面が表示されます。

http://{YOUR-INSTANCE-PUBLIC-DNS}/gadgets/ifr?url=http://miyakemusi.googlecode.com/svn/trunk/tv_gadget/tv.xml

設定に関して注意すべきことが2点挙げられます。

  • Tomcat の ROOT コンテキストで動かす。
  • Apache からプロキシするときに ROOT コンテキストが保持されるようにする。

いずれもリソースの URL 解決という意味で根っこは同じです。 OpenSocial ではクロスドメイン通信を回避するために、コンテナが HTTP リクエストをバイパスさせます。 このときに、コンテンツの URL とプロキシ用の URL を解決しなければなりませんが、 これが Java から JavaScript に変換されています。 ガジェットをうまく表示できない場合は、取得したページのソースを表示してみると問題解決の端緒となるかもしれません。 localhost の記述が存在する場合には shindig.host の設定間違いかもしれませんので、 web.xm を見直します。

ROOT コンテキスト以外で動作させようとするとパスの整合性が崩れてしまいますので、うまく動きません。 たとえば、 .war ファイルの名前を変更せずに webapps ディレクトリに配置すると、 アプリケーションにアクセスする場合には /shindig-server-2.0.0 というパスが必要になります。 一番最初のリクエストはそれで成功しますが、その後に JavaScript を取得する部分に /shindig-server-2.0.0 が渡っていないため、ガジェットを表示できません。

さらに、Apache のプロキシでこのエンドポイントを自由に変更できます。 たとえば proxy.conf に次の定義を入れると、外部からは http://{YOUR-INSTANCE-PUBLIC-DNS}/shindig でアクセスできますが、 JavaScript の通信がうまくいかずにガジェットを表示できません。

ProxyPass /shindig http://{YOUR-INSTANCE-PUBLIC-DNS}:8080/shindig-server-2.0.0

いずれの問題も将来的な実装の変更、あるいはちょっと複雑な Shindig の設定で制御できるのかもしれませんが、 ちょっと始めてみるには遠回りすぎる気がしました。 ROOT/WEB-INF/classes/containers/default/container.js が関係していると思いますが、 とりあえずは ROOT コンテキストで動かしてみることが間違いが少ないはずで、 もっと突っ込んだことを実現する場合にはソースコードを取得して mvn を使って自前でビルドした方が良さそうです。

また、Apache をフロントに置く必然性もありませんので、Tomcat を 80 番ポートで動かすか、 ファイアーウォールで 8080 番ポートを許可すれば良いのかもしれません。 ここでは、EC2 のセキュリティポリシーを使いまわすために上記のようにしています。

NOTE 1: web.xml における shindig.hostshindig-port の設定例です。

<context-param>
    <param-name>system.properties</param-name>
    <param-value>
        shindig.host={YOUR-INSTANCE-PUBLIC-DNS}
        aKey=/shindig/gadgets/proxy?container=default&amp;url=
        shindig.port=80
    </param-value>
</context-param>

NOTE 2: PHP 版は mod_php を使って構築します。
標準の AMI には PHP はインストールされていませんが、 yum でインストールできます。 他のモジュール (curl の PHP 拡張など) に関してもきっとインストールできるでしょう。 パスの問題に関しては分かりません。

ガジェットを追加する

OpenSocial の仕様に基づいた XML を用意し、Web サーバにアップロードします。 例えば、震災発生日からの経過日数を表示するガジェットは次のようになります。

show-elapsed-days-from-east-japan-earthquake.xml

<?xml version="1.0" encoding="UTF-8"?>
<Module>
  <ModulePrefs title="Pray for Japan!">
    <Require feature="opensocial-0.8" />
  </ModulePrefs>
  <Content type="html">
  <![CDATA[
    <script>
    function showElapsedDays() {
        var earthquake = new Date(2011, 2, 11),
            today = new Date(),
            diff = (today - earthquake) / 86400000;
        document.getElementById('elapsedDays').innerHTML = Math.floor(diff);
    }
    gadgets.util.registerOnLoadHandler(showElapsedDays);
    </script>
    <p>
    今日は東日本大震災から<span id="elapsedDays"></span>日目です。<br />
    1日も早い復興に向けて頑張りましょう!
    </p>
  ]]>
  </Content>
</Module>

XML とその中身の JavaScript のインデントの数に悩みますが、 XML は構造が分かるようにインデント2、JavaScript は XML とは異なることを明示するためにもインデント4にしてあります。

「Web サーバを持っていない!」という場合には Dropbox の Public フォルダを利用できます。 たとえば、上記の XML は http://dl.dropbox.com/u/1880322/os/show-elapsed-days-from-east-japan-earthquake.xml で参照できるようにしてあります。 Shindig の /gadgets/ifr エンドポイントの url パラメータにこの URL を指定することで、ガジェットを表示できます。

終わりに

Apache Shindig をインストールし、簡単なガジェットを追加しました。 ガジェットの仕様は OpenSocial で定義されていますので、仕様に沿っておけば、 コンテナの提供者も利用者も同じものを再利用できます。

仕様がひとつで同じソフトウェアを使うなら、みんなでコンテナを共有すれば良いのでは?という疑問もあるかもしれませんが、 サービスごとにコンテナを提供することにより、サービス固有のユーザー情報を参照できるのは大きなメリットです。 サービスごとにペルソナを使い分けているユーザーには特に顕著な違いとなります。 最近流行の「ソーシャルグラフ」が違うためです。 ただ、実際にサービス提供側がバックエンドのユーザー情報と繋いでいくのは大変かもしれませんが。

既存のサービスにガジェットを追加していく、という観点でも仕様が共有されたコンテナは有効です。 「よそのサービスにあるあの機能が足りない」という場合にも、それぞれが OpenSocial に対応していれば簡単に流用できます。 たとえば、災害後の緊急事態用のガジェットが考えられます。 災害後の非常体制での生活を送る中では「大きなシステム改修/移行に踏み切るほどでもないが、一時的に機能を追加したい」 という要望もあると思います。 OpenSocial でガジェットをプラガブルにしておけば、こうした要望には対応できるのではないでしょうか。 今からでは遅い... かもしれませんが、次に役立てることはできると思います。

ガジェットに関しては、すでに多数の iGoogle ガジェットが開発されていますし、XML で記述されていますから時間をかければ中身を確認できます。 エンタープライズシステムだから、うちは SNS じゃないから、といった認識ではなく、今出来ることを少しでも考えていきたいですね。

2011年3月20日

Hack for Japan の Google モデレーターのデータを見る

Hack For Japan が開催されています。

三連休を利用したスプリントで、

  1. 3/19, 3/20 - 何をするか?というアイデア出し。
  2. 3/21 - 実際にアイデアを実現する。

ということで、アイデアを見てみます。 モデレーターのデータから生成した HTML はこちらに置いてあります。

http://dl.dropbox.com/u/1880322/hack4jp-moderators.html

アイデアの一覧を見る

アイデアは Google モデレーター で管理されています。 モデレーターは、個人的な感覚だと、閲覧には不向きな印象です。 「プレゼンテーション表示」だと一覧性が向上しますので、ザーッと眺めるだけだとこちらが便利です。

CSV で出力できますので、Excel などで閲覧することもできます。。。 と思いましたが、ダウンロードしたファイルはユニコードをエンコードしていませんでしたので、 普通の人だと日本語を読むことができません。 あと、カラムもズレている印象ですね。

それは困った... ということで、データだけを抜き出して HTML に整形し直します。 とはいえ、この辺りは将来的には改善されることでしょう。

Google スプレッドシートのデータプロジェクトリスト (となっていますが、実際には議論のまとめ) もあります。

API を使って Moderator のデータを抜き出す

モデレーターにも API が用意されており、 google-api-python-client もこれに対応しています。 サンプルも同梱されていますので、これをベースにしてデータを抜き出します。 moderator に関するサンプルは2つあります。

  • samples/moderator/moderator.py - 認証に OAuth 1.0 系を使うコマンドラインツール
  • samples/oauth2/moderator/moderator.py - 認証に OAuth 2.0 系を使うコマンドラインツール

OAuth 2.0 系の方をベースにします。 認証フローに関しては Google API Python Client (2010年11月の記事) で書いたものとほぼ一緒です。 認可を許可するスコープが異なりますので、認可の画面は「モデレーターのデータにアクセスしても良いですか?」という表示になります。 認証部分のコードはこんな感じです。 認証キーなどをセットしてから run を呼び出すだけです。

from oauth2client.file import Storage
from oauth2client.client import OAuth2WebServerFlow
from oauth2client.tools import run

FLOW = OAuth2WebServerFlow(
    client_id='XXXXXXXX',
    client_secret='XXXXXXXX',
    scope='https://www.googleapis.com/auth/moderator',
    user_agent='moderator-cmdline-sample/1.0')

def main():
  storage = Storage('moderator.dat')
  credentials = storage.get()

  if credentials is None or credentials.invalid == True:
    credentials = run(FLOW, storage)

次に、サービスディスカバリの機構を使って moderator 用のサービスオブジェクトを構築します。 (ディスカバリに関しては GData 3 の discovery の中身 (2010年11月の記事) も参考に)

import httplib2
from apiclient.discovery import build

def main():

  # .. 上記の認証フロー

  http = httplib2.Http(cache=".cache")
  http = credentials.authorize(http)

  service = build("moderator", "v1", http=http)

モデレーターのデータは次の4種類から成ります。 (Moderator concepts)

  • シリーズ (Series)
  • トピック (Topic)
  • サブミッション (Submission)
  • 投票 (Vote)

それぞれのデータを扱うためにサービスからリソースを生成します。 今回はシリーズとサブミッションを扱います。 シリーズとトピックの ID は、取り扱うモデレーターのページの URL を参考にします。 (10進数表記と16進数表記に注意)

def main():

  # .. 上記の続き

  sid = 0x6441b  # seriesId of target contens.
  tid = 0x40     # topicId of target contens.

  def print_votes(vote):
    print 'Votes: +%d, -%d' % (vote['plusVotes'], vote['minusVotes'])

  series = service.series().get(seriesId=sid).execute()
  counts = int(series['counters']['submissions'])

  print series['name']
  print series['description']
  print 'Submissions: %d' % (counts,)
  print_votes(series['counters'])

  per_page = 20
  start = 0

  def printer(items):
    for item in items:
      print item['text']
      print_votes(item['counters'])

  while start < counts:
    submissions = service.topics().submissions().list(seriesId=sid,
          topicId=tid, max_results=per_page, start_index=start).execute()
    printer(submissions['items'])
    start += per_page

HTML に整形し直す

標準出力に print しただけだと見栄えが悪いので HTML に整形し直します。 ここでは、テンプレートエンジンとして Jinja2 を使います。

次の4種類の情報を表示します。

  • シリーズの概要、統計情報
  • サブミッションのテキスト
  • サブミッションの投票状況
  • サブミッションのオリジナルデータへのリンク

リンクを生成するときに、ID の文字列を16進数表記にマッピングする必要があります。

テンプレート部分

import jinja2

BASE = u'''
<!DOCTYPE HTML>
<html lang="ja"><head>
  <meta charset="UTF-8" />
  <meta name="viewport" value="width=device-width,user-scalable=no" />
  <title>Hack For Japan Moderators - Mirror</title>
</head><body><div id="wrapper">
  <div id="header">{% block series %}{% endblock %}</div>
  <div id="main">{% block submissions %}{% endblock %}</div>
  <div id="footer">Generated around {{ now }}.</div>
</div></body></html>
'''

TEMPLATE = u'''
{% extends "base.html" %}

{% block series %}
<a href="{{ series.id|to_original_url }}">
  {{ series.name }}</a> - Mirror
<p>{{ series.description }}</p>
<p>Submissions: {{ series.counters.submissions }},
   Total Votes: +{{ series.counters.plusVotes }},
                -{{ series.counters.minusVotes }}</p>
{% endblock %}

{% block submissions %}
{% for item in submissions %}
<div>
  <p>{{ item.text }}</p>
  <p>Votes: +{{ item.voteCounters.plusVotes }}
            -{{ item.voteCounters.minusVotes }}
    <a href="{{ item.id|to_original_url }}">-&gt;Go</a>
  </p>
</div>
{% endfor %}
{% endblock %}
'''

TEMPLATES = {'base.html': BASE, 'template.html': TEMPLATE}

書き出す部分

from datetime import datetime

def main():

  # .. 上記の続き

  url = 'https://www.google.com/moderator/#15/e=%s&t=%s.%s' % (hex(sid)[2:],
        hex(sid)[2:], hex(tid)[2:])

  def to_original_url(id):
    if 'submissionId' in id:
      return '%s&q=%s.%s' % (url,
            hex(int(id['seriesId']))[2:], hex(int(id['submissionId']))[2:])
    return url

  params = {'now': datetime.now(),
        'series': series, 'submissions': submissions}
  env = jinja2.Environment(loader=jinja2.DictLoader(TEMPLATES))
  env.filters['to_original_url'] = to_original_url
  tpl = env.get_template('template.html')
  writer = open('hack4jp-moderators.html', 'wb')
  writer.write(tpl.render(params).encode('utf-8'))
  writer.close()

あとは出力された HTML ファイルのデザインなどを調整すれば冒頭の HTML の出来上がりです。 使い捨てスクリプトなので jinja2.DictLoader を使っていますが、 通常は jinja2.FileSystemLoader などを使って HTML は別ファイルで管理した方が良いでしょう。

NOTE:

  • 3/20 13:20 くらい - Submissions: 130, Total Votes: +2243, -439
  • 3/20 21:30 くらい - Submissions: 179, Total Votes: +3081, -887

まとめ

Google モデレーターのデータを HTML に変換しました。 ざっくり拝見したところ、1日で成果が出そうなことから中長期的に継続していかなくてはいけないことまで、 多種多様なアイデアがありそうです。

  • いろいろなマッチング
  • 継続的な心のケア
  • 計画停電の情報
  • スマートフォンのアプリケーション、オフライン対応
  • フィーチャーフォンへの画面変換、IT に不慣れな方への対応

一方でバックエンドの仕組みとしては、汎用的に使えることと、ローカルな情報を絞り込むことの兼ね合いかなぁ、と思います。 いずれにしても、相互に交換できるデータを使って、みんなで共有できると良さそうです。

2011年3月19日

Google App Engine / Java の SDK をインストール

Google App Engine / Java の開発では Eclipse が必須のような扱いですが、 HTML / JavaScript / CSS を書き換えて表示を確認したいだけの場合には面倒に感じます。 SDK をインストールすると、コマンドラインツールを使って開発用サーバを立ち上げることができます。 Eclipse を起動する必要がありませんので、マシンのメモリ使用量を抑えられます。

手順は Google App Engine のページに記載されていますが、 しばらくすると存在自体を忘れてしまいそうなのでメモしておきます。

「プログラミング Google App Engine」の "2.1 SDK のセットアップ" の最後にある "Eclipse なしでの Java SDK のインストール" でも少しだけ触れられています。

手順

  1. appengine-java-sdk-1.4.2.zip をダウンロードする。 (ダウンロードページ)
  2. zip ファイルを展開したものを適当なディレクトリに移動させる。
  3. ターミナル / コマンドプロンプトなどを立ち上げ、Google App Engine / Java のプロジェクトのディレクトリに移動する。
  4. war ディレクトリを指定して、SDK のスクリプトを実行する。

やること

手元の環境では SDK を /usr/local/appengine-java-sdk-1.4.2 に移動させ、 バージョン番号を隠すようにシンボリックリンクを用意しました。 mv でも構わないと思いますが、複数の SDK を使えるようにしておくためには ln の方が良さそうです。 また、SDK のバージョンによって demos などが異なりますので、参照用に残しておくこともできます。

$ cd /usr/local
$ sudo ln -s appengine-java-sdk-1.4.2 appengine-java-sdk

中身は次の構成になっています。

$ tree -d -L 2 /usr/local/appengine-java-sdk
/usr/local/appengine-java-sdk
|-- bin
|-- config
|   |-- sdk
|   `-- user
|-- demos
|   |-- guestbook
|   |-- helloorm
|   |-- helloxmpp
|   |-- jdoexamples
|   |-- mandelbrot
|   |-- mediastore
|   |-- new_project_template
|   |-- shardedcounter
|   |-- sticky
|   |-- taskengine
|   `-- taskqueueexamples
|-- docs
|   |-- javadoc
|   |-- testing
|   `-- tools
|-- lib
|   |-- agent
|   |-- impl
|   |-- shared
|   |-- testing
|   |-- tools
|   `-- user
`-- src
    `-- orm

29 directories

bin ディレクトリには4つのスクリプトが用意されています。 .cmd は Windows 用、 .sh は Linux などのためですから、実質的には2種類のスクリプトです。

$ ls /usr/local/appengine-java-sdk/bin
appcfg.cmd         appcfg.sh*         dev_appserver.cmd  dev_appserver.sh*

開発用サーバを起動するスクリプトは dev_appserver で、引数には war ディレクトリを渡します。 ここではプロジェクトのディレクリに移動してあるものとして考えていますので war だけですが、 必要ならば絶対パスの方が間違いが少ないかもしれません。

$ /usr/local/appengine-java-sdk/bin/dev_appserver.sh war

スクリプトは -h オプションでヘルプが表示され、 -p オプションでポート番号を指定できます。 -a オプションでバインドするアドレスを指定できますので、他のマシンから表示を確認するためにも使えます。

$ /usr/local/appengine-java-sdk/bin/dev_appserver.sh -a 192.168.0.2 -p 8888 war

まとめ

コマンドラインから開発用サーバを立ち上げました。 まぁ、今どきそんなメモリ使用量を気にするようなマシンで開発するな、という話かもしれませんが、 たまにはそういうこともあります。たぶん。 あと、フロントエンドの開発者に Eclipse を強要しない、という点では良いと思います。 CI (Continuous Integration) との相性も良いでしょうね。

2011年3月18日

Google Buzz で Activity Streams (2)

昨年末に Google Buzz で Activity Streams (2010年12月の記事) を試してみました。 当時は認可の形式が OAuth 1.0 ベースでしたが、最近になって Google が OAuth 2.0 (Draft 10) に対応し始めました。 それに合わせて google-api-python-client にもモジュールが追加されましたので、試用してみます。

なお、InfoQ の記事にもある通り、OAuth 2.0 の最新版は Draft 13 なので、ライブラリのコードは変更されていくかもしれません。

Buzz にデータを流す

とりあえず、何もデータが存在しないと寂しいので Buzz にデータを投稿します。 Gmail を Web ブラウザから使っている場合には、Buzz を有効化すると「受信箱」(Inbox) の下に Buzz が出現します。 メニューで Buzz を選択すると投稿用のフォームがありますので、そこに適当なメッセージを入力して送信できます。 送信するときには公開範囲を選択できます。

いちいちブラウザでメールボックスを開かないよ... という場合には Twitter へのポストを Buzz に流すこともできます。 クローリング (?) も早く、おそらくリアルタイム検索と同じくらいのタイムラグ (つまり、すぐさま) で反映されます。

もうひとつ、自分がちょっと良いかも、と感じているのが、Google Reader からの共有設定です。 新聞の代わりにフィードを読んでいるような人だと、1日当たりに数百から千件くらいの情報 (もっと多いかも) に目を通すと思いますが、 情報量が多くなるとそれを選別することが大変になります。 「あとで読む」という場合にはスターを付けることが一般的だと思いますが、 「読み終わってスクラップブックに保存したい」場合にはどうでしょうか。 ひとつの方法は、ブックマークに登録することになるでしょう。 ブラウザのブックマーク、ブラウザ間の同期サービスや Evernote、ソーシャルブックマークサービスなど、いくつかの方法があります。 Google Reader からの共有がちょっと便利なのは、ブラウザ間で同期させる必要がなく、携帯電話からも使えて、別のサービスにジャンプする必要がないことです。 あと、キーボードショットカット ("S") が使えるのも嬉しいところです。 記事を読むときは一気にまとめて読んでしまい、ちょっと気になったことを共有しておくと、 一日の終わりや週の終わりにその期間のことを振り返りやすくなります。

ということで、こじつけ感が強いことは否めませんが、Buzz にデータを流せるようにしておきます。

OAuth 2.0 での認証

Google API Python Client (2010年11月の記事) をインストールします。 Mercurial で pull (https://google-api-python-client.googlecode.com/hg/) したディレクトリで、サンプルを実行します。 README は更新が追いついていないと思いますので読まなくとも。

実行するのは次の二行 (PYTHONPATH=. python samples/oauth2/buzz/buzz.py なら一行) です。

$ source setpath.sh
$ python samples/oauth2/buzz/buzz.py

基本的なフローは前述のブログ記事にある通りですが、OAuth 2.0 では「確認コード」を要求されません。 代わりに次のメッセージが表示され、コマンドライン側では認証が完了しています。

The authentication flow has completed.

これが OAuth 2.0 の嬉しいところですが、細かい部分は省略します。 実装は oauth2client.tools.run にあると思いますので、時間があるときにでも。 リダイレクトして戻って来た場合の HTTP サーバをローカルで立ち上げています。

認証フローが終わると buzz.dat というファイルが生成されます。 認証トークンなどを保持している Python オブジェクト (oauth2client.client.OAuth2Credentials) を pickle でシリアライズしたものです。

ひとつ注意すべきなのが、このサンプルは認証が成功すると書き込み処理も実行することです。

  1. 最新の Activity を二件取得する。
  2. その次の二件を取得する。
  3. 新しく Activity を POST する。
  4. その Activity にコメントを追加する。

とはいえ Web 画面からすぐに削除も変更もできますので、ちょっと buzz を撒き散らしてスミマセン、ということで。

NOTE:

Python で OAuth を扱う上で紛らわしいのが、モジュール名です。 oauth は OAuth 1.0 系のレファレンス実装で、 oauth2 はその改良版です。 モジュール名に 2 が付きますが、仕様のバージョンは 1 系です。 Google のライブラリにおける OAuth 2.0 用のモジュール名は oauth2client です。 ソースツリーには oauth2oauth2client の両方が存在します。

Activity の取得

それでは Activity Streams の解析を... といきたいところですが、 Google の新しい API は discovery の仕組みを使います。 これに関しては GData 3 の discovery の中身 (2010年11月の記事) を少しだけのぞいて、 apiclient.discovery.build の使い方をつかめれば良いと思います。

さて、 build() でサービスのインスタンスを受け取ると、 activities() メソッドの戻り値を使って Activity Streams を操作できます。

def main():
  storage = Storage('buzz.dat')
  credentials = storage.get()

  http = httplib2.Http()
  http = credentials.authorize(http)

  service = build("buzz", "v1", http=http, developerKey="XXXXXXXX")
  activities = service.activities()

Activity Streams の Resource に対しては CRUD を基本とした操作 を実行できます。 一覧を取得するためには list 、新規にポストするためには insert などです。

たとえば、自分が Buzz に投稿した Activity を10件取得するためには次のコードを実行させます。 scope='@consumption' にすると、自分がフォローしているユーザーの Activity も取得します。

activitylist = activities.list(
    max_results='10', scope='@self', userId='@me').execute()

Activity のストリーム (=流れ) ですから、10件取得してもそれで終わりだとは限りません。 たいていの場合は、何らかの条件を満たすまで、同じように Activity を手繰り寄せたくなると思います。 Resource クラスでは list_next() がこれを実現してくれます。

if activitylist:
  activitylist = activities.list_next(activitylist).execute()

取得した activitylist は Python の辞書形式になっており、 items キーで Activity の一覧にアクセスできます。

writer = sys.stdout
for item in activitylist['items']:
  print >>writer, item['updated'], item['object']['content'].encode('utf-8')

item には source キーがあり、これによって投稿元の情報が分かります。 例えば、Twitter から流しているアイテムの元のリンクを表示させたい場合は次のようになります。

if 'source' in item and item['source']['title'] == 'Twitter':
    tag = item['crosspostSource']
    href = tag[tag.rfind(':') - 4:]  # 4-char back for "http"
    print >>writer, "Original:", href

あとはこれらを整形してあげれば活動のまとめを生成できます。 旅行の記録や日常の日記の下地としては便利ではないでしょうか。

終わりに

Google Buzz にデータを投稿し、Activity Streams を受け取りました。 google-api-python-client を使うと簡単に API を実行できます。 XML の細部に立ち入る必要がないのは嬉しいことです。

Google でも OAuth 2.0 をサポートし始めたことにより、ライブラリにも機能が追加されています。 ライブラリのレベルでキレイに抽象化されていますので、アプリケーション開発者視点では特に違いを意識することなく認証フローを実装できます。 アプリケーションの利用者にとっては、OAuth 2.0 によって PIN コードを入力する必要がありませんので、ひと手間省けて導入の敷居が下がることが期待できます。

情報の流量が増加するとそれを整理することが大変になってしまい、たくさんの Web サービスを使い始めると情報が発散しがちです。 サービスによっては、操作感の違いに戸惑うこともあるかもしれませんし、サポートされるデバイスが少ないかもしれません。 しかし、最近はどのサービスも API を整備してきており、複数のサービスの情報をひとつのストリームに束ねることも現実的になってきました。 その選択肢のひとつとして Google Buzz は便利だな、と思います。 あとはソーシャルグラフなのかなぁ、と思いますが、それが一番大変だったり...

とはいえ、今回の大震災は多くの人が連絡手段の冗長性について考える契機になったはずです。 電話がダメならメール、メールがダメなら Twitter、Twitter がダメなら PFIF (People Finder Interchange Format)、 PFIF で追いつかなければ人力での文字起こし... 結局、最後は人と人とのつながりですが、それをまとめる一助として Activity Streams が使えるかもしれませんね。

おまけ

Python の pprint モジュールを使って activitylist 変数を書き出してみると次のデータを得られます。 コマンドラインからポストしたものと、Twitter から流したものです。

{u'id': u'tag:google.com,2010:buzz-feed:self:posted:XXXXXXXX',
 u'items': [{u'actor': {u'id': u'XXXXXXXX',
                        u'name': u'Shigeru Kitazaki',
                        u'profileUrl': u'XXXXXXXX',
                        u'thumbnailUrl': u'XXXXXXXX'},
             u'id': u'tag:google.com,2010:buzz:XXXXXXXX',
             u'kind': u'buzz#activity',
             u'links': {u'alternate': [{u'href': u'XXXXXXXX',
                                        u'type': u'text/html'}],
                        u'liked': [{u'count': 0,
                                    u'href': u'XXXXXXXX',
                                    u'type': u'application/json'}],
                        u'replies': [{u'count': 2,
                                      u'href': u'XXXXXXXX',
                                      u'type': u'application/json',
                                      u'updated': u'2011-03-17T09:32:07.656Z'}],
                        u'self': [{u'href': u'XXXXXXXX',
                                   u'type': u'application/json'}]},
             u'object': {u'content': u'XXXXXXXX',
                         u'links': {u'alternate': [{u'href': u'XXXXXXXX',
                                                    u'type': u'text/html'}]},
                         u'originalContent': u'XXXXXXXX',
                         u'type': u'note'},
             u'published': u'2011-03-17T09:28:09.000Z',
             u'source': {u'title': u'Google API Client Example App'},
             u'title': u'XXXXXXXX',
             u'updated': u'2011-03-17T09:28:09.580Z',
             u'verbs': [u'post'],
             u'visibility': {u'entries': [{u'id': u'G:@me:@public',
                                           u'title': u'Public'}]}},
            {u'actor': {u'id': u'XXXXXXXX',
                        u'name': u'Shigeru Kitazaki',
                        u'profileUrl': u'XXXXXXXX',
                        u'thumbnailUrl': u'XXXXXXXX'},
             u'crosspostSource': u'tag:twitter.com,2007:XXXXXXXX',
             u'id': u'tag:google.com,2010:buzz:XXXXXXXX',
             u'kind': u'buzz#activity',
             u'links': {u'alternate': [{u'href': u'XXXXXXXX',
                                        u'type': u'text/html'}],
                        u'liked': [{u'count': 0,
                                    u'href': u'XXXXXXXX',
                                    u'type': u'application/json'}],
                        u'replies': [{u'count': 0,
                                      u'href': u'XXXXXXXX',
                                      u'type': u'application/json',
                                      u'updated': u'2011-03-17T09:02:12.000Z'}],
                        u'self': [{u'href': u'XXXXXXXX',
                                   u'type': u'application/json'}]},
             u'object': {u'content': u'XXXXXXXX',
                         u'links': {u'alternate': [{u'href': u'XXXXXXXX',
                                                    u'type': u'text/html'}]},
                         u'originalContent': u'XXXXXXXX',
                         u'type': u'note'},
             u'published': u'2011-03-17T09:02:12.000Z',
             u'source': {u'title': u'Twitter'},
             u'title': u'XXXXXXXX',
             u'updated': u'2011-03-17T09:02:12.000Z',
             u'verbs': [u'post'],
             u'visibility': {u'entries': [{u'id': u'G:@me:@public',
                                           u'title': u'Public'}]}}],
 u'kind': u'buzz#activityFeed',
 u'links': {u'next': [{u'href': u'XXXXXXXX'}],
            u'self': [{u'href': u'XXXXXXXX',
                       u'type': u'application/json'}]},
 u'title': u'Google Buzz Self Feed for Shigeru Kitazaki',
 u'updated': u'2011-03-17T09:32:07.656Z'}

XML の名前空間の違いを意識することなく変換してくれますので、 とっかかりとしては分かりやすいと思います。

東日本大震災のメモ

記憶が風化しないように、引き続き Google Buzz からの転記です。 東北沖太平洋地震のメモ の続きで、Twitter でのメモ + いくつかのニュースです。

今回の大震災で被災された方には心よりご冥福をお祈りします。 原子力発電所、電気などの社会インフラ、流通関係、そして何より被災地での復興に尽力している方々がたくさんいます。 自分の現実的な行動としては募金くらいしかできませんが、何が起きているか、何を感じたかを時系列で並べておくことも後々に対して必要だと感じます。 日常的なことも織り交ぜながら、少しでも早い復旧を願い、できることをやっていきたいですね。

3/12 土曜日

交通機関のマヒだけかと構えていましたが、大震災を冠する被害の規模になってしまいました。 ただひたすら情報を収集して一日を過ごしました。

  • 10:26 起きた。余震が続くなぁ。。ちょっと片付けないと、次が心配。次はあってほしくないけれど...
  • 12:18 技術的には PFIF があります。 http://zesty.ca/pfif Google のはこれベース。 RT @ okdt: Googleのサービスをみていて思ったのだけど、安否確認情報交換プロトコルってあるといいよね。敷延して、生死確認と言ってもいいのだが、もっと ...
  • 12:23 ケータイキャリア各社がもっとオープンなデータ交換に尽力してくれればなぁと思う。自社の優位性とかを全面に出し続けたいのか、単に知らないだけのなのか...
  • 12:49 RT @ NHK_PR: 各種情報へのリンク、専用ハッシュタグ、地域別情報などがまとめられているサイトを2つご紹介します。 http://www46.atwiki.jp/earthquakematome/ http://savejapan.simone-inc.com/
  • 13:00 募金のまとめ。お金が必要なのは間違いない。 / 【東北地方太平洋沖地震 インターネット募金】 http://cause-action.jp/
  • 13:02 Yahoo!ボランティアは1ポイント1円で募金できるので良かった。金額がどうの、という話ではなく、簡単で早いのが嬉しい。でも、普段からもっとポイントを貯めておけば良かった、と反省。。
  • 13:10 まだ1000万円ちょい。来週はお酒を飲まない、と思う人が多ければもっと集まるはずなのに。 / 東北地方太平洋沖地震 義援金のお願い -【グルーポン-GROUPON】 http://www.groupon.jp/cid/7995/dtype/main
  • 13:45 ツイッター地震情報をまとめました。 - ツイナビ・Twitter 公式ナビゲーター http://t.co/wv0yo3R via @ twinavi
  • 14:36 ちょっと外出。外から見るといつもと変わらない風景だけど、お店は閉店のとこが多い。松屋も閉店だし。。新宿まで来ても人が少ない。正月よりも閑散としてる。昨日が金曜日だったのが唯一の幸いか。。。
  • 16:50 RT @ sankeisports: グルノーブル松井大輔、11日のバンヌ戦で今季初ゴール。努めて静かな口調で「大変な状況に置かれている人たちのために、できるのは得点しかないと思った」。阪神大震災当時は京都に住んでおり「怖さは分かっている。日本の状況がすごく心配」。
  • 19:33 食料のために新宿を散歩してきた。丸井、ビックカメラ、ABCマートは休業、伊勢丹は申し訳程度に営業。スタバは休業でタリーズは営業。駅前は暗い。歌舞伎町の方も然り。ってか街全体が暗く、普段の午前4時とかよりも、ある意味で暗い。。戒厳令を敷かれたりするとこんな感じなのかな、と妄想した。
  • 19:36 漫画喫茶 (マンボー) の宣伝車が走ってたけど、このタイミングでも変わらずに車を走らせ続ける姿勢は強気だな、と思った。でも、自分は今後も絶対に行かないだろうな。節電を呼びかけている状況で電飾の車を走らせるなんて、ありえない。
  • 19:45 こういう声は嬉しい。 "let pry for all those tsunami victims. all those who suffer, all those who lost their dear one's, let rise our hand for Japan."
  • 20:00 RT @ Nanas08: God bless japan

テクノロジー系企業の素早い対応が公開されてきました。 また、外国のイベントなどを見ているサイトで写真をまとめて見ると、まるで外国の出来事かのように思えます。 けれども、それが現実に起こっている、ということが二重に衝撃的です。

心強かったのは、たくさんの外国が支援を早々に表明してくれて、救援にかけつけてくれたことです。 情けは人のためならず、という言葉が頭をよぎります。

3/13 日曜日

フットサルに行く予定でしたが、すべての予定をキャンセルしました。 この日は実家に行って休憩することに。気楽に帰れる範囲が幸いしました。 将来的にも電話、メールはパンクする恐れがありますので、インターネット越しで非同期に連絡をとれるようにしておきます。

  • 12:54 実家に帰る。同じ沿線沿いなので大丈夫だと思うけど、Web サービスのアカウント関係をセットアップしておいた方が良さそう。。。
  • 23:03 両親と祖父母と伯母、あとネコとカメが元気であることを確認。ついでに新しいパソコンのセットアップをして、非常時の情報共有手段を増やしてきた。災害発声時に麻酔を受けてた、とか... 人生いろいろあるなーと思った。
  • 01:23 RT @ atusi: 停電エリア検索システム スバラシス http://bit.ly/fzdpL5
  • 01:27 新宿区と文京区は輪番停電の対象外なのか。世田谷区や目黒区の一部は対象地域なので、山手線の内側/外側なのかなーと思ったら、江東区や江戸川区は掲載されてない。多くの場合で確認が必須なのは間違いない。
  • 01:33 RT @ FacebookGeek: Facebook Causes Rallies Help For Japan’s Tsunami http://bit.ly/i3qBS2 #facebook
  • 01:40 アメリカだと地震発生は金曜日の早朝、という扱いか。時差って難しいな。。とりあえず暫定で$31,130らしい。
  • 01:41 Save the Children Deploys Emergency Response Teams to Tsunami-Affected Areas in Japan - Save the Children http://t.co/9hmuJ6x via @ AddThis
  • 01:46 5グループある。1回に3時間程度。グループ1と2は朝晩の2回。他はお昼くらいに1回。送電線単位なので区域をピンポイントで特定できない。信号も消えるので警官の手旗。 / 輪番停電(時間限定の停電)と停電前の注意点 : 痛い信者(ノ∀`) http://t.co/5A6rqye
  • 01:50 余震への感覚が麻痺してきたかも。 "地震酔いに苦しんでいる方が多いと思います。目をつむり、10秒程度深呼吸を繰り返してください。口内が乾いている方は辛くとも水等を含んでください。" / 東北地方太平洋沖地震対策まとめ : 痛い信者(ノ∀`) http://t.co/IwoqUgp
  • 01:52 RT @ daisaku: みんなのあかりが、だれかに届きますように。という思いをこめてサービスを作りました。節電してる方は写真を登録してみてください。 akarifrom.me
  • 01:53 "現在、およそ 122000 件の記録が登録されています。" / Google Person Finder (消息情報): 2011 日本地震 http://japan.person-finder.appspot.com/?lang=ja
  • 02:00 !!! "FC東京のキャプテンとして、そして宮城県仙台市出身者として、..." / FC東京 キャプテン 今野 泰幸コメント http://www.fctokyo.co.jp/home/index.phtml?cont=item&item=10871 #fctokyo

翌日から「輪番停電」という措置が取られることに決まりました。 一週間の始まりを前に、情報が錯綜しています。

3/14 月曜日

普段から自転車通勤なので、この日は会社に出社しました。 交通網が麻痺しており、緊急業務以外では出社しない会社もあったようです。 会社の業態、規模によって様々な考え方があるでしょうから、判断に迷いながら世の中が動いているように感じました。 「一律で休みにしてしまえ」という論調もありましたが、業務凍結によって業績悪化ではなく会社が傾いてしまっては大変です。難しい問題です。

  • 08:46 今日は不慣れな感じで車道を走ってる自転車が多かった。余計な自己を招くことにつながるので気を付けて欲しい。あと、ガソリンスタンドは休みの場所もあって、一ヶ所に集中しやすいので歩道寄りはさらに危ない。
  • 09:41 "テレビやパソコンなどの利用はできるだけまとめましょう。テレビの放送はインターネット経由でもリアルタイムに受信できます。" / #yj_setsuden 東京電力、東北電力管轄の地域の方へ 効果的な節電と停電の対処方法をご案内します http://yj.pn/RAdEM6
  • 09:43 "今後の需要次第では、終了時刻の午後1時までに始める可能性もあるとしている。" / <東日本大震災>第2グループ開始せず 計画停電 (毎日新聞) - Yahoo!ニュース - http://bit.ly/gZSW2U
  • 09:49 "Google Code Jam Japan 2011 ... 予選・決勝ともに日程を延期 ... 5 月の開催を視野に... 被災された皆さまには心からお見舞い申し上げるとともに被災地の一日も早い復旧をお祈り申し上げます。"
  • 09:52 早い! "People Finder Interchange Format (PFIF)" / Google Person Finder API のドキュメンテーションの翻訳について" - http://bit.ly/hQw3Uz
  • 10:05 おつ!でも、まだ余震があつから予断を許さない感じ... RT @ ymotongpoo: おそらく今日以降でトラフィックが急増することはないと思うので、僕の非公式ミラーはそこまで必要じゃなくなると思います。望ましい姿。
  • 10:07 著名人の安否は外国人にお任せしちゃった方がエコ。 / [In Progress] Compilation of celebrity statuses after earthquake/tsunami http://t.co/CCHsAlJ via @ tokyohive
  • 10:20 とても大事なことだと思う -> "「拙速な復旧を断念する」という勇気ある決断" / 災害にあったITシステムを操作しなければならない人が知るべきこと - Publickey http://t.co/qejDk46
  • 12:25 [中止] エキスパートPythonプログラミング読書会11 : ATND http://t.co/GgdLHJz via @ atnd #expertpython 変に無理しないのもエキスパート。 ATND のメッセージシステム++
  • 14:40 これはヒドイな。。。 "Yahoo!JAPANの関係者を名乗る者から、東北太平洋沖地震義援金寄付をその者の指定する銀行口座などに振り込んで欲しいなどの勧誘" / 今、Yahoo! JAPANでできること - http://bit.ly/hUSeHI
  • 14:41 RT @ fctokyo_express: 3月開催予定のJリーグ公式戦すべてが中止になることが発表されました。代替日、チケット等の詳細については、決定次第ご報告いたします。 http://bit.ly/gqSxuD #fctokyo
  • 15:39 第1、第2、第5グループが該当しそう。。かなり更新が激しいなぁ。 "電気需要が高まる午後6時〜7時の間が、実際に停電になる可能性が高いとの見通し" / 輪番停電情報 http://bit.ly/gVtuQP
  • 17:54 今朝はスタバが営業しててスゴイな、と思ったけど、いまは閉店済み。どっちも好判断だけど、どれだけ早くに来ていたのやら... いつもいつもありがとう、と実感した。
  • 18:14 RT @ gonchan20: 東京都内は他の県に比べて停電する地域が少なかったみたいだけど、住んでる人は他の県より多いから僕ら都民が今出来る事をすれば大きな力になると思う。停電がないからこそやれる事、ベストを尽くしましょう!
  • 18:16 すっかり忘れておりました... "@ yamaguchi_k: IE9日本語版だけリリース延期。そんなことが可能なのね。 http://t.co/1zAWaYo"
  • 18:21 Support YNWA For JAPAN, add a #twibbon now! - http://twb.ly/eQJSrS - Create one here - http://twb.ly/f02AU3
  • 18:22 RT @ ssense_: " You'll never walk alone! for JAPAN " 東北地方太平洋沖地震に寄せて、応援アイコンを作成しました. http://t.co/8Uq0F1z via @ Twibbon #prayforjapan #foot ...
  • 18:26 18時を過ぎると真っ暗なので早めに帰宅。。ここ数日は車椅子をトランクに積んだタクシーをたくさん見かける。活動する時間にもあるけど、有事の際には気をつけておきたい。

各種イベントの中止がアナウンスされ始めます。 また、散乱してきた情報をまとめる流れも出てきました。 まとめのまとめ、そのまたまとめ、という状況です。 こうした動きは2ちゃんねるが最も早かった印象です。

3/15 火曜日

三寒四温とは言いますが、急に冬に逆戻りです。 天候も思わしくなく、暖房による電力消費が増えそうです。

  • 07:40 東京の気温が前日比 -7 ℃でうわぁ... と思ったけど、仙台は前日比 -13 ℃で夕方から夜にかけて雪。。地盤も緩いだろうし、物資が少しでも運ばれると良いけど... #prayforjapan
  • 07:57 フランス人もいいやつらだ。 http://on.fb.me/dZXIDH
  • 08:40 ビルのスタバは8-16時で営業中。昨日と今日で連続して来てくれてる店員さんもいて、倒れないように気をつけて欲しいとこ。でも、いつもの店員さんを見るとほっとする。日常の感じは大事。
  • 12:53 バランスが難しいけど、そういうことだと思う。 "被災地への支援と、日常の責任を果たす、という2つの事柄に関して最大限努力することが今の自分に出来ること" / 今こそ|城福浩 オフィシャルブログ 「Moving Football」 - http://amba.to/eRvywI
  • 16:47 四谷三丁目駅に「とんかつさぼてん」がオープンしてる。この時間は充実の品揃えなので、困ったときは活用したい。新宿通りはかなり強いのかも。時間を選べば良さそうなのでちょっと安定。流通網は素晴らしい。
  • 22:15 "Scheduled Blackout" か。。"all japan people are brave" とか、東京から逃げないのかって言われるから何かと思った。外国から見たらあり得ない状況だよなーとしみじみ。でも、日本にいる外国人は心細いだろうなぁ、とも。
  • 22:36 次は山梨/静岡か... 東京からだと逃げ場ないじゃん。。精神的に良くない。
  • 22:44 島根県まで震度1が観測されてたらしい。 / "震源地は静岡県東部 マグニチュード 6.0" - http://www.jma.go.jp/jp/quake/20110315223637391-152231.html
  • 22:49 何をやっても集中できないけど、起きていないと何があるか分からないし。。東日本大震災に東海も追加されたら、先行き真っ暗感がヒドい。

夜に大きな地震がありました。 静岡県では震度5〜6程度になったそうです。東京も震度3でした。 原発に関する不安もこの日くらいから強くなってきました。

3/16 水曜日

会社として完全に在宅勤務の日でした。 普段から準備をしておかなかった分、やや不便でしたが、部屋の片付けをしながら気持ちも整理しつつ、といった感じです。

  • 13:53 スタバでトリビュートブレンド。昨日か今日からメニューリストなどの切り換えだったので、あんまり地震の影響を感じさせない。でも、ちょっとの地震だと誰も動じないのもどうなのやら。。意外と外国人だけ敏感なのが印象的。
  • 20:21 コンビニの看板と街灯が消灯されてると、道が暗くてビックリする。24時間あるはずのモノがないと街並みが違うもんだなぁ。片側三車線の道路なのに...
  • 20:52 RT @ DalaiLama: It is necessary to help others, not only in our prayers, but in our daily lives.
  • 22:41 昨日もこれくらいの時間に地震があった気がする。昨日の震源地は富士山だったけど今日はいったい...
  • 22:54 "16日22時39分頃地震がありました。震源地は茨城県南部 ... マグニチュード 5.3" / http://www.jma.go.jp/jp/quake/00000000091.html

ヨーロッパチャンピンズリーグの決勝トーナメントがありました。 FC東京から移籍した長友選手が所属するインテル対バイエルンの試合では "You'll never walk alone" が合唱されたそうです。 元々はリバプールのホームゲームで歌われてきたものですが、味の素スタジアムでも毎試合歌います。 今回は味スタのバージョンだったそうで、FC東京サポーターは歓喜したことでしょう。スポーツの力ですね。

3/17 木曜日

「買い占め」がちょっとした社会問題化してきました。 トイレットペーパーとガソリンが最も品薄になり、オイルショックの話を彷彿とさせます。 また、為替が大きく動き、1ドル76円台前半に突入しました。 水曜日に予定されていた雑誌の発売が一日遅れました。

  • 09:08 ガソリンが売り切れたガソリンスタンドに、ガソリンが運び込まれている最中だった。じわじわと物流が遅延してきている気がする。買い占めたい気持ちも分からなくはないけど、むしろこういうときこそ「お互い様」ということで分け合えると良いんだけど...
  • 17:55 外が暗いからか、昨日よりも店内の照明が明るい気がする。昨日は大丈夫だったからもう安心、という考えの人が増えて、今日はとても寒いので電力消費量が増えたのかも。体調を崩したら本末転倒だし、バランスが難しいとこ。。
  • 18:02 1億7千万円超。2億円まで頑張ろう! / http://www.groupon.jp/?icf=L2eGb8Ia
  • 19:52 新宿通りの暗さがスゴイ。外苑東通りと比べると別世界みたい。昨日よりも暗いんじゃないだろうか。人も少ないなぁ。
  • 21:47 おとといは 6.0、昨晩は 5.3。今日の規模はその中間。 "17日21時32分頃地震がありました。震源地は千葉県東方沖 ... マグニチュードは5.8" / http://www.jma.go.jp/jp/quake/00000000091.html

そして、三日連続で夜に地震がありました。 「余震」と呼んでよいのか別々の地震なのかが分かりません。 プレートは繋がっているのかもしれませんが、震源地は同じ地域ではありません。 ちょっとした揺れには多くの人が慣れ切ってしまっており、このタイミングで大きな地震が発生した場合が心配です。 また、「地震酔い」の人もいるかもしれません。

今日で震災発生から1週間です。 悲観していても前には進めませんので、できることからコツコツと。 ダライラマのツイートにもある通り、祈りにおいてだけでなく、日々の生活でもお互いに助け合いながら。

It is necessary to help others, not only in our prayers, but in our daily lives

2011年3月12日

東北沖太平洋地震のメモ

Google Buzz から転記。Twitter からのメモ + いくつかのニュース。

  • 14:55 16F でもグラグラ。 縦揺れの後に横揺れで気持ち悪い。でも、うちのフロアでケータイ地震速報を受け取ってた人はいなかったっぽい。。 で、揺れがおさまってからビルのアナウンス。。色んな意味で危ないことを再認識した。

職場の人と顔を見合わせて、やけに揺れますねーみたいな会話。 その後も強烈な余震が続き、帰宅できる人は明るい内に帰りましょう、ということに。

  • 17:21 帰宅した。 外堀通りも新宿通りもすごい人と車の量だった。四ッ谷駅前はJRの職員さんも交通整理にあたってくれていた。 スタバはコーヒーマシンを下げたみたいだけど、お水と食べ物で休憩できるので、歩き疲れた人にはオススメ。 店員さんには疲れが見えたけど、頑張ってほしい。。
  • 17:26 都心部は休憩できる場所も人も多いけど、 住宅街は休憩できる場所が少ないので暗くなってくると心配。。不要な事件が起こらないことを願うばかり。
  • 17:38 自宅は元から散らかってたのがちょっとズレタくらいの被害だったので、 コーヒーを煎れて気持ちを落ち着ける。母親以外の無事は確認できたけど、別の意味で母のことは心配。。こういうときの病院の中の人には本当に頑張って欲しい。

思ったより遥かにヤバいんじゃないの?と思い始めてインターネットをブラウジング。 地震の情報を得ることと並行して、2週間くらい溜まってたニュースを読む。

  • 17:48 今節J1,J2全試合の中止が決定。 詳細は決定次第ご報告します。すでに岡山に移動された方、移動中の方には残念なこととなりました。 無事に帰宅できますよう願っております。 http://bit.ly/hfy61U #fctokyo
  • 18:09 【アボットチョイス】 本日、全店舗(六本木新宿中野)あけてます。帰宅できない時のシェルター等にお使いください。 もちろん朝まで時間を潰すだけでもOKです。お困りな事があれば何でも声をかけてください。 #roppongi #shinjyuku #nakano
  • 18:19 忙しく対応している方々には失礼だけど、 日本に物理的なコンピュータがあるから云々、という話はしばらく沈静化するんだろうなー。 多少の遅延があっても確実にメッセージが届く方が安心であることは身を以て感じられたはずなので。 クラウド(雲)のはずが地震で機能しない、とかギャグにすらならない。
  • 19:03 ありがたい。 でも、日本人の助け合いの精神は半端じゃない、と再認識も。 "YNWA(You’ll never walk alone=君はひとりじゃない)" / リヴァプールが声明を発表「ご無事を祈っています。皆さんはひとりじゃない」 http://bit.ly/gQzxKZ

何となく状況を把握。今回は異常、という認識。海外にも情報が伝わっており、Twitter のトレンドには津波などが増えてくる。 友達からもメールがちらほら。

  • 19:07 遠くにいるゼネコンの友達から自慢のメールがきたw インフラってすごいな、と思う。有事のときしか目立たないけど、だからこそありがたい。
  • 19:10 「ガスが止まってしまった方へ。 東京ガスは震度4で自動停止機能が働く。復帰は簡単。 メーターの左上にある黒いキャップを外して中のボタンを奥まで押しこむ。メーター上部の赤ランプが3分点滅するので、その後復活。」
  • 19:26 余震もおさまったかな、と思ってガスを復旧させたけど、意外と余震があるな。。 あと、新潟の地震は心配。築100年超の家は大丈夫なんだろうか...

すっかり暗くなってしまったので、ライフラインを確認する。明るい内にやっておけば良かった。 余震なのか新しい地震なのか分からないが、新潟 (祖父母がいる) でも地震があったとの情報。うーむ。

  • 19:43 東京ディズニーランドが洪水でヤバいらしい、 と外国からは見られているのやも。。。間違ってはいないけど、なんて言うか... 難しいとこ。
  • Google Japan Blog 東北地方太平洋沖地震を受けて
  • 20:01 神戸と同じ液状化現象です RT @kshigeru: 東京ディズニーランドが洪水でヤバいらしい、と外国からは見られているのやも。。。間違ってはいないけど、なんて言うか... 難しいとこ。
  • 20:08 実家の近くに川の下の駐車場があるけど、埋没、、、 なんてことは無いよな、きっと。。 http://www.geocities.jp/ur_route_neo/shinkawachika.html

少しずつローカルなニュースも把握。グーグルが google.org にコンテンツを用意。 お腹がすいたのでコンビニへ行ったが、食料は何もない。

  • 21:49 母から「帰宅開始する」との連絡。 たぶん急患も多かっただろうから数倍疲れてそう。それにしても、この寒いなかで荒川を歩いて渡るのはシンドそう。。
  • 21:58 靖国通りが行軍状態になってた。 夜ピクみたい、と言っては不謹慎だけど、まだまだ道半ばの人が多そう。。山手線の内側だと、明るいことがだけがまだ救いかなぁ。

なんとなく家にあったものを食べながら、引き続きニュースを読む。 余震も続く。。

  • ギズモード・ジャパン 消息情報は「Person Finder: 2011 日本地震」にもお書きください【追記あり】
  • 23:39 日経のサイトの「特報」が非常事態な感じを端的に表してる。 1ヶ月以上も余震っていうのかなぁ。今回は「烈震」と呼ぶらしい。初耳すぎる。
  • 【2ch】ニュー速クオリティ TSUTAYA 「テレビは地震ばっかりでつまらない、そんなあなた、ご来店お待ちしています!」
  • 痛い信者(ノ∀`) 東北地方太平洋沖地震対策まとめ
  • 24:16 今でも余震が続いているけど、 とってもよくまとめてくれている。 #jishin / 東北地方太平洋沖地震対策まとめ http://bit.ly/h6Xhfn

ぼちぼち、良い話も悪い話も流れてくる。 非常事態の時ほど、発信には差が出てくるのは仕方ないが、TSUTAYA と NHK はあまりにも対照的。 冗談を言って売上を考えるか、独断で制度を色々と破っている感じでも、善かれと思うことをやるかの違いは大きい。。

  • 24:32 両親からメールが返ってこないなーと思って電話したら寝てたっぽい。 ま、まぁ、無事なら良いんだけど... 新潟の祖父母は別段変わりなかったようで。ひとまず安心。
  • 24:42 今回は PFIF が有効活用される最大規模の災害かも。 安否が分かればひとまず安心だし次のことも考えられる。Google++ http://zesty.ca/pfif/
  • Engadget Japanese Google 消息情報 2011 日本地震が開設、安否確認用公開データベース

個人的な範囲での無事を確認。 日本は先進国とかの次元を超越していることも確認。

  • コンビニで暴動は起きない。
  • 車のクラクションも鳴らさない。
  • みんな信号を守る。歩道の列もあまり乱さない。
  • 公共施設は素早く開放される。

東北地方の被災地は復旧が大変だと思うけど、本当に頑張ってほしい。 先週は茨城と福島の県境辺りまで旅行に行っていたが、おそらく地震直撃。。 M 8.8 は恐るべし。 関東大震災クラス、というか、観測史上最大だったらしい。 天災を防止することはできないけど、これからどうやって復興していくかが大事。 寄付とかは出来るはずなので、ちょっと考える。 今日は地震酔い (?) のような状態で気持ち悪いので就寝zzz

あと、地震とは関係ないけど、ザッピング中に見つけた感動的な話。 気持ちを切り替えるときに読むと前向きになれそう。

たんぶらうざテキスト
“ 先日、お手伝いさせていただいた結婚式で とっても素敵なキセキが起きました。..."

2011年3月3日

FC東京の2011年カレンダー

今週末はいよいよ J リーグが開幕します!

今年のFC東京は残念ながら J2 ですが、年間チケット (SOCIO) も届いたし、J リーグが運営するマイページへの告知も出た (Jリーグワンタッチパスマイページのオープンについて) し、米本の背番号入りのユニフォームも出来上がった (まだ受け取ってない) ので、後はスカパラのライブとFC東京の開幕ダッシュを観るだけなのですが、開幕戦後のスケジュールを確認し忘れていました。

ということで、iCal ファイルを作って Google Calendar にインポートしました。ガジェット右下の「+ Google カレンダー」をクリックすると自分のカレンダーに登録できるはずです。なお、後半戦はキックオフ時間が未定なので終日予定になっています。

Google Calendar だと...

  • 携帯電話/スマートフォンでも簡単に閲覧できる。
  • 目的ごとのカレンダーを重ね合わせることができる。表示/非表示の切り替えはクリックひとつ。
  • iCal / XML / HTML で出力できるので、再利用性が高い。認証キーを付けて共有も可能。
  • 月曜日始まりにできるから週末の予定は右側に寄っていて、J リーグの試合を概観できる。

ということで、公開された情報を共有するには便利ですね。