κeenのHappy Hacκing Blog | Lispエイリアンの狂想曲

RSPiでMongoDBを動かし、Twitter Post Alertを作った話

κeenです。ここのところ寒い日が続いてますね。寒いと家に扃(ひきこも)ってTweet数が急上昇します。 すると一日に何postしてるか気になるのでカウンタを作りました。
そのときの苦労話です。

ただ、どうせ記録取るなら色々やりたいのでRspberry Piで一日のpost数、fav数、そしてメンヘラなことにフォロー/フォロワー全員のidを毎日記録することにしました。これで誰にリムられたかブロられたか一目瞭然ですね。

ここで一つ問題が。post, fav数は良いのですがフォロー/フォロワーのid一覧は毎日変わるのでmysqlで管理するのはちょっと面倒かなと。なのでMongoDBで管理することにしたいんですが、raspbianのaptにないんですよね。仕方ないので手動ビルドで対応しました。

MongoDBのビルド

ここを参考に

cd ~/compile
sudo apt-get install build-essential libboost-filesystem-dev libboost-program-options-dev libboost-system-dev libboost-thread-dev scons libboost-all-dev python-pymongo git
git clone https://github.com/skrabban/mongo-nonx86
cd mongo-nonx86
sudo scons

としました。が、sconsに一晩かかるとのことなので放置してたら何故かraspberry piが落ちてる…
気をとりなおして再起動。もう一度sudo sconsすると今度はエラー終了。sig 9 killed…いや、私なにもしてないですよ?ダメ元で今度は

sudo scons install

したら完走。良ク分カラン。狂想曲感が出てますね。

MongoDBのインストール

さっきのでインストール終わったと思うでしょ?違うんですよ。init.dだとかmongodb.confだとかは配置されてないんですよ。debian/以下に色々入ってるので

cd debian
sudo cp mongodb.conf /etc/mongodb.conf

までは良いのですが、init.dmongodb.upstartmongodのパスが/usr/bin/mongodでハードコードされてるんですよ。上のsudo scons installだと/usr/local/bin/mongodです。さらに起動オプションに--dbpadh /var/lib/mongodb--logpath /var/log/mongodb/mongodb.logが指定されていて、mongodb.confで上書きしているにも係らずそこまでのパスが存在しないとエラー吐いて起動してくれないので修正。
mongodb.upstartは直ぐ分かるので良いとして、init.d

1
2
3
4
5
6
7
8
9
10
48d47
< 
50c49
< DAEMON=/usr/bin/mongod
---
> DAEMON=/usr/local/bin/mongod
100c99
< DAEMON_OPTS="$DAEMON_OPTS --config $CONF"
---
> DAEMON_OPTS="run --config $CONF"

な感じの修正です。なんか空行が一つ減ってますが気にしない。
ここまでしたらようやく

chmod +x init.d mongodb.upstart
sudo cp init.d /etc/init.d/mongodb
sudo cp mongodb.upstart /etc/init/mongodb

で完了です。manとかもあるのですが配置の仕方が分からないので放置←

sudo service mongodb start
mongo

で接続確認できます。

Twitterのpostを集約する

ビックリするくらい簡単。twitterのAPI keyを持ってる前提ですが。

sudo gem install twitter mongo

で必要なgemをインストールし、~/.twitter.rb

1
2
3
4
5
6
$client = Twitter::REST::Client.new do |conf|
 conf.consumer_key = "yours"
 conf.consumer_secret = "yours"
 conf.access_token = "yours"
 conf.access_token_secret = "yours"
end

と保存しておきます。昔と形式が変わりましたね。この形式になってからスレッドセーフになり、Twitter Stream APIにも対応してるようです。いつか扱ってみたい

集計ですが

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#! /usr/local/bin/ruby
# coding: utf-8
require 'twitter'
require 'mongo'
require 'time'
load "~/.twitter.rb"

doc = { "tweets" => $client.user.tweets_count,
 "favs" => $client.user.favorites_count,
 "followers" => $client.friend_ids.to_a,
 "friends" => $client.follower_ids.to_a,
 "timestamp" => Time.now.strftime("%Y%m%d%H%M%S")}
col = Mongo::Connection.new.db("twitter").collection("tweets")
last = col.find.sort(["timestamp",:desc]).first

tweets_sub = doc["tweets"] - last["tweets"]
favs_sub = doc["favs"] - last["favs"]
followers_sub = doc["followers"].length - last["followers"].length
friends_sub = doc["friends"].length - last["friends"].length
col.insert doc
message = "前回計測(#{Time.parse(last["timestamp"]).strftime "%Y-%m-%d %H:%M:%S"})以降\n"
message += "#{tweets_sub}回ツイートし\n"
message += "#{favs_sub}回favり\n"
message += "友達は#{friends_sub.abs}#{friends_sub >= 0 ? "増え" : "減り"}\n"
message += "フォロワーは#{followers_sub.abs}#{followers_sub >= 0 ? "増え" : "減り"}ました"
$client.update message

で全部です。Rubyのハッシュ+配列がそのままinsert/selectできるのでぜんぜんMongoDBを意識しなくて良いですね。

ところでdatetime型が無さげだったのでtimestampをソートキー兼idにするためにYYYYMMDDHHMMSS形式の文字列で格納してます(整数は8bitまでっぽかったです)。他に良い方法があると思うのですが思いつきませんでした。

Written by κeen
Later article
Mpd 小ネタ