2013/04/12


DSAS開発者の部屋:gitでバイナリファイルを気軽に扱えるフィルターを作りました

gits3 は Python でプロトタイプを作った後、 go で作りなおしました。

http://dsas.blog.klab.org/archives/52105107.html
S3、1年たったらタダちゃうし、Dropbox 使いたいよ... ってことで作ってみました。
mattn/git-dropbox - GitHub

Simulate hg largefile on git with dropbox Introduction When we want to add lar...

https://github.com/mattn/git-dropbox
使い方は DSAS さんのブログと同じです。まずインストール。 $ go get github.com/mattn/git-dropbox ~/.gitconfig.git/config にフィルタを登録します。 [filter "dropbox"]
    clean = git-dropbox store
    smudge = git-dropbox load
そしてリポジトリに .gitattributes というファイルを作り、以下の様にフィルタを割り当てます。 *.png  filter=dropbox
*.jpeg filter=dropbox
*.jpg  filter=dropbox
*.gif  filter=dropbox
あとは普通に git add するだけで、dropbox の Apps/git-store というフォルダに格納されていきます。
初回だけ、ブラウザが自動で起動しますのでそこで許可ボタンを押して頂く必要があります。
ローカルにもキャッシュを持っているので、他のユーザと共有する場合は、~/.gitasset/data というフォルダを rsync しておけばOKです。
もしくは dropbox 側で共有するというのもアリかもしれません。
なお、git-dropbox には -nocache というオプションもあるので、上記フィルタの登録時に [filter "dropbox"]
    clean = git-dropbox -nocache store
    smudge = git-dropbox -nocache load
-nocache を指定しておけばディスク容量が気になる方には良いかもしれません。

ちなみにコマンドラインから
$ git dropbox store fugafuga.txt < fugafuga.txt
$ git dropbox load fugafuga.txt
$ git dropbox drop fugafuga.txt
$ git dropbox list
という使い方も出来ます。
どうぞお役立て下さい。
Posted at by



2013/04/11


golang_bot 先日、Lingr がとてもホットなので「Go言語」部屋を作ったのですが、Lingr のしきたりとして、その開発言語でbotを書くというのがあったので(要出典)、go言語でbotを書いた。
mattn/go-lingrbot - GitHub
https://github.com/mattn/go-lingrbot
機能としては3つ。
  • URL が貼り付けられたらそのページのタイトルをお知らせする
  • !godoc math という発言があれば、math パッケージの説明とドキュメントの URL をお知らせする
  • mattn++ などという発言があれば、カウントアップして通算++数をお知らせする
Google AppEngine で動いてます。

URLボット

まず URL のタイトルをお知らせする部分、Go言語は内部エンコーディングが utf-8 であり、オフィシャルからはキャラクタセットを扱えるライブラリが提供されていません。かつ、Google AppEngine 上で動かすので CGO を使った物も動かせません。しかし mahonia というパッケージが CGO 無しでキャラクタセットを扱えるのでそれを使う事にしました。
mahonia - Mahonia - a character-set conversion library for Go - Google Project Hosting

Mahonia is a character-set conversion library implemented in Go. All data is compiled into the execu...

https://code.google.com/p/mahonia/
得られた HTML をパースして meta タグを調べ、キャラクタセットを得た後に、title タグの内容を utf-8 に変換しています。 if charset == "" && n.Type == html.ElementNode && n.Data == "meta" {
    kv := make(map[string]string)
    for _, a := range n.Attr {
        kv[strings.ToLower(a.Key)] = strings.ToLower(a.Val)
    }
    if v, ok := kv["http-equiv"]; ok && v == "content-type" {
        if v, ok = kv["content"]; ok {
            for _, t := range strings.Split(v, ";") {
                tt := strings.Split(strings.TrimSpace(t), "=")
                if len(tt) == 2 && strings.ToLower(tt[0]) == "charset" {
                    charset = tt[1]
                    break
                }
            }
        }
    }
    if v, ok := kv["charset"]; ok {
        charset = v
    }
}
if n.Type == html.ElementNode && n.Data == "title" {
    if charset == "" {
        charset = "utf-8"
    }
    title = mahonia.NewDecoder(charset).ConvertString(n.FirstChild.Data)
}

Godocボット

GoDoc

Popular Packages bitbucket.org/jaybill/sawsij/framework code.google.com/p/biogo code.google.com/p/go...

http://godoc.org/
github からGo言語のパッケージだけを集めてドキュメントを表示してくれるサイトを利用しました。
このサイトは Accept: text/plain ヘッダを付けて要求すると、テキスト形式で応答してくれる機能があったので、その結果からパッケージの説明を抽出しています。

プラスプラスボット

まず発言から mattn++
mattn--
mattn+=3
mattn-=5
などという発言を抽出します。 var rePlus = regexp.MustCompile(`^\s*([a-zA-Z0-9_{^}]+)\+\+\s*$`)
var reMinus = regexp.MustCompile(`^\s*([a-zA-Z0-9_{^}]+)--\s*$`)
var rePlusEq = regexp.MustCompile(`^\s*([a-zA-Z0-9_{^}]+)\+=([0-9])\s*$`)
var reMinusEq = regexp.MustCompile(`^\s*([a-zA-Z0-9_{^}]+)\-=([0-9])\s*$`)
func parsePlusPlus(message string, callback func(nick string, plus int)) bool {
    if rePlus.MatchString(message) {
        m := rePlus.FindStringSubmatch(message)
        callback(m[1], 1)
        return true
    } else if reMinus.MatchString(message) {
        m := reMinus.FindStringSubmatch(message)
        callback(m[1], -1)
        return true
    } else if rePlusEq.MatchString(message) {
        m := rePlusEq.FindStringSubmatch(message)
        callback(m[1], atoi(m[2]))
        return true
    } else if reMinusEq.MatchString(message) {
        m := reMinusEq.FindStringSubmatch(message)
        callback(m[1], -atoi(m[2]))
        return true
    }
    return false
}
そしてそこから呼ばれるコールバックで、GAE のデータストアに格納します。 parsePlusPlus(event.Message.Text, func(nick string, plus int) {
    plusplus := &PlusPlus{nick, 0}
    key := datastore.NewKey(c, "PlusPlus", nick, 0nil)
    err := datastore.Get(c, key, plusplus)
    if err == nil || err == datastore.ErrNoSuchEntity {
        plusplus.Count += plus
        _, err = datastore.Put(c, key, plusplus)
        results += fmt.Sprintf("%s (%d)\n", plusplus.Nickname, plusplus.Count)
    }
})
最後に通算++数を応答します。


これでだいたい、一般的な bot としての機能は満たせました。Lingr のGo言語部屋に24時間常駐しています。
お好きな様にお使い下さい。
Posted at by



2013/04/09


乱数生成アルゴリズムは数ありますが、省リソースで循環周期の長く、生成速度が速いアルゴリズムとして Mersenne Twister が候補として上げられます。
mruby の Random でも採用されていましたが、先日ライセンスが変更され MIT への書き換えが可能となりました。ありがたいですね。
Mersenne Twisterの商用について

2001年4月6日まで、MTはGNU Public Licenseの元に配布していましたが、 多くのユーザーから「販売用プログラムに組み込むことができない」という お便りをいただきました。

松本-西村はMTを販売用プログラムにも自由に使っていただこうと決めています。 そのため、GNU Public Licenseよりも条件のゆるい"BSD License" に準拠したLicenseの元に2002年版コードmt19937ar.c, mt19937ar-cok.cは配布されています。

また、MITライセンスに書き換えて配布してくださっても結構です。

http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/license.html
組み込み用途での利用障壁がなくなり、商用利用も可能となりました。

ちなみに Mersenne Twister は Vim script にも既に移植されていて
vim-funlib/autoload/random/mt19937ar.vim at master - ynkdir/vim-funlib - GitHub
https://github.com/ynkdir/vim-funlib/blob/master/autoload/random/mt19937ar.vim
簡単に乱数を得る事が出来ます。変態ですね。
call random#mt19937ar#seed(123)
echo random#mt19937ar#random()
Posted at by