sifue's blog

プログラマな二児の父の日常 ポートフォリオは www.soichiro.org

ScalaとSlickで発言数順位表示と名言記録をするIRCボットを作りました

【blog.soichiro.orgの閉鎖にともない転載しました】

最近IRCボットを書いたりすることが多いのですが、また汎用的なものを一つ書いてみたので公開します。今回は初めてORMとしてSlick、組み込みDBとしてH2を使ってみましたが。Slickは内部処理がわかりにくいが関数言語的にかける特徴的なORM、H2はSqliteよりも軽快でWebベースのGUIがデフォルトで用意されていて非常に使いやすい印象でした。

f:id:sifue:20140429120524p:plain

今回のビルド可能なソースコードは、GitHubにて公開しています。

今回作ったRanking Ircbotについて

IRCの発言数ランキングと名言の登録、及び登録数のランキングをチャンネルごとに設定できるIRCのボットです。 複数のチャンネルに参加し、kickされても戻ってきたり、 オペレーター権限を与えられている場合、他の参加者にオペレーター権限を分け与えたりする機能があります。

ビルド方法

java(jdk6以上)とsbt(0.12.2)をインストールの上、

$ sbt
> assembly

以上を実行することで、targetディレクトリの中に、ranking_ircbot-assembly-2.X.jarがビルドされます。

使い方

ranking_ircbot-assembly-2.X.jarと同じディレクトリに、 ranking_ircbot_template.propertiesを正しく編集して、 ranking_ircbot.propertiesというファイル名で保存ください。 さらに、ranking_ircbot_empty.h2.dbを ranking_ircbot.h2.dbという名前に変更してください。

irc.address = hostname
irc.channel = #channelname1 #channelname2
irc.nickname = ranking_ircbot
irc.charset = UTF-8
db.url = jdbc:h2:file:ranking_ircbot
db.driver = org.h2.Driver

以上のようにチャンネルはスペース区切りで複数設定することができます。 日本語のチャンネル名は、native2asciiのwebサービスなどを利用して 入力することができます。

設定の後、

$java -jar ranking_ircbot-assembly-2.X.jar

で実行することができます。 またIRCのボットが入っているチャンネルにて

ping bot_nickname

とするとWorking now.とnoticeを返して動作確認をすることができます。

使い方

ranking_ircbotが参加しているチャンネルにて以下のメッセージを打つと様々な機能が利用できます。

hourlyranking>
1時間の発言数ランキングの表示

dailyranking>
24時間の発言数ランキングの表示

weeklyranking>1週間の発言数ランキングの表示

monthlyranking>
30日間の発言数ランキングの表示

yearlyranking>
1年間の発言数ランキングの表示

覚えろ:{nickname} {message}
そのチャンネルで{nickname}の名言を保存

{nickname} 曰く
そのチャンネルで保存している{nickname}の名言をランダムで発言

消して:{nickname} {message}
そのチャンネルで{nickname}で発言登録された{message}を全て削除

wiseranking>
そのチャンネルで保存されている名言の個数のランキングを表示

ping {ircbot_nickname}
Working now. > {nickname} https://github.com/sifue/ranking_ircbot

と発言します。

 

以上のような機能を持っています。

Slickについて

今までScalaのORMにSquerylを使っていたのですが、今回はじめて、ScalaQueryの後継でtypesafeが作っているORMのSlickがScala2.10で使えるということで使ってみました。

今までのORMっぽくなく、かなり関数型言語っぽく書けるORMです。結構戸惑ったのは

Slickのコード例

 

このようにlist()を一度でも読んでしまうと、count関数がうまく流れないのではと思っていたら、ちゃんとselect count(*)が流れるように最適化されていたりするところが、ちょっとわかりにくかったところでした。

あと、GroupByの書き方がちょっと特殊でした。

Slickのコード例2


のようにタプルで受け取る形式となります。このように短く取り扱おうと思うとタブルで受け取る形式になるので、このへんはうまく書かないとわかりにくくなってしまうかもしれません。確かに短くて済むのですがコードの可読性を保つためにはちょっと工夫が必要かなと思いました。

H2 databaseについて

ダウンロードして、梱包されているh2.shを実行して、dbのURLを入力してログインすると。

f:id:sifue:20140429121245p:plain


以上のようなUIが実行できて、自由に編集することができます。今まで使って来なかったのでこの親切さにおどろきました。すばらしい。
しかも実行速度もsqliteよりも速く、とても気に入ってしまいました。今後もH2は組み込みDBとして利用していければと思っています。