CakePHPのShellでtwitterのログを保存する
ふと思い立って書いてみたので適当にメモしておきます。
CakePHPコアライブラリの使い方の勉強を兼ねてやりました。
table
適当にテーブルを作ります。
+------------+---------------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+---------------------+------+-----+---------+----------------+ | id | int(10) unsigned | NO | PRI | NULL | auto_increment | | status_id | bigint(20) unsigned | NO | | NULL | | | text | text | NO | | NULL | | | created_at | datetime | NO | | NULL | | +------------+---------------------+------+-----+---------+----------------+
model
テーブルから最新のstatus_idを取得するメソッドとAPIからのレスポンス配列を整形してsaveAllするメソッドを定義しています。
<?php class TwitterLog extends AppModel { var $name = 'TwitterLog'; function getSinceId() { $this->order = 'TwitterLog.id DESC'; $latestStatus = $this->find(); if ($latestStatus) { return $latestStatus['TwitterLog']['status_id']; } return false; } function saveStatus($statuses) { foreach ($statuses as $status) { $dateTime = date('Y-m-d H:i:s', strtotime($status['created_at'])); $data[] = array( 'status_id' => $status['id'] , 'text' => $status['text'], 'created_at' => $dateTime ); } return $this->saveAll($data); } }
shell
XmlとHttpSocketを使用します。最初にinit()を実行することでこれまでのつぶやきを全て(APIの制限内で)保存します。
<?php App::import('Core', array('Xml', 'HttpSocket')); class TwitterLogShell extends Shell { var $uses = array('TwitterLog'); const API_URL = 'http://twitter.com/statuses/user_timeline.xml'; const USER = 'username'; const PASS = 'password'; function startup() { $this->sock =& new HttpSocket(); $this->request = array( 'auth' => array( 'user' => self::USER, 'pass' => self::PASS ) ); } function main() { while (true) { $query = array( 'since_id' => $this->TwitterLog->getSinceId(), 'count' => 200 ); $ret = $this->_getStatus($query); if (empty($ret['Statuses']['Status'])) break; if (empty($ret['Statuses']['Status'][0])) { $statuses[] = $ret['Statuses']['Status']; } else { $statuses = array_reverse($ret['Statuses']['Status']); } $this->TwitterLog->saveStatus($statuses); } } function init() { $query = array('count' => 1); $ret = $this->_getStatus($query); $statusCount = $ret['Statuses']['Status']['User']['statuses_count']; $page = ceil($statusCount/20); while ($page > 0) { $query = array('page' => $page); $ret = $this->_getStatus($query); $statuses = array_reverse($ret['Statuses']['Status']); $this->TwitterLog->saveStatus($statuses); $page--; } } function _getStatus($query) { $res = $this->sock->get(self::API_URL, $query, $this->request); $xml = new Xml($res); $array = $xml->toArray(); $xml->__killParent(); $xml->__destruct(); $xml = null; unset($xml); return $array; } }
あとはcrontabで下記の様なコマンドを適当なタイミングで実行すれば自分のつぶやきログがDBに保存されていきます。
CAKE_DIR/console/cake twitter_log -app APP_DIR