Hubot ping の日本語化 — 「いるのか?」の正規表現

Hubot の ping コマンド

hubot_wapuuSlack というコミュニケーションツールを利用することになって、そこでこれは便利かもということで Hubot をいじってみています。

現時点での安定版 Debian Wheezy に Hubot をインストールするにはどうすればいいんだとか、Slack に連携させるときに Heroku を使う方法ならすぐに見つかるが、自前ホストのHubotとSlackを連携させるにはどうするんだとか、いくつか引っかかりながらも、ここにリンクした情報が既にあったのでうまくいきました。

この bot がちゃんと作動しているかどうか反応を見るのに、ping というコマンドがはじめからサンプルとして付属しています。bot の名前に ping と付けて問いかけると、PONG と答えるというものです。

user> hubot ping
hubot> PONG

さて、「HubotのScriptを翻訳するとかわいい」にありますように、日本語化すると愛着がわきます。ping の Script はとても簡単で、肝は

  robot.respond /PING$/i, (msg) ->
    msg.send "PONG"

です。使用目的はとにかく存在確認ですから、日本語にすると

  robot.respond /いるのか\?$/i, (msg) ->
    msg.send "はい、ここにいます!"

です。

また、Hubot を起動するときに bot 自身の名前と別名を付けることができます。そこでこれを日本語で

bin/hubot --name wapuu --alias わぷー

と付けてやると、ますます親しみがわきます。これで応答は

user> わぷー いるのか?
wapuu> はい、ここにいます!

となりました。

「いるのか?」のバリエーションの正規表現

このままですと、script の質問文のところは正規表現で書けるのに、ただ「いるのか?」に正確にマッチしないと返答しないということになっています。

「いるのか?」の分解存在確認の日本文「いるのか?」を考察してみます。これを4つ(疑問符を入れると5つ)に分けて、それぞれのバリエーションとその組み合わせを思いつくまま挙げてみました(図)。ありえない組み合わせ—たとえば、2段目が「ります」のとき、その前に「い」はありえない—の制限を付け加えながら、正規表現にして書いてみると、次のようになりました。

/(((い|ゐ|居)(て?))(?!り)|(お|を|居)|((い|居)(て?)は)(?!ま))((る|ん(?=の))|((り?)ます)(?!ん))((の?ん?)(です)?|(んだ)(?!か))?(か(い?な?|よ|ね)?|(よ?)(ね|な))?\s?(\?|?)/

これで、質問文は「いる?」から「いてはりますのんかいな?」(いや、これが現実にありうる表現かどうか確証は持てないのですが)まで対応できます。

ping の目的は存在確認なので、日本語では「生きてる?」とも言いそうです。1段目の前に「生きて」を付けて、元の1段目を必須から任意に変更すればよさそうです。さらに、「調子どう?」「元気?」というフレーズもよく使いそうですね。これはもうそのままということにします。だんだん手抜きになってきました。

結局、日本語版 ping はこうなりました。

  robot.respond /(((い|ゐ|居)(て?))(?!り)|(お|を|居)|((い|居)(て?)は)(?!ま))((る|ん(?=の))|((り?)ます)(?!ん))((の?ん?)(です)?|(んだ)(?!か))?(か(い?な?|よ|ね)?|(よ?)(ね|な))?\s?(\?|?)/i, (msg) ->
    msg.send "はい、ここにいます!"

  robot.respond /(い|生|活)きて(((い|ゐ|居)(て?))(?!り)|(お|を|居)|)?((る|ん(?=の))|((り?)ます)(?!ん))((の?ん?)(です)?|(んだ)(?!か))?(か(い?な?|よ|ね)?|(よ?)(ね|な))?/i, (msg) ->
    msg.send "はい、ここにいます。"

  robot.respond /(調子どう|元気)/i, (msg) ->
    msg.send "はい、元気です。"

wapuu_pingちゃんと数えていませんが、これで「いるのか?」を意味する数十種類の表現に答えることができるようになりました。

このWapuu bot は、WordPress の日本語コミュニティがこれから活用していこうとしている Slack にいます。WordPress 本体の開発元でこの Slack を使っていくことになったことに触発され、そこに収まりきれない話題—日本語圏特有の話題、日本語で話したほうが楽な話題など—を扱っていこうという場所です(たぶん)。単に「WordPressの使い方」を尋ねるような場所ではありませんが、何かちょっとでも手助けしたい(日本語圏で最も求められているのはたぶん翻訳です。本体のみならず多くのドキュメントやニュースなどが翻訳されるのを待っています。もちろんほかにも何かがあります。たとえばこの記事のように、どうでもいいような冗談を仕込むとかもきっと)と思っている方があればぜひ参加してみてください。参加資格などなく、参加方法の手続きを踏めさえすれば誰でも参加できます。Wapuu bot はそこで待っています。

昨年のクリスマスプレゼント「ビルダーキット テクノ ツールボックス」

今年もそろそろサンタクロースの代理としてクリスマスプレゼントを考えなければならない時期になりました。昨年のプレゼントを思い出してみますと……。

当時5歳のスウちゃん(仮名)に届いたのは、Quercetti の「ビルダーキット テクノ ツールボックス」。しばらく前から、大人がちょっとした家具を組み立てたり自動車のタイヤを交換したりするときに「スウちゃんも!」とスクリュードライバーやスパナを持ちたがるので、こういうものにしてみました。

難易度はそれほど高くなく、前年(4歳)の Zometool と順番が逆だったかなという感じも少ししましたが、これはこれで非常に楽しんでくれました。

簡単な作成例(完成図のみ)の冊子が付いていて、はじめはそれをまねて作っていました。徐々にオリジナルの車や、収納箱の蓋(たくさん穴が開いていてネジがきってある)に平面状に絵を作ったり。

場所によって適切な長さを選ぶとか、その頭のミゾに合わせて工具を変えるとか、さらにナットを締めるときに反対側のボルトも工具で押さえておかなくてはならないというような、どうかすると大人でもうっかりしそうな技を習得しつつあります。

プラスチック製のボルトとナットで(ほかのパーツや工具もすべて)、車のハンドルなど可動部はすぐに緩んできてしまうのがやや難ですが、逆にこれがきっちり締まるようになっていると、幼児の手ではとれなくなってしまうのかもしれません。

ドミノとさんすう

ドミノ

スウちゃん(仮名、6歳)は保育園から帰るととにかく「遊びたい」。眠っていないあいだはとにかく遊び続けなければ死んでしまうというくらい遊びたい。といって家や近所に子どもはいないから、一人遊びじゃなければ大人が相手をすることになる。いろんなゲームもやってきた。カルタ、すごろく、どうぶつしょうぎ、オセロ……。そして最近の流行はドミノだ。

【DOMINO W6 in The Wooden Box】木箱入プラスチック製ドミノ W6 白黒Premium Set of 55 Double Nine Dominoes with Wood Case, Brown いまうちにあるのは私(=スウちゃんの父)が学生の頃に麻雀牌も売っているようなおもちゃ屋で買ったもの。でもいま日本でちゃんとしたもの[1]はあまり売っていなさそうだ。「木箱入プラスチック製ドミノW6白黒」だと真ん中に鋲がないなあ。Amazon USA のダブル・ナインは鋲あり。日本から買うと送料が本体と同じくらいかかってしまう。

ルールは「ファイブ・アップ」(参考1参考2)。

しばらくは点数関係なしで、札の出し方を学習。ゲームとなれば子どもは簡単に覚える。

続いてプレイ中の得点。どれを出せば得点になるかなんて戦略もないのでとにかく出せるものを出す。たし算ができないので、出したものを大人が計算してやる。「5の倍数だったら、5で割った商が得点」なのだが、意外に早く5の倍数を覚える。「15」→「3点!」、「20」→「4点!」のように[2]

終了時は「相手の手に残った目の合計を5で割った値(うちでは端数切り捨てというローカルルール)」でやっているが、これも合計を大人がやってやれば「その中に5はいくつ入ってる?」と聞けばほぼ得点を出せる。九九で言えば「5の段」が、それも九九とは全然別の形で頭に入っているらしい[3]。ゲームだとこんなことまでできるんだなあ。

まともな勝負には程遠いが、とりあえずなんとかゲームの体をなすことはできる。さて、大人は手札を元に計算しながら出せるので、強い。同じ札でもあっちに出せば得点できるのにこっちに出すと得点できないということも起こる。子どもはだんだん悔しくなってくる。ここで「たしざんができるようにならないとつよくなれないねー」ということになる。

たたみかけるように、ここでダブル・ナインのセットに替えて同じゲームをやると目の数がぐっと増えるので、それまではたし算できなくても目を数えあげて何とか出来ていたものも追いつかなくなり、いよいよ悔しさをつのらせる。

さんすう

1年ほど前、何の拍子だったか忘れたけれど数に興味を示して、そのうち「同じ数を2回」、つまり「2と2は4」「3と3は6」「4と4は8」……を言えるようになっていた。九九で言えば「2の段」に相当する。せっかくそういう興味が出てきたのならちゃんとやってあげようか、などと考えて、道具を揃えてみた。

カラフルマスキューブ テキストには「わかるさんすう 1」。かなり古くまた検定は通しはしないけれど「教科書」としてしっかり練られたものということを知っていたので、これにしてみた。Amazon では手に入りにくいが、ふつうに街の本屋さんで注文したら簡単に入手できた。

わかるさんすう 1」では、「タイル」を使う。手作りでもいいけれど、横着して買うことにした。「タイル」ではなくて「キューブ」。似たような商品もあるが、安さと、それに「接続できる」ということでこれにした。またちょっと別のもので「100だまそろばん」というのもよく評判を聞くが、やはり自由さの点でキューブにした。

2カラーせんせい 紙が潤沢に使えるのであればそれがいいのだろうけれど、きりがないのでうちではもっぱらおえかきボードを活用している。

いまは2色の「2カラーせんせい」なんだな。うちにあるのはおさがりでもらった「スーパーせんせい」で1色のもの。元の持ち主は4歳くらいでもう飽きて遊ばなくなったからと、スウちゃんが1歳か2歳のころにもらったものだが、うちではいまだ現役。でもこういう用途だと、もうすこし画面が大きく、また解像度が高いといいなと思う。

さてさて、今から1年ほど前にこうして「さんすう」をやりかかってみたけれど、スウちゃんははじめのあいだはともかく、ほどなく興味を失ってしまった。こちらも是が非でも早期教育をとも思っていなかったし、ただ、もし数に興味を示すのなら(ほら数学の天才は幼児期からそうだと言うでしょう)その芽を摘まなくても、という程度の考えだったので、めったに日の目を見なくなっていた。つまりスウちゃんは数学に関しては天才ではなかったわけだが。

ふたたび「さんすう」

時は戻ってふたたび現在。ドミノのおかげで、たし算をできるようになりたい、という気がスウちゃんに俄然湧いてきた。こうなると見向きもしなかったテキストとキューブ(ブロック)に取り組み始める。

いまは

  • 5-2進法は強くこだわらないことにする。本人がどちらが楽かまだわからないので。
  • たし算を同時にひき算も教える。「7は5と2だから……」のように、たし算の過程でひき算に相当する部分が出てくるので。
  • ほとんど最初から筆算(縦書き)にする。この先の繰り上がりを見据えて。
  • 適宜ブロックを使う。
  • いまのところ、素過程を網羅的に、とは考えない。これは「水道方式」のいいところを落としているのかもしれないけれど。少し先にひき算(13−7など)をやるときに困るかもしれない。そのへんは行きつ戻りつやればいいか。
  • 文章題も適宜。逆に「たし算の問題を作る」ような作業も多めに。

という感じで進めている。

自由な発想

スウちゃんはすごろくなどのゲームやドミノでサイコロ(の目の形)に親しんでいたからか、「6は3と3」の意識が強い。5-2進法のための「6は5と1」とはなかなかならない。そこで「6+3」を計算する際はブロックを3×2に並べ、そこに3つのブロックを加えて3×3の形にし、「こたえは9」になる。どうやらイメージ先行らしい。

この先の発展のためにはどうかとも思うが、まだカリキュラムに沿った学習をしていない子どもの発想は自由でおもしろい。「8−2」は、まず2×2×2の立方体を作って「8」。なんだそれ。3次元じゃないか。2の3乗だよ。それから2つをとり、変形させて3×2にして「6」。このへんはボール紙で作ったタイルじゃなくて、縦横に接続できるカラフルマスキューブにしていたからこそだったかもしれない。

世の中、算数だけで出来ているわけではないから、小学校に入って型通りの授業が始まるまではこの自由な発想を楽しむことにしよう。

さて、こんな調子でスウちゃんはドミノが上手になれるだろうか。

  1. と言っても、うちのもさすがに象牙製ではない。ドミノ倒し用ではなく樹脂製の適度な重みのもの。
  2. これと同時期に時計の分針を読めるようになり、「ドミノといっしょ!」と叫んでいる。
  3. いまの段階で九九の暗誦なんて絶対にやらせたくない。

リモートに置いてある音楽ファイルをローカルPCのスピーカーで鳴らす

以前に「インターネットラジオを FM ラジオで聴く」というのを書きました。少し離れた場所にあるマシンにFMトランスミッターを付け、目の前のPCから操作する(そしてFMラジオで聴く)というものでした。

それから月日は流れ、ハードウェアを入れ換えたり、その際にOSもすっかりインストールし直したりしているうちに、そのリモートのマシンでの音声出力ができない状態になってしまいました。

そこで前回とは逆に「リモートに置いてある音楽ファイルをローカルPCのスピーカーで鳴らす」というのが、今回やりたいことです。目新しいことは何もなく、既に情報がどこかにあったので楽でした。自分のためのメモも兼ねてここに書いておきます。

先にまとめておくと、

  • リモート
    • 音楽ファイルが置いてある
    • Pulseaudio
    • MPD
  • ローカル
    • スピーカーが接続されている
    • Pulseaudio
    • gmpc

という構成になります。

Pulseaudio

ここではリモートもローカルも OS は Debian (これを書いている時点での安定版)です。

まず、ローカルで

sudo apt-get install pulseaudio
と pulseaudio をインストールし、

paplay local-sample.ogg

などとやってちゃんと動いていることを確認します。ところがここで音が出ませんでした。

sudo apt-get install pavucontrol

とやって pavucontrol で、「出力装置」を見ると、ポートが「HDMI」になっていました。ここの環境ではそこにスピーカーはなく、USBポートにサウンドアダプタを挿してその先にスピーカーがある状態です。「設定」で、GF108 High Difinition Audio Controller が HDMI になっているので、これを Off にすると、「出力装置」のポートが「スピーカー」または「デジタル出力(S/PDIF)」になって、音が出るようになりました。

リモートとローカルの Pulseaudio の設定

ローカルの /etc/pulse/default.pa で、

load-module module-native-protocol-tcp auth-ip-acl=192.168.1.0/24

リモートの /etc/pulse/client.conf で、

default-server = 192.168.1.xxx (スピーカーのあるPC)

とします。必要に応じてローカルのポート 4713 を開けます(今回のローカルPCはファイアーウォールを置いていないので特に設定の必要なし)。

テストとして、リモートで

paplay remote-sample.ogg

などとやるとローカルのスピーカーが鳴ります。

MPD

当初の目的は達成されましたが、このままでは不便なので、MPD を使うことにします。これは音楽再生やプレイリスト管理をリモートから行うためのものです。

リモート

まず

sudo apt-get install mpd

でインストールします。/etc/mpd.conf で、music_directory に音楽ファイルの置いてあるディレクトリを設定し、bind_to_address に接続を許すアドレス(今回は(LAN内の)どこからでも接続できるよう “any” としました)を設定します。

出力先の設定は

audio_output {
        type            "pulse"
        name            "My Pulse Output"
#       server          "remote_server"         # optional
#       sink            "remote_server_sink"    # optional
}

とします。ここで mpd を再起動します。

ローカル

ローカルPCには、gmpc をインストールして使います。これは高機能で、細かな設定やプレイリストの管理を行うことができます。ふだんは、再生/ポーズ/停止くらいの操作しか必要ではないので、シンプルな xfce4-mpc-plugin をパネルに置いてこれを使うことにします。

sudo apt-get install gmpc xfce4-mpc-plugin

どちらも、ホストとして MPD を動かしているリモートのマシンを指すように設定します。

Spamhaus に登録されていないか自動で定期的にチェックする方法

メールサーバーを自前で運用しています。その IP アドレスがときどき Spamhaus のリストに載ってしまうことがあります。もちろんこの自前サーバーは Spam 発信源ではありません。

Spamhaus の Blocklist Removal Center にアクセスして確認できます。どうやら自分の IP アドレスを含む xxx.xxx.xxx.xxx/15 が一網打尽にされてしまったようでした。リストから削除してもらうには、そのページから所定の手続きを踏みます。

が、はじめにリストに載ってしまったかどうか気づくのが難しいのです。メールを出しているつもりが相手に届かないという状況はなかなか気づけません(電話をかけて、自分の耳元では「プルルル…」と鳴っているのに実はどこにも繋がっていない状況を想像してみてください。ふつうは、単に相手が出ないとか相手の機器に問題があるとか、とにかく受け手に何か問題があるのだと思い、まさか呼び出してさえいないとは思わないでしょう)。相手先のサーバーからエラーメッセージでも返ってくればまだましなのですが、黙って無視するだけという場合もよくあります。今回はメール以外でもよく連絡をとっている相手に、たまたま別の手段で連絡をとった際に発覚しました。

広範囲のリスト掲載の巻き添えを食らうのは 10年ほどのあいだに2,3回という頻度なので、まさに忘れた頃にやってくるという感じです。上述の Blocklist Removal Center にアクセスして確認すればいいのですが、そうしょっちゅうもやっていられません。

自動的・定期的にチェックする方法はないかと探してみたら、FAQ に How do I check my DNS server results? というのがありました。

自分の IP アドレスがたとえば 203.0.113.50 だとしたら、それを逆さまにして .zen.spamhaus.org を付け足したものを DNS で検索します。

dig +short 50.113.0.203.zen.spamhaus.org

何も返事がなければ、リストに載っていません。

もし 127.0.*.* の返事があれば、リストに載っています(その意味は FAQ の What do the 127.*.*.* Return Codes mean? を参照のこと)。

というわけで、この1行を cron で定期的に実行して様子を見ることにしました。

『サイトの拡張性を飛躍的に高める WordPressプラグイン開発のバイブル』

事前にレビューする機会を与えられた書籍『サイトの拡張性を飛躍的に高める WordPressプラグイン開発のバイブル』が発売されました。

タイトルのとおり「プラグイン開発」に焦点を当てたもので、これまでの WordPress 関連書籍と一線を画しています。

まえがきに「開発者をターゲットとした WordPress の専門書」とあり、WordPress 固有のプラグインの仕組みの解説はもちろん、WordPress プラグイン開発に適した環境の構築から、コーディング規約、テスト方法まで、懇切丁寧に書かれています。これらをまとめて一瞥できるのは大変ありがたいことです。

WordPress の特徴としての GPL についてもひとつの章を充ててじっくりと説明されています。その上でのビジネスモデルにも言及されており、一読の価値があります。

そして開発したプラグインを公式ディレクトリで公開する方法も紹介されています。評者はこの本の出る少し前に初めて公開を前提としてプラグインを書き、公式ディレクトリに登録してみました。まったく大したものではありませんが、「公開」を念頭に置くと適当なことはできないので、ウェブであちこち検索して回ってできるだけきれいに、間違いのないようにとあらためて勉強することになりました。そのときにこの本があればかなり近道ができたはずです。

さて発売前のレビューの際に、細かな用字の指摘のほかにもやや大きな修正や加筆を必要とするようなコメントを著者に返しました。前者はともかく後者については、たぶん時間的にも分量的にも制約が大きかったのでしょう、残念ながら反映してもらうことができなかったものがありました。

そのひとつが、第8章「管理画面」の特に8-3節「管理画面を使って独自の設定を保存する」についてです。著者たちがあまりにプラグイン開発の経験に富んでいて、ずっと以前から WordPress に精通しているためか、旧来の手法による記述になっています。古いプラグインを読んで理解するにはいいかもしれませんが、これから新たに開発する場合にはこの箇所の記述のようにする必要はありません。WordPress の現在のバージョンには、より簡便で安全な手法 (Setteings API) が用意されています。せっかくこの年になって出版される日本語で初めて(たぶん)のプラグイン開発の解説書ですから、ぜひ Settings API に触れてほしかった—というか現状の8-3節と差し替えてもいいくらいでは—と思います。

そういった点はあるにしても、全体にこの本から受けることのできる恩恵は大きなものがあります。

評者は WordPress の単なるユーザーとなってから数年の時間が経過していますが、実際にプラグインを作ってみること、それも公開しても恥ずかしくないように書いてみることをやってみてはじめて、それまで適当にしか理解していなかったことについてもきちんと知る必要が出てきて、学ぶことが非常に多くありました。その経験をとおして WordPress そのものについての理解、ほかの人たちが作った便利なプラグインについての理解がかなり深まりました。

そういった意味で、この本が「ターゲットはプラグイン開発者」と謳っていても、一般のユーザーも手にとって読んでみるといいと思います。そして簡単なものでもいいので(最終的には公式ディレクトリに登録はしないにしても)「正しい」作法でプラグインを書いてみると、 WordPress をより理解し活用することにつながるでしょう。

MediaWiki のスパム対策

ほとんど放置気味の Wiki に、適当なアカウントが登録されては長文(ドイツ語)のページが作られる、というのがここ数日続いていました。見にくる人はほとんどいないし、その作られたページはさらにどこからもリンクされていないし、まったく誰にも何の得もない所業だと思うのですが、放っておくわけにもいかず、ちまちまと削除していました。

この Wiki は MediaWiki で運用しています。最近の MediaWiki には最初から ConfirmEdit という拡張機能が同梱されています。この機能の SimpleCaptcha というものを以前から有効化していました。これは、アカウント作成時や新規ページ作成時に、簡単な数式(足し算や引き算)の答を入力させるというものでした。にも関わらず変なアカウントやページを作られていたわけですから、スパムボット(いやまさか人力ではあるまい)はこれに対応したものだったようです。

数日続いたのでだんだん嫌になり、同じ ConfirmEdit の QuestyCaptcha を使うように、設定を変更しました。

LocalSettings.php の記述は

require_once( "$IP/extensions/ConfirmEdit/ConfirmEdit.php" );
require_once( "$IP/extensions/ConfirmEdit/QuestyCaptcha.php");
$wgCaptchaClass = 'QuestyCaptcha';
$wordarr = array (
        "日本語で質問に答えてください。質問1" => "答え1",
        "日本語で質問に答えてください。質問2" => "答え2",
        "日本語で質問に答えてください。質問3" => "答え3",
        "日本語で質問に答えてください。質問4" => "答え4",
        "日本語で質問に答えてください。質問5" => "答え5",
);
foreach ( $wordarr as $key => $value ) {
        $wgCaptchaQuestions[] = array( 'question' => $key, 'answer' => $value );
}

$wgCaptchaTriggers['edit']          = true; 
$wgCaptchaTriggers['create']        = true; 
$wgCaptchaTriggers['addurl']        = true; 
$wgCaptchaTriggers['createaccount'] = true;
$wgCaptchaTriggers['badlogin']      = true;

のようにします。質問はランダムに表示されます。質問と答を日本語とすることにより、日本語話者かどうかの判定も兼ねるようにしました。

しかしこの設定は、管理者の負担を善意のユーザーに転嫁するものでもあります。そのようなユーザーには CAPTCHA を求めないように、

$wgCaptchaWhitelistIP = array('192.168.0.0/24'); // 安全な接続元を IP アドレスで指定
$ceAllowConfirmedEmail = true; // メールアドレスを確認済みのユーザーは安全とみなす

も設定しておくことにします。

これでしばらく様子を見ることにします。